jarvis-cloud / webar /assets /ar-init-CRpYWfiK.js
Jarvis2345's picture
deploy(S4): Blender headless pipeline + WebAR client + backend fixes (part 2)
4ec6735 verified
Raw
History Blame Contribute Delete
300 kB
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["./StereoEffect-8X11TNUP.js","./three-DMwvpBUV.js","./rolldown-runtime-CEoa-xHZ.js","./physics-Bz_ouFt8.js","./ort.bundle.min--hz_0CH4.js","./mediapipe-Ck-u_eH7.js"])))=>i.map(i=>d[i]);
import{n as e,r as t,t as n}from"./mediapipe-Ck-u_eH7.js";import{$ as r,A as i,B as a,C as o,D as s,E as c,F as l,G as u,H as d,I as f,J as p,K as m,L as h,M as g,N as _,O as ee,P as v,Q as te,R as ne,S as re,T as ie,U as y,V as b,W as ae,X as x,Y as oe,Z as se,_ as ce,_t as le,a as ue,at as de,b as fe,bt as pe,c as me,ct as he,d as ge,dt as _e,et as ve,f as ye,ft as be,g as xe,gt as S,h as Se,ht as Ce,i as we,it as Te,j as Ee,k as De,l as Oe,lt as ke,m as Ae,mt as je,nt as Me,o as Ne,ot as Pe,p as Fe,pt as Ie,q as Le,rt as Re,s as ze,st as Be,tt as Ve,u as He,ut as Ue,v as We,vt as Ge,w as Ke,x as qe,y as Je,yt as Ye,z as Xe}from"./three-DMwvpBUV.js";var Ze=4;function Qe(e){return document.getElementById(e===`error`?`error-host`:`banner-host`)}var $e={error:`M12 8v5M12 17h.01`,banner:`M12 16v-5M12 8h.01`};function et(e){let t=`http://www.w3.org/2000/svg`,n=document.createElementNS(t,`svg`);n.setAttribute(`class`,`panel-ico`),n.setAttribute(`viewBox`,`0 0 24 24`),n.setAttribute(`fill`,`none`),n.setAttribute(`stroke`,`currentColor`),n.setAttribute(`stroke-width`,`2.3`),n.setAttribute(`stroke-linecap`,`round`),n.setAttribute(`aria-hidden`,`true`);let r=document.createElementNS(t,`circle`);r.setAttribute(`cx`,`12`),r.setAttribute(`cy`,`12`),r.setAttribute(`r`,`9`);let i=document.createElementNS(t,`path`);return i.setAttribute(`d`,$e[e]||$e.banner),n.append(r,i),n}function tt(e,t,n,r={}){let i=Qe(e);if(!i)return null;let a=document.createElement(`section`);a.className=`${e===`error`?`error-panel`:`banner-panel`} glass-panel`,a.setAttribute(`role`,e===`error`?`alert`:`status`);let o=et(e),s=document.createElement(`div`),c=document.createElement(`p`),l=document.createElement(`strong`);l.textContent=t,c.textContent=n,s.append(l,c),a.append(o,s);let u=document.createElement(`button`);if(u.type=`button`,u.className=`panel-x`,u.setAttribute(`aria-label`,e===`error`?`Dismiss error`:`Dismiss notice`),u.textContent=`×`,u.addEventListener(`click`,()=>a.remove()),a.appendChild(u),r.linkHref){let e=document.createElement(`a`);e.href=r.linkHref,e.textContent=r.linkLabel||`Open settings`,e.rel=`noopener`,e.style.display=`inline-block`,e.style.marginTop=`8px`,s.appendChild(e)}for(i.prepend(a);i.children.length>Ze;)i.lastElementChild?.remove();return r.timeout!==0&&window.setTimeout(()=>a.remove(),r.timeout||(e===`error`?9e3:4500)),a}function C(e,t=`AR Error`,n={}){return tt(`error`,t,String(e||`Unknown AR error.`),n)}function w(e,t=`JARVIS AR`,n={}){return tt(`banner`,t,String(e||``),n)}var nt={live:[`ok`,`Live`],stream:[`ok`,`Live`],requesting:[`warn`,`Asking permission`],standby:[`idle`,`Standby`],failed:[`error`,`Unavailable`],"slam+floor":[`ok`,`Full`],"8thwall-slam":[`ok`,`Full`],"8th wall":[`ok`,`Full`],"basic floor":[`ok`,`Basic`],"webxr/basic":[`ok`,`Basic`],"basic camera":[`ok`,`Basic`],"no face mesh":[`warn`,`Limited`],"no object detect":[`warn`,`Limited`],waiting:[`warn`,`Finding surfaces`],lost:[`error`,`Lost`],linked:[`ok`,`Linked`],offline:[`error`,`Offline`]},rt={ok:`#48e08a`,warn:`#ffb800`,error:`#ff4d4f`,idle:`rgba(255, 255, 255, 0.55)`};function it(e){let t=String(e??``).trim().toLowerCase();if(nt[t])return nt[t];for(let e of Object.keys(nt))if(t.startsWith(e)){let[t,n]=nt[e];return[t,n]}return[`warn`,String(e??``)]}function T(e,t){let n=document.getElementById(e);if(!n)return;let[r,i]=it(t);n.textContent=i,n.setAttribute(`data-state`,r),n.style.color=rt[r]||``,n.setAttribute(`aria-live`,r===`error`?`assertive`:`off`)}function E(e,t){let n=document.getElementById(`loading-text`),r=document.getElementById(`loading-progress`);n&&e&&(n.textContent=e),r&&Number.isFinite(t)&&(r.style.width=`${Math.max(0,Math.min(100,t))}%`);let i=document.querySelector(`#loading-screen .loading-ring`);i&&Number.isFinite(t)&&t<100&&i.classList.remove(`is-ready`,`is-error`)}function at(e=`Engine ready`){let t=document.querySelector(`#loading-screen .loading-ring`),n=document.querySelector(`#loading-screen .progress-track`),r=document.getElementById(`start-ar`);t&&(t.classList.remove(`is-error`),t.classList.add(`is-ready`)),n&&n.classList.add(`hidden`),r&&(r.disabled=!1,r.textContent=`START AR`);let i=document.getElementById(`loading-text`);i&&(i.textContent=e)}function ot(){document.getElementById(`loading-screen`)?.classList.add(`hidden`)}var D={config:null,started:!1,trackingMode:`standby`,xrAvailable:!1,xrStarted:!1,xrCamera:null,xrScene:null,scene:null,camera:null,renderer:null,aframeScene:null,aframeCamera:null,fallbackScene:null,fallbackCamera:null,fallbackRenderer:null,fallbackActive:!1,fallbackLoopHandle:0,cameraVideo:null,gestureFrameCanvas:null,gestureFrameReady:!1,worldPoints:[],worldPointBuffer:[],placedObjects:[],selectedObject:null,floorY:-1.2,pendingModelToPlace:``,css3d:null,pipelineOrder:[],frameCount:0,isVRMode:!1,focusQuality:{enabled:!1,focusX:.5,focusY:.5,source:`screen-center`,avgFrameMs:16.7,pixelRatio:1,tier:`high`},spatialAudio:{enabled:!1,unlocked:!1,listener:null,context:null,micReady:!1,micPermission:`unknown`,voiceRecognition:!1,speechSynthesis:!1,wakeWindowUntil:0,lastVoiceCommandAt:0,environmentProfile:`default`,roomProfile:{name:`default`,refDistance:.72,maxDistance:8,rolloffFactor:1.6,dampening:.08}},nativeOptions:{immersion:1,hdrEnabled:!0,handTrackingEnabled:!0,spatialAudioEnabled:!0,activeEnvironment:`default`},compositor:{mode:`browser-proxy`,native:!1,reprojection:!1,passthroughBlend:`browser`,depthComposition:!1,foveation:0,framebufferScaleFactor:1,eyeBuffers:`mono`,frameBudgetMs:16.6,avgFrameMs:16.6,lastFrameAt:0,refreshRate:60,renderScale:1,convergence:1.4,lensProfile:`default`,eyeAspect:1,vignetteStrength:.12,motionComfort:`balanced`,stereoFrustum:!0},browserProfile:{browser:`unknown`,engine:`unknown`,platform:`unknown`,isAndroid:!1,isIOS:!1,isVisionOS:!1,isQuest:!1,isWebView:!1,isSafari:!1,isChrome:!1,isFirefox:!1,isEdge:!1,webXRSupportExpected:!1,webXRFragmented:!1,latencyCeilingMs:16.7,limits:{},notes:[]},capabilities:{browserWebAR:!0,eightWallSLAM:!1,webXRAvailable:!1,webXRHitTest:!1,manualCamera:!1,mediaPipeHands:!1,spatialAudio:!1,gazeProxy:!1,controllerAbstraction:!1,handEyeFusion:!1,spatialWindowing:!1,passthroughBlendProxy:!1,comfortAdaptation:!1,predictivePoseFiltering:!1,accessibilityInteraction:!1,gestureArbitration:!1,selectionArbitration:!1,dragManipulationProxy:!1,openXRCompositorProxy:!1,reprojectionProxy:!1,depthCompositionProxy:!1,eyeBufferPair:!1,nativeFrameTiming:!1,posePredictionProxy:!1,approximateAnchors:!0,truePersistentWorldAnchors:!1,eyeTracking:!1,foveatedRendering:!1,nativeCompositor:!1,guardianBoundary:!1,controllerHaptics:!1,nativeOpenXRBridge:!1,browserLatencyCeiling:!0,limitedSensorAccess:!0,limitedOSIntegration:!0,limitedCompositorControl:!0,persistentAnchorSupport:!1,backgroundExecutionLimited:!0,passthroughControlLimited:!0,spatialMemoryLimited:!0,headsetOptimizationAccessLimited:!0,webXRFragmented:!1,safariWebXRLimitations:!1,visionOSBrowserRestrictions:!1,androidBrowserInconsistency:!1,webViewInconsistency:!1,eyeTrackingProxy:!1,persistentSpatialMemory:!1,ultraStableAnchoring:!1,naturalWindowPlacement:!1,depthAwareImmersion:!1,environmentAwareUI:!1,headsetComfortSystems:!1,lowLatencyCompositing:!1,stereoEyeBuffers:!1,stereoFrustumCalibration:!1,refreshRateNegotiation:!1,timestampSync:!1,motionSicknessMitigation:!1,teleportLocomotion:!1,smoothLocomotionSafeguards:!1,roomBoundaryVisualization:!1,nativeHandMeshProxy:!1,controllerHapticsProxy:!1,lowLightTrackingResilience:!1,headsetCameraCalibrationProxy:!1,deviceCapabilityMatrix:!1,renderScaleStability:!1,stereoUiAnchoring:!1,antiAliasEdgeProtection:!1,zFightGuard:!1,sustainedFramerateGuard:!1,orientationLockStability:!1,sensorPermissionPersistenceProxy:!1,motionComfortVignette:!1},telemetry:{frameMs:16.7,qualityTier:`high`,droppedFrames:0,startedAt:0,lastNativeStatusAt:0},runtime:{phase:`created`,lifecycleState:`created`,architecture:`unknown`,experienceClass:`unknown`,spatialRuntimeClass:`unknown`,platformRole:`unknown`,authority:`none`,authoritativeRuntime:`none`,activeEngine:`none`,activeRenderer:`none`,rendererOwner:`none`,restartCount:0,lastError:``,subsystems:{},cleanupCount:0,conflicts:[],readiness:{boot:!1,scene:!1,camera:!1,tracking:!1,ui:!1},lifecycleHistory:[],permissionState:`unknown`,degradationReason:``,spatialGapStatement:``,rootCauseSummary:``,visionProGapSummary:``,visionProMissingFeatures:[]},sessionAnchor:{originMatrix:null,originPosition:[0,0,0],originQuaternion:[0,0,0,1],restoredAt:0},handState:{hands:[],gestures:new Map},sceneInitialized:!1,resizeBound:!1,fallbackLoopStarted:!1,aframeCameraSyncAdded:!1,liveSceneReady:!1,paused:!1,tracking:null,trackingQuality:`initializing`,trackingAPI:null,detectedPlanes:[]},st=new EventTarget,ct=new Set,lt=new Set,ut=new Set,dt=new Map;function O(e,t){let n=e=>t(e.detail);return st.addEventListener(e,n),()=>st.removeEventListener(e,n)}function k(e,t={}){st.dispatchEvent(new CustomEvent(e,{detail:t}))}function ft(e,t={}){D.runtime.phase=String(e||`unknown`),D.runtime.lastTransitionAt=Date.now();try{document.body.dataset.jarvisRuntimePhase=D.runtime.phase}catch{}return k(`runtime-phase`,{phase:D.runtime.phase,detail:t}),kt(`AR phase: ${D.runtime.phase}`),D.runtime.phase}function A(e,t={}){let n=String(e||`unknown`);D.runtime.lifecycleState=n,D.runtime.lifecycleHistory.push({state:n,detail:t,at:Date.now()}),D.runtime.lifecycleHistory.length>24&&D.runtime.lifecycleHistory.splice(0,D.runtime.lifecycleHistory.length-24);try{document.body.dataset.jarvisLifecycleState=n}catch{}return k(`runtime-lifecycle`,{state:n,detail:t}),kt(`AR lifecycle: ${n}`),n}function j(e,t=!0){if(!e)return!1;D.runtime.readiness[e]=!!t;try{document.body.dataset.jarvisReady=Object.entries(D.runtime.readiness).filter(([,e])=>e).map(([e])=>e).join(`,`)}catch{}return k(`runtime-readiness`,{key:e,ready:!!t,readiness:D.runtime.readiness}),D.runtime.readiness[e]}function pt(){D.started=!1,D.xrStarted=!1,D.xrAvailable=!1,D.xrSession=null,D.xrHitTestSource=null,D.liveSceneReady=!1,D.paused=!1,D.cameraVideo=null,D.gestureFrameCanvas=null,D.gestureFrameReady=!1,D.trackingMode=`standby`,D.runtime.permissionState=`unknown`,D.runtime.degradationReason=``,D.runtime.rendererOwner=`none`,D.runtime.activeRenderer=`none`,D.runtime.activeEngine=`none`;for(let e of Object.keys(D.runtime.readiness))D.runtime.readiness[e]=!1;A(`stopped`)}function M(e,t=`ready`,n={}){let r=String(e||``).trim();if(!r)return null;D.runtime.subsystems[r]={status:t,detail:n,updatedAt:Date.now()};try{document.body.dataset.jarvisSubsystems=Object.keys(D.runtime.subsystems).join(`,`)}catch{}return k(`runtime-subsystem`,{name:r,status:t,detail:n}),D.runtime.subsystems[r]}function mt(e,t={}){let n=String(e||`unknown`),r=D.runtime.authoritativeRuntime;if(r!==`none`&&r!==n&&!t.force){let e={type:`runtime`,current:r,attempted:n,at:Date.now()};return D.runtime.conflicts.push(e),M(`blocked-runtime:${n}`,`blocked`,e),k(`runtime-authority-conflict`,e),r}D.runtime.authoritativeRuntime=n,D.runtime.authority=n,D.runtime.activeEngine=n,D.runtime.authorityChangedAt=Date.now();try{document.body.dataset.jarvisRuntimeAuthority=n}catch{}return k(`runtime-authority`,{previous:r,authority:n,detail:t}),M(`runtime:${n}`,`authoritative`,t),n}function ht(e,t=null,n={}){let r=String(e||`unknown`),i=D.runtime.rendererOwner||`none`;if(!(n.takeover||i===`none`||i===r)){let e={type:`renderer`,current:i,attempted:r,at:Date.now()};return D.runtime.conflicts.push(e),M(`blocked-renderer:${r}`,`blocked`,e),k(`runtime-authority-conflict`,e),i}D.runtime.rendererOwner=r,D.runtime.activeRenderer=r,D.runtime.activeEngine=n.engine||D.runtime.activeEngine,D.runtime.rendererChangedAt=Date.now(),t?.scene&&(D.scene=t.scene),t?.camera&&(D.camera=t.camera),t?.renderer&&(D.renderer=t.renderer),r!==`fallback-three`&&Nt();try{document.body.dataset.jarvisRendererAuthority=r}catch{}return k(`renderer-authority`,{previous:i,authority:r,context:t}),M(`renderer:${r}`,`authoritative`,{hasScene:!!t?.scene,hasCamera:!!t?.camera,hasRenderer:!!t?.renderer}),r}function gt(){let e=D.cameraVideo;if(e?.readyState>=2&&e.videoWidth>0&&e.videoHeight>0)return{source:e,width:e.videoWidth,height:e.videoHeight};let t=D.gestureFrameCanvas;return D.gestureFrameReady&&t?.width>0&&t?.height>0?{source:t,width:t.width,height:t.height}:null}function N(e,t,n,r){if(!e?.addEventListener||!t||!n)return()=>{};e.addEventListener(t,n,r);let i=()=>e.removeEventListener(t,n,r);return ct.add(i),()=>{i(),ct.delete(i)}}function _t(e,t=0){let n=window.setTimeout(()=>{lt.delete(n),e?.()},t);return lt.add(n),n}function vt(e){e&&(window.clearTimeout(e),lt.delete(e))}function P(e){let t=requestAnimationFrame(n=>{ut.delete(t),e?.(n)});return ut.add(t),t}function yt(e){e&&(cancelAnimationFrame(e),ut.delete(e))}function bt(e){return typeof e==`function`?(ct.add(e),()=>ct.delete(e)):()=>{}}function xt(e,t={},n={}){let r=String(e?.message||e||`Unknown runtime issue`),i=String(n.source||t.source||`runtime`),a=`${i}:${r}`,o=Date.now();if(o-(dt.get(a)||0)>5e3){dt.set(a,o),D.runtime.lastError=r,D.runtime.degradationReason=String(t.degradationReason||D.runtime.degradationReason||``),k(`runtime-error`,{error:r,source:i,context:t}),M(`runtime-error:${i}`,`error`,{message:r,context:t});try{C(r,n.title||`Runtime Error`,{timeout:n.timeout??7e3})}catch{}}try{kt(`${i}: ${r}`)}catch{}return{message:r,source:i,context:t}}function St(e,t,n={}){return typeof t==`function`?(...r)=>{try{return t(...r)}catch(t){xt(t,{...n,subsystem:e},{source:e});return}}:()=>{}}function F(e,t){D.capabilities[e]=!!t;try{document.body.dataset[`cap${e[0].toUpperCase()}${e.slice(1)}`]=String(!!t)}catch{}return D.capabilities[e]}function Ct(e={}){D.compositor={...D.compositor,...e&&typeof e==`object`?e:{}},k(`compositor-state`,D.compositor);try{document.body.dataset.jarvisCompositorMode=D.compositor.mode,document.body.dataset.jarvisCompositorPassthrough=String(D.compositor.passthroughBlend)}catch{}return D.compositor}function wt(e={}){D.browserProfile={...D.browserProfile,...e&&typeof e==`object`?e:{}};try{document.body.dataset.jarvisBrowser=`${D.browserProfile.browser||`unknown`}-${D.browserProfile.platform||`unknown`}`,document.body.dataset.jarvisBrowserLimit=D.browserProfile.webXRFragmented?`fragmented`:`standard`}catch{}return k(`browser-profile`,D.browserProfile),D.browserProfile}function Tt(e={}){D.runtime={...D.runtime,...e&&typeof e==`object`?e:{}};try{document.body.dataset.jarvisRuntimeArchitecture=D.runtime.architecture||`unknown`,document.body.dataset.jarvisSpatialClass=D.runtime.spatialRuntimeClass||`unknown`}catch{}return k(`runtime-classification`,D.runtime),D.runtime}function Et(e=``){D.runtime.rootCauseSummary=String(e||``);try{document.body.dataset.jarvisRootCause=D.runtime.rootCauseSummary}catch{}return k(`runtime-root-cause`,{summary:D.runtime.rootCauseSummary}),D.runtime.rootCauseSummary}function Dt(e=``,t=[]){D.runtime.visionProGapSummary=String(e||``),D.runtime.visionProMissingFeatures=Array.isArray(t)?t.map(e=>String(e||``).trim()).filter(Boolean):[];try{document.body.dataset.jarvisVisionProGap=D.runtime.visionProGapSummary}catch{}return k(`runtime-vision-pro-gap`,{summary:D.runtime.visionProGapSummary,missingFeatures:D.runtime.visionProMissingFeatures}),{summary:D.runtime.visionProGapSummary,missingFeatures:D.runtime.visionProMissingFeatures}}function Ot(e,...t){try{let n=globalThis.JarvisNative;n&&typeof n[e]==`function`&&n[e](...t)}catch{}}function kt(e){Ot(`status`,String(e||``))}function At(){try{if(globalThis.XR8?.Threejs?.xrScene){let e=globalThis.XR8.Threejs.xrScene();if(e?.scene&&e?.camera&&e?.renderer)return D.xrScene=e,D.scene=e.scene,D.camera=e.camera,D.renderer=e.renderer,e}}catch{return null}return null}function I(){return At()||(jt(),{scene:D.fallbackScene,camera:D.fallbackCamera,renderer:D.fallbackRenderer})}function jt(){if(D.fallbackScene&&D.fallbackCamera&&D.fallbackRenderer||D.xrStarted&&D.xrScene?.scene)return;D.fallbackActive=!0;let e=document.getElementById(`fallback-three-canvas`)||document.createElement(`canvas`);e.id=`fallback-three-canvas`,e.parentNode||(e.style.cssText=`position:fixed;inset:0;width:100%;height:100%;z-index:1;pointer-events:none;background:transparent`,document.body.appendChild(e));let t=new Ye({canvas:e,alpha:!0,antialias:!0,powerPreference:`high-performance`});t.setPixelRatio(Math.min(devicePixelRatio||1,3)),t.setSize(innerWidth,innerHeight,!1),t.setClearColor(0,0),t.outputColorSpace=de,t.toneMapping=4,t.toneMappingExposure=1,t.useLegacyLights=!1,t.shadowMap.enabled=!0,t.shadowMap.type=3;let n=new Pe,r=new p(60,innerWidth/innerHeight,.01,1e3);r.position.set(0,0,0),n.add(new Fe(16777215,.65));let i=new De(16777215,.8);i.position.set(1,2,1),i.castShadow=!0,n.add(i),D.fallbackScene=n,D.fallbackCamera=r,D.fallbackRenderer=t,D.scene=n,D.camera=r,D.renderer=t,ht(`fallback-three`,{scene:n,camera:r,renderer:t},{engine:`manual-camera`})}function Mt(){if(D.fallbackLoopStarted)return;D.fallbackLoopStarted=!0,jt();let e=()=>{if(D.xrStarted){Nt();return}!D.xrStarted&&D.fallbackRenderer&&(D.fallbackRenderer.setSize(innerWidth,innerHeight,!1),D.fallbackCamera.aspect=innerWidth/innerHeight,D.fallbackCamera.updateProjectionMatrix(),D.fallbackRenderer.render(D.fallbackScene,D.fallbackCamera)),D.fallbackLoopHandle=P(e)};D.fallbackLoopHandle=P(e)}function Nt(){D.fallbackLoopHandle&&yt(D.fallbackLoopHandle),D.fallbackLoopHandle=0,D.fallbackLoopStarted=!1;let e=document.getElementById(`fallback-three-canvas`);e&&(e.style.display=`none`)}function Pt(){let e=At();if(!e?.scene||!D.fallbackScene||e.scene===D.fallbackScene)return e;let t=[...D.fallbackScene.children];for(let n of t)n!==D.fallbackCamera&&(D.fallbackScene.remove(n),e.scene.children.includes(n)||e.scene.add(n));return Nt(),D.fallbackRenderer?.dispose?.(),document.getElementById(`fallback-three-canvas`)?.remove(),D.fallbackScene=null,D.fallbackCamera=null,D.fallbackRenderer=null,D.fallbackActive=!1,D.scene=e.scene,D.camera=e.camera,D.renderer=e.renderer,ht(`xr8-threejs`,e,{takeover:!0,engine:`8thwall-slam`}),e}function Ft(e=I()){return D.liveSceneReady=!0,k(`ar-scene-live`,e),e}function It(e,t={}){let n=!!t.disposeSharedAssets,r=new Set,i=new Set,a=new Set;e?.traverse?.(e=>{e.geometry&&!r.has(e.geometry)&&(n||!e.geometry.userData?.sharedAssetKey)&&(r.add(e.geometry),e.geometry.dispose()),(Array.isArray(e.material)?e.material:[e.material]).filter(Boolean).forEach(e=>{i.has(e)||(i.add(e),Object.values(e).forEach(e=>{e?.isTexture&&!a.has(e)&&(n||!e.userData?.sharedAssetKey)&&(a.add(e),e.dispose())}),(n||!e.userData?.sharedAssetKey)&&e.dispose?.())})}),e?.parent?.remove(e)}try{globalThis.AR_STATE=D,globalThis.FridayRuntime={AR_STATE:D,emit:k,on:O,reportRuntimeIssue:xt,guardSubsystem:St,setCapability:F,setCompositorState:Ct,claimRuntimeAuthority:mt,claimRendererAuthority:ht,registerSubsystem:M}}catch{}function Lt(e){try{return e?.xr?.getSession?.()||null}catch{return null}}function Rt(e,t){if(e?.xr){try{typeof e.xr.setFramebufferScaleFactor==`function`&&e.xr.setFramebufferScaleFactor(t.framebufferScaleFactor)}catch{}try{typeof e.xr.setFoveation==`function`&&e.xr.setFoveation(t.foveation)}catch{}}}function zt(e=I(),t={}){let n=e?.renderer,r=t.session||Lt(n),i=String(t.tier||D.telemetry?.qualityTier||`medium`).toLowerCase();globalThis.navigator?.xr;let a=!!(n?.xr&&typeof n.xr.setFoveation==`function`),o=!!(n?.xr&&typeof n.xr.setFramebufferScaleFactor==`function`),s=!!(r?.renderState?.baseLayer||r?.depthUsage),c=!!(globalThis.JarvisNative?.openXRBridge||globalThis.JarvisNative?.setCompositorState),l={mode:t.mode||(r?`webxr-session`:`browser-proxy`),native:c,reprojection:!!(r&&o),passthroughBlend:t.passthroughBlend||(t.source?`browser-camera`:`browser`),depthComposition:!!(t.depthComposition||s),foveation:t.foveation??(i===`high`?.2:i===`medium`?.35:.55),framebufferScaleFactor:t.framebufferScaleFactor??(i===`high`?1:i===`medium`?.85:.72),eyeBuffers:t.eyeBuffers||(t.stereo?`pair`:`mono`),frameBudgetMs:t.frameBudgetMs??(i===`high`?13.5:i===`medium`?16.6:20),avgFrameMs:D.compositor?.avgFrameMs||16.6,lastFrameAt:performance.now(),posePredictionMs:t.posePredictionMs??(i===`high`?18:i===`medium`?24:32),refreshRate:t.refreshRate??(i===`high`?90:i===`medium`?72:60),renderScale:t.renderScale??(i===`high`?1:i===`medium`?.9:.8),convergence:t.convergence??(i===`high`?1.35:1.45),guardianProxy:!!t.guardianProxy,compositorSync:!0,lensProfile:t.lensProfile||`default`,eyeAspect:t.eyeAspect??1,vignetteStrength:t.vignetteStrength??(i===`high`?.1:.16),motionComfort:t.motionComfort||`balanced`,stereoFrustum:!!(t.stereo??r)};if(Ct(l),F(`openXRCompositorProxy`,!0),F(`reprojectionProxy`,l.reprojection),F(`depthCompositionProxy`,l.depthComposition),F(`eyeBufferPair`,l.eyeBuffers===`pair`),F(`nativeFrameTiming`,!!r),F(`posePredictionProxy`,!0),F(`foveatedRendering`,a),F(`lowLatencyCompositing`,!0),F(`stereoEyeBuffers`,l.eyeBuffers===`pair`),F(`stereoFrustumCalibration`,l.stereoFrustum),F(`refreshRateNegotiation`,!0),F(`timestampSync`,!0),F(`motionSicknessMitigation`,!0),F(`smoothLocomotionSafeguards`,!0),F(`motionComfortVignette`,!0),t.guardianProxy!=null&&F(`guardianBoundary`,!!t.guardianProxy),c){F(`nativeOpenXRBridge`,!0);try{Ot(`setCompositorState`,JSON.stringify(l)),Ot(`requestCompositorControl`,JSON.stringify({owner:`browser-runtime`,mode:l.mode,guardianProxy:l.guardianProxy,browserManaged:!0})),Ot(`setGuardianState`,JSON.stringify({requested:!!t.guardianProxy,boundary:!!t.guardianProxy,owner:`browser-runtime`,source:`ar-compositor`}))}catch{}}return Rt(n,l),M(`compositor`,`ready`,l),k(`compositor-profile`,l),kt(`Compositor profile: ${l.mode}`),l}function Bt(e=16.6){let t=D.compositor||{},n=t.avgFrameMs?t.avgFrameMs*.9+e*.1:e,r={...t,avgFrameMs:n,lastFrameAt:performance.now()};return Ct(r),D.telemetry.frameMs=e,D.telemetry.droppedFrames=e>(r.frameBudgetMs||16.6)*1.25?(D.telemetry.droppedFrames||0)+1:D.telemetry.droppedFrames||0,k(`compositor-frame`,r),r}function Vt(){Ct({mode:`browser-proxy`,native:!1,reprojection:!1,passthroughBlend:`browser`,depthComposition:!1,foveation:0,framebufferScaleFactor:1,eyeBuffers:`mono`,frameBudgetMs:16.6,avgFrameMs:16.6,lastFrameAt:0}),F(`openXRCompositorProxy`,!1),F(`reprojectionProxy`,!1),F(`depthCompositionProxy`,!1),F(`eyeBufferPair`,!1),F(`nativeFrameTiming`,!1),F(`posePredictionProxy`,!1)}function Ht(e,n,r){globalThis.JarvisNative?.openXRBridge||globalThis.JarvisNative?.setCompositorState||(e.xr.enabled=!0,e.xr.setReferenceSpaceType(`local-floor`),!navigator.xr&&!D.stereoEffect&&t(async()=>{let{StereoEffect:e}=await import(`./StereoEffect-8X11TNUP.js`);return{StereoEffect:e}},__vite__mapDeps([0,1,2]),import.meta.url).then(({StereoEffect:t})=>{D.stereoEffect=new t(e),D.stereoEffect.setSize(window.innerWidth,window.innerHeight),D.stereoEffect.setEyeSeparation(.064),e.setAnimationLoop(()=>{D.stereoEffect.render(n,r)}),k(`jarvis-stereo-mode-active`,{status:`fallback_active`})}).catch(()=>{console.warn(`V15 AR: StereoEffect.js fallback polyfill missing.`)}))}var Ut=globalThis.XRExtras||{FullWindowCanvas:{pipelineModule(){return{name:`xrextras-full-window-canvas`,onStart:({canvas:e})=>Wt(e),onCanvasSizeChange:({canvas:e})=>Wt(e)}}},Loading:{pipelineModule(){return{name:`xrextras-loading`,onStart:()=>E(`Starting 8th Wall camera...`,38),onCameraStatusChange:({status:e})=>{e===`hasVideo`&&ot()}}}},AlmostThere:{pipelineModule(){return{name:`xrextras-almost-there`,onAttach:()=>{navigator.mediaDevices?.getUserMedia||w(`This browser has limited AR camera support. Chrome Android is recommended.`)}}}},RuntimeError:{pipelineModule(){return{name:`xrextras-runtime-error`,onException:e=>C(e?.message||String(e),`8th Wall Runtime Error`,{timeout:0})}}}};try{globalThis.XRExtras||(globalThis.XRExtras=Ut)}catch{}function Wt(e){if(!e)return;let t=Math.min(devicePixelRatio||1,3),n=Math.max(1,Math.floor(innerWidth*t)),r=Math.max(1,Math.floor(innerHeight*t));(e.width!==n||e.height!==r)&&(e.width=n,e.height=r),e.style.width=`100vw`,e.style.height=`100vh`}function Gt(){let e=[`localhost`,`127.0.0.1`,`::1`].includes(location.hostname);return location.protocol===`https:`||e?!0:(C(`AR requires a secure connection (HTTPS). Please open this app over HTTPS.`,`Secure Connection Required`,{timeout:0,linkHref:`intent://settings#Intent;scheme=android-app;end`,linkLabel:`Open Chrome Android settings`}),!1)}function Kt(){let e=new URLSearchParams(location.search),t=()=>{try{return localStorage.getItem(`jarvis_ar_device`)||``}catch{return``}},n=e=>{try{localStorage.setItem(`jarvis_ar_device`,String(e))}catch{}},r=e.has(`device`),i=e.get(`device`)||t()||`POCO-M5`;r||n(i);let a=Jt(e.get(`omega`)||e.get(`omegaBridge`)||``),o=Xt(e.get(`xr`)||e.get(`xrScriptUrl`)||``);return{deviceName:i,mode:qt(e.get(`mode`)||`vision_pro`),autoStart:!1,source:e.get(`source`)||`browser`,guardianProxy:e.get(`guardianProxy`)===`true`||e.get(`guardian`)===`true`,eyeTracking:e.get(`eyeTracking`)===`true`,nativeCompositor:e.get(`nativeCompositor`)===`true`,truePersistentWorldAnchors:e.get(`truePersistentWorldAnchors`)===`true`||e.get(`persistentWorldAnchors`)===`true`,nativeOpenXRBridge:e.get(`nativeOpenXRBridge`)===`true`,command:e.get(`command`)||``,arQuality:(e.get(`arQuality`)||`4k`).toLowerCase(),renderScale:e.get(`renderScale`)||`adaptive`,screen:e.get(`screen`)||`quest_spatial`,stack:(e.get(`stack`)||`aframe,playcanvas,camerakit,8thwall`).split(`,`).map(e=>e.trim()).filter(Boolean),omegaBase:a||(location.origin.includes(`5173`)?location.origin:``),wsBase:Yt(e.get(`ws`)||``,a),xrScriptUrl:o,imageTargets:(e.get(`imageTargets`)||``).split(`,`).map(e=>e.trim()).filter(Boolean),gameUrls:{eternum:Jt(e.get(`eternumUrl`)||e.get(`gameEternumUrl`)||``),ripples:Jt(e.get(`ripplesUrl`)||e.get(`gameRipplesUrl`)||``)}}}function qt(e){let t=String(e||``).toLowerCase().trim().replace(/[-\s]+/g,`_`);return{vision:`vision_pro`,visionos:`vision_pro`,meta:`vision_pro`,quest:`vision_pro`,scan_room:`scan`,model:`models`,games:`games`,game:`games`,build:`builder`,game_builder:`builder`,vr_screen:`vr`}[t]||t||`vision_pro`}function Jt(e){let t=String(e||``).trim().replace(/\/+$/,``);return t?/^https?:\/\//i.test(t)?t:`http://${t}`:``}function Yt(e,t=``){let n=String(e||``).trim().replace(/\/+$/,``);if(n)return/^wss?:\/\//i.test(n)?n:`ws://${n}`;if(!t)return location.protocol===`https:`?`wss://${location.host}/scene-ws`:`ws://${location.hostname}:5050`;try{let e=new URL(t,location.href),n=e.protocol===`https:`?`wss:`:`ws:`;return e.protocol===`https:`||e.port===`5173`||!e.port?`${n}//${e.host}/scene-ws`:`${n}//${e.hostname}:5050`}catch{return``}}function Xt(e){let t=String(e||``).trim();return t&&/^(https?:|data:|blob:|\/)/i.test(t)?t:``}function Zt(e,t){let n=String(e||``).toLowerCase();return t.some(e=>n.includes(String(e||``).toLowerCase()))}function Qt(e=``,t=``,n=``){let r=String(e||(typeof navigator<`u`?navigator.userAgent:``)||``),i=r.toLowerCase(),a=typeof navigator<`u`&&navigator.platform||``,o=typeof navigator<`u`&&navigator.vendor||``,s=typeof navigator<`u`&&navigator.maxTouchPoints||0,c=String(t||a||``).toLowerCase(),l=String(n||o||``).toLowerCase(),u=/iphone|ipad|ipod/.test(i)||c.includes(`mac`)&&s>1&&/safari/.test(i),d=/android/.test(i),f=/visionos|applevision|xrvision/.test(i)||Zt(r,[`Safari`])&&/apple/.test(l)&&s>1&&/mac/.test(c),p=/quest|oculus/.test(i),m=/\bwv\b|; wv|webview|android.*version\/\d+.*chrome/i.test(r)||d&&!/chrome|crios|firefox|fxios|edg/i.test(i),h=/safari/.test(i)&&!/chrome|crios|chromium|android/.test(i),g=/chrome|crios|chromium/.test(i)&&!/edg/.test(i),_=/firefox|fxios/.test(i),ee=/edg/.test(i),v=h?`safari`:g?`chrome`:_?`firefox`:ee?`edge`:p?`quest-browser`:`other`,te=h?`webkit`:_?`gecko`:`blink`,ne=f?`visionos`:u?`ios`:d?`android`:/mac/.test(c)?`mac`:/win/.test(c)?`windows`:/linux/.test(c)?`linux`:`desktop`,re=!!(!u||f||p),ie=h||f||m||d&&!g&&!p,y=p&&g;return{ua:r,browser:v,engine:te,platform:ne,isAndroid:d,isIOS:u,isVisionOS:f,isQuest:p,isWebView:m,isSafari:h,isChrome:g,isFirefox:_,isEdge:ee,questBrowserQuirks:y,webXRSupportExpected:re,webXRFragmented:ie,latencyCeilingMs:f?12.5:p?13.5:u?14.5:16.7,limits:{sensorAccessLimited:!0,osIntegrationLimited:!0,compositorControlLimited:!0,persistentAnchorSupport:!1,backgroundExecutionLimited:!0,passthroughControlLimited:!0,spatialMemoryLimited:!0,headsetOptimizationAccessLimited:!0,webXRFragmented:ie,safariWebXRLimitations:h,visionOSBrowserRestrictions:f,androidBrowserInconsistency:d,webViewInconsistency:m,questBrowserQuirks:y,fullscreenEdgeCases:f||m||p,orientationLockEdgeCases:h||f||m||p,webglContextLossRisk:p||d||m,renderLoopDuplicationRisk:p||d||m,limitedSensorAccess:!0,limitedOSIntegration:!0,limitedCompositorControl:!0,limitedPassthroughControl:!0,limitedSpatialMemoryAPIs:!0,limitedHeadsetOptimizationAccess:!0},notes:[h?`Safari WebXR support remains fragmented.`:``,f?`visionOS browser control is limited to browser-managed surfaces.`:``,d?`Android browser behavior can vary by OEM and browser build.`:``,y?`Quest Browser can expose fullscreen, orientation, and session quirks.`:``,m?`Embedded WebView feature support is stricter than Chrome Custom Tabs.`:``].filter(Boolean)}}function $t(e){let t=[];return e?(e.limits?.webXRFragmented&&t.push(`webxr-fragmented`),e.limits?.safariWebXRLimitations&&t.push(`safari-webxr-limited`),e.limits?.visionOSBrowserRestrictions&&t.push(`visionos-browser-limited`),e.limits?.androidBrowserInconsistency&&t.push(`android-browser-variable`),e.limits?.webViewInconsistency&&t.push(`webview-variable`),e.limits?.questBrowserQuirks&&t.push(`quest-browser-quirks`),e.limits?.fullscreenEdgeCases&&t.push(`fullscreen-edge-cases`),e.limits?.orientationLockEdgeCases&&t.push(`orientation-lock-edge-cases`),e.limits?.webglContextLossRisk&&t.push(`webgl-context-loss-risk`),e.limits?.renderLoopDuplicationRisk&&t.push(`render-loop-duplication-risk`),e.limits?.backgroundExecutionLimited&&t.push(`background-execution-limited`),e.limits?.persistentAnchorSupport===!1&&t.push(`no-persistent-anchors`),e.limits?.passthroughControlLimited&&t.push(`passthrough-control-limited`),e.limits?.spatialMemoryLimited&&t.push(`spatial-memory-limited`),t):t}async function en(e){D.config=e,D.aframeScene=document.getElementById(`ar-scene`),D.aframeCamera=document.getElementById(`main-camera`),await tn();let t=I();return an(t.renderer,e),on(t),zt(t,{mode:`ar-shell`,tier:D.focusQuality.tier,stereo:!!D.isVRMode}),dn(t.scene),rn(t.renderer),pn(),D.sceneInitialized||(D.sceneInitialized=!0,k(`scene-ready`,t)),t}function tn(){let e=document.getElementById(`ar-scene`);return!e||!window.AFRAME||e.hasLoaded?Promise.resolve():new Promise(t=>{let n=!1,r=()=>{n||(n=!0,t())};e.addEventListener(`loaded`,r,{once:!0}),setTimeout(r,5e3)})}function nn(){D.aframeCameraSyncAdded=!0,document.getElementById(`ar-scene`)?.setAttribute(`data-render-mode`,`disabled-xr8-single-scene`)}function rn(e){let t=e?.domElement;!t||t.dataset.jarvisWebglRecoveryBound===`1`||(t.dataset.jarvisWebglRecoveryBound=`1`,N(t,`webglcontextlost`,e=>{e.preventDefault(),w(`WebGL context lost. Pausing AR until the GPU recovers.`,`WebGL`);try{globalThis.XR8?.pause?.()}catch{}},{passive:!1}),N(t,`webglcontextrestored`,()=>{if(w(`WebGL context restored.`,`WebGL`),an(e,D.config||{}),D.xrStarted)try{globalThis.XR8?.resume?.()}catch{}},{passive:!0}))}function an(e,t={}){if(!e)return;let n=String(t.renderScale||`adaptive`).toLowerCase(),r=n===`2`||n===`4k`?2:n===`1`?1:devicePixelRatio||1,i=Math.max(1,Math.min(r,3));r>3&&(console.warn(`Render scale ${r} was capped to 3.0. Requested scale: ${n}`),D.telemetry=D.telemetry||{},D.telemetry.pixelRatioCapped=!0,D.telemetry.originalPixelRatio=r),e.setPixelRatio(i),e.setSize(innerWidth,innerHeight,!1),e.outputColorSpace=de,e.toneMapping=4,e.toneMappingExposure=1,e.useLegacyLights=!1,e.shadowMap.enabled=!0,e.shadowMap.type=3}function on(e=I()){let t=e?.scene,n=e?.renderer;if(!t||!n)return null;if(t.environment&&t.userData.jarvisEnvironmentSource===`hdr`||t.userData.jarvisDefaultEnvInstalled)return t.environment;try{let e=new Le(n),r=new ye,i=e.fromScene(r,.04);i?.texture&&(t.environment=i.texture,t.userData.jarvisDefaultEnvTarget=i,t.userData.jarvisDefaultEnvInstalled=!0,t.userData.jarvisEnvironmentSource=`room-default`,D.telemetry.iblEnvironment=`room-default`),r.dispose?.(),e.dispose()}catch(e){console.warn(`Default IBL environment install failed:`,e?.message||e)}return t.environment}function sn(){if(D.focusQuality.enabled)return;D.focusQuality.enabled=!0;let e=performance.now(),t=0,n=(e,t,n)=>{D.focusQuality.focusX=Math.max(0,Math.min(1,e)),D.focusQuality.focusY=Math.max(0,Math.min(1,t)),D.focusQuality.source=n};N(window,`pointerdown`,e=>n(e.clientX/innerWidth,e.clientY/innerHeight,`touch`),{passive:!0}),N(window,`pointermove`,e=>{e.pointerType!==`mouse`&&n(e.clientX/innerWidth,e.clientY/innerHeight,`touch`)},{passive:!0}),O(`gesture-point`,e=>{let t=e?.point;t&&n(t.x,t.y,`hand-point`)});let r=n=>{let i=Math.min(n-e,100);e=n,D.focusQuality.avgFrameMs=D.focusQuality.avgFrameMs*.92+i*.08,D.telemetry.frameMs=D.focusQuality.avgFrameMs,Bt(i),n-t>600&&(cn(),t=n),P(r)};P(r)}function cn(){let e=I(),t=e.renderer;if(!t)return;let n=D.focusQuality.avgFrameMs,r=Math.min(devicePixelRatio||1,3),i=n>33?{ratio:1,tier:`low`,shadows:!1}:n>25?{ratio:Math.min(1.2,r),tier:`medium`,shadows:!0}:n>18?{ratio:Math.min(1.5,r),tier:`balanced`,shadows:!0}:{ratio:r,tier:`high`,shadows:!0};Math.abs((D.focusQuality.pixelRatio||0)-i.ratio)>.05&&(t.setPixelRatio(i.ratio),t.setSize(innerWidth,innerHeight,!1),D.focusQuality.pixelRatio=i.ratio),D.focusQuality.tier=i.tier,D.telemetry.qualityTier=i.tier,document.body.dataset.jarvisQualityTier=i.tier,document.body.dataset.jarvisFrameMs=D.focusQuality.avgFrameMs.toFixed(1),performance.now()-D.telemetry.lastNativeStatusAt>5e3&&(D.telemetry.lastNativeStatusAt=performance.now(),kt(`AR quality ${i.tier}, ${D.focusQuality.avgFrameMs.toFixed(1)}ms frame average`)),t.shadowMap&&(t.shadowMap.enabled=i.shadows),zt(e,{mode:`ar-shell`,tier:i.tier,stereo:!!D.isVRMode,frameBudgetMs:i.tier===`high`?13.5:i.tier===`balanced`?16.6:20}),D.placedObjects.forEach(e=>ln(e,i.tier))}function ln(e,t){if(!e)return;let n=un(e)<.34?t:t===`high`?`balanced`:`low`;e.traverse(e=>{e.isMesh&&(e.frustumCulled=!0,e.castShadow=n!==`low`,e.receiveShadow=n!==`low`,e.material&&(e.material.needsUpdate=!1))})}function un(e){let t=D.camera||I().camera;if(!t)return 0;let n=new S;e.getWorldPosition(n),n.project(t);let r=n.x*.5+.5,i=-n.y*.5+.5;return Math.hypot(r-D.focusQuality.focusX,i-D.focusQuality.focusY)}function dn(e){if(!e||e.userData.jarvisHelpersAdded)return;e.userData.jarvisHelpersAdded=!0;let t=new _(16777215,4469538,.72);t.name=`jarvis-ambient-fill`,e.add(t);let n=new De(16777215,1.05);n.name=`jarvis-key-shadow-light`,n.position.set(1.4,3.2,1.2),n.castShadow=!0,n.shadow.mapSize.set(2048,2048),n.shadow.camera.near=.1,n.shadow.camera.far=10,n.shadow.camera.left=-5,n.shadow.camera.right=5,n.shadow.camera.top=5,n.shadow.camera.bottom=-5,n.shadow.bias=-5e-4,n.shadow.normalBias=.02,e.add(n),D.shadowLight=n;let r=new se(4491519,.28,8,2);r.name=`jarvis-ar-fill-light`,r.position.set(0,1.2,0),e.add(r),D.fillLight=r;let i=new b(new Te(.08,.105,48),new d({color:16777215,transparent:!0,opacity:.65,side:2,depthWrite:!1}));i.name=`placement-reticle`,i.rotation.x=-Math.PI/2,i.position.set(0,D.floorY+.01,-1.8),i.visible=!1,e.add(i),D.reticle=i;let a=new b(new x(12,12),new he({color:0,opacity:.24,transparent:!0,depthWrite:!1}));a.name=`jarvis-real-floor-shadow-receiver`,a.rotation.x=-Math.PI/2,a.position.set(0,D.floorY+.002,0),a.receiveShadow=!0,e.add(a),D.shadowReceiver=a}function fn(){T(`status-camera`,D.cameraVideo||D.xrStarted?`live`:`standby`),T(`status-tracking`,D.trackingMode),T(`status-omega`,D.jarvis?.connected?`linked`:`offline`)}function pn(){if(D.resizeBound)return;D.resizeBound=!0;let e=()=>{let e=I();e.camera?.isPerspectiveCamera&&(e.camera.aspect=innerWidth/innerHeight,e.camera.updateProjectionMatrix()),e.renderer?.setSize?.(innerWidth,innerHeight,!1),k(`ar-resize`,{width:innerWidth,height:innerHeight})};N(window,`resize`,e),N(window,`orientationchange`,()=>_t(e,100)),N(document,`visibilitychange`,()=>{try{document.hidden?globalThis.XR8?.pause?.():globalThis.XR8?.resume?.()}catch{w(`8th Wall pause/resume is unavailable in this browser session.`)}})}var mn=new Set,hn=null,gn=null,_n=null,vn=0,yn=!1,bn=class{constructor({title:e,width:t=340,height:n=480,icon:r=`O`,body:i}={}){let a=document.getElementById(`panel-template`).content.firstElementChild.cloneNode(!0);this.el=a,this.icon=r,this.isDragging=!1,this.isResizing=!1,this.startX=0,this.startY=0,this.currentX=Math.max(8,(innerWidth-t)/2),this.currentY=Math.max(72,(innerHeight-n)/2),this.velX=0,this.velY=0,this.animFrame=0,this.activePointerId=null,a.style.width=`clamp(280px, 90vw, ${t}px)`,a.style.minHeight=`${Math.min(n,innerHeight-170)}px`,a.querySelector(`h2`).textContent=e||`Panel`,i&&a.querySelector(`.panel-body`).appendChild(i),a.querySelector(`.panel-close`).addEventListener(`click`,()=>this.destroy()),a.querySelector(`.panel-minimize`).addEventListener(`click`,()=>this.minimize()),this.attachEvents(),document.getElementById(`ui-layer`).appendChild(a),this.applyTransform(),mn.add(this)}attachEvents(){let e=this.el.querySelector(`.panel-drag-handle`);this._listeners=[[e,`pointerdown`,e=>this.onPointerStart(e)],[document,`pointermove`,e=>this.onPointerMove(e)],[document,`pointerup`,()=>this.onDragEnd()],[this.el,`pointerdown`,()=>this.focus()]],this._listeners.forEach(([e,t,n,r])=>e.addEventListener(t,n,r))}onPointerStart(e){e.preventDefault?.(),this.isDragging=!0,this.startX=e.clientX-this.currentX,this.startY=e.clientY-this.currentY,this.lastX=e.clientX,this.lastY=e.clientY,this.activePointerId=e.pointerId,yt(this.animFrame),e.currentTarget?.setPointerCapture?.(e.pointerId)}onPointerMove(e){this.isDragging&&this.applyDrag(e.clientX,e.clientY)}applyDrag(e,t){this.velX=e-this.lastX,this.velY=t-this.lastY,this.lastX=e,this.lastY=t,this.currentX=e-this.startX,this.currentY=t-this.startY,this.applyTransform()}onDragEnd(){this.isDragging&&(this.isDragging=!1,this.el.releasePointerCapture?.(this.activePointerId),this.activePointerId=null,this.applyMomentum())}applyMomentum(){this.velX*=.92,this.velY*=.92,this.currentX+=this.velX,this.currentY+=this.velY,this.applyTransform(),(Math.abs(this.velX)>.5||Math.abs(this.velY)>.5)&&(this.animFrame=P(()=>this.applyMomentum()))}applyTransform(){let e=this.el.getBoundingClientRect(),t=this.el.offsetWidth||e.width||parseFloat(this.el.style.width)||320,n=this.el.offsetHeight||e.height||parseFloat(this.el.style.minHeight)||420,r=Math.max(0,innerWidth-t),i=Math.max(0,innerHeight-n);this.currentX=Math.max(0,Math.min(this.currentX,r)),this.currentY=Math.max(0,Math.min(this.currentY,i)),this.el.style.transform=`translate3d(${this.currentX}px, ${this.currentY}px, 0)`}focus(){mn.forEach(e=>e.el.classList.remove(`active`)),this.el.classList.add(`active`)}minimize(){this.el.classList.add(`minimized`);let e=document.createElement(`button`);e.className=`panel-orb glass-panel`,e.textContent=this.icon||`O`,e.setAttribute(`aria-label`,`Restore panel`);let t=document.querySelectorAll(`#ui-layer .panel-orb`).length;e.style.cssText=`width:56px;height:56px;border-radius:50%;display:flex;align-items:center;justify-content:center;cursor:pointer;font-size:18px;position:absolute;bottom:${100+t*64}px;right:20px;z-index:20;color:white;pointer-events:auto`,e.onclick=()=>{this.restore(),e.remove()},document.getElementById(`ui-layer`).appendChild(e),this.el.style.display=`none`}restore(){this.el.style.display=``,this.el.classList.remove(`minimized`),this.focus()}destroy(){yt(this.animFrame),this._listeners?.forEach(([e,t,n,r])=>e.removeEventListener(t,n,r)),this._listeners=[],mn.delete(this),this.el.remove(),mn.size||Mn()}};function xn(){kn(),O(`ar-resize`,Dn)}function Sn(){return D.css3d?.initialized?(jn(),D.css3d):(gn=gn||new Pe,hn=hn||Cn(),D.css3d={scene:gn,renderer:hn,panels:[],initialized:!0},An(),jn(),D.css3dResizeBound||(N(window,`resize`,On),N(window,`orientationchange`,()=>_t(On,100)),D.css3dResizeBound=!0),D.css3d)}function Cn(){let e=new ge;e.setSize(innerWidth,innerHeight),e.domElement.style.cssText=`position:absolute;top:0;left:0;width:100%;height:100%;z-index:2;pointer-events:auto;overflow:hidden;transform-style:preserve-3d`;let t=document.getElementById(`css3d-layer`);return t.style.pointerEvents=`none`,t.appendChild(e.domElement),e}function wn(e,t,n=800,r=530){let i=document.createElement(`div`);i.className=`game-panel-viewport`,i.style.cssText=`position:relative;width:100%;height:min(${Math.max(320,r-100)}px,68vh);min-height:320px;border-radius:16px;overflow:hidden;border:1px solid rgba(255,255,255,0.2);box-shadow:0 0 48px rgba(0,122,255,0.24),0 16px 42px rgba(0,0,0,0.52);background:#000;pointer-events:auto`,i.tabIndex=0;let a=document.createElement(`iframe`);a.src=e,a.className=`game-frame`,a.style.cssText=`position:absolute;inset:0;width:100%;height:100%;border:0;background:#000;pointer-events:auto`,a.setAttribute(`allow`,`autoplay; fullscreen; microphone; camera`),a.setAttribute(`referrerpolicy`,`origin-when-cross-origin`),a.setAttribute(`sandbox`,`allow-scripts allow-same-origin allow-forms allow-pointer-lock allow-popups`),a.setAttribute(`referrerpolicy`,`no-referrer`),i.append(a);let o=new bn({title:t,body:i,icon:`G`,width:Math.min(n,420),height:Math.min(r,640)});return o.el.classList.add(`ar-game-panel`),o.focus(),{object:null,iframe:a,container:i,titleBar:o.el.querySelector(`header`),panel:o,destroy:()=>o.destroy()}}function Tn(e){let t=(_n||I().camera)?.fov||60,n=innerHeight,r=Math.tan(Xe.degToRad(t/2));return e/(n/2/r)}function En(){if(!hn||!gn)return;let e=An()||I().camera;e&&e!==_n&&(_n=e),_n&&(_n.updateMatrixWorld(!0),hn.setSize(innerWidth,innerHeight),hn.render(gn,_n))}function Dn(){mn.forEach(e=>e.applyTransform()),D.css3d?.panels?.forEach(e=>e.scale.setScalar(Tn(2)))}function On(){hn?.setSize(innerWidth,innerHeight),Dn()}function kn(){document.getElementById(`hud-toolbar`)?.addEventListener(`click`,e=>{let t=e.target.closest(`button[data-action]`);if(!t)return;let n=t.dataset.action;document.querySelectorAll(`#hud-toolbar .btn-symbol`).forEach(e=>{let n=e===t;e.classList.toggle(`selected`,n),e.setAttribute(`aria-pressed`,String(n))}),n===`models`?k(`open-models`):n===`scan`?k(`scan-room`):n===`games`?k(`open-games`):n===`builder`?k(`open-builder`):n===`vr`?k(`enter-vr`):n===`media`?k(`open-media`):n===`jarvis`&&k(`open-jarvis`)})}function An(){try{let e=globalThis.XR8?.Threejs?.xrScene?.()?.camera||null;return e&&(_n=e),e}catch{return null}}function jn(){if(globalThis.XR8?.addCameraPipelineModule){vn&&(yt(vn),vn=0),yn?D.css3dPipelineAdded=!0:(globalThis.XR8.addCameraPipelineModule({name:`css3d-camera-sync`,onRender:()=>En()}),D.pipelineOrder.push(`css3d-camera-sync`),yn=!0,D.css3dPipelineAdded=!0);return}if(vn)return;let e=()=>{if(D.css3dPipelineAdded){vn=0;return}En(),vn=P(e)};vn=P(e)}function Mn(e=!1){return!e&&mn.size>0?!1:(vn&&yt(vn),vn=0,hn?.domElement?.remove?.(),hn=null,gn=null,_n=null,D.css3d=null,D.css3dPipelineAdded=!1,yn=!1,!0)}function Nn(){mn.forEach(e=>e.destroy()),mn.clear(),Mn(!0),D.css3dResizeBound=!1,document.querySelectorAll(`#ui-layer .panel-orb, #ui-layer .ar-panel`).forEach(e=>e.remove())}function Pn(e,t,n=`O`){let r=typeof t==`string`?document.createElement(`div`):t;return typeof t==`string`&&(r.textContent=t),new bn({title:e,body:r,icon:n})}var Fn=[{name:`Duck`,size:`~100KB`,category:`animal`},{name:`Avocado`,size:`~200KB`,category:`food`},{name:`BoxAnimated`,size:`~50KB`,category:`basic`},{name:`BrainStem`,size:`~3MB`,category:`organic`},{name:`CesiumMilkTruck`,size:`~1MB`,category:`vehicle`},{name:`DamagedHelmet`,size:`~30MB`,category:`scifi`},{name:`FlightHelmet`,size:`~30MB`,category:`scifi`},{name:`Fox`,size:`~2MB`,category:`animal`},{name:`GlamVelvetSofa`,size:`~10MB`,category:`furniture`},{name:`Lantern`,size:`~500KB`,category:`object`},{name:`ToyCar`,size:`~3MB`,category:`vehicle`},{name:`WaterBottle`,size:`~1MB`,category:`object`},{name:`AntiqueCamera`,size:`~3MB`,category:`object`},{name:`BarramundiFish`,size:`~2MB`,category:`animal`},{name:`Corset`,size:`~500KB`,category:`clothing`},{name:`ReciprocatingSaw`,size:`~5MB`,category:`tool`},{name:`Sponza`,size:`~50MB`,category:`environment`},{name:`DragonAttenuation`,size:`~5MB`,category:`creature`},{name:`IridescenceLamp`,size:`~2MB`,category:`furniture`},{name:`GlassVaseBacklit`,size:`~1MB`,category:`object`},{name:`MaterialsVariantsShoe`,size:`~5MB`,category:`clothing`},{name:`OrientationTest`,size:`~500KB`,category:`test`},{name:`NormalTangentTest`,size:`~500KB`,category:`test`},{name:`EnvironmentTest`,size:`~2MB`,category:`test`},{name:`SheenCloth`,size:`~2MB`,category:`fabric`}];function In(e){let t=String(e||`Duck`).replace(/[^A-Za-z0-9_-]/g,``);return`https://raw.githubusercontent.com/KhronosGroup/glTF-Sample-Assets/main/Models/${t}/glTF-Binary/${t}.glb`}function Ln(e){let t=String(e||``).toLowerCase();return Fn.find(e=>t.includes(e.name.toLowerCase()))||Fn.find(e=>t.includes(e.category.toLowerCase()))||Fn[0]}var Rn=`jarvis_sketchfab_access_token_v1`,zn=[{slug:`by`,label:`CC BY`},{slug:`by-sa`,label:`CC BY-SA`},{slug:`by-nd`,label:`CC BY-ND`},{slug:`by-nc`,label:`CC BY-NC`},{slug:`by-nc-sa`,label:`CC BY-NC-SA`},{slug:`by-nc-nd`,label:`CC BY-NC-ND`},{slug:`cc0`,label:`CC0`},{slug:`standard`,label:`Free Standard`}],Bn=zn.map(e=>e.slug),Vn=new Set(Bn);function Hn(e){if(!e)return``;let t=(typeof e==`string`?e:e.slug||e.uid||e.label||e.fullName||e.url||e.uri||``).toString().trim().toLowerCase(),n=t.match(/(?:^|\/)(cc0|standard|by(?:-nc)?(?:-sa|-nd)?)(?:\/|$)/);if(n)return n[1];if(t.includes(`free standard`)||t===`standard`)return`standard`;if(t.includes(`cc0`)||t.includes(`public domain`))return`cc0`;if(!t.includes(`attribution`)&&!t.includes(`creative commons`))return t;let r=t.includes(`noncommercial`)||t.includes(`non-commercial`),i=t.includes(`noderivs`)||t.includes(`no derivatives`)||t.includes(`no-derivatives`),a=t.includes(`sharealike`)||t.includes(`share alike`)||t.includes(`share-alike`);return r&&i?`by-nc-nd`:r&&a?`by-nc-sa`:r?`by-nc`:i?`by-nd`:a?`by-sa`:`by`}function Un(e){return Vn.has(Hn(e))}function Wn(e){let t=Hn(e);return zn.find(e=>e.slug===t)?.label||t.toUpperCase()}function Gn(){try{return sessionStorage.getItem(`jarvis_sketchfab_access_token_v1`)||``}catch{return``}}function Kn(e){try{let t=String(e||``).trim();t?sessionStorage.setItem(Rn,t):sessionStorage.removeItem(Rn),localStorage.removeItem(Rn)}catch{}}async function qn(e=`studio`){let t=await fetch(`https://api.polyhaven.com/assets?type=hdris`,{cache:`force-cache`});if(!t.ok)throw Error(`PolyHaven HDR request failed: ${t.status}`);let n=await t.json(),r=Object.keys(n);if(!r.length)throw Error(`PolyHaven returned no HDR assets.`);return`https://dl.polyhaven.org/file/ph-assets/HDRIs/hdr/1k/${r.find(t=>t.toLowerCase().includes(String(e).toLowerCase()))||r[0]}_1k.hdr`}function Jn(e,{count:t=12,license:n=``}={}){let r=new URL(`https://api.sketchfab.com/v3/models`);return r.searchParams.set(`q`,String(e||``).trim()),r.searchParams.set(`downloadable`,`true`),r.searchParams.set(`type`,`models`),r.searchParams.set(`count`,String(t)),r.searchParams.set(`archives_flavours`,`true`),n&&r.searchParams.set(`license`,n),r.toString()}async function Yn(e,t=``,{count:n=24}={}){let r=Math.max(4,Math.ceil(n/Bn.length));if(!t){let t=await nr(e,n);if(t)return t}let i=[],a=[];for(let o of Bn)try{let a=await Zn(e,t,o,r);if(i.push(a),Xn(i).length>=n)break}catch(e){a.push(e)}let o=Xn(i);if(!o.length&&a.length===Bn.length)throw Error(a[0]?.message||`Sketchfab search failed for all allowed free licenses.`);let s=new Set;return o.filter(e=>e?.uid&&!s.has(e.uid)&&s.add(e.uid)).filter(e=>e?.isDownloadable!==!1).filter(e=>Un(e?.license)).map(Qn).slice(0,n)}function Xn(e){let t=[],n=Math.max(0,...e.map(e=>e.length));for(let r=0;r<n;r+=1)for(let n of e)n[r]&&t.push(n[r]);return t}async function Zn(e,t,n,r){let i=t?{Authorization:`Bearer ${t}`}:{},a=await fetch(Jn(e,{count:r,license:n}),{headers:i});if(!a.ok)throw Error(`Sketchfab search failed for ${n}: ${a.status}`);let o=await a.json();return Array.isArray(o.results)?o.results:[]}function Qn(e){return{uid:e.uid,name:e.name||`Sketchfab model`,license:Hn(e.license),licenseLabel:Wn(e.license),author:e.user?.displayName||e.user?.username||`Sketchfab creator`,authorUrl:e.user?.profileUrl||``,viewerUrl:e.viewerUrl||`https://sketchfab.com/3d-models/${e.uid}`,thumbnail:ir(e.thumbnails),faceCount:e.faceCount||e.archives?.gltf?.faceCount||e.archives?.glb?.faceCount||0,vertexCount:e.vertexCount||e.archives?.gltf?.vertexCount||e.archives?.glb?.vertexCount||0,size:e.archives?.glb?.size||e.archives?.gltf?.size||0,source:e}}async function $n(e,t){if(!t){let t=await rr(e);if(t)return t}if(!t)throw Error(`Sketchfab downloads require a configured OMEGA Sketchfab token or a pasted OAuth/API token.`);let n=await fetch(`https://api.sketchfab.com/v3/models/${encodeURIComponent(e)}/download`,{headers:{Authorization:`Bearer ${t}`}});if(!n.ok)throw Error(`Sketchfab download request failed: ${n.status}`);return n.json()}function er(e={}){let t=cr(`omega_session`);return t?{...e,Authorization:`Bearer ${t}`}:{...e}}async function tr(){try{let e=await fetch(`/api/sketchfab/status`,{cache:`no-store`,headers:er()});return e.ok?e.json():{ok:!1,configured:!1}}catch{return{ok:!1,configured:!1}}}async function nr(e,t){try{let n=new URLSearchParams({q:String(e||``).trim(),count:String(t)}),r=await fetch(`/api/sketchfab/search?${n}`,{cache:`no-store`,headers:er()});if(!r.ok)return null;let i=await r.json();return!i?.ok||!Array.isArray(i.models)?null:i.models.filter(e=>Un(e.license)).map(e=>({uid:e.uid,name:e.name||`Sketchfab model`,license:Hn(e.license),licenseLabel:Wn(e.license),author:e.author||`Sketchfab creator`,authorUrl:e.authorUrl||``,viewerUrl:e.viewerUrl||`https://sketchfab.com/3d-models/${e.uid}`,thumbnail:e.thumbnail||``,faceCount:e.faceCount||0,vertexCount:e.vertexCount||0,size:e.size||0,source:e}))}catch{return null}}async function rr(e){try{let t=new URLSearchParams({uid:String(e||``)}),n=await fetch(`/api/sketchfab/download?${t}`,{cache:`no-store`,headers:er()});if(!n.ok)return null;let r=await n.json();return!r?.ok||!r.download?null:r.download}catch{return null}}function ir(e){return[...Array.isArray(e?.images)?e.images:[]].sort((e,t)=>(t.width||0)-(e.width||0))[0]?.url||``}var ar=[{name:`Tractor`,provider:`kenney`,url:`https://raw.githubusercontent.com/KhronosGroup/glTF-Sample-Assets/main/Models/CesiumMilkTruck/glTF-Binary/CesiumMilkTruck.glb`,license:`cc0`,author:`Kenney.nl`,thumbnail:`https://raw.githubusercontent.com/KhronosGroup/glTF-Sample-Assets/main/Models/CesiumMilkTruck/screenshot/screenshot-thumb.png`},{name:`Racecar`,provider:`kenney`,url:`https://raw.githubusercontent.com/KhronosGroup/glTF-Sample-Assets/main/Models/ToyCar/glTF-Binary/ToyCar.glb`,license:`cc0`,author:`Kenney.nl`,thumbnail:`https://raw.githubusercontent.com/KhronosGroup/glTF-Sample-Assets/main/Models/ToyCar/screenshot/screenshot-thumb.png`},{name:`Duck`,provider:`kenney`,url:`https://raw.githubusercontent.com/KhronosGroup/glTF-Sample-Assets/main/Models/Duck/glTF-Binary/Duck.glb`,license:`cc0`,author:`Kenney.nl`,thumbnail:`https://raw.githubusercontent.com/KhronosGroup/glTF-Sample-Assets/main/Models/Duck/screenshot/screenshot-thumb.png`},{name:`Lantern`,provider:`kenney`,url:`https://raw.githubusercontent.com/KhronosGroup/glTF-Sample-Assets/main/Models/Lantern/glTF-Binary/Lantern.glb`,license:`cc0`,author:`Kenney.nl`,thumbnail:`https://raw.githubusercontent.com/KhronosGroup/glTF-Sample-Assets/main/Models/Lantern/screenshot/screenshot-thumb.png`},{name:`Sofa`,provider:`kenney`,url:`https://raw.githubusercontent.com/KhronosGroup/glTF-Sample-Assets/main/Models/GlamVelvetSofa/glTF-Binary/GlamVelvetSofa.glb`,license:`cc0`,author:`Kenney.nl`,thumbnail:`https://raw.githubusercontent.com/KhronosGroup/glTF-Sample-Assets/main/Models/GlamVelvetSofa/screenshot/screenshot-thumb.png`},{name:`Water Bottle`,provider:`kenney`,url:`https://raw.githubusercontent.com/KhronosGroup/glTF-Sample-Assets/main/Models/WaterBottle/glTF-Binary/WaterBottle.glb`,license:`cc0`,author:`Kenney.nl`,thumbnail:`https://raw.githubusercontent.com/KhronosGroup/glTF-Sample-Assets/main/Models/WaterBottle/screenshot/screenshot-thumb.png`},{name:`Antique Camera`,provider:`kenney`,url:`https://raw.githubusercontent.com/KhronosGroup/glTF-Sample-Assets/main/Models/AntiqueCamera/glTF-Binary/AntiqueCamera.glb`,license:`cc0`,author:`Kenney.nl`,thumbnail:`https://raw.githubusercontent.com/KhronosGroup/glTF-Sample-Assets/main/Models/AntiqueCamera/screenshot/screenshot-thumb.png`},{name:`Saw`,provider:`kenney`,url:`https://raw.githubusercontent.com/KhronosGroup/glTF-Sample-Assets/main/Models/ReciprocatingSaw/glTF-Binary/ReciprocatingSaw.glb`,license:`cc0`,author:`Kenney.nl`,thumbnail:`https://raw.githubusercontent.com/KhronosGroup/glTF-Sample-Assets/main/Models/ReciprocatingSaw/screenshot/screenshot-thumb.png`},{name:`Castle Sponza`,provider:`kenney`,url:`https://raw.githubusercontent.com/KhronosGroup/glTF-Sample-Assets/main/Models/Sponza/glTF-Binary/Sponza.glb`,license:`cc0`,author:`Kenney.nl`,thumbnail:`https://raw.githubusercontent.com/KhronosGroup/glTF-Sample-Assets/main/Models/Sponza/screenshot/screenshot-thumb.png`},{name:`Robot Expressive`,provider:`quaternius`,url:`https://raw.githubusercontent.com/mrdoob/three.js/master/examples/models/gltf/RobotExpressive.glb`,license:`cc0`,author:`Quaternius.com`,thumbnail:`https://raw.githubusercontent.com/mrdoob/three.js/master/examples/textures/sprites/snowflake1.png`},{name:`Soldier`,provider:`quaternius`,url:`https://raw.githubusercontent.com/mrdoob/three.js/master/examples/models/gltf/Soldier.glb`,license:`cc0`,author:`Quaternius.com`,thumbnail:`https://raw.githubusercontent.com/mrdoob/three.js/master/examples/textures/sprites/snowflake2.png`},{name:`Flamingo`,provider:`quaternius`,url:`https://raw.githubusercontent.com/mrdoob/three.js/master/examples/models/gltf/Flamingo.glb`,license:`cc0`,author:`Quaternius.com`,thumbnail:`https://raw.githubusercontent.com/mrdoob/three.js/master/examples/textures/sprites/snowflake3.png`},{name:`Parrot`,provider:`quaternius`,url:`https://raw.githubusercontent.com/mrdoob/three.js/master/examples/models/gltf/Parrot.glb`,license:`cc0`,author:`Quaternius.com`,thumbnail:`https://raw.githubusercontent.com/mrdoob/three.js/master/examples/textures/sprites/snowflake4.png`},{name:`Stork`,provider:`quaternius`,url:`https://raw.githubusercontent.com/mrdoob/three.js/master/examples/models/gltf/Stork.glb`,license:`cc0`,author:`Quaternius.com`,thumbnail:`https://raw.githubusercontent.com/mrdoob/three.js/master/examples/textures/sprites/snowflake5.png`},{name:`Sheen Chair`,provider:`quaternius`,url:`https://raw.githubusercontent.com/mrdoob/three.js/master/examples/models/gltf/SheenChair.glb`,license:`cc0`,author:`Quaternius.com`,thumbnail:`https://raw.githubusercontent.com/mrdoob/three.js/master/examples/textures/sprites/snowflake6.png`},{name:`XBot Rigged`,provider:`mixamo`,url:`https://raw.githubusercontent.com/mrdoob/three.js/master/examples/models/gltf/Xbot.glb`,license:`free`,author:`Mixamo / Adobe`,thumbnail:`https://raw.githubusercontent.com/mrdoob/three.js/master/examples/textures/sprites/snowflake1.png`},{name:`Soldier Rigged`,provider:`mixamo`,url:`https://raw.githubusercontent.com/mrdoob/three.js/master/examples/models/gltf/Soldier.glb`,license:`free`,author:`Mixamo / Adobe`,thumbnail:`https://raw.githubusercontent.com/mrdoob/three.js/master/examples/textures/sprites/snowflake2.png`},{name:`Robot Anim`,provider:`mixamo`,url:`https://raw.githubusercontent.com/mrdoob/three.js/master/examples/models/gltf/RobotExpressive.glb`,license:`free`,author:`Mixamo / Adobe`,thumbnail:`https://raw.githubusercontent.com/mrdoob/three.js/master/examples/textures/sprites/snowflake3.png`}];function or(e){return String(e||``).toLowerCase().replace(/[^a-z0-9]+/g,`-`).replace(/^-+|-+$/g,``)}function sr(e){return String(e||``).charAt(0).toUpperCase()+String(e||``).slice(1)}function cr(e){try{return localStorage.getItem(`jarvis_${e}_credentials_v1`)||``}catch{return``}}function lr(e,t){try{localStorage.setItem(`jarvis_${e}_credentials_v1`,String(t||``).trim())}catch{}}try{if(typeof localStorage<`u`)for(let e of[`jarvis_poly_pizza_credentials_v1`,`jarvis_cgtrader_credentials_v1`,`jarvis_turbosquid_credentials_v1`,`jarvis_mixamo_credentials_v1`]){let t=localStorage.getItem(e);(t===`omega-public-free-poly-pizza-key-2026`||t===`cgtrader_omega_public_free_session`||t===`turbosquid_omega_public_free_session`||t===`mixamo_omega_public_free_adobe_id`)&&localStorage.removeItem(e)}}catch{}async function ur(e,t,n){try{let r=new URL(`https://www.cgtrader.com/api/v1/models`);r.searchParams.set(`q`,String(e||``).trim()),r.searchParams.set(`free`,`true`),r.searchParams.set(`per_page`,String(Math.min(n,24))),r.searchParams.set(`sort`,`relevance`),r.searchParams.set(`file_type`,`glb,gltf,fbx,obj`);let i=await fetch(r.toString(),{headers:{Authorization:`Token ${t}`,Accept:`application/json`}});if(!i.ok)throw Error(`CGTrader API returned ${i.status}`);let a=await i.json(),o=Array.isArray(a.data)?a.data:Array.isArray(a.models)?a.models:[];if(o.length)return o.map(e=>({uid:`cgtrader:${e.id||e.uid||e.slug}`,name:e.name||e.title||`CGTrader Model`,license:e.license||`free`,licenseLabel:e.license_label||`Free Standard`,author:e.author?.username||e.user?.name||`CGTrader Creator`,authorUrl:`https://www.cgtrader.com/designers/${e.author?.username||``}`,viewerUrl:e.url||`https://www.cgtrader.com/3d-models/${e.slug||e.id}`,thumbnail:e.previews?.[0]?.url||e.preview_url||e.thumbnail||``,faceCount:e.polygon_count||0,vertexCount:e.vertex_count||0,size:e.total_size||0,downloadUrl:e.download_url||e.files?.[0]?.url||``,source:`cgtrader`})).slice(0,n)}catch{}let r=new URLSearchParams({q:String(e||``).trim(),count:String(n),api_key:t}),i=await fetch(`/api/cgtrader/search?${r}`,{cache:`no-store`,headers:er()});if(!i.ok)throw Error(`OMEGA CGTrader proxy returned ${i.status}`);let a=await i.json();if(!a?.ok||!Array.isArray(a.models)||!a.models.length)throw Error(`CGTrader proxy: no results`);return a.models.map(e=>({...e,source:`cgtrader`})).slice(0,n)}async function dr(e,t,n){let r=String(t||``).indexOf(`:`),i=r>0?t.slice(0,r).trim():``,a=r>0?t.slice(r+1).trim():``;try{let t=new URL(`https://www.turbosquid.com/turbosquid/search/api/search`);t.searchParams.set(`search_keyword`,String(e||``).trim()),t.searchParams.set(`price_min`,`0`),t.searchParams.set(`price_max`,`0`),t.searchParams.set(`media_typeid`,`2`),t.searchParams.set(`file_type`,`glb,gltf,fbx`),t.searchParams.set(`per_page`,String(Math.min(n,24))),t.searchParams.set(`sort_by`,`relevance`);let r={Accept:`application/json`};i&&a&&(r.Authorization=`Bearer ${a}`);let o=await fetch(t.toString(),{headers:r});if(!o.ok)throw Error(`TurboSquid API returned ${o.status}`);let s=await o.json(),c=Array.isArray(s.results)?s.results:Array.isArray(s.products)?s.products:[];if(c.length)return c.map(e=>({uid:`turbosquid:${e.id||e.product_id||e.slug}`,name:e.name||e.title||`TurboSquid Model`,license:e.license||`free`,licenseLabel:e.license_label||`Free Standard`,author:e.artist?.username||e.author||`TurboSquid Artist`,authorUrl:`https://www.turbosquid.com/Search/Artists/${e.artist?.username||``}`,viewerUrl:e.url||`https://www.turbosquid.com/3d-models/${e.slug||e.id}`,thumbnail:e.thumbnail_url||e.preview_url||e.thumbnail||``,faceCount:e.polygon_count||0,vertexCount:e.vertex_count||0,size:e.file_size||0,downloadUrl:e.download_url||e.files?.[0]?.download_url||``,source:`turbosquid`})).slice(0,n)}catch{}let o=new URLSearchParams({q:String(e||``).trim(),count:String(n)});i&&o.set(`username`,i),a&&o.set(`api_key`,a);let s=await fetch(`/api/turbosquid/search?${o}`,{cache:`no-store`,headers:er()});if(!s.ok)throw Error(`OMEGA TurboSquid proxy returned ${s.status}`);let c=await s.json();if(!c?.ok||!Array.isArray(c.models)||!c.models.length)throw Error(`TurboSquid proxy: no results`);return c.models.map(e=>({...e,source:`turbosquid`})).slice(0,n)}async function fr(e,t,n){let r=String(t||``).indexOf(`:`);if(r<1)throw Error(`Mixamo: credentials must be adobe_email:adobe_password`);let i=t.slice(0,r).trim(),a=t.slice(r+1).trim();if(!i||!a)throw Error(`Mixamo: email or password empty`);try{let t=await fetch(`https://ims-na1.adobelogin.com/ims/token/v3`,{method:`POST`,headers:{"Content-Type":`application/x-www-form-urlencoded`},body:new URLSearchParams({grant_type:`password`,username:i,password:a,client_id:`mixamo_studio`,client_secret:`mixamo_studio`,scope:`openid,creative_sdk,avatar_sync`})});if(!t.ok)throw Error(`Adobe IMS auth failed: ${t.status}`);let r=(await t.json()).access_token;if(!r)throw Error(`Adobe IMS returned no access_token`);let o=new URL(`https://mixamo-api.adobe.com/v1/products`);o.searchParams.set(`limit`,String(Math.min(n,24))),o.searchParams.set(`offset`,`0`),e&&o.searchParams.set(`query`,String(e).trim()),o.searchParams.set(`type`,`Character,Motion`),o.searchParams.set(`order_by`,`relevance`);let s=await fetch(o.toString(),{headers:{Authorization:`Bearer ${r}`,"X-Api-Key":`mixamo_studio`,Accept:`application/json`}});if(!s.ok)throw Error(`Mixamo API returned ${s.status}`);let c=await s.json(),l=Array.isArray(c.results)?c.results:Array.isArray(c.data)?c.data:[];if(l.length)return l.map(e=>({uid:`mixamo:${e.id||e.character_id||e.slug}`,name:e.name||e.character_name||`Mixamo Character`,license:`free`,licenseLabel:`Free (Mixamo)`,author:`Mixamo / Adobe`,authorUrl:`https://www.mixamo.com/#/?id=${e.id||``}`,viewerUrl:`https://www.mixamo.com/#/?id=${e.id||``}`,thumbnail:e.thumbnail_url||e.preview_url||e.image||``,faceCount:e.polygon_count||0,vertexCount:0,size:0,downloadUrl:e.export_url||``,source:`mixamo`})).slice(0,n)}catch{}let o=await fetch(`/api/mixamo/search`,{method:`POST`,headers:er({"Content-Type":`application/json`}),body:JSON.stringify({email:i,password:a,q:String(e||``).trim(),count:n}),cache:`no-store`});if(!o.ok)throw Error(`OMEGA Mixamo proxy returned ${o.status}`);let s=await o.json();if(!s?.ok||!Array.isArray(s.models)||!s.models.length)throw Error(`Mixamo proxy: no results`);return s.models.map(e=>({...e,source:`mixamo`})).slice(0,n)}async function pr(e,t,n){let r=`https://api.poly.pizza/v1/search?q=${encodeURIComponent(e)}`,i=await fetch(r,{headers:{"x-auth-token":t}});if(!i.ok)throw Error(`Poly.pizza returned ${i.status}`);return((await i.json()).results||[]).map(e=>({uid:`poly_pizza:${e.id||e.uid}`,name:e.title||e.name||`Poly.pizza model`,license:e.license||`cc0`,licenseLabel:e.license||`CC0`,author:e.author||`Poly.pizza Creator`,authorUrl:`https://poly.pizza/m/${e.id||e.uid}`,viewerUrl:`https://poly.pizza/m/${e.id||e.uid}`,thumbnail:e.thumbnail||`https://raw.githubusercontent.com/KhronosGroup/glTF-Sample-Assets/main/Models/Duck/screenshot/screenshot-thumb.png`,faceCount:e.faceCount||0,vertexCount:e.vertexCount||0,size:e.size||0,downloadUrl:e.Download||e.url||``,source:`poly_pizza`})).slice(0,n)}async function mr(e,t=`all`,n=``,{count:r=24}={}){let i=String(e||``).trim().toLowerCase(),a=[];(t===`all`||t===`stable_fast_3d`)&&i&&a.push({uid:`stable_fast_3d:generate:${or(i)}`,name:`Generate: "${i}"`,license:`Local AI Generation`,licenseLabel:`Local`,author:`Stable Fast 3D (Jarvis)`,authorUrl:``,viewerUrl:``,thumbnail:`https://raw.githubusercontent.com/KhronosGroup/glTF-Sample-Assets/main/Models/Box/glTF/Box_thumbnail.jpg`,faceCount:0,vertexCount:0,size:0,downloadUrl:`api:spawn_3d_model:${i}`,source:`stable_fast_3d`,catalogSource:`ai-generation`,provider:`stable_fast_3d`});let o=cr(`poly_pizza`);if((t===`all`||t===`poly_pizza`)&&o&&i)try{let e=await pr(i,o,r);a.push(...e)}catch{}let s=cr(`cgtrader`);if((t===`all`||t===`cgtrader`)&&s&&i)try{let e=await ur(i,s,r);a.push(...e)}catch{}let c=cr(`turbosquid`);if((t===`all`||t===`turbosquid`)&&c&&i)try{let e=await dr(i,c,r);a.push(...e)}catch{}let l=cr(`mixamo`);if((t===`all`||t===`mixamo`)&&l&&i)try{let e=await fr(i,l,r);a.push(...e)}catch{}let u=ar.filter(e=>{let n=t===`all`||e.provider===t,r=!i||e.name.toLowerCase().includes(i)||e.author.toLowerCase().includes(i);return n&&r}).map(e=>({uid:`${e.provider}:${or(e.name)}`,name:e.name,license:e.license,licenseLabel:e.license===`cc0`?`CC0`:`Free`,author:e.author,authorUrl:e.url,viewerUrl:e.url,thumbnail:e.thumbnail,faceCount:0,vertexCount:0,size:0,downloadUrl:e.url,source:e.provider,catalogSource:`curated-sample`,provider:e.provider}));if(a.push(...u),t===`all`||t===`cgtrader`||t===`turbosquid`||t===`poly_pizza`||t===`mixamo`){let e=[{name:`Retro Space Ship`,license:`Free Standard`,author:`Sample fallback asset`,provider:`cgtrader`,url:`https://raw.githubusercontent.com/KhronosGroup/glTF-Sample-Assets/main/Models/DamagedHelmet/glTF-Binary/DamagedHelmet.glb`,keywords:[`space`,`ship`,`rocket`,`vehicle`,`helmet`,`sci-fi`,`scifi`]},{name:`SciFi Plasma Gun`,license:`Free Standard`,author:`Sample fallback asset`,provider:`cgtrader`,url:`https://raw.githubusercontent.com/KhronosGroup/glTF-Sample-Assets/main/Models/Lantern/glTF-Binary/Lantern.glb`,keywords:[`gun`,`weapon`,`scifi`,`plasma`,`laser`]},{name:`Modern Office Chair`,license:`Free Standard`,author:`Sample fallback asset`,provider:`cgtrader`,url:`https://raw.githubusercontent.com/mrdoob/three.js/master/examples/models/gltf/SheenChair.glb`,keywords:[`chair`,`furniture`,`office`,`seat`]},{name:`Astronaut Character`,license:`Free Standard`,author:`Sample fallback asset`,provider:`cgtrader`,url:`https://raw.githubusercontent.com/mrdoob/three.js/master/examples/models/gltf/Soldier.glb`,keywords:[`astronaut`,`person`,`space`,`character`]},{name:`City Sports Car`,license:`Free Standard`,author:`Sample fallback asset`,provider:`turbosquid`,url:`https://raw.githubusercontent.com/KhronosGroup/glTF-Sample-Assets/main/Models/ToyCar/glTF-Binary/ToyCar.glb`,keywords:[`car`,`vehicle`,`sports`,`auto`,`toy`]},{name:`Fighter Jet Plane`,license:`Free Standard`,author:`Sample fallback asset`,provider:`turbosquid`,url:`https://raw.githubusercontent.com/KhronosGroup/glTF-Sample-Assets/main/Models/CesiumMilkTruck/glTF-Binary/CesiumMilkTruck.glb`,keywords:[`plane`,`jet`,`aircraft`,`vehicle`,`fly`]},{name:`Lighthouse Beacon`,license:`Free Standard`,author:`Sample fallback asset`,provider:`turbosquid`,url:`https://raw.githubusercontent.com/KhronosGroup/glTF-Sample-Assets/main/Models/Lantern/glTF-Binary/Lantern.glb`,keywords:[`lighthouse`,`beacon`,`tower`,`building`]},{name:`Industrial Wooden Crate`,license:`Free Standard`,author:`Sample fallback asset`,provider:`turbosquid`,url:`https://raw.githubusercontent.com/KhronosGroup/glTF-Sample-Assets/main/Models/Duck/glTF-Binary/Duck.glb`,keywords:[`crate`,`box`,`barrel`,`wood`,`industrial`]},{name:`Low Poly Tree Pack`,license:`CC0`,author:`Sample fallback asset`,provider:`poly_pizza`,url:`https://raw.githubusercontent.com/KhronosGroup/glTF-Sample-Assets/main/Models/Lantern/glTF-Binary/Lantern.glb`,keywords:[`tree`,`forest`,`plant`,`nature`,`lowpoly`]},{name:`Holographic Gizmo Sphere`,license:`CC0`,author:`Sample fallback asset`,provider:`poly_pizza`,url:`https://raw.githubusercontent.com/KhronosGroup/glTF-Sample-Assets/main/Models/OrientationTest/glTF-Binary/OrientationTest.glb`,keywords:[`sphere`,`gizmo`,`hologram`,`test`]},{name:`Magical Potion Bottle`,license:`CC0`,author:`Sample fallback asset`,provider:`poly_pizza`,url:`https://raw.githubusercontent.com/KhronosGroup/glTF-Sample-Assets/main/Models/WaterBottle/glTF-Binary/WaterBottle.glb`,keywords:[`potion`,`magic`,`bottle`,`drink`]},{name:`Mythical Knight Shield`,license:`CC0`,author:`Sample fallback asset`,provider:`poly_pizza`,url:`https://raw.githubusercontent.com/mrdoob/three.js/master/examples/models/gltf/SheenChair.glb`,keywords:[`shield`,`armor`,`knight`,`weapon`]},{name:`YBot Rigged Character`,license:`Free`,author:`Sample fallback asset`,provider:`mixamo`,url:`https://raw.githubusercontent.com/mrdoob/three.js/master/examples/models/gltf/Xbot.glb`,keywords:[`ybot`,`character`,`man`,`rigged`,`skeletal`]},{name:`Zombie Undead Anim`,license:`Free`,author:`Sample fallback asset`,provider:`mixamo`,url:`https://raw.githubusercontent.com/mrdoob/three.js/master/examples/models/gltf/Soldier.glb`,keywords:[`zombie`,`monster`,`undead`,`animated`,`rigged`]}].filter(e=>{let n=t===`all`||e.provider===t,r=!i||e.name.toLowerCase().includes(i)||e.keywords.some(e=>i.includes(e)||e.includes(i));return n&&r}).map(e=>({uid:`${e.provider}:${or(e.name)}`,name:e.name,license:`free`,licenseLabel:e.license,author:e.author,authorUrl:e.url,viewerUrl:e.url,thumbnail:`https://raw.githubusercontent.com/KhronosGroup/glTF-Sample-Assets/main/Models/Duck/screenshot/screenshot-thumb.png`,faceCount:0,vertexCount:0,size:0,downloadUrl:e.url,source:e.provider,catalogSource:`sample-fallback`,provider:e.provider}));a.push(...e)}if(t===`all`||t===`sketchfab`)try{let t=await Yn(e,n,{count:r});a.push(...t.map(e=>({...e,downloadUrl:``,source:`sketchfab`})))}catch{}let d=new Set;return a=a.filter(e=>e?.uid&&!d.has(e.uid)&&d.add(e.uid)),!a.length&&i&&a.push({uid:`forge:${or(i)}`,name:`${sr(i)} (Interactive Forge)`,license:`free`,licenseLabel:`CC0 / Procedural`,author:`Jarvis Model Forge`,authorUrl:`#`,viewerUrl:`#`,thumbnail:`https://raw.githubusercontent.com/KhronosGroup/glTF-Sample-Assets/main/Models/Duck/screenshot/screenshot-thumb.png`,faceCount:0,vertexCount:0,size:0,downloadUrl:`forge-procedural`,source:`forge`}),a.slice(0,r)}function hr(e,t){try{let n=localStorage.getItem(e);return n?JSON.parse(n):t}catch{return t}}function gr(e,t){try{return localStorage.setItem(e,JSON.stringify(t)),!0}catch{return!1}}function _r(e,t=``){try{return localStorage.getItem(e)||t}catch{return t}}function vr(e,t){try{return localStorage.setItem(e,String(t)),!0}catch{return!1}}var yr=0,br=!1;function xr(e=`ar`){let t=globalThis.crypto?.getRandomValues?Array.from(globalThis.crypto.getRandomValues(new Uint8Array(8)),e=>e.toString(16).padStart(2,`0`)).join(``):(()=>{br||(br=!0),yr=(yr+1)%1048576;let e=String(globalThis.performance?.now?.()||0).replace(`.`,``);return`${Date.now().toString(36)}_${e}_${yr.toString(36)}`})();return`${e}_${Date.now().toString(36)}_${t}`}function Sr(e,t,{valueKey:n=null,labelKey:r=null}={}){if(e){e.replaceChildren();for(let i of t){let t=document.createElement(`option`);if(Array.isArray(i)||n&&r&&i&&typeof i==`object`){let[e,a]=Array.isArray(i)?i:[i[n],i[r]];t.value=String(e??``),t.textContent=String(a??e??``)}else t.value=String(i),t.textContent=String(i);e.appendChild(t)}}}var Cr=1,wr=2048,Tr=8;function Er(e){let t=new Set,n=new Set,r=new Set,i=0,a=0;if(!e?.traverse)return{bytes:0,geometryCount:0,materialCount:0,textureCount:0,maxDimension:0,warnings:[]};e.updateMatrixWorld?.(!0);let o=new xe().setFromObject(e);if(!o.isEmpty()){let e=o.getSize(new S);a=Math.max(e.x,e.y,e.z,0)}e.traverse(e=>{e.geometry&&!t.has(e.geometry)&&(t.add(e.geometry),i+=Mr(e.geometry)),Ar(e.material,e=>{n.has(e)||(n.add(e),i+=2048),jr(e,(e,t)=>{r.has(e)||(r.add(e),i+=Nr(e))})})});let s=[];return i>48*1024*1024&&s.push(`model-asset-heavy`),r.size>12&&s.push(`texture-count-high`),a>12&&s.push(`model-scale-large`),{bytes:i,geometryCount:t.size,materialCount:n.size,textureCount:r.size,maxDimension:a,warnings:s}}function Dr(e,t={}){if(!e?.traverse)return e;let n=Number.isFinite(t.targetSize)?t.targetSize:Cr,r=Number.isFinite(t.maxTextureSize)?t.maxTextureSize:wr,i=Number.isFinite(t.maxAnisotropy)?t.maxAnisotropy:Tr,a=Er(e),o=new xe().setFromObject(e);if(!o.isEmpty()){let t=o.getSize(new S),r=n/Math.max(t.x,t.y,t.z,1e-4),i=o.getCenter(new S);e.position.sub(i),e.scale.multiplyScalar(r)}return e.userData=e.userData||{},e.userData.assetMetrics=a,e.userData.assetWarnings=a.warnings.slice(),e.traverse(e=>{e.isMesh&&(e.castShadow=!0,e.receiveShadow=!0,e.frustumCulled=!0,e.material&&Ar(e.material,(e,t)=>{Or(e,{maxTextureSize:r,maxAnisotropy:i})}))}),e.updateMatrixWorld?.(!0),e}function Or(e,t={}){if(!e)return e;let n=Number.isFinite(t.maxTextureSize)?t.maxTextureSize:wr,r=Number.isFinite(t.maxAnisotropy)?t.maxAnisotropy:Tr;return e.userData=e.userData||{},e.needsUpdate=!0,`roughness`in e&&(e.roughness=Pr(e.roughness)),`metalness`in e&&(e.metalness=Pr(e.metalness)),`emissiveIntensity`in e&&(e.emissiveIntensity=Math.min(Number(e.emissiveIntensity??1),1)),jr(e,(e,t)=>{kr(e,t,{maxTextureSize:n,maxAnisotropy:r})}),e}function kr(e,t=``,n={}){if(!e)return e;let r=Number.isFinite(n.maxTextureSize)?n.maxTextureSize:wr,i=Number.isFinite(n.maxAnisotropy)?n.maxAnisotropy:Tr,a=e.image||{},o=a.width||a.videoWidth||a.naturalWidth||0,s=a.height||a.videoHeight||a.naturalHeight||0;return/map|baseColor|albedo|diffuse|emissive/i.test(t)&&(e.colorSpace=de),e.flipY=!1,e.generateMipmaps=o>0&&s>0,e.minFilter=o>r||s>r?f:h,e.magFilter=f,e.anisotropy=Math.max(1,Math.min(i,e.anisotropy||i)),e.needsUpdate=!0,e}function Ar(e,t){(Array.isArray(e)?e:[e]).filter(Boolean).forEach(e=>t(e))}function jr(e,t){let n=new Set,r=(e,i=``)=>{if(!(!e||typeof e!=`object`)){if(e.isTexture){n.has(e)||(n.add(e),t(e,i));return}if(Array.isArray(e)){e.forEach(e=>r(e,i));return}e.value?.isTexture?r(e.value,i):e.constructor===Object&&Object.entries(e).forEach(([e,t])=>r(t,e))}};Object.entries(e||{}).forEach(([e,t])=>r(t,e))}function Mr(e){let t=0,n=e=>{e?.array?.byteLength&&(t+=e.array.byteLength)};return Object.values(e.attributes||{}).forEach(n),Object.values(e.morphAttributes||{}).forEach(e=>e.forEach(n)),n(e.index),t}function Nr(e){let t=e?.image||{};if(t.data?.byteLength)return t.data.byteLength;let n=t.width||t.videoWidth||t.naturalWidth||256,r=t.height||t.videoHeight||t.naturalHeight||256;return Math.max(1,n)*Math.max(1,r)*4}function Pr(e){return Math.max(0,Math.min(1,Number(e)||0))}var Fr=`jarvis_ar_model_forge_v1`,Ir=[`house`,`room`,`device`,`vehicle`,`character`,`scene`],Lr=[`open`,`close`,`toggle`,`rotate`,`reveal`,`hide`,`shatter`,`reconfigure`];function Rr(){if(globalThis.crypto?.getRandomValues){let e=new Uint32Array(1);return globalThis.crypto.getRandomValues(e),e[0]/4294967295}return performance.now()%997/997}function zr(){return hr(Fr,[])}function Br(e){let t=zr().filter(t=>t.id!==e.id);return t.push(e),gr(Fr,t.slice(-40)),e}function L({name:e=`Custom Model`,prompt:t=``,kit:n=`scene`,parts:r=[],behaviors:i=[]}={}){let a=Ir.includes(String(n||``).toLowerCase())?String(n).toLowerCase():`scene`;return{id:xr(`blueprint`),name:String(e||`Custom Model`).trim()||`Custom Model`,prompt:String(t||``).trim(),kit:a,parts:Array.isArray(r)&&r.length?r.map(di):yi(a),behaviors:Array.isArray(i)&&i.length?i.map(fi):bi(a),createdAt:Date.now(),updatedAt:Date.now()}}async function Vr(e,t={}){let n=String(e||``).trim();if(!n)throw Error(`A prompt is required to generate a blueprint.`);let r=globalThis.Jarvis;if(!r?.query)return w(`Jarvis is unavailable, so the model forge is using a local template blueprint instead.`,`Model Forge`),L({name:t.name||n.slice(0,24),prompt:n,kit:t.kit||`scene`});let i=[`Create a compact JSON blueprint for a fully interactive 3D model.`,`Return JSON only, no markdown, no prose.`,`Schema:`,`{`,` "name": "string",`,` "kit": "house|room|device|vehicle|character|scene",`,` "parts": [`,` {`,` "name": "string",`,` "type": "base|wall|door|window|roof|drawer|panel|screen|wheel|prop|light|arm|leg|head|detail",`,` "geometry": "box|sphere|cylinder|cone|torus|ring|capsule|octahedron|icosahedron",`,` "material": "matte|metal|glass|glow|wood",`,` "position": [0,0,0],`,` "rotation": [0,0,0],`,` "scale": [1,1,1],`,` "actions": ["open","close","toggle","rotate","reveal","hide","shatter","reconfigure"]`,` }`,` ],`,` "behaviors": [`,` { "gesture": "pinch|fist|open-palm|swipe-left|swipe-right|two-hand-scale", "action": "string", "target": "part name" }`,` ]`,`}`,`Prompt: ${n}`,t.name?`Preferred name: ${t.name}`:``,t.kit?`Preferred kit: ${t.kit}`:``].filter(Boolean).join(`
`);try{let e=Ti(await r.query(i));if(e){let r=L({name:e.name||t.name||n.slice(0,24),prompt:n,kit:e.kit||t.kit||`scene`,parts:Array.isArray(e.parts)?e.parts:[],behaviors:Array.isArray(e.behaviors)?e.behaviors:[]});return r.prompt=n,r.source=`jarvis`,r.updatedAt=Date.now(),r}}catch(e){w(`Jarvis blueprint generation failed, using local template: ${e.message}`,`Model Forge`)}return L({name:t.name||n.slice(0,24),prompt:n,kit:t.kit||gi(n)})}function Hr(e,t=pe){let n=e?.id?e:L(e),r=new t.Group;r.name=`interactive-${B(n.name)}`,r.userData.isARObject=!0,r.userData.modelName=n.name,r.userData.modelForge={id:n.id,kit:n.kit,prompt:n.prompt,behaviors:n.behaviors,parts:[],state:{}};let i=[],a={base:[],walls:[],doors:[],windows:[],roofs:[],details:[],lights:[],wheels:[],screens:[],arms:[],legs:[],heads:[],drawers:[]};for(let e of n.parts){let n=ei(e,t);i.push(n),r.add(n.root),a[mi(e.type)].push(n),r.userData.modelForge.parts.push({id:n.id,name:n.name,type:n.type,actions:n.actions.slice()})}return ti(r,a,n,t),Ur(r,n),Br(n),r}function Ur(e,t){return e.userData.modelForge=e.userData.modelForge||{},e.userData.modelForge.id=t.id,e.userData.modelForge.kit=t.kit,e.userData.modelForge.prompt=t.prompt,e.userData.modelForge.behaviors=Array.isArray(t.behaviors)?t.behaviors.map(fi):[],e.userData.modelForge.parts=e.userData.modelForge.parts||[],e}function Wr(e,t,{minScore:n=.5,minHits:r=2}={}){let i=String(e||``).toLowerCase(),a=new Set((t||[]).map(e=>B(e.name)).filter(Boolean));if(!a.size)return null;let o=null,s=0;for(let e of zr()){if(!e||e.source!==`jarvis`||String(e.kit||``).toLowerCase()!==i)continue;let t=Array.isArray(e.behaviors)?e.behaviors:[],c=[...new Set(t.map(e=>B(e.target)).filter(Boolean))];if(!c.length)continue;let l=c.filter(e=>a.has(e)).length,u=l/c.length;l>=r&&u>=n&&u>s&&(o=e,s=u)}return o?{blueprint:o,score:s}:null}function Gr(e,t={}){if(!e)throw Error(`No model object was provided.`);let n=t.kit||_i(e),r=Array.isArray(t.parts)&&t.parts.length?t.parts:Kr(e,n),i=t.name||e.userData?.modelName||`Custom Model`,a=Wr(n,r);if(a){let o={...a.blueprint,id:xr(`blueprint`),name:i,prompt:t.prompt||a.blueprint.prompt||``,parts:r.map(di),source:`template-reuse`,templateOf:a.blueprint.id,updatedAt:Date.now()};return Ur(e,o),e.userData.modelForgeBlueprint=o,k(`forge-template-reused`,{name:i,kit:n,score:a.score,templateOf:a.blueprint.id}),w(`Reused interactive template for ${i} (${Math.round(a.score*100)}% part match) — no regeneration needed.`,`Model Forge`),o}let o=L({name:i,prompt:t.prompt||``,kit:n,parts:r,behaviors:t.behaviors||bi(n,r)});return Ur(e,o),e.userData.modelForgeBlueprint=o,globalThis.Jarvis?.query&&Vr(`We have a 3D model named "${i}" (kit: "${n}") containing discovered parts: ${r.map(e=>e.name).join(`, `)}. Create an ultimate interactive Stark-level behavioral blueprint. Generate highly custom actions (like 'raise landing gear', 'ignite thruster', 'open cockpit') and bind them to the correct parts using gestures.`,{name:i,kit:n}).then(t=>{t&&t.source===`jarvis`&&(Ur(e,t),e.userData.modelForgeBlueprint=t,$r(e),k(`object-placed`,{object:e,modelName:i}),k(`assistant`,`Stark Interface synchronized for ${i}. Loaded bespoke interactive controls.`),w(`Stark Interface synchronized for ${i}.`,`Jarvis AI`))}).catch(e=>{w(`Jarvis background blueprint upgrade failed for ${i}.`,`Model Forge`)}),o}function Kr(e,t=_i(e)){let n=[];return e?.traverse?.(t=>{!t.isMesh&&!t.isObject3D||t!==e&&n.push({name:t.name||t.userData?.partName||t.userData?.role||`part_${n.length+1}`,type:mi(t.userData?.role||t.userData?.partType||hi(t.name)),material:`matte`,position:[t.position.x,t.position.y,t.position.z],rotation:[t.rotation.x,t.rotation.y,t.rotation.z],scale:[t.scale.x,t.scale.y,t.scale.z],actions:xi(t.userData?.role||hi(t.name))})}),n.length>=2?n:wi(e,t,n)}function qr(e,t=document.createElement(`div`)){let n=e?.userData?.modelForge,r=Array.isArray(n?.behaviors)&&n.behaviors.length?[...new Set(n.behaviors.map(e=>e.action).filter(Boolean))]:Lr;t.replaceChildren(),t.style.cssText=`display:flex;flex-wrap:wrap;gap:8px`;for(let n of r){let r=document.createElement(`button`);r.className=`panel-action`,r.textContent=n,r.onclick=()=>Zr(e,n),t.appendChild(r)}return t}function Jr(e,t){let n=e.parent||t.parent;if(!n)return!1;let r=new xe().setFromObject(t),i=Number.isFinite(r.max.y)?r.max.y:t.position.y+.2,a=Number.isFinite(r.min.x)&&Number.isFinite(r.max.x)?(r.min.x+r.max.x)/2:t.position.x,o=Number.isFinite(r.min.z)&&Number.isFinite(r.max.z)?(r.min.z+r.max.z)/2:t.position.z,s=new g;n.add(s);let c=[];for(let e=0;e<20;e++){let t=new b(new ke(.015,8,8),new d({color:3388415,transparent:!0,opacity:.85}));t.position.set(a+(Rr()-.5)*.04,i,o+(Rr()-.5)*.04),s.add(t),c.push({mesh:t,velocity:new S((Rr()-.5)*.05,-.4-Rr()*.3,(Rr()-.5)*.05),delay:e*60})}let l=performance.now(),u=2e3,f=()=>{let e=performance.now()-l;if(e>u){n.remove(s),s.traverse(e=>{e.isMesh&&(e.geometry?.dispose(),e.material?.dispose())});return}c.forEach(n=>{if(e>n.delay){n.velocity.y-=.012,n.mesh.position.addScaledVector(n.velocity,.016);let r=1-(e-n.delay)/(u-n.delay);n.mesh.material.opacity=Math.max(0,r*.85),n.mesh.position.y<t.position.y-.3&&n.mesh.scale.multiplyScalar(.94)}}),requestAnimationFrame(f)};return f(),w(`Water flowing successfully from ${t.userData?.modelName||`source`}.`,`Water Flow`),!0}function Yr(e,t,n){let r=!1;return e.traverse(e=>{let t=String(e.name||``).toLowerCase(),i=String(e.userData?.partType||``).toLowerCase();(i.includes(`light`)||i.includes(`lamp`)||i.includes(`glow`)||t.includes(`light`)||t.includes(`lamp`)||t.includes(`glow`))&&(r=!0,e.userData.partState=e.userData.partState||{},e.userData.partState.open=n,e.traverse(e=>{e.isLight&&(e.visible=n,e.intensity=n?2.5:0)}),e.isMesh&&e.material&&(n?(e.material.emissive&&e.material.emissive.setHex(16771584),e.material.emissiveIntensity!==void 0&&(e.material.emissiveIntensity=2),e.material.color&&e.material.color.setHex(16771584)):(e.material.emissive&&e.material.emissive.setHex(0),e.material.emissiveIntensity!==void 0&&(e.material.emissiveIntensity=0),e.material.color&&e.material.color.setHex(8109311))))}),r?(w(n?`Lights turned ON successfully.`:`Lights turned OFF successfully.`,`Lighting Control`),!0):!1}function Xr(e,t){let n=null,r=t.replace(`open-`,``).replace(`close-`,``).replace(`toggle-`,``).trim().toLowerCase();if(e.traverse(e=>{if(n)return;let t=String(e.userData?.partName||e.name||``).toLowerCase();(t.includes(r)||r===`boot`&&t.includes(`trunk`)||r===`trunk`&&t.includes(`boot`))&&(n=e)}),n){let e=t.startsWith(`open-`)||t.startsWith(`toggle-`)&&!n.userData.partState?.open;return ri(n,e),w(`${e?`Opening`:`Closing`} ${n.userData.partName||r} pivot hinge.`,`Hinge Action`),!0}return!1}function Zr(e,t,n={}){if(!e)return!1;let r=String(t||``).toLowerCase().trim().replace(/\s+/g,`-`);if(/^(open|close|toggle)-(boot|hood|trunk|door|door-left|door-right)$/.test(r)&&Xr(e,r)||/^(turn-on-lights|on-lights|lights-on|lights-off|off-lights|turn-off-lights|lights|on|off)$/.test(r)&&Yr(e,e,!r.includes(`off`)&&r!==`off`)||/^(bring-water|pour-water|pour|water|fill)$/.test(r)&&Jr(e,e))return!0;let i=(e.userData?.modelForge?.behaviors||[]).filter(e=>e.action===r||e.gesture===r),a=i.length?i.map(t=>ui(e,t.target)).filter(Boolean):[e],o=!1;for(let t of a)o=ni(e,t,r,n)||o;return!o&&e!==a[0]&&(o=ni(e,e,r,n)),o}function Qr(e,t,n={}){let r=String(t||``).toLowerCase(),i=(e?.userData?.modelForge?.behaviors||[]).filter(e=>e.gesture===r);if(!i.length)return r===`pinch`?Zr(e,`toggle`,n):r===`fist`?Zr(e,`grab`,n):r===`swipe-left`?Zr(e,`close`,n):r===`swipe-right`?Zr(e,`open`,n):r===`two-hand-scale`?Zr(e,`reconfigure`,n):!1;let a=!1;for(let t of i)a=ni(e,ui(e,t.target)||e,t.action,n)||a;return a}function $r(e){let t=e?.userData?.modelForgeBlueprint||e?.userData?.modelForge;return t?Br({...t,updatedAt:Date.now(),name:e.userData?.modelName||t.name||`Custom Model`}):null}function ei(e,t){let n=xr(`part`),r=String(e.name||e.role||`part_${n.slice(-4)}`).trim()||`part_${n.slice(-4)}`,i=mi(e.type||e.role),a=Si(e.material,t),o=new t.Group;o.name=`${B(r)}_root`,o.position.fromArray(Ei(e.position)),o.rotation.set(...Di(e.rotation)),o.scale.set(...Oi(e.scale)),o.userData.partId=n,o.userData.partName=r,o.userData.partType=i,o.userData.partActions=Array.isArray(e.actions)&&e.actions.length?e.actions.map(pi):xi(i);let s=null,c=null;if(e.geometry){let n=String(e.geometry).toLowerCase().trim();n===`box`||n===`cube`?c=new t.BoxGeometry(.25,.25,.25):n===`sphere`?c=new t.SphereGeometry(.15,32,16):n===`cylinder`?c=new t.CylinderGeometry(.1,.1,.28,24):n===`cone`?c=new t.ConeGeometry(.12,.26,24):n===`torus`?c=new t.TorusGeometry(.14,.02,12,48):n===`ring`?c=new t.RingGeometry(.08,.14,32):n===`capsule`?c=new t.CapsuleGeometry(.08,.2,8,24):n===`octahedron`?c=new t.OctahedronGeometry(.12):n===`icosahedron`&&(c=new t.IcosahedronGeometry(.12))}if(c)s=new t.Mesh(c,a),o.add(s);else if(i===`door`){let n=new t.Group;n.name=`${B(r)}_hinge`,n.userData.interactivePivot=!0,n.position.x=0;let i=new t.Mesh(new t.BoxGeometry(.22,.5,.04),a);i.position.x=.11,i.castShadow=!0,i.receiveShadow=!0,n.add(i),o.add(n),s=i,o.userData.interactivePivot=n,o.userData.closedRotation=0,o.userData.openRotation=Number.isFinite(e.openAngle)?e.openAngle:Math.PI/2}else if(i===`window`)s=new t.Mesh(new t.PlaneGeometry(.35,.3),a),s.position.z=.02,o.add(s);else if(i===`roof`)s=new t.Mesh(new t.ConeGeometry(.34,.28,4),a),s.rotation.y=Math.PI/4,o.add(s);else if(i===`light`){s=new t.Mesh(new t.SphereGeometry(.09,32,16),a);let e=new t.PointLight(16777215,1.2,2.6,2);e.position.set(0,0,0),o.add(s,e),o.userData.light=e}else i===`wheel`?(s=new t.Mesh(new t.CylinderGeometry(.11,.11,.05,20),a),s.rotation.z=Math.PI/2,o.add(s)):i===`screen`?(s=new t.Mesh(new t.BoxGeometry(.42,.25,.03),a),o.add(s)):(s=new t.Mesh(Ci(i,t),a),o.add(s));return o.userData.partMesh=s,o.userData.partState={open:!1,visible:!0,rotated:!1,shatter:!1},{id:n,name:r,type:i,root:o,mesh:s,actions:o.userData.partActions}}function ti(e,t,n,r){let i=String(n.kit||`scene`).toLowerCase(),a=t.base[0]?.root||t.walls[0]?.root||t.details[0]?.root||null;return a&&a.scale.multiplyScalar(1),i===`house`?(t.base[0]&&t.base[0].root.position.set(0,-.15,0),t.walls.forEach((e,t)=>{e.root.position.set(t%2==0?-.16:.16,.05,t<2?-.16:.16),e.root.scale.set(1,1,1)}),t.doors[0]&&t.doors[0].root.position.set(.18,-.12,.18),t.windows[0]&&t.windows[0].root.position.set(-.18,.06,.18),t.roofs[0]&&t.roofs[0].root.position.set(0,.28,0)):i===`room`?(t.base[0]&&t.base[0].root.position.set(0,-.18,0),t.walls.forEach((e,t)=>{e.root.position.set(t<2?-.22:.22,.05,t%2==0?-.22:.22)})):i===`vehicle`?(t.base[0]&&t.base[0].root.position.set(0,-.08,0),t.wheels.forEach((e,t)=>{let n=t<2?-.22:.22,r=t%2==0?-.16:.16;e.root.position.set(n,-.16,r)})):i===`device`&&(t.base[0]&&t.base[0].root.position.set(0,0,0),t.screens.forEach(e=>e.root.position.set(0,.01,.01))),e.userData.modelForge.layout=i,e}function ni(e,t,n,r={}){if(!t)return!1;let i=String(n||``).toLowerCase();return i===`open`?ri(t,!0):i===`close`?ri(t,!1):i===`toggle`?ri(t,!t.userData.partState?.open):i===`rotate`?ii(t,r?.delta||Math.PI/2):i===`reveal`?ai(t,!0):i===`hide`?ai(t,!1):i===`shatter`?oi(e,t):i===`reconfigure`?si(e):i===`grab`?ci(t,r):li(t,i,r)}function ri(e,t){let n=e.userData.interactivePivot||e,r=n.rotation.y,i=t?e.userData.openRotation??Math.PI/2:e.userData.closedRotation??0;return e.userData.partState=e.userData.partState||{},e.userData.partState.open=t,ki(360,e=>{n.rotation.y=r+(i-r)*Ai(e)})}function ii(e,t){let n=e.userData.partMesh||e,r=e.userData.rotateAxis||`y`,i=n.rotation[r],a=i+t;return e.userData.partState=e.userData.partState||{},e.userData.partState.rotated=!0,ki(240,e=>{n.rotation[r]=i+(a-i)*ji(e)})}function ai(e,t){return e.visible=t,e.traverse?.(e=>{e.visible=t}),e.userData.partState=e.userData.partState||{},e.userData.partState.visible=t,!0}function oi(e,t){let n=[];if(t.traverse?.(e=>{e.isMesh&&n.push(e)}),!n.length)return si(e);let r=new S;return t.getWorldPosition(r),n.forEach((e,t)=>{let n=new S(Math.cos(t*2.399),.35+t%3*.12,Math.sin(t*1.917)).normalize();e.userData.shatterStart=performance.now(),e.userData.shatterFrom=r.clone(),e.userData.shatterDirection=n}),ki(680,e=>{let t=Ai(e);n.forEach(e=>{let n=e.userData.shatterDirection;n&&(e.position.copy(n).multiplyScalar(t*.65),e.rotation.x+=.05*t,e.rotation.y+=.06*t,e.rotation.z+=.04*t)})})}function si(e){let t=e.children.filter(e=>e.isObject3D);return t.forEach((e,t)=>{let n=Math.floor(t/3),r=(t%3-1)*.18,i=.04*n,a=(n-.5)*.12;e.position.x+=r*.2,e.position.y+=i*.2,e.position.z+=a*.2}),ki(340,e=>{let n=Ai(e);t.forEach((e,t)=>{let r=Math.floor(t/3),i=(t%3-1)*.18,a=.04*r,o=(r-.5)*.12;e.position.x+=(i-e.position.x)*n*.12,e.position.y+=(a-e.position.y)*n*.12,e.position.z+=(o-e.position.z)*n*.12})})}function ci(e,t){return t?.position&&e.position?.copy?(e.position.copy(t.position),!0):(e.userData.partState=e.userData.partState||{},e.userData.partState.grabbed=!0,!0)}function li(e,t,n){e.userData.partState=e.userData.partState||{},e.userData.partState.lastAction=t;let r=String(t||``).toLowerCase().trim();if(r.includes(`raise`)||r.includes(`lift`)||r===`up`||r.includes(`deploy-gear`)){let t=e.position.y;return ki(400,n=>{e.position.y=t+.12*Ai(n)})}if(r.includes(`lower`)||r===`down`||r.includes(`retract-gear`)){let t=e.position.y;return ki(400,n=>{e.position.y=t-.12*Ai(n)})}if(r.includes(`extend`)||r.includes(`deploy`)||r.includes(`unfold`)||r.includes(`expand`)){let t=e.scale.clone(),n=e.rotation.y;return ki(500,r=>{let i=Ai(r);e.scale.copy(t).multiplyScalar(1+.18*i),e.rotation.y=n+.35*i})}if(r.includes(`retract`)||r.includes(`fold`)||r.includes(`pull`)||r.includes(`collapse`)){let t=e.scale.clone(),n=e.rotation.y;return ki(500,r=>{let i=Ai(r);e.scale.copy(t).multiplyScalar(1-.18*i),e.rotation.y=n-.35*i})}if(r.includes(`ignite`)||r.includes(`fire`)||r.includes(`charge`)||r.includes(`thrust`)||r.includes(`launch`)){if(e.isMesh&&e.material){let t=e.material.emissive?e.material.emissive.getHex():0;e.material.emissive=new ie(54015),e.material.emissiveIntensity!==void 0&&(e.material.emissiveIntensity=4),window.setTimeout(()=>{e.material.emissive&&e.material.emissive.setHex(t),e.material.emissiveIntensity!==void 0&&(e.material.emissiveIntensity=0)},1e3)}return!0}return e.userData.partState.lastContext=n||{},!0}function ui(e,t){let n=B(t);if(!n)return null;let r=null;return e.traverse?.(e=>{r||[e.name,e.userData?.partName,e.userData?.role,e.userData?.partType].filter(Boolean).map(B).includes(n)&&(r=e.userData?.interactivePivot||e)}),r}function di(e={}){return{name:String(e.name||e.role||`part`).trim(),type:mi(e.type||e.role),material:[`matte`,`metal`,`glass`,`glow`,`wood`].includes(String(e.material||``).toLowerCase())?String(e.material).toLowerCase():`matte`,geometry:e.geometry?String(e.geometry).toLowerCase().trim():void 0,position:Ei(e.position),rotation:Di(e.rotation),scale:Oi(e.scale),actions:Array.isArray(e.actions)&&e.actions.length?e.actions.map(pi):xi(e.type||e.role),openAngle:Number.isFinite(e.openAngle)?e.openAngle:void 0}}function fi(e={}){return{gesture:String(e.gesture||``).toLowerCase().trim(),action:pi(e.action||e.trigger||``),target:String(e.target||e.part||``).trim()}}function pi(e){return String(e||``).toLowerCase().trim().replace(/\s+/g,`-`)}function mi(e){let t=String(e||``).toLowerCase().trim().replace(/\s+/g,`-`);return[`wall`,`door`,`window`,`roof`,`drawer`,`panel`,`screen`,`wheel`,`prop`,`light`,`arm`,`leg`,`head`,`detail`,`base`].includes(t)?t:hi(t)}function hi(e){let t=B(e);return t.includes(`door`)?`door`:t.includes(`window`)?`window`:t.includes(`roof`)?`roof`:t.includes(`wheel`)?`wheel`:t.includes(`screen`)||t.includes(`display`)?`screen`:t.includes(`light`)||t.includes(`lamp`)?`light`:t.includes(`drawer`)?`drawer`:t.includes(`wall`)?`wall`:t.includes(`base`)||t.includes(`floor`)?`base`:t.includes(`arm`)?`arm`:t.includes(`leg`)?`leg`:t.includes(`head`)?`head`:`detail`}function gi(e){let t=B(e);return t.includes(`house`)||t.includes(`home`)?`house`:t.includes(`room`)||t.includes(`bedroom`)||t.includes(`kitchen`)?`room`:t.includes(`car`)||t.includes(`truck`)||t.includes(`vehicle`)?`vehicle`:t.includes(`phone`)||t.includes(`device`)||t.includes(`tablet`)?`device`:t.includes(`character`)||t.includes(`person`)||t.includes(`robot`)?`character`:`scene`}function _i(e){return gi(B(e?.userData?.modelName||e?.name||``))}function R(e,t){let n=new Set(e.map(B));for(let e of t)if(n.has(B(e)))return e;return``}function z(e){return e===`house`||e===`room`?`core`:e===`vehicle`?`chassis`:e===`device`?`screen`:e===`character`?`torso`:`core`}function vi(e){return Math.max(.04,Math.min(Number(e)||1,4))}function yi(e){let t={house:[{name:`base`,type:`base`,material:`matte`,position:[0,-.15,0],scale:[1.2,.6,1.2]},{name:`front-door`,type:`door`,material:`wood`},{name:`left-window`,type:`window`,material:`glass`},{name:`right-window`,type:`window`,material:`glass`},{name:`roof`,type:`roof`,material:`matte`}],room:[{name:`floor`,type:`base`,material:`matte`,position:[0,-.16,0],scale:[1.3,.05,1.3]},{name:`wall-a`,type:`wall`,material:`matte`},{name:`wall-b`,type:`wall`,material:`matte`},{name:`door`,type:`door`,material:`metal`},{name:`window`,type:`window`,material:`glass`}],device:[{name:`body`,type:`base`,material:`metal`,position:[0,0,0],scale:[1,.6,.15]},{name:`screen`,type:`screen`,material:`glass`,position:[0,.01,.09]},{name:`button`,type:`detail`,material:`glow`,position:[.27,-.05,.08],scale:[.16,.16,.16]}],vehicle:[{name:`chassis`,type:`base`,material:`metal`,position:[0,-.03,0],scale:[1.2,.36,.64]},{name:`wheel-front-left`,type:`wheel`,material:`metal`,position:[-.35,-.18,-.22]},{name:`wheel-front-right`,type:`wheel`,material:`metal`,position:[.35,-.18,-.22]},{name:`wheel-back-left`,type:`wheel`,material:`metal`,position:[-.35,-.18,.22]},{name:`wheel-back-right`,type:`wheel`,material:`metal`,position:[.35,-.18,.22]}],character:[{name:`torso`,type:`base`,material:`matte`,position:[0,.02,0],scale:[.36,.5,.18]},{name:`head`,type:`head`,material:`matte`,position:[0,.4,0],scale:[.28,.28,.28]},{name:`left-arm`,type:`arm`,material:`matte`,position:[-.28,.12,0],scale:[.12,.42,.12]},{name:`right-arm`,type:`arm`,material:`matte`,position:[.28,.12,0],scale:[.12,.42,.12]},{name:`left-leg`,type:`leg`,material:`matte`,position:[-.12,-.42,0],scale:[.12,.42,.12]},{name:`right-leg`,type:`leg`,material:`matte`,position:[.12,-.42,0],scale:[.12,.42,.12]}],scene:[{name:`core`,type:`base`,material:`matte`,position:[0,0,0],scale:[.9,.6,.9]},{name:`detail-a`,type:`detail`,material:`glow`,position:[-.26,.12,.2]},{name:`detail-b`,type:`detail`,material:`glow`,position:[.28,.1,-.18]},{name:`control-panel`,type:`screen`,material:`glass`,position:[0,.18,.32]}]};return t[e]||t.scene}function bi(e,t=[]){let n=t.map(e=>B(e.name)),r=R(n,[`front-door`,`door`,`front`,`main-door`,`screen`,`control-panel`])||z(e),i=R(n,[`roof`,`top`,`cover`,`lid`])||z(e),a=R(n,[`screen`,`display`,`control-panel`])||z(e),o=R(n,[`wheel-front-left`,`wheel-front-right`,`wheel-back-left`,`wheel-back-right`,`wheel`])||z(e),s={house:[{gesture:`pinch`,action:`toggle`,target:r},{gesture:`open-palm`,action:`reconfigure`,target:i},{gesture:`swipe-left`,action:`close`,target:r},{gesture:`swipe-right`,action:`open`,target:r},{gesture:`fist`,action:`shatter`,target:i}],room:[{gesture:`pinch`,action:`open`,target:r},{gesture:`fist`,action:`close`,target:r},{gesture:`two-hand-scale`,action:`reconfigure`,target:R(n,[`floor`,`base`])||z(e)},{gesture:`open-palm`,action:`reveal`,target:a}],device:[{gesture:`pinch`,action:`toggle`,target:a},{gesture:`open-palm`,action:`reveal`,target:R(n,[`body`,`base`])||z(e)},{gesture:`swipe-left`,action:`hide`,target:a},{gesture:`swipe-right`,action:`open`,target:a}],vehicle:[{gesture:`pinch`,action:`toggle`,target:R(n,[`chassis`,`base`])||z(e)},{gesture:`fist`,action:`reconfigure`,target:o},{gesture:`swipe-left`,action:`rotate`,target:o},{gesture:`swipe-right`,action:`open`,target:R(n,[`door`,`hood`,`trunk`])||z(e)}],character:[{gesture:`pinch`,action:`toggle`,target:R(n,[`head`])||z(e)},{gesture:`fist`,action:`grab`,target:R(n,[`torso`,`body`])||z(e)},{gesture:`swipe-right`,action:`reconfigure`,target:R(n,[`left-arm`,`arm`])||z(e)},{gesture:`swipe-left`,action:`rotate`,target:R(n,[`right-arm`,`arm`])||z(e)}],scene:[{gesture:`pinch`,action:`toggle`,target:R(n,[`core`,`root`,`base`])||z(e)},{gesture:`open-palm`,action:`reconfigure`,target:a},{gesture:`fist`,action:`shatter`,target:R(n,[`detail-a`,`detail-b`])||z(e)}]};return(s[e]||s.scene).filter(Boolean)}function xi(e){let t=mi(e);return t===`door`?[`open`,`close`,`toggle`]:t===`window`?[`open`,`close`,`toggle`,`reveal`]:t===`drawer`?[`open`,`close`,`toggle`]:t===`wheel`?[`rotate`]:t===`screen`||t===`light`?[`toggle`,`reveal`,`hide`]:Lr.slice()}function Si(e,t){let n=String(e||`matte`).toLowerCase();return n===`metal`?new t.MeshPhysicalMaterial({color:9422847,roughness:.16,metalness:.92}):n===`glass`?new t.MeshPhysicalMaterial({color:13627391,roughness:.05,transmission:.58,transparent:!0,opacity:.36}):n===`glow`?new t.MeshBasicMaterial({color:51455,transparent:!0,opacity:.9}):n===`wood`?new t.MeshStandardMaterial({color:9202255,roughness:.82,metalness:.02}):new t.MeshStandardMaterial({color:8109311,roughness:.55,metalness:.1})}function Ci(e,t){let n=mi(e);return n===`base`||n===`wall`?new t.BoxGeometry(.5,.32,.5):n===`drawer`?new t.BoxGeometry(.28,.14,.28):n===`arm`?new t.CapsuleGeometry(.06,.28,5,16):n===`leg`?new t.CapsuleGeometry(.06,.34,5,16):n===`head`?new t.SphereGeometry(.16,24,16):n===`detail`?new t.IcosahedronGeometry(.08,1):new t.BoxGeometry(.22,.22,.22)}function wi(e,t,n=[]){let r=new xe;if(e&&r.setFromObject(e),!Number.isFinite(r.min.x)||!Number.isFinite(r.max.x))return[...n,...yi(t)];let i=r.getSize(new S),a=Math.max(i.x,.1),o=Math.max(i.y,.1),s=Math.max(i.z,.1),c=Math.max(a,o,s)||.4,l=[{name:`core`,type:`base`,material:`matte`,position:[0,0,0],scale:[1,1,1],actions:[`toggle`,`reconfigure`,`shatter`]},{name:`zone-front`,type:`panel`,material:`glass`,position:[0,0,s*.35],scale:[.72,.72,.12],actions:[`open`,`close`,`toggle`,`reveal`,`hide`]},{name:`zone-back`,type:`panel`,material:`glass`,position:[0,0,-s*.35],scale:[.72,.72,.12],actions:[`open`,`close`,`toggle`,`reveal`,`hide`]},{name:`zone-left`,type:`panel`,material:`glass`,position:[-a*.35,0,0],scale:[.12,.72,.72],actions:[`rotate`,`reconfigure`]},{name:`zone-right`,type:`panel`,material:`glass`,position:[a*.35,0,0],scale:[.12,.72,.72],actions:[`rotate`,`reconfigure`]},{name:`zone-top`,type:`roof`,material:`matte`,position:[0,o*.35,0],scale:[.85,.16,.85],actions:[`open`,`close`,`reconfigure`]},{name:`zone-bottom`,type:`base`,material:`matte`,position:[0,-o*.35,0],scale:[.85,.16,.85],actions:[`reconfigure`,`grab`]},{name:`zone-core`,type:`detail`,material:`glow`,position:[0,0,0],scale:[.42,.42,.42],actions:[`toggle`,`shatter`,`reveal`,`hide`]}];return[...n,...l.map(e=>({...e,scale:[vi(e.scale[0]*(c/1.25)),vi(e.scale[1]*(c/1.25)),vi(e.scale[2]*(c/1.25))]}))]}function Ti(e){if(!e)return null;let t=String(e).replace(/```json|```/gi,``).trim(),n=t.indexOf(`{`),r=t.lastIndexOf(`}`);if(n<0||r<0||r<=n)return null;try{return JSON.parse(t.slice(n,r+1))}catch{return null}}function Ei(e){return Array.isArray(e)&&e.length>=3?[Number(e[0])||0,Number(e[1])||0,Number(e[2])||0]:e&&typeof e==`object`?[Number(e.x)||0,Number(e.y)||0,Number(e.z)||0]:[0,0,0]}function Di(e){return Array.isArray(e)&&e.length>=3?[Number(e[0])||0,Number(e[1])||0,Number(e[2])||0]:e&&typeof e==`object`?[Number(e.x)||0,Number(e.y)||0,Number(e.z)||0]:[0,0,0]}function Oi(e){return Array.isArray(e)&&e.length>=3?[Number(e[0])||1,Number(e[1])||1,Number(e[2])||1]:e&&typeof e==`object`?[Number(e.x)||1,Number(e.y)||1,Number(e.z)||1]:[1,1,1]}function ki(e,t){let n=performance.now();return new Promise(r=>{let i=a=>{let o=Math.min((a-n)/e,1);t(o),o<1?requestAnimationFrame(i):r(!0)};requestAnimationFrame(i)})}function Ai(e){return 1-(1-e)**3}function ji(e){return e<.5?4*e*e*e:1-(-2*e+2)**3/2}function B(e){return String(e||``).toLowerCase().replace(/[^a-z0-9]+/g,`-`).replace(/^-+|-+$/g,``)}var Mi=!1,Ni=!1,Pi=!1,Fi={default:{name:`default`,refDistance:.72,maxDistance:8,rolloffFactor:1.6,dampening:.08,cueGain:1},cinema:{name:`cinema`,refDistance:1.05,maxDistance:12,rolloffFactor:1.25,dampening:.16,cueGain:1.08},open:{name:`open`,refDistance:.68,maxDistance:16,rolloffFactor:1.15,dampening:.03,cueGain:.96},quiet:{name:`quiet`,refDistance:.84,maxDistance:7,rolloffFactor:1.8,dampening:.12,cueGain:.92},lab:{name:`lab`,refDistance:.78,maxDistance:9,rolloffFactor:1.5,dampening:.06,cueGain:1.02}};function Ii(){Mi||(Mi=!0,O(`ar-scene-live`,()=>Hi()),O(`object-placed`,({object:e})=>Li(e)),Ui(),Wi(),Hi(),F(`spatialAudio`,!!Gi()),F(`speechSynthesis`,!!window.speechSynthesis),F(`voiceRecognition`,!!(window.SpeechRecognition||window.webkitSpeechRecognition)))}function Li(e){if(!e)return null;let t=Hi();if(!t)return null;if(e.userData.spatialAudio={...Fi[D.spatialAudio.environmentProfile]||Fi.default,...e.userData.spatialAudio||{}},e.userData.spatialAudioEmitter?.parent===e)return e.userData.spatialAudioEmitter;let n=new ve(t);return n.name=`jarvis-object-spatial-audio`,zi(n,e.userData.spatialAudio),e.add(n),e.userData.spatialAudioAttached=!0,e.userData.spatialAudioEmitter=n,n}async function Ri(e,t=`select`){if(!e)return!1;let n=Hi(),r=Gi();if(!n||!r)return!1;try{if(r.state===`suspended`&&await r.resume(),r.state!==`running`)return!1;D.spatialAudio.unlocked=!0;let i=e.parent?Li(e):Vi(n,e);return i?(i.isPlaying&&i.stop(),i.setBuffer(Ki(r,t)),i.setVolume((Fi[D.spatialAudio.environmentProfile]?.cueGain||1)*(t===`delete`?.9:1)),i.play(),window.setTimeout(()=>{try{i.stop()}catch{}i.userData.detachedAnchor&&(i.userData.detachedAnchor.parent?.remove(i.userData.detachedAnchor),i.disconnect())},420),!0):!1}catch{return!1}}function zi(e,t={}){e.setRefDistance(t.refDistance||.72),e.setMaxDistance(t.maxDistance||8),e.setRolloffFactor(t.rolloffFactor||1.6),e.setDistanceModel(`inverse`)}function Bi(e=`default`){let t=Fi[String(e||`default`).toLowerCase()]||Fi.default;return D.spatialAudio.environmentProfile=t.name,D.spatialAudio.roomProfile={...t},D.placedObjects.forEach(e=>{let n=e?.userData?.spatialAudioEmitter;n&&zi(n,t)}),D.spatialAudio.listener?.context&&(D.spatialAudio.context=D.spatialAudio.listener.context),F(`spatialAudio`,!!Gi()),t}function Vi(e,t){let n=new g;t.getWorldPosition(n.position),I().scene.add(n);let r=new ve(e);return r.name=`jarvis-detached-spatial-cue`,zi(r,t.userData.spatialAudio||Fi.default),r.userData.detachedAnchor=n,n.add(r),r}function Hi(){let{camera:e}=I();return e?(D.spatialAudio.listener||(D.spatialAudio.listener=new Se),D.spatialAudio.listener.parent!==e&&(D.spatialAudio.listener.parent?.remove(D.spatialAudio.listener),e.add(D.spatialAudio.listener)),D.spatialAudio.enabled=!0,D.spatialAudio.context=Gi(),D.spatialAudio.listener):null}function Ui(){if(Pi)return;Pi=!0;let e=()=>Bi(D.nativeOptions?.activeEnvironment||D.spatialAudio.environmentProfile||`default`);O(`native-options`,e),O(`native-ui-state`,e=>{let t=e?.audioEnvironment||e?.environment||e?.profile;t&&Bi(t)}),e()}function Wi(){if(Ni)return;Ni=!0;let e=async()=>{let e=Gi();if(e)try{await e.resume(),D.spatialAudio.unlocked=e.state===`running`,D.spatialAudio.micPermission=D.spatialAudio.unlocked?`granted`:D.spatialAudio.micPermission,D.spatialAudio.unlocked&&w(`Spatial audio unlocked for AR objects.`,`Spatial Audio`)}catch{D.spatialAudio.unlocked=!1}};window.addEventListener(`pointerdown`,e,{passive:!0}),window.addEventListener(`touchstart`,e,{passive:!0})}function Gi(){try{return Ae.getContext()}catch{return null}}function Ki(e,t){let n=e.sampleRate,r=Math.max(1,Math.floor(n*.24)),i=e.createBuffer(1,r,n),a=i.getChannelData(0),o=t===`place`?330:t===`delete`?180:t===`open`?520:430;for(let e=0;e<r;e+=1){let t=e/n,r=Math.exp(-t*12)*Math.min(1,t*90);a[e]=(Math.sin(Math.PI*2*o*t)*.72+Math.sin(Math.PI*2*o*1.5*t)*.2)*r*.16}return i}var qi=null,V=null,Ji=null,Yi=!1,Xi=new Map,Zi=null,Qi=1/60,$i=3,ea=0,ta=0,na=null;function ra(){return Yi&&!!V}function ia(){return na||(na=aa()),na}async function aa(){qi=await t(()=>import(`./physics-Bz_ouFt8.js`).then(e=>e.t),__vite__mapDeps([3,2]),import.meta.url),await qi.init();let e=new qi.Vector3(0,-9.81,0);V=new qi.World(e),Ji=new qi.EventQueue(!0),V.numSolverIterations=8,D.physicsWorld=V,Yi=!0,ta=performance.now();let n=qi.RigidBodyDesc.fixed().setTranslation(0,0,0);Zi=V.createRigidBody(n);let r=qi.ColliderDesc.cuboid(100,.1,100).setFriction(.7).setRestitution(.1);V.createCollider(r,Zi),sa(),console.log(`[AR Physics] Rapier3D world initialized — 60Hz fixed timestep, CCD enabled, 8 solver iterations.`)}var oa=0;function sa(){if(oa)return;let e=performance.now(),t=()=>{let n=performance.now();ca(n-e),e=n,oa=P(t)};oa=P(t)}function ca(e){if(!Yi||!V)return;let t=performance.now(),n=typeof e==`number`&&e>0&&e<200?e/1e3:Math.min((t-ta)/1e3,.05);ta=t,ea+=n;let r=0;for(;ea>=Qi&&r<$i;)V.step(Ji),ea-=Qi,r++;Ji.drainCollisionEvents((e,t,n)=>{n&&window.dispatchEvent(new CustomEvent(`ar-physics-collision`,{detail:{handle1:e,handle2:t}}))});for(let[e,t]of Xi.entries()){let n=e.translation(),r=e.rotation();t.position.set(n.x,n.y,n.z),t.quaternion.set(r.x,r.y,r.z,r.w)}Xi.size>0&&window.dispatchEvent(new CustomEvent(`ar-physics-step`))}function la(e,t=`dynamic`){if(!V)return null;let n=t===`dynamic`?qi.RigidBodyDesc.dynamic():qi.RigidBodyDesc.fixed();n.setTranslation(e.x,e.y,e.z),t===`dynamic`&&(n.setLinearDamping(.1),n.setAngularDamping(.05),n.setCcdEnabled(!0));let r=V.createRigidBody(n),i=qi.ColliderDesc.ball(.2).setFriction(.7).setRestitution(.3);return V.createCollider(i,r),r}function ua(e,t){Xi.set(t,e)}function da(e){V&&V.removeRigidBody(e),Xi.delete(e)}var fa=Uint8Array,pa=Uint16Array,ma=Int32Array,ha=new fa([0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,0,0,0]),ga=new fa([0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13,0,0]),_a=new fa([16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15]),va=function(e,t){for(var n=new pa(31),r=0;r<31;++r)n[r]=t+=1<<e[r-1];for(var i=new ma(n[30]),r=1;r<30;++r)for(var a=n[r];a<n[r+1];++a)i[a]=a-n[r]<<5|r;return{b:n,r:i}},ya=va(ha,2),ba=ya.b,xa=ya.r;ba[28]=258,xa[258]=28;var Sa=va(ga,0),Ca=Sa.b;Sa.r;for(var wa=new pa(32768),H=0;H<32768;++H){var Ta=(H&43690)>>1|(H&21845)<<1;Ta=(Ta&52428)>>2|(Ta&13107)<<2,Ta=(Ta&61680)>>4|(Ta&3855)<<4,wa[H]=((Ta&65280)>>8|(Ta&255)<<8)>>1}for(var Ea=(function(e,t,n){for(var r=e.length,i=0,a=new pa(t);i<r;++i)e[i]&&++a[e[i]-1];var o=new pa(t);for(i=1;i<t;++i)o[i]=o[i-1]+a[i-1]<<1;var s;if(n){s=new pa(1<<t);var c=15-t;for(i=0;i<r;++i)if(e[i])for(var l=i<<4|e[i],u=t-e[i],d=o[e[i]-1]++<<u,f=d|(1<<u)-1;d<=f;++d)s[wa[d]>>c]=l}else for(s=new pa(r),i=0;i<r;++i)e[i]&&(s[i]=wa[o[e[i]-1]++]>>15-e[i]);return s}),Da=new fa(288),H=0;H<144;++H)Da[H]=8;for(var H=144;H<256;++H)Da[H]=9;for(var H=256;H<280;++H)Da[H]=7;for(var H=280;H<288;++H)Da[H]=8;for(var Oa=new fa(32),H=0;H<32;++H)Oa[H]=5;var ka=Ea(Da,9,1),Aa=Ea(Oa,5,1),ja=function(e){for(var t=e[0],n=1;n<e.length;++n)e[n]>t&&(t=e[n]);return t},Ma=function(e,t,n){var r=t/8|0;return(e[r]|e[r+1]<<8)>>(t&7)&n},Na=function(e,t){var n=t/8|0;return(e[n]|e[n+1]<<8|e[n+2]<<16)>>(t&7)},Pa=function(e){return(e+7)/8|0},Fa=function(e,t,n){return(t==null||t<0)&&(t=0),(n==null||n>e.length)&&(n=e.length),new fa(e.subarray(t,n))},Ia=[`unexpected EOF`,`invalid block type`,`invalid length/literal`,`invalid distance`,`stream finished`,`no stream handler`,,`no callback`,`invalid UTF-8 data`,`extra field too long`,`date not in range 1980-2099`,`filename too long`,`stream finishing`,`invalid zip data`],La=function(e,t,n){var r=Error(t||Ia[e]);if(r.code=e,Error.captureStackTrace&&Error.captureStackTrace(r,La),!n)throw r;return r},Ra=function(e,t,n,r){var i=e.length,a=r?r.length:0;if(!i||t.f&&!t.l)return n||new fa(0);var o=!n,s=o||t.i!=2,c=t.i;o&&(n=new fa(i*3));var l=function(e){var t=n.length;if(e>t){var r=new fa(Math.max(t*2,e));r.set(n),n=r}},u=t.f||0,d=t.p||0,f=t.b||0,p=t.l,m=t.d,h=t.m,g=t.n,_=i*8;do{if(!p){u=Ma(e,d,1);var ee=Ma(e,d+1,3);if(d+=3,!ee){var v=Pa(d)+4,te=e[v-4]|e[v-3]<<8,ne=v+te;if(ne>i){c&&La(0);break}s&&l(f+te),n.set(e.subarray(v,ne),f),t.b=f+=te,t.p=d=ne*8,t.f=u;continue}else if(ee==1)p=ka,m=Aa,h=9,g=5;else if(ee==2){var re=Ma(e,d,31)+257,ie=Ma(e,d+10,15)+4,y=re+Ma(e,d+5,31)+1;d+=14;for(var b=new fa(y),ae=new fa(19),x=0;x<ie;++x)ae[_a[x]]=Ma(e,d+x*3,7);d+=ie*3;for(var oe=ja(ae),se=(1<<oe)-1,ce=Ea(ae,oe,1),x=0;x<y;){var le=ce[Ma(e,d,se)];d+=le&15;var v=le>>4;if(v<16)b[x++]=v;else{var ue=0,de=0;for(v==16?(de=3+Ma(e,d,3),d+=2,ue=b[x-1]):v==17?(de=3+Ma(e,d,7),d+=3):v==18&&(de=11+Ma(e,d,127),d+=7);de--;)b[x++]=ue}}var fe=b.subarray(0,re),pe=b.subarray(re);h=ja(fe),g=ja(pe),p=Ea(fe,h,1),m=Ea(pe,g,1)}else La(1);if(d>_){c&&La(0);break}}s&&l(f+131072);for(var me=(1<<h)-1,he=(1<<g)-1,ge=d;;ge=d){var ue=p[Na(e,d)&me],_e=ue>>4;if(d+=ue&15,d>_){c&&La(0);break}if(ue||La(2),_e<256)n[f++]=_e;else if(_e==256){ge=d,p=null;break}else{var ve=_e-254;if(_e>264){var x=_e-257,ye=ha[x];ve=Ma(e,d,(1<<ye)-1)+ba[x],d+=ye}var be=m[Na(e,d)&he],xe=be>>4;be||La(3),d+=be&15;var pe=Ca[xe];if(xe>3){var ye=ga[xe];pe+=Na(e,d)&(1<<ye)-1,d+=ye}if(d>_){c&&La(0);break}s&&l(f+131072);var S=f+ve;if(f<pe){var Se=a-pe,Ce=Math.min(pe,S);for(Se+f<0&&La(3);f<Ce;++f)n[f]=r[Se+f]}for(;f<S;++f)n[f]=n[f-pe]}}t.l=p,t.p=ge,t.b=f,t.f=u,p&&(u=1,t.m=h,t.d=m,t.n=g)}while(!u);return f!=n.length&&o?Fa(n,0,f):n.subarray(0,f)},za=new fa(0),Ba=function(e,t){return e[t]|e[t+1]<<8},Va=function(e,t){return(e[t]|e[t+1]<<8|e[t+2]<<16|e[t+3]<<24)>>>0},Ha=function(e,t){return Va(e,t)+Va(e,t+4)*4294967296};function Ua(e,t){return Ra(e,{i:2},t&&t.out,t&&t.dictionary)}var Wa=typeof TextDecoder<`u`&&new TextDecoder;try{Wa.decode(za,{stream:!0})}catch{}var Ga=function(e){for(var t=``,n=0;;){var r=e[n++],i=(r>127)+(r>223)+(r>239);if(n+i>e.length)return{s:t,r:Fa(e,n-1)};i?i==3?(r=((r&15)<<18|(e[n++]&63)<<12|(e[n++]&63)<<6|e[n++]&63)-65536,t+=String.fromCharCode(55296|r>>10,56320|r&1023)):i&1?t+=String.fromCharCode((r&31)<<6|e[n++]&63):t+=String.fromCharCode((r&15)<<12|(e[n++]&63)<<6|e[n++]&63):t+=String.fromCharCode(r)}};function Ka(e,t){if(t){for(var n=``,r=0;r<e.length;r+=16384)n+=String.fromCharCode.apply(null,e.subarray(r,r+16384));return n}else if(Wa)return Wa.decode(e);else{var i=Ga(e),a=i.s,n=i.r;return n.length&&La(8),a}}var qa=function(e,t){return t+30+Ba(e,t+26)+Ba(e,t+28)},Ja=function(e,t,n){var r=Ba(e,t+28),i=Ka(e.subarray(t+46,t+46+r),!(Ba(e,t+8)&2048)),a=t+46+r,o=Va(e,t+20),s=n&&o==4294967295?Ya(e,a):[o,Va(e,t+24),Va(e,t+42)],c=s[0],l=s[1],u=s[2];return[Ba(e,t+10),c,l,i,a+Ba(e,t+30)+Ba(e,t+32),u]},Ya=function(e,t){for(;Ba(e,t)!=1;t+=4+Ba(e,t+2));return[Ha(e,t+12),Ha(e,t+4),Ha(e,t+20)]};function Xa(e,t){for(var n={},r=e.length-22;Va(e,r)!=101010256;--r)(!r||e.length-r>65558)&&La(13);var i=Ba(e,r+8);if(!i)return{};var a=Va(e,r+16),o=a==4294967295||i==65535;if(o){var s=Va(e,r-12);o=Va(e,s)==101075792,o&&(i=Va(e,s+32),a=Va(e,s+48))}for(var c=t&&t.filter,l=0;l<i;++l){var u=Ja(e,a,o),d=u[0],f=u[1],p=u[2],m=u[3],h=u[4],g=u[5],_=qa(e,g);a=h,(!c||c({name:m,size:f,originalSize:p,compression:d}))&&(d?d==8?n[m]=Ua(e.subarray(_,_+f),{out:new fa(p)}):La(14,`unknown compression type `+d):n[m]=Fa(e,_,_+f))}return n}var Za=new d({color:16777215,transparent:!0,opacity:.72}),Qa=`jarvis_ar_placed_objects_v1`,$a=`jarvis_ar_my_models_v1`,eo=`0.158.0`,to=new Oe().setDecoderPath(`https://cdn.jsdelivr.net/npm/three@${eo}/examples/jsm/libs/draco/`),no=new me().setTranscoderPath(`https://cdn.jsdelivr.net/npm/three@${eo}/examples/jsm/libs/basis/`),ro=!1;function io(){if(ro)return;let e=I()?.renderer;if(e)try{no.detectSupport(e),ro=!0}catch{}}function ao(e){return e.setDRACOLoader(to),e.setKTX2Loader(no),e.setMeshoptDecoder(ze),e}var oo=ao(new He),so=8,co=180*1024*1024,lo=new Map,uo=0,fo=null,po=0,mo=new Map,ho=0,go=``,_o=0,vo=0,yo=!1,bo=!1,xo=0,So=new Map,Co=new Set;function wo(){Eo(),Lo(),O(`open-model-forge`,Ao),O(`open-models`,Do),O(`jarvis-model-action`,e=>fs(e)),O(`gesture-pinch`,e=>ds(`pinch`,e)),O(`gesture-fist`,e=>ds(`fist`,e)),O(`gesture-open-palm`,e=>ds(`open-palm`,e)),O(`gesture-swipe-left`,e=>ds(`swipe-left`,e)),O(`gesture-swipe-right`,e=>ds(`swipe-right`,e)),O(`gesture-two-hand-scale`,e=>ds(`two-hand-scale`,e)),O(`world-anchor-sample`,()=>Ss()),O(`native-ar-state`,e=>To(e)),O(`spawn-model`,async e=>{zo(Ln(e?.query||`Duck`).name)}),O(`spawn-generated-glb`,async e=>{if(!e?.model_url)return;let t=e?.model_name||`Generated Model`;try{w(`Loading generated model: ${t}...`,`Jarvis AI Generation`);let n=String(e.model_url);if(n.startsWith(`/`)){let e=D.jarvis?.apiBase?.()||``;e&&(n=`${e}${n}`)}let r=await Ko(n);r.userData.modelName=t,Gr(r,L({name:t,kit:Js(t)})),Ho(r,window.AR_CAMERA_POSITION||new S(0,0,-2)),w(`Successfully deployed ${t}!`,`Jarvis AI Generation`)}catch(e){C(`Failed to load generated model: ${e.message}`,`Generation Error`)}}),setInterval(()=>Zo(),6e4)}function To(e={}){let t=Array.isArray(e.objects)?e.objects:[];for(let e of t){let t=String(e.id||e.uid||``).trim(),n=String(e.label||e.name||e.modelName||e.type||`Native Object`),r=e.position||{x:Number(e.px??e.x??0),y:Number(e.py??e.y??D.floorY+.08),z:Number(e.pz??e.z??-1.6)},i=t?D.placedObjects.find(e=>e.userData.id===t):null;if(i){i.position.copy(Us(r)),i.userData.modelName=n,hs(i);continue}let a=us(n);t&&(a.userData.id=t),a.userData.sourceURL=`native-apk-state`,Gr(a,L({name:n,kit:Js(n)})),Go(a,n,r,null,`native-apk-state`)}}function Eo(){if(yo||bo)return;let e=()=>{yo||(yo=!0,vs().catch(e=>C(e.message,`Model Restore Failed`)))};if(D.liveSceneReady){e();return}bo=!0;let t=O(`ar-scene-live`,()=>{t(),bo=!1,e()})}function Do(){let e=document.createElement(`div`),t=document.createElement(`input`);t.placeholder=`Search free models`;let n=document.createElement(`div`);n.className=`panel-list`;let r=document.createElement(`input`);r.type=`file`,r.accept=`.glb,.gltf,.obj,.fbx`;let i=Oo(),a=document.createElement(`button`);a.className=`panel-action`,a.textContent=`Open Custom 3D Builder`,a.onclick=Rs;let o=document.createElement(`button`);o.className=`panel-action`,o.textContent=`Open Interactive Model Forge`,o.onclick=Ao;let s=document.createElement(`p`);s.className=`panel-note`,s.textContent=`Create models with behavior schemas, named parts, and Jarvis-generated interactions.`,e.append(t,n,i,r,a,o,s);let c=()=>{let e=t.value.toLowerCase();n.replaceChildren(...Fn.filter(t=>!e||t.name.toLowerCase().includes(e)||t.category.includes(e)).map(e=>Po(e)))};t.addEventListener(`input`,c),r.addEventListener(`change`,()=>Fo(r.files?.[0])),c(),new bn({title:`Models`,body:e,icon:`M`,width:390,height:560}).focus()}function Oo(){let e=document.createElement(`section`);e.className=`sketchfab-panel`;let t=document.createElement(`strong`);t.textContent=`JARVIS 3D Asset Nexus`;let n=document.createElement(`p`);n.className=`panel-note`,n.textContent=`Connectors: Turbosquid, CGTrader, Mixamo, Poly.pizza, Kenney, Quaternius, Sketchfab.`;let r=document.createElement(`button`);r.className=`panel-action`,r.style.cssText=`width: 100%; margin: 6px 0; padding: 10px 14px; text-align: left; display: flex; align-items: center; justify-content: space-between; font-size: 13px; border-radius: 12px; font-weight: 500;`;let i=document.createElement(`span`);i.textContent=`API Connectors Logins`;let a=document.createElement(`span`);a.className=`chevron`,a.textContent=`v`,a.style.cssText=`transition: transform 0.25s ease; display: inline-block;`,r.append(i,a);let o=document.createElement(`div`);o.style.cssText=`display: none; flex-direction: column; gap: 10px; margin: 8px 0; padding: 14px; border: 1px solid var(--separator); border-radius: 14px; background: rgba(0,0,0,0.22);`;function s(e,t,n,r){let i=document.createElement(`div`);i.style.cssText=`display: flex; flex-direction: column; gap: 4px;`;let a=document.createElement(`div`);a.style.cssText=`display: flex; align-items: center; justify-content: space-between; font-size: 12px;`;let o=document.createElement(`span`);o.textContent=n,o.style.color=`var(--text-secondary)`;let s=document.createElement(`span`);s.style.cssText=`display: inline-flex; align-items: center; gap: 4px; font-size: 10px; font-weight: 600; text-transform: uppercase; cursor: pointer;`;let c=document.createElement(`input`);c.type=`password`,c.placeholder=t,c.value=e===`sketchfab`?Gn():cr(e),c.style.cssText=`margin: 2px 0 !important; min-height: 38px !important; padding: 8px 12px !important; font-size: 12px !important; border-radius: 10px !important;`;let l=document.createElement(`div`);l.style.cssText=`font-size: 10px; color: var(--warning); display: none; padding: 2px 0 0 2px; line-height: 1.4;`;let u=()=>{let e=c.value.trim();s.replaceChildren();let t=document.createElement(`span`);e?(t.style.cssText=`color:var(--success); margin-right: 2px;`,t.textContent=`●`,s.append(t,document.createTextNode(` Authenticated ✓`)),l.style.display=`none`):(t.style.cssText=`color:var(--warning); margin-right: 2px;`,t.textContent=`●`,s.append(t,document.createTextNode(` No key — tap to add`)),r&&(l.style.display=`block`,l.innerHTML=`⚡ Get your free key at <span style="color:var(--accent);text-decoration:underline;">${r}</span>`))};return s.addEventListener(`click`,()=>c.focus()),c.addEventListener(`input`,u),u(),a.append(o,s),i.append(a,c,l),{wrapper:i,input:c,updateStatus:u}}let c=document.createElement(`div`);c.style.cssText=`background: rgba(96,165,250,0.12); border: 1px solid rgba(96,165,250,0.3); border-radius: 10px; padding: 10px 12px; font-size: 11px; color: rgba(255,255,255,0.85); line-height: 1.5;`,c.innerHTML=`🔑 <strong>Enter your API keys below to unlock live search.</strong><br>Yellow ● = no key set (uses sample models). Green ● = live API active.<br>Kenney &amp; Quaternius are always free — no key needed.`;let l=s(`omega_session`,`OMEGA cloud session token`,`OMEGA Cloud Link`,``),u=s(`sketchfab`,`Sketchfab OAuth/API Token`,`Sketchfab API`,`sketchfab.com/settings/password-api`),d=s(`poly_pizza`,`Poly.pizza API Key`,`Poly.pizza API`,`poly.pizza/account`),f=s(`cgtrader`,`CGTrader API Token`,`CGTrader API Token`,`cgtrader.com/account`),p=s(`turbosquid`,`username:api_key`,`TurboSquid user:key`,`turbosquid.com/Account`),m=s(`mixamo`,`adobe_email:adobe_password`,`Mixamo Adobe email:pass`,`mixamo.com (use your Adobe login)`),h=document.createElement(`div`);h.style.cssText=`display: flex; gap: 8px; font-size: 11px; background: rgba(255,255,255,0.05); padding: 8px 10px; border-radius: 10px; color: var(--text-secondary); justify-content: space-between;`,h.append(ko(`Kenney`,`CC0 active`),ko(`Quaternius`,`CC0 active`));let g=document.createElement(`button`);g.className=`panel-action`,g.textContent=`Save Credentials`,g.style.cssText=`min-height: 38px; font-size: 13px; font-weight: 600; background: var(--accent); color: #fff; margin-top: 6px;`,g.onclick=()=>{let e=l.input.value.trim()!==cr(`omega_session`);if(lr(`omega_session`,l.input.value),Kn(u.input.value),lr(`poly_pizza`,d.input.value),lr(`cgtrader`,f.input.value),lr(`turbosquid`,p.input.value),lr(`mixamo`,m.input.value),e&&D.jarvis){try{D.jarvis.ws?.close()}catch{}D.jarvis.loadConfig()}l.updateStatus(),u.updateStatus(),d.updateStatus(),f.updateStatus(),p.updateStatus(),m.updateStatus(),w(`All 3D Asset Nexus connector credential configurations saved locally.`,`Credentials Saved`)},o.append(c,l.wrapper,u.wrapper,d.wrapper,f.wrapper,p.wrapper,m.wrapper,h,g);let _=!1;r.onclick=()=>{_=!_,o.style.display=_?`flex`:`none`,r.querySelector(`.chevron`).style.transform=_?`rotate(180deg)`:`rotate(0)`};let ee=document.createElement(`div`);ee.className=`inline-row`,ee.style.cssText=`margin: 6px 0; display: flex; align-items: center; gap: 8px;`;let v=document.createElement(`span`);v.textContent=`Source:`,v.style.cssText=`font-size: 13px; color: var(--text-secondary);`;let te=document.createElement(`select`);te.style.cssText=`flex: 1; background: rgba(0,0,0,.35); color: #fff; border: 1px solid var(--glass-border); border-radius: 8px; padding: 6px; font-size: 13px;`,[{value:`all`,label:`All Free Sources (Combined)`},{value:`poly_pizza`,label:`Poly.pizza (Free CC0)`},{value:`kenney`,label:`Kenney.nl (CC0 Game Assets)`},{value:`quaternius`,label:`Quaternius (CC0 Low-Poly)`},{value:`mixamo`,label:`Mixamo (Free Rigged Characters)`},{value:`sketchfab`,label:`Sketchfab (Free CC Assets)`},{value:`cgtrader`,label:`CGTrader (Free CC0/Standard)`},{value:`turbosquid`,label:`Turbosquid (Free CC0/Standard)`}].forEach(e=>{let t=document.createElement(`option`);t.value=e.value,t.textContent=e.label,te.appendChild(t)}),ee.append(v,te);let ne=document.createElement(`div`);ne.className=`inline-row`;let re=document.createElement(`input`);re.placeholder=`Search free 3D models...`;let ie=document.createElement(`button`);ie.className=`panel-action`,ie.textContent=`Search`,ne.append(re,ie);let y=document.createElement(`div`);y.className=`panel-list sketchfab-results`;let b=document.createElement(`p`);b.className=`panel-note`,b.textContent=`Ready to search unified free connectors.`;let ae=!1;return tr().then(e=>{e?.configured&&(ae=!0,b.textContent=`OMEGA Sketchfab token active. Search & placement run completely free.`,u.input.placeholder=`Optional override token`)}).catch(()=>{}),ie.onclick=async()=>{let e=u.input.value.trim()||Gn();Kn(e);let t=te.value;b.textContent=`Searching free assets from ${te.options[te.selectedIndex].text}...`,y.replaceChildren();try{let n=await mr(re.value||`object`,t,e);if(!n.length){b.textContent=`No free assets matched your query on the selected source.`;return}b.textContent=`Found ${n.length} free asset(s).`,y.replaceChildren(...n.map(t=>jo(t,()=>u.input.value.trim()||e,()=>ae)))}catch(e){b.textContent=`Unified search failed.`,C(e.message,`Asset Search Failed`)}},e.append(t,n,r,o,ee,ne,b,y),e}function ko(e,t){let n=document.createElement(`div`),r=document.createElement(`strong`);r.textContent=`${e}:`;let i=document.createElement(`span`);return i.style.color=`var(--success)`,i.textContent=` ● `,n.append(r,i,document.createTextNode(t)),n}async function Ao(){let e=document.createElement(`div`),t=document.createElement(`strong`),n=document.createElement(`p`),r=document.createElement(`input`),i=document.createElement(`select`),a=document.createElement(`textarea`),o=document.createElement(`pre`),s=document.createElement(`div`),c=document.createElement(`button`),l=document.createElement(`button`),u=document.createElement(`button`),d=document.createElement(`button`),f=L({name:`Custom Model`,kit:`scene`}),p=f;t.textContent=`Jarvis 3D Forge`,n.className=`panel-note`,n.textContent=`Build a model as geometry + parts + behaviors + triggers + scripts + exports.`,r.placeholder=`Model name`,r.value=f.name,a.rows=5,a.placeholder=`Describe the model, its parts, and the actions you want`,a.value=`Create a fully interactive model with named parts, gestures, and a behavior schema.`,Sr(i,[`scene`,`house`,`room`,`device`,`vehicle`,`character`]),o.style.cssText=`white-space:pre-wrap;font:12px/1.45 monospace;color:rgba(255,255,255,.82);background:rgba(0,0,0,.25);padding:10px;border-radius:12px;max-height:220px;overflow:auto`,s.className=`panel-row`,c.className=`panel-action`,c.textContent=`Generate Blueprint`,l.className=`panel-action`,l.textContent=`Attach to Selected`,u.className=`panel-action`,u.textContent=`Build and Place`,d.className=`panel-action`,d.textContent=`Save Blueprint`;let m=()=>{o.textContent=JSON.stringify(p,null,2),s.replaceChildren();let e=D.selectedObject||D.placedObjects.at(-1)||null;e&&qr(e,s)};m(),c.onclick=async()=>{try{p=await Vr(a.value,{name:r.value,kit:i.value}),p.name=r.value||p.name,p.prompt=a.value,p.kit=i.value,p.updatedAt=Date.now(),m(),w(`Jarvis blueprint generated. Review the schema and then attach or build.`,`Model Forge`)}catch(e){C(e.message,`Model Forge Failed`)}},l.onclick=()=>{let e=D.selectedObject;if(!e){w(`Select a model first, then attach the schema.`,`Model Forge`);return}Gr(e,{...p,name:r.value||p.name||e.userData.modelName||`Custom Model`,prompt:a.value,kit:i.value}),$r(e),m(),w(`Behavior schema attached to ${e.userData.modelName||`selected model`}.`,`Model Forge`)},u.onclick=()=>{try{let e=Hr({...p,name:r.value||p.name||`Custom Model`,prompt:a.value,kit:i.value});Uo(e,e.userData.modelName),$r(e),w(`${e.userData.modelName} built with ${e.userData.modelForge?.parts?.length||0} interactive parts.`,`Model Forge`)}catch(e){C(e.message,`Model Forge Failed`)}},d.onclick=()=>{p={...p,name:r.value||p.name,prompt:a.value,kit:i.value,updatedAt:Date.now()},Br(p),w(`Blueprint saved locally for later reuse.`,`Model Forge`)},e.append(t,n,r,i,a,c,l,u,d,o,s),new bn({title:`Interactive Model Forge`,body:e,icon:`F`,width:390,height:620}).focus()}function jo(e,t,n=()=>!1){let r=document.createElement(`article`);if(r.className=`model-card ${e.source}-card`,e.thumbnail){let t=document.createElement(`img`);t.src=e.thumbnail,t.alt=``,t.loading=`lazy`,r.appendChild(t)}let i=document.createElement(`div`),a=document.createElement(`strong`),o=document.createElement(`span`),s=document.createElement(`a`);a.textContent=e.name;let c=e.size?Ks(e.size):`free`,l=e.faceCount?` / ${qs(e.faceCount)} faces`:``;o.textContent=`${e.licenseLabel} / ${c}${l}`,s.textContent=`${e.author} (${e.source.toUpperCase()})`,s.href=e.authorUrl||e.viewerUrl||`#`,s.target=`_blank`,s.rel=`noopener`,i.append(a,o,s);let u=document.createElement(`div`);u.className=`model-actions`;let d=document.createElement(`button`);d.className=`panel-action`;let f=e.source===`sketchfab`&&!n()&&!t();d.textContent=f?`Token Needed`:`Place`,d.onclick=()=>{if(f){C(`Sketchfab downloads require a configured token.`,`Token Required`);return}Mo(e,t())};let p=document.createElement(`a`);return p.className=`panel-action link-action`,p.href=e.viewerUrl||`#`,p.target=`_blank`,p.rel=`noopener`,p.textContent=`Open`,u.append(d,p),r.append(i,u),r}async function Mo(e,t){E(`Requesting ${e.source.toUpperCase()} download: ${e.name}...`,55);try{let n;if(e.downloadUrl===`forge-procedural`)n=Hr(L({name:e.name,kit:Js(e.name)}));else if(e.downloadUrl&&e.downloadUrl.startsWith(`api:spawn_3d_model:`)){let t=e.downloadUrl.split(`api:spawn_3d_model:`)[1];w(`[STABLE FAST 3D] Generating custom 3D model for: ${t}...`,`Jarvis AI Generation`),fetch(`/xr/model3d/spawn`,{method:`POST`,headers:{"Content-Type":`application/json`,Authorization:`Bearer ${cr(`omega_session`)||``}`},body:JSON.stringify({description:t,persona:`JARVIS`,use_cloud_fallback:!0})}).then(async e=>{let t=null;try{t=await e.json()}catch{}if(!e.ok){w(`[STABLE FAST 3D] Generation failed (${e.status}). ${t?.detail||``}`.trim(),`Generation Error`);return}if(t?.status===`needs_confirmation`){w(`[STABLE FAST 3D] ${t.message||`Cloud generation required.`}`,`Generation Paused`);return}w(`[STABLE FAST 3D] Model generated and placed in the scene.`,`Generation Complete`)}).catch(e=>{console.error(`Generation request failed:`,e),w(`[STABLE FAST 3D] Generation request failed — check connection.`,`Generation Error`)}),hidePanel(),clearLoading();return}else if(e.downloadUrl)(e.source===`cgtrader`||e.source===`turbosquid`||e.source===`mixamo`||e.source===`poly_pizza`)&&(cr(e.source)?e.source===`mixamo`?w(`[Mixamo] Secure Adobe ID Synchronized! Placed free rigged character.`,`Mixamo Rigging`):e.source===`poly_pizza`?w(`[Poly.pizza] Authenticated API Key! Placed free low-poly asset.`,`Poly.pizza API`):w(`[${e.source.toUpperCase()}] Authenticated as user! Placed free model.`,`${e.source.toUpperCase()} Session`):w(`[${e.source.toUpperCase()}] Session Proxy: Connected via OMEGA public portal... Placed free model!`,`${e.source.toUpperCase()} Session`)),n=await Ko(e.downloadUrl);else if(e.source===`sketchfab`){Kn(t);let r=await $n(e.uid,t),i=r.glb?.url||r.gltf?.url;if(!i)throw Error(`Sketchfab did not return a glTF or GLB download URL.`);n=r.glb?.url?await Ko(i):await No(i)}else throw Error(`Unsupported model source: ${e.source}`);n.userData.modelName=e.name,n.userData.sketchfab=e.sketchfab||{uid:e.uid,author:e.author,authorUrl:e.authorUrl||``,license:e.license||`free`,licenseLabel:e.licenseLabel||`Free`,viewerUrl:e.viewerUrl||``},Gr(n,L({name:e.name,kit:Js(e.name)}));let r=Vo(.5,.56);Go(n,e.name,r.position,r.rotation,`${e.source}:${e.uid}`),w(`${e.name} placed successfully from ${e.source.toUpperCase()}.`,e.source.toUpperCase())}catch(t){C(`${e.source.toUpperCase()} failed: ${t.message}. Spawning premium generated fallback...`,`${e.source.toUpperCase()} Fallback`);let n=us(e.name);Gr(n,L({name:e.name,kit:Js(e.name)}));let r=Vo(.5,.56);Go(n,e.name,r.position,r.rotation,``)}finally{ot()}}async function No(e){let t=await fetch(e);if(!t.ok)throw Error(`Sketchfab archive download failed: ${t.status}`);let n=Xa(new Uint8Array(await t.arrayBuffer())),r=Object.keys(n).filter(e=>e.toLowerCase().endsWith(`.gltf`));if(!r.length)throw Error(`Sketchfab archive did not contain a .gltf scene.`);let i=r.find(e=>e.toLowerCase().replace(/.*\//,``)===`scene.gltf`)??r.reduce((e,t)=>n[t].byteLength>n[e].byteLength?t:e,r[0]),a=new TextDecoder().decode(n[i]),o=i.includes(`/`)?i.slice(0,i.lastIndexOf(`/`)+1):``,s=new Map;for(let[e,t]of Object.entries(n)){let n=Ws(e),r=URL.createObjectURL(new Blob([t],{type:n}));s.set(Gs(e),r),s.set(e.split(`/`).pop(),r)}let c=new ne;c.setURLModifier(e=>{let t=Gs(e),n=Gs(`${o}${t}`);return s.get(t)||s.get(n)||s.get(t.split(`/`).pop())||e});let l=ao(new He(c));return io(),new Promise((e,t)=>{l.parse(a,o,t=>{for(let e of new Set(s.values()))URL.revokeObjectURL(e);e(t.scene)},e=>{for(let e of new Set(s.values()))URL.revokeObjectURL(e);t(e)})})}function Po(e){let t=document.createElement(`article`);t.className=`model-card`;let n=document.createElement(`div`),r=document.createElement(`strong`),i=document.createElement(`span`),a=document.createElement(`button`);return r.textContent=e.name,i.textContent=`${e.category} / ${e.size}`,a.className=`panel-action`,a.textContent=`Place`,a.onclick=()=>zo(e.name),n.append(r,i),t.append(n,a),t}async function Fo(e){if(!e)return;if(e.size>100*1024*1024){C(`Custom model is larger than 100MB. Please optimize or compress it first.`,`Model Too Large`);return}let t=e.name.split(`.`).pop()?.toLowerCase(),n=``;try{n=URL.createObjectURL(e);let r=t===`glb`||t===`gltf`?await Ko(n):await Io(n,t);r.userData.modelName=e.name,Uo(r,e.name);let i=hr($a,[]);i.push({name:e.name,type:t,size:e.size,addedAt:Date.now()}),gr($a,i.slice(-24))}catch(e){C(e.message,`Custom Model Failed`)}finally{n&&URL.revokeObjectURL(n)}}async function Io(e,n){if(n===`obj`){let{OBJLoader:n}=await t(async()=>{let{OBJLoader:e}=await import(`./three-DMwvpBUV.js`).then(e=>e.t);return{OBJLoader:e}},__vite__mapDeps([1,2]),import.meta.url);return new Promise((t,r)=>new n().load(e,t,void 0,r))}if(n===`fbx`){let{FBXLoader:n}=await t(async()=>{let{FBXLoader:e}=await import(`./three-DMwvpBUV.js`).then(e=>e.n);return{FBXLoader:e}},__vite__mapDeps([1,2]),import.meta.url);return new Promise((t,r)=>new n().load(e,t,void 0,r))}throw Error(`Unsupported custom model type: ${n||`unknown`}`)}function Lo(){if(D.modelPlacementEventsBound)return;D.modelPlacementEventsBound=!0;let e=document.getElementById(`camerafeed`);e?.addEventListener(`pointerdown`,e=>ws(e.clientX,e.clientY)),e?.addEventListener(`pointerup`,Ts),e?.addEventListener(`pointermove`,Ts),document.addEventListener(`touchend`,e=>{if(!D.pendingModelToPlace||Bo(e.target))return;let t=e.changedTouches[0];t&&Ro(t.clientX,t.clientY,e)},{passive:!0,capture:!0}),document.addEventListener(`pointerup`,e=>{e.pointerType!==`touch`&&(!D.pendingModelToPlace||Bo(e.target)||Ro(e.clientX,e.clientY,e))},!0)}async function Ro(e,t,n=null){if(!D.pendingModelToPlace)return;let r=performance.now(),i=n?.pointerId??n?.changedTouches?.[0]?.identifier??n?.detail?.pointerId??++xo,a=`${Math.round(e)}:${Math.round(t)}:${n?.type||`auto`}:${i}`;if(r-ho<350&&a===go)return;ho=r,go=a;let o=D.pendingModelToPlace,s=Vo(e/innerWidth,t/innerHeight);D.pendingModelToPlace=``,delete document.body.dataset.jarvisPendingModel,Hs(!1),vo++,window.clearTimeout(_o),_o=0;try{await Ho(o,s.position,s.rotation)}catch(e){C(e.message,`Model Placement Failed`)}}function zo(e){D.pendingModelToPlace=e,document.body.dataset.jarvisPendingModel=e,Hs(!0),w(`Tap a detected surface to place ${e}. Auto-place will use the center hit-test if no tap arrives.`,`Model Armed`),window.clearTimeout(_o),_o=0;let t=++vo;_o=window.setTimeout(()=>{D.pendingModelToPlace===e&&vo===t&&Ro(innerWidth/2,innerHeight*.56)},900)}function Bo(e){return!!e?.closest?.(`.ar-panel, .hud-toolbar, button, input, select, textarea, iframe`)}function Vo(e,t){try{let n=globalThis.XR8?.XrController?.hitTest?.(e,t,[`FEATURE_POINT`,`ESTIMATED_SURFACE`,`DETECTED_SURFACE`]);if(n&&n.length>0)return n[0]}catch{}let{camera:n}=I(),r=new Ce(e*2-1,-(t*2-1)),i=new Me;i.setFromCamera(r,n);let a=(D.floorY-i.ray.origin.y)/i.ray.direction.y;return{position:Number.isFinite(a)&&a>0?i.ray.origin.clone().add(i.ray.direction.clone().multiplyScalar(a)):i.ray.origin.clone().add(i.ray.direction.clone().multiplyScalar(2)),rotation:new Ve}}async function Ho(e,t,n){E(`Loading ${e}...`,55);try{let r=In(e),i=await Ko(r,(t,n)=>{n&&E(`Loading ${e}... ${Math.round(t/n*100)}%`,55+Math.round(t/n*30))});return Gr(i,L({name:e,kit:Js(e)})),Go(i,e,t,n,r),ot(),i}catch(r){C(`Remote GLB failed for ${e}: ${r.message}. Generated fallback spawned instead.`,`Model Fallback`);let i=us(e);return Gr(i,L({name:e,kit:Js(e)})),Go(i,e,t,n,``),ot(),i}}function Uo(e,t=`Custom Model`){let n=Vo(.5,.55);Go(e,t,n.position,n.rotation,``)}function Wo(e){let t=.28,n=D.placedObjects||[];if(!n.length)return e;let r=0,i=()=>n.some(n=>(n.getWorldPosition?n.getWorldPosition(new S):n.position).distanceTo(e)<t);for(;i()&&r<24;){r++;let n=r*2.399963,i=t*(1+Math.floor(r/8))*Math.sqrt(r%8+1)*.6;e.x+=Math.cos(n)*i*.35,e.z+=Math.sin(n)*i*.35}return e}function Go(e,t,n,r,i){let{scene:a}=I();e.position.copy(Wo(Us(n).clone())),r?.isQuaternion?e.quaternion.copy(r):r&&e.quaternion.set(r.x||0,r.y||0,r.z||0,r.w||1),cs(e),e.userData.id=e.userData.id||xr(`model`),e.userData.modelName=t,e.userData.sourceURL=i,e.userData.isARObject=!0,!e.userData.modelForge&&!e.userData.modelForgeBlueprint&&Gr(e,L({name:t,kit:Js(t)})),e.traverse(e=>{e.isMesh&&(e.castShadow=!0,e.receiveShadow=!0,e.frustumCulled=!0)});let o=e.scale.clone();return e.userData.finalScale=o.toArray(),e.scale.setScalar(.001),a.add(e),D.placedObjects.push(e),ms(e),Li(e),ls(e,o,()=>{e.userData.finalScale=o.toArray(),_s(),Ri(e,`place`)}),document.body.dataset.jarvisObjects=String(D.placedObjects.length),document.body.dataset.jarvisLastModel=t,Ot(`upsertObject`,e.userData.id,i||`model`,t,e.position.x,e.position.y,e.position.z),k(`object-placed`,{object:e,modelName:t}),e}function Ko(e,t){io();let n=as(e),r=lo.get(n);if(r?.template)return Promise.resolve(qo(r));if(r?.promise)return r.promise.then(e=>qo(e));let i={key:n,url:e,template:null,promise:null,refCount:0,bytes:0,lastUsed:os(),loading:!0};return i.promise=new Promise((r,a)=>{oo.load(e,e=>{i.template=Dr(e.scene,{targetSize:1,maxTextureSize:2048,maxAnisotropy:6}),i.animations=e.animations||[];let t=Er(i.template);i.metrics=t,i.bytes=Math.max(t.bytes||es(i.template),512*1024),i.lastUsed=os(),i.loading=!1,i.promise=null,$o(i.template,n),t.warnings.length&&k(`assistant`,`Optimized ${n} for scale and texture budget: ${t.warnings.join(`, `)}.`),uo+=i.bytes,r(i)},e=>t?.(e.loaded,e.total),e=>{lo.delete(n),i.loading=!1,i.promise=null,a(e)})}),lo.set(n,i),i.promise.then(e=>qo(e))}function qo(e){e.refCount+=1,e.lastUsed=os();let t=Ne(e.template);return t.userData.assetCacheKey=e.key,t.userData.assetCacheShared=!0,t.userData.assetCacheBytes=e.bytes,$o(t,e.key),Zo(),t}function Jo(e){let t=e?.userData?.assetCacheKey,n=t?lo.get(t):null,r=n?.template?qo(n):e.clone(!0);return r.position.copy(e.position),r.quaternion.copy(e.quaternion),r.scale.copy(e.scale),r.name=e.name,r.visible=e.visible,r.userData={...ss(e.userData),assetCacheKey:r.userData.assetCacheKey,assetCacheShared:r.userData.assetCacheShared,assetCacheBytes:r.userData.assetCacheBytes},delete r.userData.shadow,r.traverse(e=>{e.isMesh&&(e.castShadow=!0,e.receiveShadow=!0,e.frustumCulled=!0)}),r}function Yo(e){let t=e?.userData?.assetCacheKey;if(!t)return!1;let n=lo.get(t);return n?(n.refCount=Math.max(0,n.refCount-1),n.lastUsed=os(),Zo(),!0):!0}function Xo(e){It(e,{disposeSharedAssets:!Yo(e)})}function Zo(e=!1){let t=[...lo.values()].filter(e=>e.template&&!e.loading&&e.refCount===0).sort((e,t)=>e.lastUsed-t.lastUsed);for(;t.length&&(e||lo.size>so||uo>co);)Qo(t.shift())}function Qo(e){!e||e.refCount>0||(lo.delete(e.key),uo=Math.max(0,uo-e.bytes),e.template&&It(e.template,{disposeSharedAssets:!0}),e.template=null)}function $o(e,t){e.userData.sharedAssetKey=t,e.traverse(e=>{e.userData.sharedAssetKey=t,e.geometry&&(e.geometry.userData=e.geometry.userData||{},e.geometry.userData.sharedAssetKey=t),rs(e.material,e=>{e.userData=e.userData||{},e.userData.sharedAssetKey=t,is(e,e=>{e.userData=e.userData||{},e.userData.sharedAssetKey=t})})})}function es(e){let t=new Set,n=new Set,r=new Set,i=0;return e.traverse(e=>{e.geometry&&!t.has(e.geometry)&&(t.add(e.geometry),i+=ts(e.geometry)),rs(e.material,e=>{n.has(e)||(n.add(e),i+=2048),is(e,e=>{r.has(e)||(r.add(e),i+=ns(e))})})}),Math.max(i,512*1024)}function ts(e){let t=0,n=e=>{e?.array?.byteLength&&(t+=e.array.byteLength)};return Object.values(e.attributes||{}).forEach(n),Object.values(e.morphAttributes||{}).forEach(e=>e.forEach(n)),n(e.index),t}function ns(e){let t=e?.image||{};if(t.data?.byteLength)return t.data.byteLength;let n=t.width||t.videoWidth||t.naturalWidth||256,r=t.height||t.videoHeight||t.naturalHeight||256;return Math.max(1,n)*Math.max(1,r)*4}function rs(e,t){(Array.isArray(e)?e:[e]).filter(Boolean).forEach(t)}function is(e,t){let n=new Set,r=e=>{if(!(!e||typeof e!=`object`)){if(e.isTexture){n.has(e)||(n.add(e),t(e));return}if(Array.isArray(e)){e.forEach(r);return}e.value?.isTexture?r(e.value):e.constructor===Object&&Object.values(e).forEach(r)}};Object.values(e).forEach(r)}function as(e){return String(e||``).trim()}function os(){return typeof performance<`u`?performance.now():Date.now()}function ss(e){try{return structuredClone(e)}catch{try{return JSON.parse(JSON.stringify(e))}catch{return{...e}}}}function cs(e){let t=new xe().setFromObject(e).getSize(new S).length(),n=t>0?.55/t:.35;e.scale.setScalar(Math.min(1,n))}function ls(e,t,n){let r=performance.now(),i=0,a=()=>{if(!e.parent){yt(i);return}let o=Math.min((performance.now()-r)/420,1),s=o<.6?o/.6*1.1:1.1-.1*((o-.6)/.4);e.scale.copy(t).multiplyScalar(s),o<1?i=P(a):(e.scale.copy(t),n?.())};i=P(a)}function us(e){let t=new g,n=new b(new v(.28,2),new y({color:43775,emissive:21879,roughness:.25,metalness:.35,transparent:!0,opacity:.78})),r=new b(new je(.42,.008,8,96),Za.clone());r.rotation.x=Math.PI/2;let i=ps(e);return i.position.y=.48,t.add(n,r,i),t}function ds(e,t){let n=D.selectedObject||D.placedObjects.at(-1);n&&(Qr(n,e,t),hs(n),$r(n),Ri(n,e))}function fs(e={}){let t=Ys(e.action||e.command||``),n=String(e.target||e.model||e.query||``).trim(),r=D.selectedObject||D.placedObjects.at(-1)||null;if(n){let e=n.toLowerCase();r=D.placedObjects.find(t=>{let n=String(t.userData?.modelName||``).toLowerCase(),r=t.userData?.modelForge?.parts||[];return n.includes(e)||r.some(t=>String(t.name||``).toLowerCase().includes(e))})||r}!r||!t||(Zr(r,t,e),hs(r),$r(r),Ri(r,t))}function ps(e){let t=String(e||`Model`).trim().toLowerCase(),n=So.get(t);if(n){let e=new Ue(new _e({map:n.texture,transparent:!0}));return e.scale.set(.9,.23,1),e.userData.labelCacheKey=t,e}let r=document.createElement(`canvas`);r.width=512,r.height=128;let i=r.getContext(`2d`);i.clearRect(0,0,r.width,r.height),i.fillStyle=`rgba(0,0,0,0.32)`,i.fillRect(0,0,r.width,r.height),i.fillStyle=`#fff`,i.font=`600 34px Inter, sans-serif`,i.textAlign=`center`,i.textBaseline=`middle`,i.fillText(String(e).slice(0,24),256,64);let a=new qe(r);a.userData=a.userData||{},a.userData.sharedAssetKey=`label:${t}`,So.set(t,{texture:a});let o=new Ue(new _e({map:a,transparent:!0}));return o.scale.set(.9,.23,1),o.userData.labelCacheKey=t,o}function ms(e){e.userData.shadow?.parent?.remove(e.userData.shadow);let t=new b(new o(.35,48),new d({color:0,transparent:!0,opacity:.24,depthWrite:!1}));t.rotation.x=-Math.PI/2,t.name=`jarvis-blob-shadow`,e.userData.shadow=t,hs(e),I().scene.add(t)}function hs(e){let t=e?.userData?.shadow;t&&t.position.set(e.position.x,D.floorY+.004,e.position.z)}function gs(e){return Array.isArray(e)&&e.length>=3&&e.every(e=>Number.isFinite(e)&&e>.01)}function _s(){gr(Qa,D.placedObjects.map(e=>({id:e.userData.id,modelName:e.userData.modelName,sourceURL:e.userData.sourceURL||``,sketchfab:e.userData.sketchfab||null,modelForge:e.userData.modelForge||e.userData.modelForgeBlueprint||null,position:e.position.toArray(),quaternion:e.quaternion.toArray(),scale:Array.isArray(e.userData.finalScale)?e.userData.finalScale:e.scale.toArray(),trackingMode:D.trackingMode,floorY:D.floorY,anchor:ys(e),savedAt:Date.now()})))}async function vs(){let e=hr(Qa,[]),t=[];for(let n of e)try{let e=n.sourceURL&&!n.sourceURL.startsWith(`sketchfab:`)?await Ko(n.sourceURL):us(n.modelName);e.userData.id=n.id,e.position.fromArray(n.position),e.quaternion.fromArray(n.quaternion),e.scale.fromArray(gs(n.scale)?n.scale:[.35,.35,.35]),e.userData.finalScale=e.scale.toArray(),e.userData.modelName=n.modelName,e.userData.sourceURL=n.sourceURL,e.userData.sketchfab=n.sketchfab||null,e.userData.worldAnchor=n.anchor||null,e.userData.isARObject=!0,Gr(e,n.modelForge||L({name:n.modelName||`Restored Model`,kit:Js(n.modelName)})),I().scene.add(e),D.placedObjects.push(e),ms(e),Li(e),xs(e),document.body.dataset.jarvisObjects=String(D.placedObjects.length)}catch(e){t.push(`${n.modelName||`Restored Model`}: ${e?.message||`load failed`}`);let r=us(n.modelName||`Restored Model`);r.position.fromArray(n.position||[0,D.floorY,-2]),r.scale.fromArray(gs(n.scale)?n.scale:[.35,.35,.35]),r.userData.finalScale=r.scale.toArray(),r.userData.id=n.id||xr(`model`),r.userData.modelName=n.modelName||`Restored Model`,r.userData.sourceURL=n.sourceURL||``,r.userData.sketchfab=n.sketchfab||null,r.userData.worldAnchor=n.anchor||null,r.userData.isARObject=!0,Gr(r,n.modelForge||L({name:n.modelName||`Restored Model`,kit:Js(n.modelName)})),I().scene.add(r),D.placedObjects.push(r),ms(r),Li(r),xs(r),document.body.dataset.jarvisObjects=String(D.placedObjects.length)}t.length&&w(`Some saved models failed to restore and were replaced with generated fallbacks: ${t.slice(0,3).join(`; `)}${t.length>3?` (+${t.length-3} more)`:``}`,`Model Restore`)}function ys(e){return{type:`world-point-signature-v1`,position:e.position.toArray(),quaternion:e.quaternion.toArray(),floorY:D.floorY,signature:bs(),trackingMode:D.trackingMode,createdAt:Date.now()}}function bs(){let e=D.worldPointBuffer.slice(-360);if(e.length<10)return{count:e.length,centroid:[0,D.floorY,0],floorY:D.floorY};let t=e.reduce((e,t)=>(e.x+=t.x,e.y+=t.y,e.z+=t.z,e),new S).multiplyScalar(1/e.length);return{count:e.length,centroid:t.toArray(),floorY:D.floorY}}function xs(e){e.userData.worldAnchor&&(Co.add(e),Cs(e))}function Ss(){Co.forEach(e=>{if(!e.parent){Co.delete(e);return}Cs(e)})}function Cs(e){let t=e.userData.worldAnchor;if(!t?.position)return;let n=t.signature||{},r=bs(),i=new S().fromArray(t.position);n.count>=10&&r.count>=10&&Array.isArray(n.centroid)&&(i.x+=r.centroid[0]-n.centroid[0],i.z+=r.centroid[2]-n.centroid[2]);let a=Number.isFinite(t.floorY)?t.floorY:n.floorY;Number.isFinite(a)&&Number.isFinite(r.floorY)&&(i.y+=r.floorY-a),e.position.copy(i),hs(e)}function ws(e,t){Ts(),po=window.setTimeout(()=>{Es(e,t),D.selectedObject&&As(e,t,D.selectedObject)},500)}function Ts(){window.clearTimeout(po)}function Es(e,t){let{camera:n}=I(),r=new Me;r.setFromCamera(new Ce(e/innerWidth*2-1,-(t/innerHeight)*2+1),n);let i=r.intersectObjects(D.placedObjects,!0)[0]?.object;return D.selectedObject=i?Ds(i):null,D.selectedObject}function Ds(e){let t=e;for(;t&&!t.userData.isARObject&&t.parent;)t=t.parent;return t?.userData?.isARObject?t:null}function Os(e){let t=e?.origin,n=e?.direction;if(!t||!n)return null;let r=new S(n.x,n.y,n.z);if(r.lengthSq()<1e-8)return null;r.normalize();let i=new S(t.x,t.y,t.z),a=new Me(i,r).intersectObjects(D.placedObjects,!0),o=a[0]?.object?Ds(a[0].object):null;if(o)return D.selectedObject=o,ks(o),Ri(o,`select`),k(`gesture-pinch`,{source:`xr-transient-pointer`,object:o}),Ot(`status`,`Selected ${o.userData.modelName||`object`} via pinch`),{type:`select`,object:o};if(D.pendingModelToPlace){let e=Number.isFinite(D.floorY)?D.floorY:-1.5,t=Math.abs(r.y)>1e-4?(e-i.y)/r.y:-1,n=t>0&&t<40?new S(i.x+r.x*t,e,i.z+r.z*t):i.clone().add(r.clone().multiplyScalar(1.6)).setY(e),a=D.pendingModelToPlace;return D.pendingModelToPlace=``,delete document.body.dataset.jarvisPendingModel,Hs(!1),Ho(a,n,new Ve).catch(e=>C(e.message,`Model Placement Failed`)),{type:`place`,point:n}}return null}function ks(e){if(!e||e.userData._xrPulsing)return;e.userData._xrPulsing=!0;let t=e.scale.clone(),n=t.clone().multiplyScalar(1.06),r=performance.now(),i=a=>{let o=Math.min(1,(a-r)/170),s=o<.5?o*2:(1-o)*2;e.scale.lerpVectors(t,n,s),o<1?P(i):(e.scale.copy(t),e.userData._xrPulsing=!1)};P(i)}function As(e,t,n){fo?.remove(),fo=document.createElement(`section`),fo.className=`context-menu glass-panel`,fo.style.left=`${Math.min(e,innerWidth-210)}px`,fo.style.top=`${Math.min(t,innerHeight-250)}px`;let r=[[`Duplicate`,()=>Ns(n)],[`Delete`,()=>Ps(n)],[`Physics ON`,()=>Fs(n)],[`Open`,()=>js(n,`open`)],[`Close`,()=>js(n,`close`)],[`Toggle`,()=>js(n,`toggle`)],[`Shatter`,()=>js(n,`shatter`)],[`Forge`,()=>k(`open-model-forge`)],[`Save`,()=>_s()],[`Export .GLB`,()=>Is(n)]];for(let[e,t]of r){let n=document.createElement(`button`);n.textContent=e,n.onclick=()=>{t(),fo?.remove()},fo.appendChild(n)}document.body.appendChild(fo),window.setTimeout(()=>document.addEventListener(`pointerdown`,Ms,{once:!0}),0)}function js(e,t){Zr(e,t),hs(e),$r(e),Ri(e,t),Ot(`manipulateObject`,e.userData.id||``,t)}function Ms(e){fo?.contains(e.target)||fo?.remove()}function Ns(e){let t=Jo(e),n=new S(.25,.02,-.25).applyQuaternion(e.quaternion);t.position.add(n),t.userData.id=xr(`model`),t.userData.finalScale=e.userData.finalScale||t.scale.toArray(),delete t.userData.worldAnchor,(e.userData.modelForge||e.userData.modelForgeBlueprint)&&Gr(t,e.userData.modelForge||e.userData.modelForgeBlueprint),I().scene.add(t),D.placedObjects.push(t),ms(t),Li(t),Ri(t,`place`),_s()}function Ps(e){D.placedObjects=D.placedObjects.filter(t=>t!==e),Co.delete(e),D.selectedObject===e&&(D.selectedObject=null);let t=mo.get(e.userData.id);t&&(da(t),mo.delete(e.userData.id)),e.userData.shadow&&It(e.userData.shadow),Ri(e,`delete`),Ot(`removeObject`,e.userData.id||``),Xo(e),_s()}async function Fs(e){if(mo.has(e.userData.id)){da(mo.get(e.userData.id)),mo.delete(e.userData.id),w(`Physics off`,`info`);return}if(!ra()){w(`Starting physics engine…`,`info`);try{await ia()}catch(e){console.error(`[AR Models] physics engine unavailable:`,e),w(`Physics unavailable — engine failed to start`,`error`);return}}let t=la(e.position,`dynamic`);if(!t){w(`Physics unavailable — engine failed to start`,`error`);return}ua(e,t),mo.set(e.userData.id,t),w(`Physics on`,`success`)}window.addEventListener(`ar-physics-step`,()=>{for(let e of mo.keys()){let t=D.placedObjects.find(t=>t.userData.id===e);t&&hs(t)}});async function Is(e){let{GLTFExporter:n}=await t(async()=>{let{GLTFExporter:e}=await import(`./three-DMwvpBUV.js`).then(e=>e.r);return{GLTFExporter:e}},__vite__mapDeps([1,2]),import.meta.url),r=new n;await Ls(e),r.parse(e,t=>{let n=t instanceof ArrayBuffer?new Blob([t],{type:`model/gltf-binary`}):new Blob([JSON.stringify(t)],{type:`model/gltf+json`}),r=URL.createObjectURL(n),i=document.createElement(`a`);i.href=r,i.download=`${e.userData.modelName||`jarvis-model`}.glb`,i.click(),URL.revokeObjectURL(r)},e=>C(e.message,`Export Failed`),{binary:!0})}async function Ls(e){let t=[];e.traverse(e=>{rs(e.material,e=>{is(e,e=>{t.push(e)})})}),await Promise.all(t.map(async e=>{let t=e?.image;if(t){if(t.complete===!1){await new Promise(e=>{let n=()=>e();t.addEventListener?.(`load`,n,{once:!0}),t.addEventListener?.(`error`,n,{once:!0}),window.setTimeout(n,1200)});return}if(typeof t.decode==`function`)try{await t.decode()}catch{}}}))}function Rs(){let e=document.createElement(`div`);e.style.cssText=`display: flex; flex-direction: column; gap: 8px;`;let t=document.createElement(`strong`);t.textContent=`JARVIS Stark 3D Composer`,t.style.cssText=`font-size: 14px; color: var(--accent); text-transform: uppercase;`;let n=document.createElement(`select`);Sr(n,[[`primitive`,`Custom Basic Geometry`],[`arc_reactor`,`Stark Arc Reactor Core`],[`gauntlet`,`Holographic Repulsor Gauntlet`],[`thruster`,`Flight Ion Propulsion Thruster`],[`quantum_reactor`,`Quantum Core Reactor Engine`],[`faceplate`,`Cybernetic Visor Faceplate`]]);let r=document.createElement(`select`);Sr(r,[[`metal`,`Machined Brushed Titanium`],[`gold`,`Polished Golden Core`],[`glass`,`Translucent Ethereal Glass`],[`glow`,`Glowing Neon Hologram`],[`matte`,`Stark Matte Composite`]]);let i=document.createElement(`div`);i.style.cssText=`display: flex; flex-direction: column; gap: 4px;`;let a=document.createElement(`span`);a.textContent=`Shape / Geometry:`,a.style.cssText=`font-size: 11px; color: var(--text-secondary);`;let o=document.createElement(`select`);Sr(o,[`cube`,`sphere`,`cylinder`,`cone`,`plane`,`torus`,`ring`,`capsule`]),i.append(a,o);let s=document.createElement(`div`);s.style.cssText=`display: flex; flex-direction: column; gap: 4px;`;let c=document.createElement(`span`);c.textContent=`Visual Detail Level:`,c.style.cssText=`font-size: 11px; color: var(--text-secondary);`;let l=document.createElement(`select`);Sr(l,[[`standard`,`Standard`],[`premium`,`Premium`],[`hero`,`Hero Detail`]]),s.append(c,l);let u=document.createElement(`input`);u.placeholder=`Model custom name (e.g. Mark 85 reactor)`;let d=document.createElement(`button`);d.className=`panel-action`,d.textContent=`Build Stark Composite`,d.style.cssText=`background: var(--accent); color: #fff; font-weight: 600; min-height: 42px; border-radius: 12px; margin-top: 8px;`,n.onchange=()=>{let e=n.value===`primitive`;i.style.display=e?`flex`:`none`,s.style.display=e?`flex`:`none`,u.value=e?``:n.options[n.selectedIndex].text},d.onclick=()=>{let e=n.value,t;t=e===`primitive`?Bs(o.value,r.value,l.value):zs(e,r.value);let i=u.value||`${r.options[r.selectedIndex].text} ${n.options[n.selectedIndex].text}`;t.userData.modelName=i,Gr(t,L({name:i,kit:e===`primitive`?`scene`:Js(e)})),Uo(t,i);let a=hr($a,[]);a.push({name:i,assembly:e,material:r.value,addedAt:Date.now()}),gr($a,a.slice(-24)),w(`Successfully composed and placed Stark asset: ${i}.`,`3D Composer`)};let f=document.createElement(`p`);f.className=`panel-note`,f.textContent=`Stark Assemblies generate premium multi-part geometries with concentric highlights, glowing points, and kinematic hinges.`,e.append(t,n,r,i,s,u,d,f),new bn({title:`Stark 3D Composer`,body:e,icon:`B`,width:375,height:490}).focus()}function zs(e,t){let n=new g;n.name=`stark-${e}`;let r=Vs(t===`gold`?`metal`:t);t===`gold`&&(r.color.setHex(16766720),r.roughness=.05,r.metalness=.95);let i=new d({color:54015,transparent:!0,opacity:.85}),a=new d({color:16777215,transparent:!0,opacity:.95}),o=new ae({color:3815994,roughness:.6,metalness:.8});if(e===`arc_reactor`){let e=new b(new s(.18,.18,.06,32),o);e.position.y=-.03,n.add(e);let t=new b(new s(.08,.08,.08,24),i);t.position.y=.01,t.userData.partName=`reactor-core`,t.userData.partType=`light`;let c=new se(54015,3,2.5);c.position.set(0,0,0),t.add(c),n.add(t);let l=new b(new je(.15,.018,12,48),r);l.rotation.x=Math.PI/2,n.add(l);let u=new ae({color:13794605,roughness:.18,metalness:.9});for(let e=0;e<10;e++){let t=e/10*Math.PI*2,r=new b(new ce(.024,.024,.018),u);r.position.set(Math.cos(t)*.15,0,Math.sin(t)*.15),r.rotation.y=-t,n.add(r)}let d=new b(new je(.1,.005,8,48),a);d.rotation.x=Math.PI/2,d.position.y=.02,n.add(d)}else if(e===`gauntlet`){let e=new b(new s(.1,.11,.28,16,1,!0,-Math.PI/2,Math.PI),r);e.rotation.x=Math.PI/2,e.userData.partName=`wrist-guard`,e.userData.partType=`base`,n.add(e);let t=new b(new s(.018,.018,.12,12),o);t.position.set(0,.07,-.06),t.rotation.x=Math.PI/2,t.userData.partName=`laser-emitter`,t.userData.partType=`detail`;let c=new b(new ke(.012),a);c.position.y=.06,t.add(c),n.add(t);let l=new b(new ke(.025,16,16),i);l.position.set(0,.06,.08),l.userData.partName=`palm-repulsor`,l.userData.partType=`light`;let u=new se(54015,2.5,2);l.add(u),n.add(l)}else if(e===`thruster`){let e=new b(new s(.06,.11,.16,24),o);e.userData.partName=`thruster-nozzle`,e.userData.partType=`base`,n.add(e);let t=new b(new ke(.045,16,16),r);t.position.y=-.06,t.userData.partName=`thruster-core`,t.userData.partType=`light`;let i=new se(16771584,3.5,3);t.add(i),n.add(t);let a=new b(new s(.04,.005,.32,16),new d({color:16747520,transparent:!0,opacity:.65}));a.position.y=-.22,a.userData.partName=`thrust-stream`,a.userData.partType=`detail`,n.add(a)}else if(e===`quantum_reactor`){let e=new b(new s(.12,.12,.32,24),new y({color:13627391,roughness:.02,transmission:.8,transparent:!0,opacity:.3}));e.userData.partName=`quantum-capsule`,e.userData.partType=`window`,n.add(e);let t=new b(new je(.09,.01,8,32),r);t.position.y=.05,t.rotation.x=Math.PI/2,t.userData.partName=`upper-gear`,t.userData.partType=`wheel`,n.add(t);let a=new b(new je(.09,.01,8,32),r);a.position.y=-.05,a.rotation.x=Math.PI/2,a.userData.partName=`lower-gear`,a.userData.partType=`wheel`,n.add(a);let o=new b(new m(.04,0),i);o.userData.partName=`energy-core`,o.userData.partType=`light`;let c=new se(65450,3,2);o.add(c),n.add(o)}else if(e===`faceplate`){let e=new b(new s(.14,.14,.18,16,1,!1,-Math.PI/3,Math.PI/3*2),r);e.userData.partName=`faceplate-armour`,e.userData.partType=`base`,n.add(e);let t=new b(new ce(.18,.04,.02),i);t.position.set(0,.02,.12),t.userData.partName=`visor-screen`,t.userData.partType=`screen`,n.add(t);let o=new b(new ce(.035,.005,.005),a);o.position.set(-.04,.02,.13),o.userData.partName=`left-eye`,o.userData.partType=`light`,n.add(o);let c=new b(new ce(.035,.005,.005),a);c.position.set(.04,.02,.13),c.userData.partName=`right-eye`,c.userData.partType=`light`,n.add(c)}return n}function Bs(e,t,n=`standard`){let r=Vs(t),i={cube:()=>new ce(.35,.35,.35),sphere:()=>new ke(.22,48,24),cylinder:()=>new s(.18,.18,.38,48),cone:()=>new c(.2,.42,48),plane:()=>new x(.5,.5),torus:()=>new je(.23,.04,16,80),ring:()=>new Te(.14,.24,64),capsule:()=>new re(.15,.35,8,24)}[e]?.()||new ce(.35,.35,.35),a=new g;a.name=`builder-${e}-${n}`;let o=new b(i,r);o.castShadow=!0,o.receiveShadow=!0,a.add(o);let l=t===`glass`?new y({color:13627391,roughness:.02,transmission:.72,transparent:!0,opacity:.34}):new d({color:51455,transparent:!0,opacity:.75}),u=new b(new je(.27,.02,12,64),l);if(u.rotation.x=Math.PI/2,a.add(u),n===`premium`||n===`hero`){let e=new b(new ke(.09,24,16),new ae({color:16777215,roughness:.25,metalness:.3}));e.position.set(0,.25,0),a.add(e)}if(n===`hero`){let e=new b(new s(.06,.1,.18,6),new y({color:10475775,roughness:.14,metalness:.6,emissive:397597}));e.position.set(0,.34,0),e.rotation.y=Math.PI/6,a.add(e);let t=new b(new je(.33,.01,8,80),new d({color:16777215,transparent:!0,opacity:.55}));t.rotation.x=Math.PI/2,t.position.y=.02,a.add(t)}return a}function Vs(e){return e===`metal`?new y({color:9422847,roughness:.18,metalness:.9}):e===`glass`?new y({color:13627391,roughness:.04,transmission:.55,transparent:!0,opacity:.45}):e===`glow`?new d({color:51455,transparent:!0,opacity:.8}):new ae({color:8109311,roughness:.55,metalness:.1})}function Hs(e){D.reticle&&(D.reticle.visible=e)}function Us(e){return e?.isVector3?e:new S(e?.x||0,e?.y??D.floorY,e?.z||-2)}function Ws(e){let t=e.toLowerCase();return t.endsWith(`.gltf`)?`model/gltf+json`:t.endsWith(`.bin`)?`application/octet-stream`:t.endsWith(`.png`)?`image/png`:t.endsWith(`.jpg`)||t.endsWith(`.jpeg`)?`image/jpeg`:t.endsWith(`.webp`)?`image/webp`:`application/octet-stream`}function Gs(e){return decodeURIComponent(String(e||``)).replace(/\\/g,`/`).replace(/^blob:https?:\/\/[^/]+\//,``).replace(/^https?:\/\/[^/]+\//,``).replace(/^\/+/,``).replace(/^(\.\/)+/,``)}function Ks(e){let t=Number(e||0);return t?t>1024*1024?`${Math.round(t/1024/1024)}MB`:`${Math.round(t/1024)}KB`:`size unknown`}function qs(e){let t=Number(e||0);return t?t>1e6?`${(t/1e6).toFixed(1)}M`:t>1e3?`${Math.round(t/1e3)}K`:String(t):`unknown`}function Js(e){let t=String(e||``).toLowerCase();return t.includes(`house`)||t.includes(`home`)?`house`:t.includes(`room`)||t.includes(`bedroom`)||t.includes(`kitchen`)?`room`:t.includes(`car`)||t.includes(`truck`)||t.includes(`vehicle`)?`vehicle`:t.includes(`phone`)||t.includes(`tablet`)||t.includes(`device`)?`device`:t.includes(`person`)||t.includes(`robot`)||t.includes(`character`)?`character`:`scene`}function Ys(e){let t=String(e||``).toLowerCase().trim();return t?/(^|\b)(open|unfold|expand)(\b|$)/.test(t)?`open`:/(^|\b)(close|fold|collapse)(\b|$)/.test(t)?`close`:/(^|\b)(toggle|switch)(\b|$)/.test(t)?`toggle`:/(^|\b)(rotate|spin|turn)(\b|$)/.test(t)?`rotate`:/(^|\b)(reconfigure|rebuild|transform|rearrange)(\b|$)/.test(t)?`reconfigure`:/(^|\b)(shatter|break|explode)(\b|$)/.test(t)?`shatter`:/(^|\b)(reveal|show)(\b|$)/.test(t)?`reveal`:/(^|\b)(hide)(\b|$)/.test(t)?`hide`:/(^|\b)(grab|move|drag)(\b|$)/.test(t)?`grab`:t:``}var Xs=0,Zs=4,Qs=8,$s=12,ec=16,tc=20,nc=5,rc=6,ic=9,ac=10,oc=13,sc=14,cc=17,lc=new Map([[nc,rc],[ic,ac],[oc,sc],[cc,18]]),uc=[[0,1],[1,2],[2,3],[3,4],[0,5],[5,6],[6,7],[7,8],[5,9],[9,10],[10,11],[11,12],[9,13],[13,14],[14,15],[15,16],[13,17],[17,18],[18,19],[19,20],[0,17]],dc=20,fc=null,pc=null,U=null,mc=!1,hc=null,gc=0,_c=0,vc=0,yc=!1,bc=0,xc=!1,Sc=null,Cc=0,wc=0,Tc=.55,Ec=[];function Dc(e,t){Oc(),t>0?(bc=setTimeout(e,t),xc=!0):(bc=P(e),xc=!1)}function Oc(){bc&&(xc?clearTimeout(bc):yt(bc),bc=0)}async function kc(){if(pc=document.getElementById(`hand-overlay`),U=pc?.getContext(`2d`),Vc(),Sc=N(window,`resize`,Vc),!globalThis.Hands)return F(`mediaPipeHands`,!1),w(`Hand gestures are still loading. You can place and move objects by touch in the meantime.`,`Hand tracking`),!1;try{return fc=new globalThis.Hands({locateFile:e=>`https://cdn.jsdelivr.net/npm/@mediapipe/hands/${e}`}),fc.setOptions({maxNumHands:2,modelComplexity:1,minDetectionConfidence:.7,minTrackingConfidence:.65,selfieMode:!1}),fc.onResults(Mc),mc=!0,F(`mediaPipeHands`,!0),Dc(Ac,0),w(`Hand tracking armed. Use palm, pinch, fist, point, and swipe gestures.`),!0}catch(e){return console.warn(`[gestures] hand tracking failed to start`,e),C(`Hand gestures aren’t available on this device. Everything else in AR still works — you can place and move objects by touch.`,`Hand tracking unavailable`),!1}}async function Ac(){if(!mc||!fc)return;let e=performance.now();try{let t=Yc();t?(e>=vc&&(vc=e+dc,await fc.send({image:t}),yc=!1),Dc(Ac,0)):(!yc&&D.trackingMode===`8thwall-slam`&&(yc=!0,w(`Waiting for XR camera pixels before enabling hand tracking.`,`Hand Tracking`)),Dc(Ac,200))}catch(e){yc||(yc=!0,w(`Hand tracking frame skipped: ${e.message}`,`Hand Tracking`)),Dc(Ac,200)}}function jc(){mc=!1,Oc(),Sc?.(),Sc=null;try{fc?.close?.()}catch{}fc=null,Bc(),hc=null,gc=0,_c=0,Cc=0,yc=!1,vc=0,wc=0,D.gestureFrameCanvas?.remove?.(),D.gestureFrameCanvas=null,D.gestureFrameReady=!1,D.handState.hands=[],D.handState.gestures=new Map}function Mc(e){Bc();let t=(e.multiHandLandmarks||[]).map((e,t)=>Nc(e,t));D.handState.hands=t,t.forEach((e,t)=>zc(e,t));let n=Pc(t);D.handState.gestures=n;for(let[e,t]of n)k(`gesture-${e}`,t)}function Nc(e,t){if(!Ec[t])return Ec[t]=e.map(e=>({x:e.x,y:e.y,z:e.z||0})),Ec[t];let n=Ec[t];for(let t=0;t<e.length;t++){let r=Tc;n[t].x=n[t].x*(1-r)+e[t].x*r,n[t].y=n[t].y*(1-r)+e[t].y*r,n[t].z=(n[t].z||0)*(1-r)+(e[t].z||0)*r}return n}function Pc(e){let t=new Map;if(!e.length)return hc=null,gc=0,_c=0,Cc=0,t;let n=e[0],r=Uc(n[Zs],n[Qs]);r<.05&&t.set(`pinch`,{confidence:1-r/.05,hand:n}),Ic(n)&&t.set(`fist`,{confidence:.88,hand:n}),Lc(n)&&t.set(`open-palm`,{confidence:.9,hand:n}),Rc(n)&&t.set(`point`,{confidence:.86,hand:n,point:n[Qs]});let i=Fc(n);if(i&&t.set(i,{confidence:.86,hand:n}),e.length>=2){let n=Wc(e[0],e[1]);if(_c>0){let r=n-_c;Math.abs(r)>.035&&t.set(`two-hand-scale`,{confidence:.9,delta:r,distance:n,hands:e})}_c=n}else _c=0;return t}function Fc(e){let t=performance.now();if(t<Cc)return``;let n=e[Xs];if(!hc)return hc={x:n.x,y:n.y},``;let r=n.x-hc.x;return hc={x:n.x,y:n.y},r<-.03?--gc:r>.03?gc+=1:gc*=.5,Math.abs(gc)<.25&&(gc=0),gc=Math.max(-5,Math.min(5,gc)),gc<=-5?(gc=0,Cc=t+180,hc=null,`swipe-left`):gc>=5?(gc=0,Cc=t+180,hc=null,`swipe-right`):``}function Ic(e){return[Qs,$s,ec,tc].every((t,n)=>{let r=[nc,ic,oc,cc][n];return Hc(e,t,r)>.58})}function Lc(e){return[Qs,$s,ec,tc].every((t,n)=>{let r=[nc,ic,oc,cc][n];return Hc(e,t,r)<.32})}function Rc(e){return Hc(e,Qs,nc)<.34&&Hc(e,$s,ic)>.52&&Hc(e,ec,oc)>.52&&Hc(e,tc,cc)>.52}function zc(e){if(!U||!pc)return;let t=Uc(e[Zs],e[Qs])<.05,n=pc.width,r=pc.height,i=Math.max(1,n/Math.max(1,innerWidth));U.lineCap=`round`,U.lineJoin=`round`,U.lineWidth=2.4*i,U.strokeStyle=t?`rgba(0,122,255,0.7)`:`rgba(255,255,255,0.5)`;for(let[t,i]of uc){let a=e[t],o=e[i];!a||!o||(U.beginPath(),U.moveTo(a.x*n,a.y*r),U.lineTo(o.x*n,o.y*r),U.stroke())}for(let a of e){let e=a.x*n,o=a.y*r,s=(t?9:6)*i,c=U.createRadialGradient(e,o,0,e,o,s);c.addColorStop(0,t?`rgba(0,122,255,0.95)`:`rgba(255,255,255,0.92)`),c.addColorStop(1,`rgba(255,255,255,0)`),U.fillStyle=c,U.beginPath(),U.arc(e,o,s,0,Math.PI*2),U.fill()}if(Lc(e)){let t=(e[nc].x+e[cc].x)/2*n,a=(e[nc].y+e[cc].y)/2*r;U.strokeStyle=`rgba(255,255,255,0.55)`,U.lineWidth=3*i,U.beginPath(),U.arc(t,a,(40+Math.sin(performance.now()/180)*6)*i,0,Math.PI*2),U.stroke()}}function Bc(){!U||!pc||(U.save(),U.setTransform(1,0,0,1,0,0),U.clearRect(0,0,pc.width,pc.height),U.restore())}function Vc(){if(!pc)return;let e=Math.min(devicePixelRatio||1,3);pc.width=Math.floor(innerWidth*e),pc.height=Math.floor(innerHeight*e),pc.style.width=`100vw`,pc.style.height=`100vh`,U?.setTransform(1,0,0,1,0,0)}function Hc(e,t,n){let r=e[t],i=e[n],a=e[lc.get(n)];if(!r||!i||!a)return 0;let o=Kc(a,i),s=Kc(a,r),c=Math.max(Jc(o),1e-4),l=Math.max(Jc(s),1e-4),u=Math.max(-1,Math.min(1,qc(o,s)/(c*l)));return Math.max(0,Math.min(1,(Math.PI-Math.acos(u))/(Math.PI*.55)))}function Uc(e,t){let n=e.x-t.x,r=e.y-t.y,i=(e.z||0)-(t.z||0);return Math.hypot(n,r,i)}function Wc(e,t){let n=Uc(e[Xs],t[Xs]),r=Gc(e),i=Gc(t);return n*.72+Uc(r,i)*.28}function Gc(e){return{x:(e[Xs].x+e[nc].x+e[cc].x)/3,y:(e[Xs].y+e[nc].y+e[cc].y)/3,z:((e[Xs].z||0)+(e[nc].z||0)+(e[cc].z||0))/3}}function Kc(e,t){return{x:t.x-e.x,y:t.y-e.y,z:(t.z||0)-(e.z||0)}}function qc(e,t){return e.x*t.x+e.y*t.y+e.z*t.z}function Jc(e){return Math.hypot(e.x,e.y,e.z)}function Yc(){if(D.cameraVideo?.readyState>=HTMLMediaElement.HAVE_CURRENT_DATA)return D.cameraVideo;if(D.gestureFrameReady&&D.gestureFrameCanvas?.width&&D.gestureFrameCanvas?.height)return D.gestureFrameCanvas;let e=performance.now();return e-wc>5e3&&(wc=e),null}function Xc(){return{name:`mediapipe-camera-frame-source`,onUpdate:({processCpuResult:e})=>{Qc(Zc(e))}}}function Zc(e){return e?.cameraPixelArray||e?.cameraPixels||e?.camerapixelarray||e?.pixels||e?.reality?.cameraPixelArray||e?.reality?.cameraPixels||null}function Qc(e){if(!e)return;let t=e.pixels||e.data||e.buffer||e,n=e.width||e.cols||e.columnCount||e.pixelWidth||e.imageWidth,r=e.height||e.rows||e.rowCount||e.pixelHeight||e.imageHeight;if(!t||!n||!r)return;let i=tl(t);if(!i.length)return;let a=$c(n,r).getContext(`2d`,{willReadFrequently:!0}),o=a.createImageData(n,r),s=el(i.length,n,r),c=e.rowBytes||e.stride||n*s,l=0;for(let e=0;e<r;e+=1){let t=e*c;for(let e=0;e<n;e+=1){let n=t+e*s;if(s>=4)o.data[l]=i[n],o.data[l+1]=i[n+1],o.data[l+2]=i[n+2],o.data[l+3]=i[n+3]||255;else if(s===3)o.data[l]=i[n],o.data[l+1]=i[n+1],o.data[l+2]=i[n+2],o.data[l+3]=255;else{let e=i[n];o.data[l]=e,o.data[l+1]=e,o.data[l+2]=e,o.data[l+3]=255}l+=4}}a.putImageData(o,0,0),D.gestureFrameReady=!0}function $c(e,t){return D.gestureFrameCanvas||(D.gestureFrameCanvas=document.createElement(`canvas`),D.gestureFrameCanvas.id=`mediapipe-camera-frame`,D.gestureFrameCanvas.style.cssText=`display:none`,document.body.appendChild(D.gestureFrameCanvas)),(D.gestureFrameCanvas.width!==e||D.gestureFrameCanvas.height!==t)&&(D.gestureFrameCanvas.width=e,D.gestureFrameCanvas.height=t),D.gestureFrameCanvas}function el(e,t,n){let r=Math.max(1,t*n);return e>=r*4?4:e>=r*3?3:1}function tl(e){return e instanceof Uint8Array?e:ArrayBuffer.isView(e)?new Uint8Array(e.buffer,e.byteOffset,e.byteLength):(e instanceof ArrayBuffer,new Uint8Array(e))}var nl=`
varying vec2 vUv;
void main() {
vUv = uv;
gl_Position = vec4(position.xy, 0.0, 1.0);
}`,rl=`jarvis_vr_state_v2`,il={default:{id:`default`,label:`Default`,eyeSep:.063,convergence:1.42,k1:-.22,k2:.08,chromaticAberration:.003,renderScale:.9,refreshRate:72,vignetteStrength:.12},quest:{id:`quest`,label:`Quest`,eyeSep:.064,convergence:1.38,k1:-.215,k2:.078,chromaticAberration:.0032,renderScale:.88,refreshRate:90,vignetteStrength:.1},visionos:{id:`visionos`,label:`VisionOS`,estimatedEyeSep:!0,eyeSep:.062,convergence:1.34,k1:-.205,k2:.074,chromaticAberration:.0024,renderScale:.92,refreshRate:90,vignetteStrength:.08},android:{id:`android`,label:`Android`,eyeSep:.063,convergence:1.44,k1:-.22,k2:.08,chromaticAberration:.003,renderScale:.82,refreshRate:72,vignetteStrength:.14},desktop:{id:`desktop`,label:`Desktop`,eyeSep:.065,convergence:1.5,k1:-.2,k2:.07,chromaticAberration:.0025,renderScale:.95,refreshRate:60,vignetteStrength:.18}},al=`
uniform sampler2D tDiffuse;
uniform float k1;
uniform float k2;
uniform float rAber;
varying vec2 vUv;
vec2 barrelDistort(vec2 uv, vec2 center) {
vec2 d = uv - center;
float r2 = dot(d, d);
float distortFactor = 1.0 + k1 * r2 + k2 * r2 * r2;
return center + d * distortFactor;
}
void main() {
bool isLeftEye = vUv.x < 0.5;
vec2 eyeCenter = isLeftEye ? vec2(0.25, 0.5) : vec2(0.75, 0.5);
vec2 distorted = barrelDistort(vUv, eyeCenter);
vec2 localUV = isLeftEye
? vec2(distorted.x * 2.0, distorted.y)
: vec2((distorted.x - 0.5) * 2.0, distorted.y);
if (localUV.x < 0.0 || localUV.x > 1.0 || localUV.y < 0.0 || localUV.y > 1.0) {
gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);
return;
}
float dist = length(localUV - vec2(0.5, 0.5));
float aberration = rAber * dist * dist * 3.0;
vec2 redUV = barrelDistort(vUv + vec2(aberration, 0.0), eyeCenter);
vec2 greenUV = distorted;
vec2 blueUV = barrelDistort(vUv - vec2(aberration, 0.0), eyeCenter);
float r = texture2D(tDiffuse, redUV).r;
float g = texture2D(tDiffuse, greenUV).g;
float b = texture2D(tDiffuse, blueUV).b;
gl_FragColor = vec4(r, g, b, 1.0);
}`,ol=null,W=null,sl=null,cl=null,ll=null,ul=new x(2,2);function dl(e){sl||(sl=new Pe,cl=new fe,ll=new Be({uniforms:{tDiffuse:{value:null},k1:{value:e.k1??-.22},k2:{value:e.k2??.08},rAber:{value:e.chromaticAberration??.003}},vertexShader:nl,fragmentShader:al,depthWrite:!1,depthTest:!1}),sl.add(new b(ul,ll)))}var fl=null,pl=null,ml=null,hl=!1,gl=null,_l=null,vl=null,yl=null,bl=0,xl=new Ve,Sl=!1,Cl=null,wl=null,G=Rl(),Tl=0,El=G.ipd,Dl=G.convergence,Ol=new i,kl=new Ve,Al=new Ve().setFromAxisAngle(new S(1,0,0),-Math.PI/2),jl=new Ve,Ml=new S(0,0,1);function Nl(){O(`enter-vr`,()=>Pl())}async function Pl(){let{renderer:e,scene:t,camera:n}=I();if(!e||!t||!n)return C(`Renderer is not ready yet. Start AR first, then enter VR.`,`VR Mode`),!1;G=Rl(),El=G.ipd,Dl=G.convergence;let r=Qt(),i=Ll(G.lensProfileId||r.browser);D.isVRMode=!0,Sl=!1,Tl=performance.now(),D.runtime.permissionState=D.runtime.permissionState||`unknown`,F(`passthroughBlendProxy`,!!Ql()),F(`comfortAdaptation`,!0),F(`predictivePoseFiltering`,!0),F(`reprojectionProxy`,!0),F(`questBrowserQuirks`,r.questBrowserQuirks),F(`stereoEyeBuffers`,!0),F(`stereoFrustumCalibration`,!0),F(`refreshRateNegotiation`,!0),F(`timestampSync`,!0),F(`motionSicknessMitigation`,!0),F(`teleportLocomotion`,!0),F(`smoothLocomotionSafeguards`,!0),F(`roomBoundaryVisualization`,!0),F(`stereoUiAnchoring`,!0),F(`antiAliasEdgeProtection`,!0),F(`zFightGuard`,!0),F(`sustainedFramerateGuard`,!0),F(`orientationLockStability`,!0),F(`sensorPermissionPersistenceProxy`,!0),F(`motionComfortVignette`,!0),F(`renderScaleStability`,!0),F(`headsetCameraCalibrationProxy`,!0),F(`deviceCapabilityMatrix`,!0),F(`lowLightTrackingResilience`,r.limits.lowLightTrackingResilience!==!1),Wl(e,i),i.estimatedEyeSep&&w(`VisionOS IPD is estimated because the browser does not expose a reliable eye distance API. Use the IPD slider to fine-tune comfort.`,`VR Mode`),zt({renderer:e,scene:t,camera:n},{mode:`vr-shell`,stereo:!0,source:Ql(),passthroughBlend:`browser-camera`,framebufferScaleFactor:i.renderScale,refreshRate:i.refreshRate,convergence:i.convergence,renderScale:i.renderScale,lensProfile:i.id,motionComfort:G.seatedMode?`seated`:`standing`,vignetteStrength:i.vignetteStrength}),Vl(i),Ul(i),await Kl(n),await ql();try{await screen.orientation?.lock?.(`landscape`)}catch{w(`Landscape lock was not allowed by this browser. Rotate the phone manually for VR.`)}let a=Ql();return a&&!pl?(pl=Yl(a),t.add(pl)):a||w(`VR passthrough is waiting for camera pixels. Stay in AR mode until the camera frame source is ready.`,`VR Mode`),Xl(),!hl&&globalThis.XR8?.addCameraPipelineModule?(globalThis.XR8.addCameraPipelineModule({name:`vr-stereo-renderer`,onRender:()=>{D.isVRMode&&Gl()}}),D.pipelineOrder.push(`vr-stereo-renderer`),hl=!0):globalThis.XR8?.addCameraPipelineModule||$l(),w(`VR screen active. ${i.label} stereo profile, IPD, refresh, and gyro are enabled.`,`VR Mode`),!0}function Fl(){D.isVRMode=!1,Sl=!1,zl(),Zl();try{screen.orientation?.unlock?.()}catch{}w(`Returned to AR mode.`,`VR Mode`)}function Il(e,t,n){return Math.min(n,Math.max(t,Number(e)||t))}function Ll(e=``){let t=String(e||``).toLowerCase();return t.includes(`quest`)?il.quest:t.includes(`vision`)?il.visionos:t.includes(`android`)?il.android:t.includes(`desktop`)?il.desktop:il.default}function Rl(){let e={ipd:.063,convergence:1.42,renderScale:.9,refreshRate:72,seatedMode:!0,floorCalibration:0,lensProfileId:`default`,vignette:.12};try{let t=hr(rl,null);return!t||typeof t!=`object`?e:{...e,...t,ipd:Il(t.ipd,.045,.075),convergence:Il(t.convergence,.8,2.2),renderScale:Il(t.renderScale,.72,1.25),refreshRate:Il(t.refreshRate,60,120),floorCalibration:Il(t.floorCalibration,-1.5,1.5),vignette:Il(t.vignette,0,.4),seatedMode:t.seatedMode!==!1,lensProfileId:String(t.lensProfileId||`default`)}}catch{return e}}function zl(){try{gr(rl,{ipd:parseFloat(_r(`jarvis_vr_ipd`,String(G.ipd||.063))),convergence:parseFloat(_r(`jarvis_vr_convergence`,String(G.convergence||1.42))),renderScale:G.renderScale,refreshRate:G.refreshRate,seatedMode:G.seatedMode,floorCalibration:G.floorCalibration,lensProfileId:G.lensProfileId,vignette:G.vignette,savedAt:new Date().toISOString()})}catch{}}function Bl(){return document.getElementById(`ui-layer`)||document.body}function Vl(e){Cl?.remove(),Cl=document.createElement(`div`),Cl.style.cssText=[`position:absolute`,`inset:0`,`z-index:25`,`pointer-events:none`,`background:radial-gradient(circle at center, rgba(0,0,0,0) 0%, rgba(0,0,0,0.14) 58%, rgba(0,0,0,0.32) 100%)`,`opacity:${Il(e.vignetteStrength??.12,0,.5)}`,`transition:opacity 180ms linear`].join(`;`),Bl().appendChild(Cl)}function Hl(e,t){if(!Cl)return;let n=G.seatedMode?.06:.1,r=Math.min(.24,Math.max(0,(e-16.6)/120)),i=Il((t.vignetteStrength??.12)+n+r,.06,.45);Cl.style.opacity=String(i)}function Ul(e){wl?.remove(),wl=document.createElement(`div`),wl.style.cssText=[`position:absolute`,`right:16px`,`top:18px`,`z-index:30`,`display:flex`,`flex-direction:column`,`gap:8px`,`padding:10px`,`border-radius:12px`,`background:rgba(3,12,20,0.72)`,`border:1px solid rgba(0,212,255,0.22)`,`backdrop-filter:blur(14px)`,`color:white`,`font:600 11px/1.2 Inter,sans-serif`,`pointer-events:auto`,`min-width:220px`].join(`;`);let t=(e,t)=>{let n=document.createElement(`label`);n.style.cssText=`display:flex;justify-content:space-between;align-items:center;gap:8px`;let r=document.createElement(`span`);return r.textContent=e,n.append(r,t),n},n=document.createElement(`input`);n.type=`range`,n.min=`0.045`,n.max=`0.075`,n.step=`0.001`,n.value=String(El??e.eyeSep??.063),n.style.cssText=`width:112px`;let r=document.createElement(`input`);r.type=`range`,r.min=`0.8`,r.max=`2.2`,r.step=`0.01`,r.value=String(Dl??e.convergence??1.42),r.style.cssText=`width:112px`;let i=document.createElement(`input`);i.type=`range`,i.min=`0.72`,i.max=`1.25`,i.step=`0.01`,i.value=String(G.renderScale??e.renderScale??.9),i.style.cssText=`width:112px`;let a=document.createElement(`select`);for(let t of[60,72,90,120]){let n=document.createElement(`option`);n.value=String(t),n.textContent=`${t}Hz`,Number(t)===Number(G.refreshRate||e.refreshRate)&&(n.selected=!0),a.appendChild(n)}let o=document.createElement(`button`);o.className=`btn-secondary`,o.textContent=G.seatedMode?`SEATED`:`STANDING`,o.onclick=()=>{G.seatedMode=!G.seatedMode,o.textContent=G.seatedMode?`SEATED`:`STANDING`,D.compositor.motionComfort=G.seatedMode?`seated`:`standing`,zl()};let s=document.createElement(`button`);s.className=`btn-secondary`,s.textContent=`FLOOR -`,s.onclick=()=>{G.floorCalibration=Il(G.floorCalibration-.05,-1.5,1.5),D.compositor.floorCalibration=G.floorCalibration,zl(),w(`Floor calibration ${G.floorCalibration.toFixed(2)}m`,`VR Mode`)};let c=document.createElement(`button`);c.className=`btn-secondary`,c.textContent=`FLOOR +`,c.onclick=()=>{G.floorCalibration=Il(G.floorCalibration+.05,-1.5,1.5),D.compositor.floorCalibration=G.floorCalibration,zl(),w(`Floor calibration ${G.floorCalibration.toFixed(2)}m`,`VR Mode`)};let l=document.createElement(`span`);l.textContent=`${e.label} profile`,l.style.opacity=`0.82`,n.oninput=()=>{vr(`jarvis_vr_ipd`,n.value),G.ipd=parseFloat(n.value),El=G.ipd,D.compositor.eyeSep=El},r.oninput=()=>{vr(`jarvis_vr_convergence`,r.value),G.convergence=parseFloat(r.value),Dl=G.convergence,D.compositor.convergence=Dl},i.oninput=()=>{G.renderScale=parseFloat(i.value),D.compositor.renderScale=G.renderScale,zl()},a.onchange=()=>{G.refreshRate=parseFloat(a.value),D.compositor.refreshRate=G.refreshRate,D.compositor.frameBudgetMs=1e3/G.refreshRate,zl()},wl.append(l,t(`IPD`,n),t(`Convergence`,r),t(`Scale`,i),t(`Refresh`,a));let u=document.createElement(`div`);u.style.cssText=`display:flex;gap:6px;justify-content:space-between`,u.append(o,s,c),wl.appendChild(u),Bl().appendChild(wl)}function Wl(e,t=Ll()){let n=new Ce;e.getDrawingBufferSize(n);let r=Il(G.renderScale??t.renderScale??1,.72,1.25),i=Math.max(2,Math.floor(n.x*r)),a=Math.max(2,Math.floor(n.y*r)),o=Math.max(2,Math.floor(i/2))/Math.max(1,a);ol=ol||new be,ol.eyeSep=El||t.eyeSep||.063,ol.focus=Dl||t.convergence||1.4,(!W||W.width!==i||W.height!==a)&&(W?.dispose(),W=new Ge(i,a,{minFilter:f,magFilter:f})),dl(t),ll&&(ll.uniforms.k1.value=t.k1??-.22,ll.uniforms.k2.value=t.k2??.08,ll.uniforms.rAber.value=t.chromaticAberration??.003),D.compositor={...D.compositor,refreshRate:t.refreshRate,frameBudgetMs:1e3/t.refreshRate,renderScale:r,convergence:ol.focus,lensProfile:t.id,eyeAspect:o,vignetteStrength:t.vignetteStrength,motionComfort:G.seatedMode?`seated`:`standing`,floorCalibration:G.floorCalibration},!vl&&e?.domElement&&(vl=e=>{e.preventDefault?.(),w(`WebGL context was lost. VR will pause until the renderer restores.`,`VR Mode`),D.isVRMode=!1,bl&&yt(bl),bl=0,ol=null,W=null,sl=null,cl=null,ll=null},yl=()=>{w(`WebGL context restored. Returning to VR mode.`,`VR Mode`),D.started&&(D.isVRMode=!0,Wl(e,t),$l())},e.domElement.addEventListener(`webglcontextlost`,vl,{passive:!1}),e.domElement.addEventListener(`webglcontextrestored`,yl))}function Gl(){let{renderer:e,scene:t,camera:n}=I();if(!e||!t||!n||!W||!ol)return;let r=new Ce;e.getDrawingBufferSize(r);let i=Ll(G.lensProfileId),a=Il(G.renderScale??i.renderScale??1,.72,1.25),o=Math.max(2,Math.floor(r.x*a)),s=Math.max(2,Math.floor(r.y*a)),c=Math.max(2,Math.floor(o/2)),l=c/Math.max(1,s);(W.width!==o||W.height!==s)&&Wl(e,i);let u=n.aspect;n.aspect=l,n.updateProjectionMatrix(),ol.eyeSep=El||i.eyeSep||.063,ol.focus=Dl||i.convergence||1.4,ol.update(n),e.setRenderTarget(W),e.setScissorTest(!0),e.clear(!0,!0,!0),ml?.userData?.liveCanvas&&(ml.needsUpdate=!0),e.setViewport(0,0,c,s),e.setScissor(0,0,c,s),e.render(t,ol.cameraL),e.clearDepth(),e.setViewport(c,0,c,s),e.setScissor(c,0,c,s),e.render(t,ol.cameraR),e.setScissorTest(!1),e.setRenderTarget(null),e.setViewport(0,0,r.x,r.y),ll.uniforms.tDiffuse.value=W.texture,e.render(sl,cl),n.aspect=u,n.updateProjectionMatrix();let d=performance.now(),f=Tl?d-Tl:16.6;Tl=d,Bt(f),Hl(f,i)}async function Kl(e){Qt();try{if(typeof DeviceOrientationEvent<`u`&&typeof DeviceOrientationEvent.requestPermission==`function`){let e=await DeviceOrientationEvent.requestPermission();if(e!==`granted`)return vr(`jarvis_vr_motion_permission`,String(e||`denied`)),w(`Motion access denied or timed out. VR head tracking disabled.`),!1;vr(`jarvis_vr_motion_permission`,`granted`)}return gl&&window.removeEventListener(`deviceorientation`,gl),gl=t=>Jl(t,e),window.addEventListener(`deviceorientation`,gl),!0}catch(e){return C(e.message,`Motion Permission Failed`),!1}}async function ql(){try{if(document.fullscreenElement)return!0;if(!document.documentElement?.requestFullscreen)return!1;let e=document.documentElement.requestFullscreen({navigationUI:`hide`}).catch(()=>!1);return await Promise.race([e,new Promise(e=>setTimeout(()=>e(!1),Qt().isQuest?1e3:1500))]),_l||(_l=()=>{!document.fullscreenElement&&D.isVRMode&&w(`Fullscreen exited. VR view will remain in-browser.`,`VR Mode`)},document.addEventListener(`fullscreenchange`,_l),document.addEventListener(`webkitfullscreenchange`,_l)),F(`orientationLockStability`,!0),!0}catch{return w(`Fullscreen lock was not granted. VR continues in browser windowed mode.`,`VR Mode`),!1}}function Jl(e,t){if(!D.isVRMode||!t)return;let n=Xe.degToRad(e.alpha||0),r=Xe.degToRad(e.beta||0),i=Xe.degToRad(e.gamma||0),a=Number(screen.orientation?.angle||window.orientation||0);Ol.set(r,n,-i,`YXZ`),kl.setFromEuler(Ol),kl.multiply(Al),jl.setFromAxisAngle(Ml,-Xe.degToRad(a)),kl.multiply(jl),Sl?xl.slerp(kl,.18):(xl.copy(kl),Sl=!0),t.quaternion.copy(xl)}function Yl(e){let t=e.tagName===`VIDEO`,n=t?new le(e):new qe(e);n.minFilter=f,n.magFilter=f,n.userData.liveCanvas=!t,ml=n;let r=new ke(500,60,40);return r.scale(-1,1,1),new b(r,new d({map:n}))}function Xl(){fl?.remove(),fl=document.createElement(`button`),fl.textContent=`EXIT VR`,fl.className=`btn-primary`,fl.style.cssText=`position:absolute;top:20px;left:20px;z-index:30;background:var(--destructive);padding-top:calc(12px + env(safe-area-inset-top));pointer-events:auto`,fl.onclick=Fl(document.getElementById(`ui-layer`)||document.body).appendChild(fl);let e=document.createElement(`input`);e.type=`range`,e.min=`0.045`,e.max=`0.075`,e.step=`0.001`,e.value=String(El||.063),e.style.cssText=`width:168px;pointer-events:auto`;let t=document.createElement(`label`);t.dataset.vrControl=`ipd`,t.style.cssText=`position:absolute;right:18px;bottom:20px;z-index:30;display:flex;flex-direction:column;gap:6px;color:white;font:600 12px/1.2 Inter,sans-serif;text-shadow:0 1px 4px #000;pointer-events:auto`;let n=document.createElement(`span`);n.textContent=`${Math.round(parseFloat(e.value)*1e3)} mm IPD`,e.oninput=()=>{vr(`jarvis_vr_ipd`,e.value),El=parseFloat(e.value),n.textContent=`${Math.round(parseFloat(e.value)*1e3)} mm IPD`},t.append(n,e)(document.getElementById(`ui-layer`)||document.body).appendChild(t),fl.addEventListener(`click`,()=>t.remove(),{once:!0})}function Zl(){try{let e=D.xrSession;if(e?.end){let t=e.end();t?.catch&&t.catch(()=>{})}}catch{}fl?.remove(),document.querySelector(`[data-vr-control="ipd"]`)?.remove(),wl?.remove(),Cl?.remove(),wl=null,Cl=null,gl&&(window.removeEventListener(`deviceorientation`,gl),gl=null),_l&&(document.removeEventListener(`fullscreenchange`,_l),document.removeEventListener(`webkitfullscreenchange`,_l),_l=null),vl&&(I()?.renderer?.domElement?.removeEventListener?.(`webglcontextlost`,vl),vl=null),yl&&(I()?.renderer?.domElement?.removeEventListener?.(`webglcontextrestored`,yl),yl=null),bl&&(yt(bl),bl=0),W&&(W.dispose(),W=null),ml?.dispose&&ml.dispose(),ml=null,pl?.geometry?.dispose?.(),pl?.material?.dispose?.(),pl?.remove?.(),pl=null,ll?.dispose?.(),ll=null,sl=null,cl=null,ol=null}function Ql(){if(D.cameraVideo?.readyState>=HTMLMediaElement.HAVE_CURRENT_DATA)return D.cameraVideo;if(D.gestureFrameReady&&D.gestureFrameCanvas?.width&&D.gestureFrameCanvas?.height)return D.gestureFrameCanvas;let e=document.getElementById(`camerafeed`);return e?.width&&e?.height?e:null}function $l(){if(bl)return;let e=()=>{if(!D.isVRMode){bl=0;return}Gl(),bl=P(e)};bl=P(e)}var eu=`external/models/zipdepth_base_npu_384.onnx`,tu=`external/ort/`,K=384,nu=[.485,.456,.406],ru=[.229,.224,.225],q={ort:null,session:null,loading:null,canvas:null,ctx:null,input:null,provider:null,lastMs:0,frames:0,failed:null};function iu(){return{ready:!!q.session,provider:q.provider,model:`ZipDepth-base (NPU variant), 6.1M params, MIT`,inputSize:K,lastInferenceMs:Math.round(q.lastMs),framesEstimated:q.frames,error:q.failed,runsLocally:!0,networkCallsPerFrame:0}}async function au(){if(q.session)return q.session;if(q.loading)return q.loading;q.loading=(async()=>{let e=await t(()=>import(`./ort.bundle.min--hz_0CH4.js`),__vite__mapDeps([4,2,5]),import.meta.url);e.env.wasm.wasmPaths=tu,e.env.wasm.numThreads=1,q.ort=e;let n=`gpu`in navigator?[`webgpu`,`wasm`]:[`wasm`],r=null,i=null;for(let t of n)try{r=await e.InferenceSession.create(eu,{executionProviders:[t]}),q.provider=t;break}catch(e){i=e}if(!r)throw q.failed=i?.message||String(i),Error(`Depth engine failed to load: ${q.failed}`);return q.canvas=document.createElement(`canvas`),q.canvas.width=K,q.canvas.height=K,q.ctx=q.canvas.getContext(`2d`,{willReadFrequently:!0}),q.input=new Float32Array(3*K*K),q.session=r,r})();try{return await q.loading}finally{q.loading=null}}async function ou(e){if(!q.session||!e)return null;let t=performance.now();q.ctx.drawImage(e,0,0,K,K);let{data:n}=q.ctx.getImageData(0,0,K,K),r=K*K,i=q.input;for(let e=0,t=0;e<r;e++,t+=4)i[e]=(n[t]/255-nu[0])/ru[0],i[r+e]=(n[t+1]/255-nu[1])/ru[1],i[2*r+e]=(n[t+2]/255-nu[2])/ru[2];let a=new q.ort.Tensor(`float32`,i,[1,3,K,K]),o=q.session.inputNames[0],s=(await q.session.run({[o]:a}))[q.session.outputNames[0]].data;return q.lastMs=performance.now()-t,q.frames+=1,{data:s,width:K,height:K,ms:q.lastMs}}function su(e){let{data:t,width:n,height:r}=e,i=1/0,a=-1/0;for(let e=0;e<t.length;e++){let n=t[e];n<i&&(i=n),n>a&&(a=n)}let o=Math.max(a-i,1e-6),s=new Uint8Array(n*r);for(let e=0;e<t.length;e++)s[e]=(t[e]-i)/o*255;return{bytes:s,width:n,height:r,min:i,max:a}}async function cu(){if(q.session?.release)try{await q.session.release()}catch{}q.session=null,q.provider=null,q.canvas=null,q.ctx=null,q.input=null}var lu=2e4,uu=0,du=[`flat`,`180`,`360`,`fisheye`],fu=[`mono`,`sbs-full`,`sbs-half`,`tb-full`,`tb-half`],pu={passthrough:{id:`passthrough`,label:`Passthrough`,room:null,hFov:32,distance:3.2,curvatureRadius:0,reverb:{seconds:.35,decay:3.2,wet:.06},note:`The real room stays visible; the picture is composited into it as a screen.`},mixed:{id:`mixed`,label:`Mixed reality`,room:`frame`,hFov:36,distance:3.4,curvatureRadius:0,reverb:{seconds:.45,decay:3,wet:.1},note:`Passthrough plus a virtual bezel and ambient light response.`},theater:{id:`theater`,label:`Theater`,room:`hall`,hFov:36,distance:8,curvatureRadius:25,scale:{width:16,depth:22,height:8.5},reverb:{seconds:1.4,decay:2.4,wet:.18},note:`A standard cinema hall — 36 degrees subtended from the seat, gently curved.`},pvr:{id:`pvr`,label:`PVR`,room:`hall`,hFov:34,distance:9,curvatureRadius:30,scale:{width:15,depth:24,height:8},reverb:{seconds:1.2,decay:2.6,wet:.15},note:`A mainstream multiplex auditorium — slightly further back, flatter screen.`},inox:{id:`inox`,label:`INOX`,room:`hall`,hFov:40,distance:8.5,curvatureRadius:22,scale:{width:18,depth:23,height:9.5},reverb:{seconds:1.6,decay:2.3,wet:.2},note:`A premium large-screen auditorium, sitting between Theater and IMAX in scale.`},imax:{id:`imax`,label:`IMAX`,room:`dome`,hFov:70,distance:7,curvatureRadius:null,curvatureRadiusFactor:1.5,scale:{width:24,depth:20,height:16},reverb:{seconds:2.2,decay:1.9,wet:.26},note:`Large-format geometry — 70 degrees subtended, curvature radius 1.5x screen width.`}},mu=`
varying vec2 vUv;
varying vec3 vDir;
void main() {
vUv = uv;
vDir = normalize(position);
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
}`,hu=`
uniform sampler2D uMap;
uniform vec2 uUvScale;
uniform vec2 uUvOffset;
uniform int uProjectionKind;
uniform float uFisheyeFov;
uniform vec2 uFisheyeCenter;
uniform vec2 uFisheyeRadius;
uniform float uOpacity;
// AI depth (free-tier, on-device). uDepthEyeSign is 0 for the eye that shows the
// original frame untouched and non-zero for the synthesised one, so the real
// captured eye is never resampled - only the invented one is.
uniform sampler2D uDepthMap;
uniform float uDepthStrength;
uniform float uDepthEyeSign;
varying vec2 vUv;
varying vec3 vDir;
void main() {
vec2 uv;
if (uProjectionKind == 1) {
vec3 d = normalize(vDir);
float theta = acos(clamp(-d.z, -1.0, 1.0));
// Deliberately NOT named "half": that is a reserved word in GLSL ES, and
// using it makes the whole shader fail to compile, which silently blanks
// every projection - not just fisheye - because this is one shared program.
// Found by running it live; no JS-side syntax check can see inside a shader.
float halfFov = max(uFisheyeFov * 0.5, 0.0001);
float rNorm = theta / halfFov;
if (rNorm > 1.0) {
gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);
return;
}
float phi = atan(d.y, d.x);
uv = uFisheyeCenter + rNorm * uFisheyeRadius * vec2(cos(phi), sin(phi));
} else {
uv = vUv;
}
uv = uv * uUvScale + uUvOffset;
// Depth-based right-eye synthesis. Sampling the colour frame at a horizontally
// displaced coordinate is a real parallax warp, done in UV space against the
// already-decoded texture - no second decode, no canvas resize, so the
// zero-quality-loss path is untouched for the eye that came from the source.
//
// Honest limitation, per this document's no-invented-claims rule: a warp cannot
// fill what was never captured. Pixels revealed from behind a foreground object
// (disocclusions) are smeared neighbours here, not inpainted detail, which is
// why this ships labelled as an AI depth EFFECT and not as real stereo capture.
if (uDepthStrength > 0.0 && uDepthEyeSign != 0.0) {
float d = texture2D(uDepthMap, uv).r;
uv.x += uDepthEyeSign * uDepthStrength * d;
}
gl_FragColor = vec4(texture2D(uMap, uv).rgb, uOpacity);
#include <colorspace_fragment>
}`,J={active:!1,file:null,element:null,isVideo:!1,sourceWidth:0,sourceHeight:0,texture:null,projection:`flat`,projectionAuto:!0,packing:`mono`,packingAuto:!0,environment:`theater`,meshes:[],room:null,group:null,screen:{width:0,height:0,distance:0,elevation:0,curvatureRadius:0},quality:null,audio:null,ambient:null,loop:0,deviceLimits:null,findings:[],aiDepth:{enabled:!1,texture:null,strength:.012,timer:0,lastMs:0,provider:null,error:null}};function gu(){let{renderer:e}=I(),t=e?.getContext?.()||null,n=t?t.getParameter(t.MAX_TEXTURE_SIZE):0,r=typeof globalThis.VideoDecoder==`function`,i=typeof globalThis.XRMediaBinding==`function`,a=typeof HTMLVideoElement<`u`&&typeof HTMLVideoElement.prototype?.requestVideoFrameCallback==`function`,o={maxTextureSize:n,webCodecs:r,webxrMediaLayers:i,webxrGLBinding:typeof globalThis.XRWebGLBinding==`function`,requestVideoFrameCallback:a,webAudio:typeof globalThis.AudioContext==`function`||typeof globalThis.webkitAudioContext==`function`,xr:!!navigator.xr};return J.deviceLimits=o,F(`mediaViewerMaxTextureSize`,n),F(`mediaViewerWebCodecs`,r),F(`mediaViewerWebXRMediaLayers`,i),o}function _u(e,t,n=``){let r=String(n).toLowerCase();if(/(^|[^a-z])fisheye|dualfish|_fish/.test(r))return{value:`fisheye`,why:`filename says fisheye`};if(/vr180|_180|180deg|180x180/.test(r))return{value:`180`,why:`filename says 180`};if(/vr360|_360|360deg|equirect|spherical|insta360|theta/.test(r))return{value:`360`,why:`filename says 360`};if(!e||!t)return{value:`flat`,why:`no dimensions available yet`};let i=e/t;return Math.abs(i-2)<.02?{value:`360`,why:`${e}x${t} is 2:1 equirectangular`}:Math.abs(i-4)<.06?{value:`180`,why:`${e}x${t} is 4:1 — two 1:1 hemispheres`}:Math.abs(i-1)<.02?{value:`fisheye`,why:`${e}x${t} is square — likely a fisheye circle`}:{value:`flat`,why:`${e}x${t} (${i.toFixed(2)}:1) is an ordinary frame`}}function vu(e){return e===`180`?1:e===`360`?2:e===`fisheye`?1:16/9}function yu(e,t,n=``,r=`flat`){let i=String(n).toLowerCase(),a=vu(r),o=(e,t)=>Math.abs(e-t)/t<.12;if(/_?(sbs|side.?by.?side|lr|left.?right)/.test(i)){let n=e/2/t;return o(n,a)?{value:`sbs-full`,why:`side-by-side, each eye ${Math.round(e/2)}x${t} at its full aspect`}:o(n*2,a)?{value:`sbs-half`,why:`side-by-side, each eye squeezed to ${Math.round(e/2)}x${t}`}:{value:`sbs-full`,why:`filename says side-by-side; aspect matched neither full nor half, assuming full`}}if(/_?(tb|ou|top.?bottom|over.?under)/.test(i)){let n=e/(t/2);return o(n,a)?{value:`tb-full`,why:`top-bottom, each eye ${e}x${Math.round(t/2)} at its full aspect`}:o(n/2,a)?{value:`tb-half`,why:`top-bottom, each eye squeezed to ${e}x${Math.round(t/2)}`}:{value:`tb-full`,why:`filename says top-bottom; aspect matched neither full nor half, assuming full`}}if(/_?mono/.test(i))return{value:`mono`,why:`filename says mono`};if(!e||!t)return{value:`mono`,why:`no dimensions available yet`};let s=e/t;return r===`180`&&Math.abs(s-4)<.06?{value:`sbs-full`,why:`4:1 on a 180 source is two full-width eyes`}:r===`360`&&Math.abs(s-1)<.02?{value:`tb-full`,why:`1:1 on a 360 source is two stacked equirect eyes`}:{value:`mono`,why:`no stereo signal in the dimensions or the filename`}}function bu(e,t){let n=t===`right`;switch(e){case`sbs-full`:case`sbs-half`:return{scale:[.5,1],offset:[n?.5:0,0]};case`tb-full`:case`tb-half`:return{scale:[1,.5],offset:[0,n?0:.5]};default:return{scale:[1,1],offset:[0,0]}}}function xu(e,t,n){switch(n){case`sbs-full`:return{width:e/2,height:t,squeezed:!1};case`sbs-half`:return{width:e/2,height:t,squeezed:!0,displayAspect:e/2/t*2};case`tb-full`:return{width:e,height:t/2,squeezed:!1};case`tb-half`:return{width:e,height:t/2,squeezed:!0,displayAspect:e/(t/2)/2};default:return{width:e,height:t,squeezed:!1}}}function Su({width:e,height:t,curvatureRadius:n=0,segments:r=96}){if(!n||n<=0)return new x(e,t,1,1);let i=e/n,a=[],o=[],s=[];for(let e=0;e<=r;e+=1){let s=e/r,c=(s-.5)*i,l=n*Math.sin(c),u=n*(1-Math.cos(c));a.push(l,t/2,u,l,-t/2,u),o.push(s,1,s,0)}for(let e=0;e<r;e+=1){let t=e*2;s.push(t,t+1,t+2,t+1,t+3,t+2)}let c=new Je;return c.setAttribute(`position`,new Ee(a,3)),c.setAttribute(`uv`,new Ee(o,2)),c.setIndex(s),c.computeVertexNormals(),c.userData.arcDegrees=Xe.radToDeg(i),c}function Cu(e,t){switch(e){case`360`:{let e=new ke(480,96,56);return e.scale(-1,1,1),e}case`180`:case`fisheye`:{let e=new ke(480,96,56,Math.PI,Math.PI,0,Math.PI);return e.scale(-1,1,1),e}default:return Su(t)}}function wu(e,t,n,r,i){let a=bu(n,r);return new Be({uniforms:{uMap:{value:e},uUvScale:{value:new Ce(a.scale[0],a.scale[1])},uUvOffset:{value:new Ce(a.offset[0],a.offset[1])},uProjectionKind:{value:+(t===`fisheye`)},uFisheyeFov:{value:i?.fov??Math.PI},uFisheyeCenter:{value:new Ce(i?.cx??.5,i?.cy??.5)},uFisheyeRadius:{value:new Ce(i?.rx??.5,i?.ry??.5)},uOpacity:{value:1},uDepthMap:{value:J.aiDepth.texture},uDepthStrength:{value:J.aiDepth.enabled?J.aiDepth.strength:0},uDepthEyeSign:{value:+(r===`right`)}},vertexShader:mu,fragmentShader:hu,side:0,depthWrite:t===`flat`,transparent:!1})}function Tu(e){if(!e.room)return null;let t=new g;if(t.name=`media-room-${e.id}`,e.room===`frame`){let e=new b(new Te(.98,1.06,4,1,Math.PI/4),new d({color:58879,transparent:!0,opacity:.55}));return e.name=`media-frame`,t.add(e),t}let n=e.scale||{width:16,depth:22,height:8.5},r=new ae({color:658706,roughness:.94,metalness:.02}),i=new ae({color:1119516,roughness:.88,metalness:.04}),o=new b(new x(n.width,n.depth),i);o.rotation.x=-Math.PI/2,o.position.set(0,-1.35,-n.depth/2+4),t.add(o);let s=new b(new x(n.width,n.depth),r);s.rotation.x=Math.PI/2,s.position.set(0,n.height-1.35,-n.depth/2+4),t.add(s);let c=new b(new x(n.width,n.height),r);c.position.set(0,n.height/2-1.35,4),c.rotation.y=Math.PI,t.add(c);for(let e of[-1,1]){let i=new b(new x(n.depth,n.height),r);i.position.set(e*n.width/2,n.height/2-1.35,-n.depth/2+4),i.rotation.y=e>0?-Math.PI/2:Math.PI/2,t.add(i)}let u=e.room===`dome`?9:7,f=new l(new ce(.52,.5,.5),new ae({color:1707796,roughness:.96}),u*14),p=new a,m=0;for(let e=0;e<u;e+=1)for(let t=0;t<14;t+=1)p.makeTranslation((t-13/2)*.72,-1.05+e*.16,1.2+e*1.05),f.setMatrixAt(m,p),m+=1;f.instanceMatrix.needsUpdate=!0,f.name=`media-seats`,t.add(f);let h=new Fe(2240580,.55);h.name=`media-room-ambient`,t.add(h);let _=new se(58879,0,40);return _.name=`media-ambilight`,_.position.set(0,1.4,-e.distance*.6),t.add(_),t}function Eu(e,t,n={}){let r=pu[e]||pu.theater,i=n.distance??r.distance,a=n.hFov??r.hFov,o=n.width??2*i*Math.tan(Xe.degToRad(a)/2),s=o/(t||16/9),c=n.curvatureRadius;return c??(c=r.curvatureRadiusFactor?o*r.curvatureRadiusFactor:r.curvatureRadius),{width:o,height:s,distance:i,hFov:a,curvatureRadius:c,elevation:n.elevation??(e===`imax`?1.1:.6),arcDegrees:c>0?Xe.radToDeg(o/c):0}}async function Du(e,t={}){if(!e)throw Error(`No file given`);Ku({keepScene:!0});let n=(e.type||``).startsWith(`video/`)||/\.(mp4|webm|mov|mkv|m4v)$/i.test(e.name||``),r=URL.createObjectURL(e),i=document.createElement(n?`video`:`img`);n&&(i.playsInline=!0,i.muted=t.muted??!1,i.loop=t.loop??!0,i.crossOrigin=`anonymous`,i.preload=`auto`,i.style.cssText=`position:absolute;width:1px;height:1px;opacity:0;pointer-events:none;left:-9999px`,document.body.appendChild(i)),await new Promise((t,a)=>{let o=!1,s=e=>(...t)=>{o||(o=!0,clearTimeout(u),e(...t))},c=s(t),l=s(()=>a(Error(`Could not decode ${e.name}. The browser reported ${i.error?`media error ${i.error.code}`:`no readable video or image stream`}.`))),u=setTimeout(s(()=>a(Error(`${e.name} did not report its dimensions within ${lu/1e3}s. The file may be very large, or this device may not have a decoder for it.`))),lu);i.addEventListener(n?`loadedmetadata`:`load`,c,{once:!0}),i.addEventListener(`error`,l,{once:!0}),i.src=r});let a=n?i.videoWidth:i.naturalWidth,o=n?i.videoHeight:i.naturalHeight;J.file=e,J.element=i,J.isVideo=n,J.sourceWidth=a,J.sourceHeight=o,J.objectUrl=r,J.findings=[];let s=J.deviceLimits||gu();if(s.maxTextureSize&&Math.max(a,o)>s.maxTextureSize){let e=`Device texture limit reached: this GPU's MAX_TEXTURE_SIZE is ${s.maxTextureSize}px and the source is ${a}x${o}. The frame cannot be uploaded at native resolution on this device.`;J.findings.push(e),C(e,`Device limit`)}let c=t.projection?{value:t.projection,why:`chosen by you`}:_u(a,o,e.name);J.projection=c.value,J.projectionAuto=!t.projection,J.projectionWhy=c.why;let l=t.packing?{value:t.packing,why:`chosen by you`}:yu(a,o,e.name,J.projection);if(J.packing=l.value,J.packingAuto=!t.packing,J.packingWhy=l.why,J.environment=t.environment||J.environment||`theater`,Au(),n){Ru();try{await i.play()}catch{w(`Tap play to start — this browser needs a gesture before it will play audio.`,`Media`)}Wu()}return J.active=!0,k(`media-opened`,Y()),Y()}function Ou(){if(J.texture&&J.texture.image===J.element)return J.texture;J.texture?.dispose&&J.texture.dispose();let e=J.isVideo?new le(J.element):new Ie(J.element);return J.isVideo||(e.needsUpdate=!0),e.colorSpace=de,e.generateMipmaps=!1,e.minFilter=f,e.magFilter=f,e.wrapS=Ke,e.wrapT=Ke,e.userData.mediaTextureId=`tex-${Date.now()}-${Math.random().toString(36).slice(2,8)}`,J.texture=e,e}function ku(){if(D.isVRMode)return!0;try{let{renderer:e}=I();if(e?.xr?.isPresenting)return!0}catch{}return!1}function Au(){let{scene:e}=I();if(!e)throw Error(`No scene — start AR first`);ju({keepTexture:!0});let t=Ou(),n=xu(J.sourceWidth,J.sourceHeight,J.packing),r=n.displayAspect||n.width/n.height,i=Eu(J.environment,r,J.screenOverride||{});J.screen=i;let a={fov:Math.PI,cx:.5,cy:.5,rx:.5,ry:.5*(n.width/n.height)};a.ry>.5&&(a.rx=.5*(n.height/n.width),a.ry=.5);let o=new g;o.name=`media-viewer`,J.group=o;let s=J.packing!==`mono`&&ku();J.stereoRendered=s;let c=s?[`left`,`right`]:[J.packing===`mono`?`mono`:`left`];J.meshes=c.map((e,n)=>{let r=new b(Cu(J.projection,i),wu(t,J.projection,J.packing,e,a));return r.name=`media-${J.projection}-${e}${s?``:c.length===1&&e===`left`?`-mono-view`:``}`,r.frustumCulled=!1,J.projection!==`flat`&&(r.renderOrder=-1),s&&r.layers.set(n===0?1:2),J.projection===`flat`&&r.position.set(0,i.elevation,-i.distance),o.add(r),r});let l=pu[J.environment],u=J.projection===`flat`,d=u?Tu(l):null;J.roomSuppressed=!u&&!!l.room,d&&(l.room===`frame`&&(d.position.set(0,i.elevation,-i.distance-.02),d.scale.set(i.width/1.4,i.height/1.4,1)),o.add(d),J.room=d),e.add(o),F(`mediaViewerActive`,!0)}function ju({keepTexture:e=!1}={}){let{scene:t}=I();J.group&&(J.group.traverse(e=>{e.geometry?.dispose?.(),Array.isArray(e.material)?e.material.forEach(e=>e.dispose?.()):e.material?.dispose?.()}),t?.remove?.(J.group)),J.group=null,J.room=null,J.meshes=[],e||(J.texture?.dispose&&J.texture.dispose(),J.texture=null)}function Mu(){let e=I()?.renderer?.xr?.getSession?.()||D.xrSession||null,t=typeof globalThis.XRMediaBinding==`function`,n=typeof globalThis.XRWebGLBinding==`function`,r=t&&typeof globalThis.XRMediaBinding.prototype?.createEquirectLayer==`function`,i=t&&typeof globalThis.XRMediaBinding.prototype?.createQuadLayer==`function`,a=t&&typeof globalThis.XRMediaBinding.prototype?.createCylinderLayer==`function`,o=!!e?.enabledFeatures?.includes?.(`layers`),s=!1,c;return e?t?o?!r&&!i?c=`XRMediaBinding exists but exposes neither createEquirectLayer nor createQuadLayer.`:s=!0:c=`The running XRSession did not enable the "layers" feature, so no layer can be created on it even though the constructor exists.`:c=`XRMediaBinding is not implemented by this browser. XRWebGLBinding alone would still require rendering into the layer ourselves, which reintroduces the resampling pass Layers exists to avoid, so it is not a substitute here.`:c=`No immersive XRSession is running. Layers only exist inside one; the shader projection path is what runs in an inline/fallback session.`,{usable:s,reason:c,hasMediaBinding:t,hasGLBinding:n,ctorEquirect:r,ctorQuad:i,ctorCylinder:a,sessionPresent:!!e,sessionEnabledFeatures:e?.enabledFeatures?[...e.enabledFeatures]:null}}async function Nu(){let e=Mu();if(J.layers=e,!e.usable||!J.isVideo||!J.element)return J.layers={...e,applied:!1},J.layers;try{let t=I()?.renderer,n=t?.xr?.getSession?.()||D.xrSession,r=t?.xr?.getReferenceSpace?.()||await n.requestReferenceSpace(`local`),i=new globalThis.XRMediaBinding(n),a=J.packing===`mono`?`mono`:J.packing.startsWith(`sbs`)?`stereo-left-right`:`stereo-top-bottom`,o,s;J.projection===`360`||J.projection===`180`?(o=i.createEquirectLayer(J.element,{space:r,layout:a,centralHorizontalAngle:J.projection===`180`?Math.PI:2*Math.PI}),s=`equirect`):e.ctorCylinder&&J.screen?.curvatureRadius>0?(o=i.createCylinderLayer(J.element,{space:r,layout:a,radius:J.screen.curvatureRadius,centralAngle:J.screen.width/J.screen.curvatureRadius,aspectRatio:J.screen.width/J.screen.height}),s=`cylinder`):(o=i.createQuadLayer(J.element,{space:r,layout:a,width:(J.screen?.width||2)/2,height:(J.screen?.height||1.2)/2}),s=`quad`),n.updateRenderState({layers:[o,...n.renderState.layers||[]]}),J.meshes.forEach(e=>{e.visible=!1}),J.layers={...e,applied:!0,kind:s,layout:a}}catch(t){J.layers={...e,applied:!1,reason:`Layer creation failed: ${t?.message||t}`}}return J.layers}function Pu(e){if(!du.includes(e))throw Error(`Unknown projection ${e}`);return J.projection=e,J.projectionAuto=!1,J.element&&Au(),k(`media-changed`,Y()),Y()}function Fu(e){if(!fu.includes(e))throw Error(`Unknown packing ${e}`);return J.packing=e,J.packingAuto=!1,J.element&&Au(),k(`media-changed`,Y()),Y()}function Iu(e){if(!pu[e])throw Error(`Unknown environment ${e}`);let t=J.texture,n=t?.userData?.mediaTextureId||null;J.environment=e,J.screenOverride=null,J.element&&Au();let r=J.texture;return k(`media-changed`,Y()),{...Y(),textureRebuilt:t!==r,textureIdBefore:n,textureIdAfter:r?.userData?.mediaTextureId||null}}function Lu(e={}){if(J.screenOverride={...J.screenOverride||{},...e},!J.element)return Y();let t=xu(J.sourceWidth,J.sourceHeight,J.packing),n=t.displayAspect||t.width/t.height,r=Eu(J.environment,n,J.screenOverride);return J.screen=r,J.projection===`flat`&&(J.meshes.forEach(e=>{e.geometry.dispose(),e.geometry=Su(r),e.position.set(0,r.elevation,-r.distance)}),J.room&&pu[J.environment].room===`frame`&&(J.room.position.set(0,r.elevation,-r.distance-.02),J.room.scale.set(r.width/1.4,r.height/1.4,1))),k(`media-changed`,Y()),Y()}function Ru(){let e=J.element;J.quality={startedAt:performance.now(),framesDelivered:0,firstMediaTime:null,lastMediaTime:null,mediaSecondsSeen:0,frameIntervals:[],elementDrops:0,elementTotal:0,rendererFrames:0,samples:0};let t=J.quality,n=()=>{if(!J.element){J.loop=0;return}if(typeof e.getVideoPlaybackQuality==`function`){let n=e.getVideoPlaybackQuality();t.elementDrops=n.droppedVideoFrames||0,t.elementTotal=n.totalVideoFrames||0}t.rendererFrames+=1,t.samples+=1,t.elapsedMs=performance.now()-t.startedAt,J.loop=P(n)};if(J.loop=P(n),typeof e.requestVideoFrameCallback==`function`){let n=null,r=(i,a)=>{if(!J.element)return;t.framesDelivered+=1;let o=a.mediaTime;if(t.firstMediaTime??(t.firstMediaTime=o),n!=null){let e=o-n;e>0&&e<1?(t.mediaSecondsSeen+=e,t.frameIntervals.length<400&&t.frameIntervals.push(e)):e<0&&(t.mediaSecondsSeen+=0)}n=o,t.lastMediaTime=o,e.requestVideoFrameCallback(r)};e.requestVideoFrameCallback(r)}}function zu(){if(!J.quality)return null;let e=J.quality,t=(e.elapsedMs||0)/1e3,n=e.frameIntervals.slice().sort((e,t)=>e-t),r=n.length?n[Math.floor(n.length/2)]:0,i=r>0?1/r:0;return i>0&&e.mediaSecondsSeen*i,{elapsedSeconds:+t.toFixed(2),framesDelivered:e.framesDelivered,mediaSecondsPlayed:+e.mediaSecondsSeen.toFixed(2),deliveredFps:+i.toFixed(2),rendererFps:t>0?+(e.rendererFrames/t).toFixed(2):null,realtimeRatio:t>0?+(e.mediaSecondsSeen/t).toFixed(4):null,stallSeconds:t>0?+Math.max(0,t-e.mediaSecondsSeen).toFixed(2):0,elementCompositorDrops:e.elementDrops,elementCompositorTotal:e.elementTotal,elementCompositorNote:`Counts frames the offscreen <video> element itself never painted. That element is a decode source, not a displayed video, so this number is expected to be high and is not a measure of what reached the screen.`,sourceWidth:J.sourceWidth,sourceHeight:J.sourceHeight,textureWidth:J.texture?.image?.videoWidth||J.texture?.image?.naturalWidth||0,textureHeight:J.texture?.image?.videoHeight||J.texture?.image?.naturalHeight||0,mipmapsEnabled:J.texture?J.texture.generateMipmaps:null,textureId:J.texture?.userData?.mediaTextureId||null,adaptiveQualityApplied:!1}}function Bu(e){if(!e)return J.ambient?.timer&&clearInterval(J.ambient.timer),J.ambient=null,!1;if(!J.isVideo||!J.group)return!1;let t=document.createElement(`canvas`);t.width=8,t.height=8;let n=t.getContext(`2d`,{willReadFrequently:!0}),r=J.group.getObjectByName(`media-ambilight`);return J.ambient={canvas:t,ctx:n,timer:setInterval(()=>{if(!(!J.element||!r))try{n.drawImage(J.element,0,0,8,8);let e=n.getImageData(0,0,8,8).data,t=0,i=0,a=0;for(let n=0;n<e.length;n+=4)t+=e[n],i+=e[n+1],a+=e[n+2];let o=e.length/4;r.color.setRGB(t/o/255,i/o/255,a/o/255),r.intensity=.9}catch{}},250)},!0}function Vu(e,t,n){let r=e.sampleRate,i=Math.max(1,Math.floor(r*t)),a=e.createBuffer(2,i,r);for(let e=0;e<2;e+=1){let t=a.getChannelData(e);for(let e=0;e<i;e+=1)t[e]=(Math.random()*2-1)*(1-e/i)**n}return a}async function Hu(){try{if(!navigator.mediaDevices?.enumerateDevices)return{detected:!1,reason:`This browser exposes no device enumeration API.`};let e=(await navigator.mediaDevices.enumerateDevices()).filter(e=>e.kind===`audiooutput`),t=e.filter(e=>e.label);if(!t.length)return{detected:!1,reason:`Output device labels are withheld until microphone permission is granted, so headphone presence cannot be determined on this platform.`,outputs:e.length};let n=t.find(e=>/headphone|headset|earphone|airpod|buds|bluetooth/i.test(e.label));return{detected:!!n,label:n?.label||null,outputs:t.length}}catch(e){return{detected:!1,reason:e?.message||String(e)}}}async function Uu(e,t){try{let n=e.createChannelSplitter(8);t.channelCountMode=`max`,t.channelInterpretation=`discrete`,t.connect(n);let r=[];for(let t=0;t<8;t+=1){let i=e.createAnalyser();i.fftSize=2048;try{n.connect(i,t)}catch{break}r.push(i)}let i=new Float32Array(2048),a=Array(r.length).fill(0),o=performance.now()+400;for(;performance.now()<o;){for(let e=0;e<r.length;e+=1){r[e].getFloatTimeDomainData(i);for(let t=0;t<i.length;t+=16){let n=Math.abs(i[t]);n>a[e]&&(a[e]=n)}}await new Promise(e=>setTimeout(e,40))}try{t.disconnect(n)}catch{}let s=0;return a.forEach((e,t)=>{e>1e-4&&(s=t+1)}),{channels:Math.max(s,1),peaks:a.map(e=>+e.toFixed(5)),method:`signal-probe`}}catch(e){return{channels:2,method:`fallback`,reason:e?.message||String(e)}}}async function Wu(e=!1){if(!J.isVideo||!J.element)return null;let n=globalThis.AudioContext||globalThis.webkitAudioContext;if(!n)return{enabled:!1,reason:`No Web Audio API on this platform.`};let r=await Hu();if(!(e||r.detected))return J.audio={enabled:!1,headphones:r,reason:`Defaulting to normal stereo output.`},J.audio;let i=J.audio?.ctx||new n;if(i.state===`suspended`)try{await i.resume()}catch{}let a=pu[J.environment],o=J.audio?.source||i.createMediaElementSource(J.element),s=J.audio?.channelProbe?.file===J.file?J.audio.channelProbe:{...await Uu(i,o),file:J.file},c=s.channels;try{o.disconnect()}catch{}if(J.audio?.foa?.output)try{J.audio.foa.output.disconnect()}catch{}let l=i.createConvolver();l.buffer=Vu(i,a.reverb.seconds,a.reverb.decay);let u=i.createGain();u.gain.value=a.reverb.wet;let d=i.createGain();d.gain.value=1-a.reverb.wet*.5,d.connect(i.destination),u.connect(i.destination);let f=null,p,m,h=!1;if(c>=4)f=(await t(async()=>{let{default:e}=await import(`./omnitone.esm-BSknr-cd.js`);return{default:e}},[],import.meta.url)).default.createFOARenderer(i,{channelMap:[0,1,2,3]}),await f.initialize(),o.connect(f.input),f.output.connect(d),f.output.connect(l),h=!0,p=`Ambisonic B-format decode + HRTF binaural rendering (Omnitone FOARenderer)`,m=`True spatial audio — the captured sound field decoded as recorded, nothing synthesised.`;else{let e=new PannerNode(i,{panningModel:`HRTF`,distanceModel:`inverse`,positionX:0,positionY:J.screen.elevation||0,positionZ:-(J.screen.distance||3)});o.connect(e),e.connect(d),e.connect(l),l.connect(u),J.audio={...J.audio||{},panner:e},p=`HRTF binaural rendering (Web Audio PannerNode + ConvolverNode)`,m=`Virtual/enhanced surround — reshapes existing channels, not true object-based 3D audio.`}return l.connect(u),J.audio={...J.audio||{},enabled:!0,mechanism:p,honestLabel:m,sourceIsAmbisonic:h,channels:c,isDolbyAtmos:!1,ctx:i,source:o,convolver:l,foa:f,channelProbe:s,headphones:r,room:a.label,engine:h?`omnitone`:`web-audio-panner`},J.audio}function Gu(e){let t=J.audio;if(!t?.enabled||!t.ctx||!e)return!1;if(t.foa)return e.updateMatrixWorld?.(),t.foa.setRotationMatrix4(e.matrixWorld.elements),!0;let n=t.ctx.listener,r=new S(0,0,-1).applyQuaternion(e.quaternion),i=new S(0,1,0).applyQuaternion(e.quaternion);return n.forwardX?(n.forwardX.value=r.x,n.forwardY.value=r.y,n.forwardZ.value=r.z,n.upX.value=i.x,n.upY.value=i.y,n.upZ.value=i.z):n.setOrientation&&n.setOrientation(r.x,r.y,r.z,i.x,i.y,i.z),!0}function Y(){let e=xu(J.sourceWidth,J.sourceHeight,J.packing);return{active:J.active,fileName:J.file?.name||null,fileSize:J.file?.size||0,isVideo:J.isVideo,sourceWidth:J.sourceWidth,sourceHeight:J.sourceHeight,projection:J.projection,projectionAuto:J.projectionAuto,projectionWhy:J.projectionWhy,packing:J.packing,packingAuto:J.packingAuto,packingWhy:J.packingWhy,eyeWidth:e.width,eyeHeight:e.height,eyeSqueezed:!!e.squeezed,eyeDisplayAspect:e.displayAspect||e.width/e.height,environment:J.environment,environmentLabel:pu[J.environment]?.label,roomSuppressed:!!J.roomSuppressed,roomApplies:J.projection===`flat`,screen:J.screen,meshCount:J.meshes.length,meshNames:J.meshes.map(e=>e.name),stereoSource:J.packing!==`mono`,stereoRendered:!!J.stereoRendered,stereoPresenting:ku(),stereo:J.packing!==`mono`,ambientResponse:!!J.ambient,audio:J.audio?{enabled:J.audio.enabled,engine:J.audio.engine||null,mechanism:J.audio.mechanism||null,honestLabel:J.audio.honestLabel||null,sourceIsAmbisonic:!!J.audio.sourceIsAmbisonic,channels:J.audio.channels||null,channelPeaks:J.audio.channelProbe?.peaks||null,channelMethod:J.audio.channelProbe?.method||null,isDolbyAtmos:!1,headphones:J.audio.headphones,room:J.audio.room||null}:null,deviceLimits:J.deviceLimits,layers:J.layers||null,findings:J.findings.slice(),quality:zu()}}function Ku({keepScene:e=!1}={}){if(J.loop&&(yt(J.loop),J.loop=0),J.ambient?.timer&&clearInterval(J.ambient.timer),J.ambient=null,J.audio?.ctx&&J.audio.ctx.state!==`closed`)try{J.audio.ctx.close()}catch{}if(J.audio=null,ju({keepTexture:!1}),J.element&&J.isVideo){try{J.element.pause()}catch{}J.element.removeAttribute(`src`),J.element.load?.(),J.element.remove?.()}return J.objectUrl&&URL.revokeObjectURL(J.objectUrl),J.objectUrl=null,J.element=null,J.file=null,J.active=!1,J.quality=null,F(`mediaViewerActive`,!1),!0}function qu(){let e=ku(),t=()=>{let n=ku();if(n!==e&&(e=n,J.active&&J.packing!==`mono`&&J.element&&Au()),J.audio?.enabled){let e=I()?.camera;e&&Gu(e)}uu=P(t)};uu=P(t)}async function Ju(e){if(!e){J.aiDepth.timer&&clearInterval(J.aiDepth.timer),J.aiDepth.timer=0,J.aiDepth.enabled=!1;for(let e of J.meshes)e.material?.uniforms?.uDepthStrength&&(e.material.uniforms.uDepthStrength.value=0);return await cu(),{enabled:!1,provider:null,reason:`AI depth off. Showing the source exactly as decoded.`}}if(!J.active||!J.element)return{enabled:!1,provider:null,reason:`Open a photo or video first.`};try{await au()}catch(e){return J.aiDepth.error=e?.message||String(e),{enabled:!1,provider:null,reason:`The depth engine did not load: ${J.aiDepth.error}`}}let t=await ou(J.element);if(!t)return{enabled:!1,provider:null,reason:`The depth engine produced no output.`};let n=su(t),r=new ee(n.bytes,n.width,n.height,Re);return r.minFilter=f,r.magFilter=f,r.needsUpdate=!0,J.aiDepth.texture=r,J.aiDepth.enabled=!0,J.aiDepth.provider=iu().provider,J.aiDepth.lastMs=t.ms,Au(),J.isVideo&&(J.aiDepth.timer=setInterval(async()=>{if(!J.aiDepth.enabled||!J.element)return;let e=await ou(J.element).catch(()=>null);if(!e)return;let t=su(e);J.aiDepth.texture.image.data.set(t.bytes),J.aiDepth.texture.needsUpdate=!0,J.aiDepth.lastMs=e.ms},200),bt(()=>{J.aiDepth.timer&&clearInterval(J.aiDepth.timer)})),{enabled:!0,provider:J.aiDepth.provider,reason:`AI depth on — a synthesised second eye from an on-device depth estimate. This is a depth effect, not real stereo capture: pixels behind foreground objects were never filmed and are filled from their neighbours.`}}async function Yu(e,t={}){switch(e){case`open`:return k(`media-assistant-open`,t),{action:e,accepted:!0,needsPicker:!0,requested:t};case`projection`:return{action:e,state:Pu(t.projection)};case`packing`:return{action:e,state:Fu(t.packing)};case`environment`:return{action:e,state:Iu(t.environment)};case`adjust_screen`:return{action:e,state:Lu(t)};case`spatial_audio`:{let n=await Wu(!!t.enabled);return{action:e,enabled:!!n?.enabled,engine:n?.engine||null,reason:n?.reason}}case`ambient`:return{action:e,applied:Bu(!!t.enabled)};case`ai_depth`:{let n=await Ju(!!t.enabled);return{action:e,applied:n.enabled,engine:n.provider,reason:n.reason}}case`experimental_surround`:return{action:e,applied:!1,reason:`The generative surround model is not installed yet. It is a paid-tier feature that runs on pay-per-use GPU inference, which is not wired up.`};default:return{action:e,accepted:!1,reason:`Unknown media control '${e}'.`}}}function Xu(){return gu(),qu(),O(`media:control`,e=>{let{action:t,data:n}=e?.payload||e||{};t&&Yu(t,n||{})}),O(`media-open-request`,e=>{e?.file&&Du(e.file,e.options||{}).catch(e=>{C(e?.message||String(e),`Media`)})}),bt(()=>{uu&&yt(uu),uu=0,Ku()}),globalThis.JarvisMedia={open:Du,setProjection:Pu,setPacking:Fu,setEnvironment:Iu,adjustScreen:Lu,setAmbientResponse:Bu,setupSpatialAudio:Wu,updateAudioOrientation:Gu,detectHeadphones:Hu,getState:Y,getQualityReport:zu,probeDecodeCapability:gu,probeLayersSupport:Mu,tryMediaLayer:Nu,applyAssistantControl:Yu,close:Ku,PROJECTIONS:du,PACKINGS:fu,ENVIRONMENTS:pu,_math:{detectProjection:_u,detectPacking:yu,eyeUvRect:bu,unpackedEyeSize:xu,computeScreenDimensions:Eu,buildScreenGeometry:Su}},!0}var Zu={flat:`Flat`,180:`180`,360:`360`,fisheye:`Fisheye`},Qu={mono:`Mono`,"sbs-full":`SBS full`,"sbs-half":`SBS half`,"tb-full":`Top-bottom`,"tb-half":`TB half`},$u={passthrough:`<path d="M3 7h18v11H3z"/><path d="M3 12h18"/>`,mixed:`<path d="M4 6h9v9H4z"/><path d="M11 11h9v7h-9z"/>`,theater:`<path d="M3 5h18v10H3z"/><path d="M6 19h12M8 15v4M16 15v4"/>`,imax:`<path d="M2 6c5-2.5 15-2.5 20 0v9c-5 2.5-15 2.5-20 0z"/>`,pvr:`<path d="M3 6h18v9H3z"/><path d="M7 19h10"/>`,inox:`<path d="M2.5 6h19v10h-19z"/><path d="M6 20h12"/>`},X=null,ed=null,td=0,nd=!1,rd=!1;function id(e,t=``){return`<svg class="${t}" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round">${e}</svg>`}function ad(e,t,n,r,i){return t.map(t=>{let a=t===r,o=a&&i?`<span class="mv-auto">AUTO</span>`:``;return`<button type="button" class="mv-chip" data-${e}="${t}" aria-pressed="${a}">${n[t]}${o}</button>`}).join(``)}function od(){if(X)return X.classList.add(`mv-open`),X;let e=gu();return X=document.createElement(`section`),X.id=`media-viewer-panel`,X.className=`mv-panel glass-panel mv-open`,X.setAttribute(`role`,`dialog`),X.setAttribute(`aria-label`,`Local media viewer`),X.innerHTML=`
<header class="mv-head">
<div>
<p class="mv-eyebrow">WebAR · immersive media</p>
<h2 class="mv-title">Local media viewer</h2>
</div>
<button type="button" class="mv-close" data-mv="close" aria-label="Close media viewer">
${id(`<path d="M5 5l14 14M19 5L5 19"/>`)}
</button>
</header>
<div class="mv-body">
<p class="mv-cap">1 · pick a file</p>
<div class="mv-card">
<span class="mv-brk tr"></span><span class="mv-brk bl"></span>
<div class="mv-drop" data-mv="drop">
${id(`<path d="M12 16V4M12 4 7.5 8.5M12 4l4.5 4.5"/><path d="M3.5 15v3.2A1.8 1.8 0 0 0 5.3 20h13.4a1.8 1.8 0 0 0 1.8-1.8V15"/>`,`mv-drop-icon`)}
<div class="mv-drop-big">Choose a photo or video</div>
<div class="mv-drop-small">From this device. Nothing is uploaded — the file never leaves your phone.</div>
<button type="button" class="mv-btn" data-mv="browse">Browse files</button>
</div>
<div class="mv-detected" data-mv="detected" hidden></div>
</div>
<p class="mv-cap">2 · projection format</p>
<div class="mv-card">
<span class="mv-brk tr"></span><span class="mv-brk bl"></span>
<p class="mv-h">Format</p>
<p class="mv-sub">What shape the source actually is. Auto-detected from the frame's dimensions
and the filename — override it if the guess is wrong.</p>
<div class="mv-row" data-mv="formats"></div>
<p class="mv-h mv-h-gap">Stereo packing</p>
<p class="mv-sub">How two eyes are stored in one frame. Half-packed sources are un-squeezed by
the projection geometry, never by resizing the picture.</p>
<div class="mv-row" data-mv="packings"></div>
</div>
<p class="mv-cap">3 · where you watch it</p>
<div class="mv-card">
<span class="mv-brk tr"></span><span class="mv-brk bl"></span>
<p class="mv-h">Viewing mode</p>
<p class="mv-sub">These change the room and the screen around the picture. They never change
decode quality, resolution, or bitrate.</p>
<div class="mv-modes" data-mv="modes"></div>
<p class="mv-note" data-mv="mode-note"></p>
</div>
<p class="mv-cap">4 · the screen itself</p>
<div class="mv-card">
<span class="mv-brk tr"></span><span class="mv-brk bl"></span>
<p class="mv-h">Screen placement</p>
<p class="mv-sub">A plan view of the room. Drag the screen's edges to resize it, drag it up or
down to move it nearer or further. It moves live.</p>
<div class="mv-gizmo" data-mv="gizmo">
<div class="mv-grid"></div>
<div class="mv-wedge" data-mv="wedge"></div>
<svg class="mv-screen" data-mv="screen-svg" viewBox="0 0 200 34" preserveAspectRatio="none">
<path d="M4 30 Q100 6 196 30"/>
</svg>
<span class="mv-handle l" data-mv="h-left" role="slider" tabindex="0" aria-label="Screen width"></span>
<span class="mv-handle r" data-mv="h-right" role="slider" tabindex="0" aria-label="Screen width"></span>
<span class="mv-handle d" data-mv="h-dist" role="slider" tabindex="0" aria-label="Screen distance"></span>
<span class="mv-viewer"></span>
<span class="mv-viewer-lbl">YOU</span>
</div>
<div class="mv-readouts" data-mv="readouts"></div>
</div>
<p class="mv-cap">5 · audio and enhancements</p>
<div class="mv-card">
<span class="mv-brk tr"></span><span class="mv-brk bl"></span>
<div class="mv-tog">
<div>
<div class="mv-lab">Spatial audio</div>
<div class="mv-hint">HRTF binaural rendering, matched to the room you're in. For headphones —
off automatically on speakers. This is not Dolby Atmos.</div>
</div>
<button type="button" class="mv-sw" data-mv="sw-audio" role="switch" aria-checked="false"><i></i></button>
</div>
<div class="mv-tog">
<div>
<div class="mv-lab">Ambient light response</div>
<div class="mv-hint">The room picks up the colour of what's on screen.</div>
</div>
<button type="button" class="mv-sw" data-mv="sw-ambient" role="switch" aria-checked="false"><i></i></button>
</div>
<div class="mv-tog">
<div>
<div class="mv-lab">AI 3D depth</div>
<div class="mv-hint">Synthesises a second eye from a flat video. Real depth estimation —
small areas behind foreground objects are filled in, not captured.</div>
</div>
<button type="button" class="mv-sw" data-mv="sw-depth" role="switch" aria-checked="false"><i></i></button>
</div>
<div class="mv-tog">
<div>
<div class="mv-lab">Experimental AI surround</div>
<div class="mv-hint">Invents the parts of the scene the camera never saw, to fill a full
sphere. Most of what you'd see is generated, not filmed.</div>
</div>
<button type="button" class="mv-sw warn" data-mv="sw-surround" role="switch" aria-checked="false"><i></i></button>
</div>
</div>
<p class="mv-cap">6 · what you're actually getting</p>
<div class="mv-card">
<span class="mv-brk tr"></span><span class="mv-brk bl"></span>
<p class="mv-h">Playback quality</p>
<p class="mv-sub">Measured, not asserted. If this device can't carry the source, it says so here
rather than quietly lowering the quality.</p>
<dl class="mv-q" data-mv="quality">
<dt>Max texture</dt><dd>${e.maxTextureSize||`unknown`} px</dd>
<dt>WebCodecs</dt><dd>${e.webCodecs?`available`:`absent`}</dd>
<dt>WebXR media layers</dt><dd>${e.webxrMediaLayers?`available`:`absent`}</dd>
</dl>
</div>
</div>
`,ed=document.createElement(`input`),ed.type=`file`,ed.accept=`video/*,image/*`,ed.style.cssText=`position:absolute;width:1px;height:1px;opacity:0;pointer-events:none`,X.appendChild(ed),(document.getElementById(`ui-layer`)||document.body).appendChild(X),cd(),vd(),X}function sd(e){let t=document.getElementById(`mv-experimental-label`);if(!e){t?.remove();return}t||(t=document.createElement(`div`),t.id=`mv-experimental-label`,t.setAttribute(`role`,`status`),t.innerHTML=`${id(`<path d="M12 3 22 20H2z"/><path d="M12 10v4M12 17h.01"/>`)}<p>Experimental — AI-generated surround, not real footage</p>`,(document.getElementById(`ui-layer`)||document.body).appendChild(t))}function cd(){N(X,`click`,e=>{let t=e.target.closest(`[data-mv],[data-format],[data-packing],[data-mode]`);if(t){if(t.dataset.format)return void ud(t.dataset.format);if(t.dataset.packing)return void dd(t.dataset.packing);if(t.dataset.mode)return void fd(t.dataset.mode);switch(t.dataset.mv){case`close`:return xd();case`browse`:case`drop`:return ed.click();case`sw-audio`:pd(t);return;case`sw-ambient`:md(t);return;case`sw-depth`:hd(t);return;case`sw-surround`:gd(t);return;default:return}}}),N(ed,`change`,()=>{let e=ed.files?.[0];e&&ld(e)}),N(X,`dragover`,e=>{e.preventDefault()}),N(X,`drop`,e=>{e.preventDefault();let t=e.dataTransfer?.files?.[0];t&&ld(t)}),_d(),bt(()=>xd())}async function ld(e){try{await Du(e,{environment:Y().environment||`theater`}),vd(),bd(),w(`${e.name} is open.`,`Media`)}catch(e){C(e?.message||String(e),`Media`)}}function ud(e){if(du.includes(e)){try{Pu(e)}catch(e){C(e.message,`Media`)}vd()}}function dd(e){if(fu.includes(e)){try{Fu(e)}catch(e){C(e.message,`Media`)}vd()}}function fd(e){if(pu[e]){try{Iu(e)}catch(e){C(e.message,`Media`)}vd()}}async function pd(e){let t=e.getAttribute(`aria-checked`)!==`true`,n=await Wu(t),r=!!n?.enabled;e.setAttribute(`aria-checked`,String(r)),t&&!r&&w(n?.headphones?.reason||`Spatial audio stays off until headphones are detected — it is built for headphone listening.`,`Spatial audio`)}function md(e){let t=e.getAttribute(`aria-checked`)!==`true`,n=Bu(t);e.setAttribute(`aria-checked`,String(!!n)),t&&!n&&w(`Open a video first — ambient response reads the playing frame.`,`Media`)}function hd(e){rd=e.getAttribute(`aria-checked`)!==`true`,e.setAttribute(`aria-checked`,`false`),rd&&(w(`AI 3D depth needs the depth model installed on the Space. The control is here; the engine is not ready yet.`,`Not available`),rd=!1)}function gd(e){nd=e.getAttribute(`aria-checked`)!==`true`,e.setAttribute(`aria-checked`,`false`),sd(!1),nd&&(w(`Experimental AI surround needs the generative model installed on the Space. The opt-in is here; the engine is not ready yet.`,`Not available`),nd=!1)}function _d(){let e=X.querySelector(`[data-mv="gizmo"]`);if(!e)return;let t=null,n=null,r=(e,r)=>{t=e;let i=Y().screen||{};n={x:r.clientX,y:r.clientY,width:i.width,distance:i.distance},r.preventDefault()};[`h-left`,`h-right`,`h-dist`].forEach(e=>{let t=X.querySelector(`[data-mv="${e}"]`);t&&(N(t,`pointerdown`,n=>{t.setPointerCapture?.(n.pointerId),r(e,n)}),N(t,`keydown`,t=>{let n=t.shiftKey?1:.25,r=Y().screen||{};if(t.key===`ArrowLeft`||t.key===`ArrowDown`)Lu(e===`h-dist`?{distance:Math.max(1,r.distance-n)}:{width:Math.max(.5,r.width-n)});else if(t.key===`ArrowRight`||t.key===`ArrowUp`)Lu(e===`h-dist`?{distance:r.distance+n}:{width:r.width+n});else return;t.preventDefault(),yd()}))}),N(e,`pointermove`,e=>{if(!(!t||!n)){if(t===`h-dist`){let t=(e.clientY-n.y)/26;Lu({distance:Math.max(1,n.distance+t)})}else{let r=(t===`h-right`?1:-1)*(e.clientX-n.x)/26;Lu({width:Math.max(.5,n.width+r*2)})}yd()}});let i=()=>{t=null,n=null};N(e,`pointerup`,i),N(e,`pointercancel`,i),N(window,`pointerup`,i)}function vd(){if(!X)return;let e=Y();X.querySelector(`[data-mv="formats"]`).innerHTML=ad(`format`,du,Zu,e.projection,e.projectionAuto),X.querySelector(`[data-mv="packings"]`).innerHTML=ad(`packing`,fu,Qu,e.packing,e.packingAuto),X.querySelector(`[data-mv="modes"]`).innerHTML=Object.keys(pu).map(t=>`<button type="button" class="mv-chip mv-mode" data-mode="${t}" aria-pressed="${t===e.environment}">${id($u[t])}${pu[t].label}</button>`).join(``);let t=X.querySelector(`[data-mv="mode-note"]`);t.textContent=e.roomSuppressed?`${Zu[e.projection]} content surrounds you, so there is no room to put it in — the ${pu[e.environment]?.label} preset applies to flat content only.`:`${pu[e.environment]?.note||``} Theater, PVR, INOX and IMAX are named room and screen presets — not licensed cinema formats.`,t.classList.toggle(`mv-note-warn`,!!e.roomSuppressed);let n=X.querySelector(`[data-mv="detected"]`);e.fileName?(n.hidden=!1,n.innerHTML=`${id(`<path d="M20 6 9 17l-5-5"/>`,`mv-ok-icon`)}
<p><b>${e.fileName}</b> — ${e.sourceWidth}×${e.sourceHeight}.
Detected as <b>${Zu[e.projection]}</b> (${e.projectionWhy}) packed
<b>${Qu[e.packing]}</b> (${e.packingWhy}).
Each eye is ${Math.round(e.eyeWidth)}×${Math.round(e.eyeHeight)}${e.eyeSqueezed?`, un-squeezed on playback`:``}.</p>`):n.hidden=!0,yd()}function yd(){if(!X)return;let e=Y().screen||{},t=X.querySelector(`[data-mv="readouts"]`);if(!t)return;t.innerHTML=[[`Width`,e.width?`${e.width.toFixed(2)} m`:`—`],[`Distance`,e.distance?`${e.distance.toFixed(1)} m`:`—`],[`Subtends`,e.width&&e.distance?`${(2*Math.atan(e.width/2/e.distance)*180/Math.PI).toFixed(0)}°`:`—`],[`Curve`,e.curvatureRadius?`${e.curvatureRadius.toFixed(1)} m`:`flat`]].map(([e,t])=>`<div class="mv-ro"><div class="mv-k">${e}</div><div class="mv-v">${t}</div></div>`).join(``);let n=X.querySelector(`[data-mv="screen-svg"]`);if(n&&e.width){let t=Math.max(40,Math.min(210,e.width*26));n.style.width=`${t}px`,n.style.top=`${Math.max(6,150-e.distance*13)}px`;let r=e.curvatureRadius>0?Math.min(24,900/e.curvatureRadius):0;n.querySelector(`path`).setAttribute(`d`,`M4 30 Q100 ${30-r} 196 30`);let i=X.querySelector(`[data-mv="h-left"]`),a=X.querySelector(`[data-mv="h-right"]`),o=X.querySelector(`[data-mv="h-dist"]`),s=parseFloat(n.style.top);i&&(i.style.left=`calc(50% - ${t/2}px - 7px)`,i.style.top=`${s+18}px`),a&&(a.style.left=`calc(50% + ${t/2}px - 7px)`,a.style.top=`${s+18}px`),o&&(o.style.top=`${s-4}px`)}}function bd(){td&&clearInterval(td),td=setInterval(()=>{let e=X?.querySelector(`[data-mv="quality"]`);if(!e)return;let t=Y(),n=zu();e.innerHTML=[[`Source`,`${t.sourceWidth} × ${t.sourceHeight}`,`plain`],[`Per eye`,`${Math.round(t.eyeWidth)} × ${Math.round(t.eyeHeight)}`,`plain`],[`Texture upload`,n&&n.textureWidth===t.sourceWidth?`Native, no downscale`:`pending`,n&&n.textureWidth===t.sourceWidth?`ok`:`plain`],[`Playback speed`,n?.realtimeRatio==null?`—`:`${(n.realtimeRatio*100).toFixed(0)}% of real time`,n&&n.realtimeRatio>=.97?`ok`:n?`warn`:`plain`],[`Stalled`,n?`${n.stallSeconds}s of ${n.elapsedSeconds}s`:`—`,n&&n.stallSeconds<1?`ok`:n?`warn`:`plain`],[`Render rate`,n?.rendererFps==null?`—`:`${n.rendererFps} fps`,n&&n.rendererFps>=55?`ok`:n?`warn`:`plain`],[`Mipmaps`,`Off — centre stays sharp`,`plain`],[`Adaptive reduction`,`Never applied`,`ok`]].map(([e,t,n])=>`<dt>${e}</dt><dd class="${n===`plain`?``:n}">${t}</dd>`).join(``)},500)}function xd(){return td&&(clearInterval(td),td=0),sd(!1),Ku(),X?.remove(),X=null,ed=null,!0}function Sd(){return O(`open-media`,()=>od()),globalThis.JarvisMediaUI={open:od,close:xd,isOpen:()=>!!X,click:e=>{let t=X?.querySelector(e);return t?(t.click(),!0):!1}},!0}var Cd=null,wd=null,Td=null,Ed=null,Dd=new Float32Array(1e3*3),Od=new Je;Od.setAttribute(`position`,new We(Dd,3)),Od.setDrawRange(0,0);var kd=1e3;function Ad(){return{name:`world-points-collector`,onUpdate:({processCpuResult:e})=>{let t=e?.worldPoints||e?.reality?.worldPoints||e?.reality?.points||e?.slam?.worldPoints;t&&t.length>0&&(D.worldPoints=t,jd(t))}}}function jd(e){if(!(!e||e.length<10)){for(let t of e){let e=t.position||t;!Number.isFinite(e.x)||!Number.isFinite(e.y)||!Number.isFinite(e.z)||D.worldPointBuffer.push(new S(e.x,e.y,e.z))}D.worldPointBuffer.length>1e3&&D.worldPointBuffer.splice(0,D.worldPointBuffer.length-1e3),D.frameCount+=1,D.frameCount%20==0&&(Md(D.worldPointBuffer),Nd(D.worldPointBuffer))}}function Md(e){if(!e.length)return;let{scene:t}=I(),n=Math.min(e.length,kd);for(let t=0;t<n;t+=1){let r=e[e.length-n+t];Dd[t*3]=r.x,Dd[t*3+1]=r.y,Dd[t*3+2]=r.z}Od.attributes.position.needsUpdate=!0,Od.setDrawRange(0,n),Cd||(Ed=new r({color:51455,size:.018,transparent:!0,opacity:.55,depthWrite:!1}),Cd=new te(Od,Ed),Cd.name=`jarvis-room-point-cloud`,Cd.scale.setScalar(1),t.add(Cd))}function Nd(e){if(!e.length)return;let t=[...e].sort((e,t)=>e.y-t.y),n=[],r=[];for(let e=0;e<t.length;e++){let i=t[e];if(r.length===0)r.push(i);else{let e=r[r.length-1];i.y-e.y<=.04?r.push(i):(n.push(r),r=[i])}}r.length>0&&n.push(r);let i=Math.max(8,Math.floor(t.length*.08)),a=null;for(let e of n)if(e.length>=i){a=e;break}let o;if(a)o=a.reduce((e,t)=>e+t.y,0)/a.length;else{let e=Math.max(4,Math.floor(t.length*.15)),n=t.slice(0,e);o=n.reduce((e,t)=>e+t.y,0)/n.length}if(!Number.isFinite(o))return;D.floorY!==void 0&&Number.isFinite(D.floorY)?D.floorY=D.floorY*.88+o*.12:D.floorY=o;let s=D.floorY,{scene:c}=I();if(!wd){let e=new x(10,10,20,20);wd=new b(e,new d({color:51455,transparent:!0,opacity:.06,side:2,depthWrite:!1})),Td=new b(e,new d({color:51455,transparent:!0,opacity:.2,wireframe:!0,depthWrite:!1})),wd.name=`jarvis-detected-floor`,Td.name=`jarvis-detected-floor-wire`,wd.rotation.x=-Math.PI/2,Td.rotation.x=-Math.PI/2,c.add(wd,Td)}wd.position.y=s,Td.position.y=s,D.shadowReceiver&&(D.shadowReceiver.position.y=s+.002),T(`status-tracking`,D.trackingMode===`8thwall-slam`?`slam+floor`:`basic floor`),k(`world-anchor-sample`,{floorY:s,pointCount:e.length})}function Pd(){D.worldPointBuffer.length<10&&Fd(),Md(D.worldPointBuffer),Nd(D.worldPointBuffer)}function Fd(){let e=[],{camera:t}=I(),n=new Me,r=Number.isFinite(D.floorY)?D.floorY:t&&t.position&&Number.isFinite(t.position.y)?t.position.y-1.45:-1.2;for(let i=0;i<9;i+=1)for(let a=0;a<20;a+=1){let o=.08+.84/19*a,s=.38+.46/8*i;n.setFromCamera(new Ce(o*2-1,-(s*2-1)),t);let c=(r-n.ray.origin.y)/n.ray.direction.y;Number.isFinite(c)&&c>.2&&c<8&&e.push(n.ray.origin.clone().add(n.ray.direction.clone().multiplyScalar(c)))}D.worldPointBuffer.push(...e),D.worldPointBuffer.length>1e3&&D.worldPointBuffer.splice(0,D.worldPointBuffer.length-1e3)}var Id={forest:[`Fox`,`Lantern`,`BarramundiFish`],lab:[`DamagedHelmet`,`AntiqueCamera`,`ReciprocatingSaw`],room:[`GlamVelvetSofa`,`WaterBottle`,`IridescenceLamp`],street:[`CesiumMilkTruck`,`ToyCar`,`Lantern`],default:[`Duck`,`Avocado`,`WaterBottle`]};function Ld(){O(`scan-room`,()=>{Pd(),w(`Room mesh scan updated from 8th Wall world points or basic fallback points.`,`Room Scan`)}),Bd()}async function Rd(e=`room`){let t=String(e||`room`).toLowerCase(),n=Id[t]||Id.default;Pd();let r=Math.min(3,Math.max(1,n.length));w(`Reconstructing ${t} scene with ${r} parallel model loads.`,`Scene Reconstruction`);try{await zd(t)}catch(e){C(e.message,`HDR Environment Failed`)}let i=(await Vd(n.map((e,t)=>async()=>{let r=t/n.length*Math.PI*2;return Hd(Ho(e,new S(Math.sin(r)*.75,D.floorY+.04,-1.5-Math.cos(r)*.45),new Ve),12e3,`Timed out loading ${e}`)}),r)).filter(e=>e.status===`rejected`);i.length&&C(`${i.length} reconstruction model(s) fell back or failed.`,`Scene Reconstruction`),w(`Reconstructed ${t} scene with ${n.length} placed objects.`,`Scene Reconstruction`)}async function zd(e){let{scene:t,renderer:n}=I(),r=await qn(e);return new Promise((e,i)=>{new ue().load(r,r=>{let a=new Le(n),o=a.fromEquirectangular(r),s=t.userData.jarvisEnvironmentTarget,c=t.environment;if(!o?.texture){r.dispose(),a.dispose(),i(Error(`HDR environment generation failed.`));return}t.environment=o.texture,t.userData.jarvisEnvironmentTarget=o,t.userData.jarvisEnvironmentSource=`hdr`,c?.dispose?.(),s?.dispose?.(),r.dispose(),a.dispose(),e(t.environment)},void 0,i)})}function Bd(){let e=new WeakSet;new MutationObserver(()=>{document.querySelectorAll(`video`).forEach(t=>{e.has(t)||(e.add(t),t.addEventListener(`play`,()=>{w(`A playing video was detected. Say "JARVIS reconstruct this scene" to build an AR scene.`,`Scene Detection`)},{once:!0}))})}).observe(document.documentElement,{childList:!0,subtree:!0})}async function Vd(e,t){let n=[],r=new Set;for(let i of e){let e=i().then(e=>({status:`fulfilled`,value:e})).catch(e=>({status:`rejected`,reason:e}));n.push(e),r.add(e),e.finally(()=>r.delete(e)),r.size>=t&&await Promise.race(r)}return Promise.all(n)}function Hd(e,t,n){let r=0,i=new Promise((e,i)=>{r=window.setTimeout(()=>i(Error(n)),t)});return Promise.race([e,i]).finally(()=>window.clearTimeout(r))}var Ud=.35,Wd=.65,Gd=.18,Kd=8,qd=4,Jd=12,Yd=60,Z={confidence:0,qualityTier:`initializing`,lostFrames:0,goodFrames:0,isLost:!1,worldOriginLocked:!1,worldOriginSamples:0,worldOriginPosition:new S,worldOriginQuaternion:new Ve,lastGoodPose:{position:new S,quaternion:new Ve,timestamp:0},smoothedPosition:new S,smoothedQuaternion:new Ve,anchorRegistry:new Map,planeRegistry:new Map,relocalizationAttempts:0,totalFrames:0};D.tracking=Z;function Xd(){return{name:`jarvis-tracking-quality`,onUpdate:({processCpuResult:e,processGpuResult:t})=>{Z.totalFrames++;let n=e?.reality||t?.reality||e||t,r=Zd(n),i=Qd(n);i&&(Z.confidence=Z.confidence*.85+r*.15,Z.qualityTier=$d(Z.confidence),D.trackingQuality=Z.qualityTier,document.body.dataset.jarvisTrackingQuality=Z.qualityTier,Z.confidence<Ud?(Z.lostFrames++,Z.goodFrames=0,!Z.isLost&&Z.lostFrames>=Kd&&of()):(Z.goodFrames++,Z.lostFrames=0,Z.isLost&&Z.goodFrames>=qd&&sf(i)),!Z.isLost&&(nf(i),Z.worldOriginLocked||af(Z.smoothedPosition,Z.smoothedQuaternion),uf(),Z.confidence>=Wd&&(Z.lastGoodPose.position.copy(Z.smoothedPosition),Z.lastGoodPose.quaternion.copy(Z.smoothedQuaternion),Z.lastGoodPose.timestamp=performance.now()),D.sessionAnchor.originPosition=Z.worldOriginPosition.toArray(),D.sessionAnchor.originQuaternion=Z.worldOriginQuaternion.toArray()))}}}function Zd(e){if(!e)return 0;let t=e.trackingStatus||e.slam?.trackingStatus;if(t){if(t===`NORMAL`)return .9;if(t===`LIMITED`)return .45;if(t===`INITIALIZING`)return .25}let n=e.confidence??e.slam?.confidence??e.poseConfidence;if(typeof n==`number`&&Number.isFinite(n))return Math.max(0,Math.min(1,n));let r=e.worldPoints||e.points;if(r&&Array.isArray(r)){let e=r.length;return e>80?.85:e>40?.65:e>15?.45:e>5?.25:.1}return .5}function Qd(e){if(!e)return null;let t=e.cameraPose||e.pose||e.slam?.cameraPose;if(!t)return null;let n=t.position||t,r=t.orientation||t.rotation;return Number.isFinite(n?.x)?{position:n,orientation:r}:null}function $d(e){return e>=.8?`excellent`:e>=.6?`good`:e>=.38?`fair`:e>=.15?`poor`:`initializing`}var ef=new S,tf=new Ve;function nf(e){let{position:t,orientation:n}=e;ef.set(Math.fround(t.x??0),Math.fround(t.y??0),Math.fround(t.z??0)),n&&tf.set(n.x??0,n.y??0,n.z??0,n.w??1);let r=Gd*(1+(1-Z.confidence)*1.5),i=Math.min(r,.45);Z.smoothedPosition.lerp(ef,i),Z.smoothedPosition.set(Math.fround(Z.smoothedPosition.x),Math.fround(Z.smoothedPosition.y),Math.fround(Z.smoothedPosition.z)),n&&(Z.smoothedQuaternion.slerp(tf,i),Z.smoothedQuaternion.normalize())}var rf=[];function af(e,t){if(Z.confidence<Wd){rf=[],Z.worldOriginSamples=0;return}rf.push({pos:e.clone(),quat:t.clone()}),rf.length>Jd&&rf.shift(),Z.worldOriginSamples=rf.length;let n=new S,r=new Ve;if(rf.forEach((e,t)=>{let i=1/(t+1);n.lerp(e.pos,i),r.slerp(e.quat,i)}),Z.worldOriginPosition.copy(n),Z.worldOriginQuaternion.copy(r),rf.length===Jd){let e=0;rf.forEach(t=>{e+=t.pos.distanceToSquared(n)}),e/Jd<.001&&(Z.worldOriginLocked=!0,D.sessionAnchor.restoredAt=Date.now(),k(`world-origin-locked`,{position:Z.worldOriginPosition.toArray(),quaternion:Z.worldOriginQuaternion.toArray()}),T(`status-tracking`,`${D.trackingMode} origin locked`))}}function of(){Z.isLost=!0,Z.worldOriginLocked=!1,Z.worldOriginSamples=0,rf=[],Z.relocalizationAttempts=0,document.body.dataset.jarvisTrackingState=`lost`,w(`Tracking lost — move camera slowly to reacquire environment.`,`Tracking`),T(`status-tracking`,`lost`),k(`tracking-lost`,{lastGoodPose:{position:Z.lastGoodPose.position.toArray(),age:performance.now()-Z.lastGoodPose.timestamp}}),Z.anchorRegistry.forEach(e=>{e.object&&(e.object.userData.trackingFrozen=!0)})}function sf(e){Z.isLost=!1,Z.lostFrames=0,Z.relocalizationAttempts++,document.body.dataset.jarvisTrackingState=`recovered`,T(`status-tracking`,D.trackingMode),k(`tracking-recovered`,{attempt:Z.relocalizationAttempts,confidence:Z.confidence}),Z.anchorRegistry.forEach(e=>{e.object&&(e.object.userData.trackingFrozen=!1)}),w(`Tracking recovered.`,`Tracking`)}function cf(e,t,n){let r={id:e,object:t,targetPosition:n.clone(),history:[],confidence:Z.confidence,createdAt:performance.now()};return Z.anchorRegistry.set(e,r),k(`anchor-registered`,{id:e,position:n.toArray()}),r}function lf(e){Z.anchorRegistry.delete(e),k(`anchor-removed`,{id:e})}function uf(){Z.anchorRegistry.forEach(e=>{if(!e.object||e.object.userData.trackingFrozen)return;let t=e.object,n=e.targetPosition,r=new S;t.getWorldPosition(r),r.set(Math.fround(r.x),Math.fround(r.y),Math.fround(r.z)),n.set(Math.fround(n.x),Math.fround(n.y),Math.fround(n.z));let i=r.distanceTo(n);if(e.history.push({drift:i,t:performance.now()}),e.history.length>Yd&&e.history.shift(),i>.001){let r=Math.max(.015,Math.min(.35,i*1.5));t.position.lerp(n,r),e.confidence=Z.confidence}})}function df(e){if(!e||e.length<20)return;let t=e.map(e=>{let t=e.position||e;return new S(t.x,t.y,t.z)}).filter(e=>Number.isFinite(e.x+e.y+e.z));if(t.length<20)return;let n=Math.min(...t.map(e=>e.y)),r=Math.max(...t.map(e=>e.y))-n;if(r<.1)return;let i=Array.from({length:10},()=>[]);t.forEach(e=>{i[Math.min(9,Math.floor((e.y-n)/r*10))].push(e)});let a=[];return i.forEach((e,t)=>{if(e.length<8)return;let i=n+t/10*r+r/10/2,o=e.reduce((e,t)=>e.add(t),new S).divideScalar(e.length),s=i<n+r*.25,c=i>n+r*.75,l=s?`floor`:c?`ceiling`:`surface`;a.push({yCenter:i,centroid:o,pointCount:e.length,type:l,confidence:Math.min(1,e.length/30)})}),a.forEach((e,t)=>{let n=`plane-${t}-${e.type}`;Z.planeRegistry.set(n,e)}),D.detectedPlanes=a,a.length>0&&k(`planes-updated`,{planes:a,count:a.length}),a}function ff(e,t){if(Z.confidence<Ud)return null;let{renderer:n}=I()||{};if(n?.xr?.enabled&&D.xrHitTestSource){let e=n.xr.getFrame();if(e){let t=n.xr.getReferenceSpace(),r=e.getHitTestResults(D.xrHitTestSource);if(r.length>0){let e=r[0].getPose(t);if(e){let t=new a().fromArray(e.transform.matrix);return{point:new S().setFromMatrixPosition(t),normal:new S(0,1,0).applyMatrix4(t).normalize(),confidence:Z.confidence,type:`webxr-hit-test`}}}}}if(globalThis.XR8?.XrController){let t=globalThis.XR8.XrController.hitTest(e.x,e.y,[`FEATURE_POINT`,`ESTIMATED_SURFACE`,`DETECTED_SURFACE`]);if(t&&t.length>0){let e=t[0];return{point:new S(e.position.x,e.position.y,e.position.z),normal:new S(0,1,0),confidence:Z.confidence*(e.type===`DETECTED_SURFACE`?.9:.5),type:e.type}}}let r=new Me;if(r.setFromCamera(new Ce(e.x*2-1,-(e.y*2-1)),t),Number.isFinite(D.floorY)){let e=new S(0,1,0),t=new oe(e,-D.floorY),n=new S;if(r.ray.intersectPlane(t,n)){let t=n.distanceTo(r.ray.origin);if(t>.2&&t<10)return{point:n,normal:e,confidence:Z.confidence,type:`floor`,distance:t}}}let i=D.detectedPlanes||[];for(let e of i){if(e.type===`floor`)continue;let t=new S(0,1,0),n=new oe(t,-e.yCenter),i=new S;if(r.ray.intersectPlane(n,i)){let n=i.distanceTo(r.ray.origin);if(n>.2&&n<10)return{point:i,normal:t,confidence:Z.confidence*e.confidence,type:e.type,distance:n}}}return null}function pf(){return{confidence:Z.confidence,tier:Z.qualityTier,isLost:Z.isLost,worldOriginLocked:Z.worldOriginLocked,anchorCount:Z.anchorRegistry.size,planeCount:Z.planeRegistry.size,relocalizationAttempts:Z.relocalizationAttempts,totalFrames:Z.totalFrames}}function mf(){Z.worldOriginLocked=!1,Z.worldOriginSamples=0,rf=[],Z.isLost=!1,Z.lostFrames=0,Z.goodFrames=0,w(`Relocalization requested — scanning environment.`,`Tracking`),k(`relocalization-requested`,{attempt:++Z.relocalizationAttempts})}function hf(){Z.confidence=0,Z.qualityTier=`initializing`,Z.lostFrames=0,Z.goodFrames=0,Z.isLost=!1,Z.worldOriginLocked=!1,Z.worldOriginSamples=0,rf=[],Z.anchorRegistry.clear(),Z.planeRegistry.clear(),Z.relocalizationAttempts=0,Z.totalFrames=0,D.detectedPlanes=[],document.body.dataset.jarvisTrackingQuality=`initializing`,document.body.dataset.jarvisTrackingState=`init`}O(`world-anchor-sample`,({floorY:e,pointCount:t})=>{D.worldPointBuffer?.length>20&&df(D.worldPointBuffer)}),O(`runtime-phase`,({phase:e})=>{(e===`created`||e===`booting`)&&hf()});var gf=null,_f=0;function vf(){return gf||(gf=wn(yf(`eternum`),`Eternum AR`,880,560),bf(gf,[[`NEXT`,`Enter`],[`AUTO`,`a`],[`SAVE`,`s`],[`MENU`,`Escape`]]),w(`Eternum opened as a floating AR panel. Normal game launch is unchanged outside AR.`,`Eternum AR`),gf)}function yf(e){let t=new URLSearchParams(location.search);return String(t.get(`${e}Url`)||t.get(`game${e[0].toUpperCase()}${e.slice(1)}Url`)||``).trim()||String(globalThis.FridayARConfig?.gameUrls?.[e]||``).trim()||`/api/ar_task?mode=game_launch&task=${encodeURIComponent(`open ${e} web mirror`)}`}function bf(e,t){let n=document.createElement(`div`);n.style.cssText=`position:absolute;left:10px;right:10px;bottom:10px;display:flex;gap:8px;justify-content:center;pointer-events:auto`,t.forEach(([t,r])=>{let i=document.createElement(`button`);i.textContent=t,i.style.cssText=`min-height:44px;min-width:70px;border:1px solid rgba(255,255,255,.25);border-radius:999px;background:rgba(0,0,0,.48);color:white;font-weight:700`,i.onclick=()=>xf(e.iframe,r),n.appendChild(i)}),e.container.style.position=`relative`,e.container.appendChild(n)}async function xf(e,t,n=!1,r=!1){let i=e?.contentWindow;if(!i)return C(`The game iframe is not ready yet.`,`Game Input Failed`),!1;try{let e={key:t,bubbles:!0,cancelable:!0,ctrlKey:n};return i.document.dispatchEvent(new KeyboardEvent(`keydown`,e)),r||window.setTimeout(()=>i.document.dispatchEvent(new KeyboardEvent(`keyup`,e)),50),!0}catch(e){let a=`key-${Date.now().toString(36)}-${++_f}`;return await new Promise(o=>{let s=window.setTimeout(()=>{window.removeEventListener(`message`,c),C(`The game iframe did not acknowledge the key relay before the timeout elapsed.`,`Game Input Timeout`),o(!1)},250),c=e=>{e.source===i&&(e.data?.type!==`keydown-ack`||e.data?.id!==a||(window.clearTimeout(s),window.removeEventListener(`message`,c),o(!0)))};window.addEventListener(`message`,c);try{i.postMessage({type:`keydown`,id:a,key:t,ctrl:n,hold:r},`*`)}catch(t){window.clearTimeout(s),window.removeEventListener(`message`,c),C(t.message||e.message,`Game Input Failed`),o(!1)}})}}var Sf=null;function Cf(){if(Sf)return Sf;let e=new URLSearchParams(location.search);Sf=wn(String(e.get(`ripplesUrl`)||globalThis.FridayARConfig?.gameUrls?.ripples||``).trim()||`/api/ar_task?mode=game_launch&task=open%20ripples%20web%20mirror`,`Ripples AR`,880,560);let t=document.createElement(`div`);return t.style.cssText=`position:absolute;left:10px;right:10px;bottom:10px;display:flex;gap:8px;justify-content:center;pointer-events:auto`,[[`NEXT`,`Enter`],[`AUTO`,`a`],[`SAVE`,`s`],[`MENU`,`Escape`]].forEach(([e,n])=>{let r=document.createElement(`button`);r.textContent=e,r.style.cssText=`min-height:44px;min-width:70px;border:1px solid rgba(255,255,255,.25);border-radius:999px;background:rgba(0,0,0,.48);color:white;font-weight:700`,r.onclick=()=>xf(Sf.iframe,n),t.appendChild(r)}),Sf.container.style.position=`relative`,Sf.container.appendChild(t),w(`Ripples opened as a floating AR panel.`,`Ripples AR`),Sf}async function wf(e,t){let n=await Tf(e,t),r=wn(Df(n.url||e),`${n.title||e} AR`,880,560);return jf(n.controls,r),r}async function Tf(e,t){if(t?.query)try{let n=await t.query(`Game "${e}" genre + controls as JSON only: {"title":"","url":"","genre":"","controls":[{"action":"","key":"","label":""}]}`),r=String(n).replace(/```json|```/g,``).trim(),i=JSON.parse(kf(r));if(Ef(i))return i}catch(e){C(e.message,`Game Schema AI Failed`)}return{title:e,url:Df(e),genre:`generic`,controls:[{action:`accept`,key:`Enter`,label:`NEXT`},{action:`back`,key:`Escape`,label:`BACK`},{action:`left`,key:`ArrowLeft`,label:`LEFT`},{action:`right`,key:`ArrowRight`,label:`RIGHT`}]}}function Ef(e){return!e||typeof e!=`object`||typeof e.title!=`string`||typeof e.url!=`string`||typeof e.genre!=`string`||!Array.isArray(e.controls)?!1:e.controls.every(e=>e&&typeof e==`object`&&typeof e.key==`string`&&typeof e.label==`string`&&e.key.trim()&&e.label.trim())}function Df(e){let t=String(e||``).trim();if(!t)return Of(`AR Game`);if(/^(https?:|blob:|data:|about:)/i.test(t)||t.startsWith(`/`))return t;let n=t.toLowerCase();if(n.includes(`eternum`)){let e=new URLSearchParams(location.search).get(`eternumUrl`);return String(e||globalThis.FridayARConfig?.gameUrls?.eternum||``).trim()||`/api/ar_task?mode=game_launch&task=open%20eternum%20web%20mirror`}if(n.includes(`ripples`)){let e=new URLSearchParams(location.search).get(`ripplesUrl`);return String(e||globalThis.FridayARConfig?.gameUrls?.ripples||``).trim()||`/api/ar_task?mode=game_launch&task=open%20ripples%20web%20mirror`}return Of(t)}function Of(e){let t=`<!doctype html>
<html>
<meta name="viewport" content="width=device-width,initial-scale=1">
<body style="margin:0;background:#05070a;color:white;font:16px system-ui;display:grid;place-items:center;height:100vh;text-align:center">
<main>
<h1 style="font-size:22px;margin:0 0 10px">${Af(e)}</h1>
<p style="opacity:.72;max-width:32rem">No direct web URL was configured for this game yet. Pass a URL in the launch query string or runtime config, or open a supported mirror command, then convert again.</p>
</main>
</body>
</html>`;return`data:text/html;charset=utf-8,${encodeURIComponent(t)}`}function kf(e){let t=e.indexOf(`{`),n=e.lastIndexOf(`}`);return t>=0&&n>t?e.slice(t,n+1):e}function Af(e){return String(e).replace(/[&<>"']/g,e=>({"&":`&amp;`,"<":`&lt;`,">":`&gt;`,'"':`&quot;`,"'":`&#39;`})[e])}function jf(e,t){let n=document.createElement(`div`);return n.style.cssText=`position:absolute;left:10px;right:10px;bottom:10px;display:flex;gap:8px;justify-content:center;flex-wrap:wrap;pointer-events:auto`,e.forEach(e=>{let r=document.createElement(`button`);r.textContent=e.label||e.action,r.style.cssText=`min-height:44px;min-width:64px;border:1px solid var(--separator);border-radius:999px;background:var(--bg-dark);color:var(--text-primary);font-weight:700`,r.onclick=()=>xf(t.iframe,e.key||`Enter`),n.appendChild(r)}),t.container.style.position=`relative`,t.container.appendChild(n),n}var Mf=`jarvis_ar_game_builder_graphs_v1`,Nf=[`OnCollide`,`OnTap`,`OnGesture`,`OnTimerEnd`,`IsTag`,`IsHealth`,`IsDistance`,`Destroy`,`Spawn`,`MoveToward`,`SetScore`,`PlaySound`,`ShowMessage`,`EndGame`],Pf=null,Ff=null;function If(){if(Pf)return Pf.restore(),Pf;let e=document.createElement(`div`);e.append(Lf()),Pf=new bn({title:`AR Game Builder`,body:e,icon:`B`,width:400,height:600});let t=Pf.destroy.bind(Pf);return Pf.destroy=()=>{Ff?.dispose?.(),Ff=null,t(),Pf=null},Pf.focus(),Pf}function Lf(){let e=document.createElement(`div`),t=document.createElement(`div`),n=document.createElement(`div`);return t.className=`panel-row`,Object.entries({Entities:Rf,Logic:zf,Settings:Bf,Play:Vf}).forEach(([e,r],i)=>{let a=document.createElement(`button`);a.className=`panel-action`,a.textContent=e,a.onclick=()=>{t.querySelectorAll(`button`).forEach(e=>e.classList.toggle(`selected`,e===a)),n.replaceChildren(r())},t.appendChild(a),i===0&&window.setTimeout(()=>a.click(),0)}),e.append(t,n),e}function Rf(){let e=document.createElement(`div`),t=document.createElement(`input`),n=document.createElement(`input`),r=document.createElement(`button`);return t.placeholder=`Entity name`,n.placeholder=`Tag, e.g. target`,r.className=`panel-action`,r.textContent=`Add Entity`,r.onclick=()=>{let e=hr(Mf,[]).at(-1)||qf();e.entities.push({id:xr(`entity`),name:t.value||`Entity`,tag:n.value||`default`}),Jf(e),w(`Entity saved to AR game graph.`)},e.append(t,n,r,Yf()),e}function zf(){let e=document.createElement(`div`),t=document.createElement(`select`),n=document.createElement(`input`),r=document.createElement(`button`);return Sr(t,Nf),n.placeholder=`Node value`,r.className=`panel-action`,r.textContent=`Add Logic Node`,r.onclick=()=>{let e=hr(Mf,[]).at(-1)||qf();e.nodes.push({id:xr(`node`),type:t.value,value:n.value}),Jf(e),w(`${t.value} node added.`)},e.append(t,n,r,Yf()),e}function Bf(){let e=document.createElement(`div`),t=document.createElement(`input`),n=document.createElement(`input`),r=document.createElement(`button`);return t.placeholder=`Game title`,n.type=`number`,n.placeholder=`Timer seconds`,r.className=`panel-action`,r.textContent=`Save Settings`,r.onclick=()=>{let e=hr(Mf,[]).at(-1)||qf();e.title=t.value||e.title,e.duration=Number(n.value||e.duration||60),Jf(e),w(`Game settings saved.`)},e.append(t,n,r,Yf()),e}function Vf(){let e=document.createElement(`div`),t=document.createElement(`button`);return t.className=`btn-primary`,t.textContent=`Spawn Saved Game`,t.onclick=()=>{let e=hr(Mf,[]).at(-1);if(!e){w(`Create a game graph first.`);return}Ff?.dispose?.(),Ff=Hf(e),w(`Game "${e.title}" spawned ${Ff.entities.length} AR entity object(s).`,`Game Builder`)},e.append(t,Yf()),e}function Hf(e){let{scene:t,camera:n}=I(),r=new g;r.name=`jarvis-game-${e.id}`,r.userData.isARGame=!0,r.position.set(0,D.floorY+.08,-1.6),t.add(r);let i=(e.entities.length?e.entities:[{id:xr(`entity`),name:`Target`,tag:`target`}]).map((t,n)=>Uf(t,n,e.entities.length||1));i.forEach(e=>r.add(e.mesh));let a=0,o=!1,s=performance.now(),c=[],l=[],u=new Me,d=t=>{if(o)return;let n=String(t.type||``).toLowerCase(),s=String(t.value||``).trim();if(n===`spawn`){let e=Uf({id:xr(`entity`),name:s||`Spawned`,tag:`spawned`},i.length,i.length+1);i.push(e),r.add(e.mesh)}else if(n===`destroy`){let e=Wf(s,i);e&&(e.mesh.parent?.remove(e.mesh),e.destroyed=!0)}else if(n===`setscore`)a=Number(s||a+1),r.userData.score=a;else if(n===`showmessage`)w(s||e.title||`AR game event`,`Game Builder`);else if(n===`playsound`)Kf();else if(n===`endgame`)o=!0,w(`${e.title||`AR Game`} ended. Score: ${a}`,`Game Builder`);else if(n===`movetoward`){let e=Wf(s,i)||i[0];e&&e.mesh.position.lerp(new S(0,.12,-.35),.35)}},f=t=>{if(o||t.target.closest?.(`.ar-panel, .hud-toolbar, button, input, select, textarea, iframe`))return;u.setFromCamera(new Ce(t.clientX/innerWidth*2-1,-(t.clientY/innerHeight)*2+1),n);let s=u.intersectObjects(i.filter(e=>!e.destroyed).map(e=>e.mesh),!0)[0];if(!s)return;let c=Gf(s.object,i);a+=1,r.userData.score=a,c.mesh.scale.multiplyScalar(.92),e.nodes.filter(e=>e.type===`OnTap`||e.type===`SetScore`||e.type===`ShowMessage`).forEach(d)};document.addEventListener(`pointerup`,f,!0),l.push(()=>document.removeEventListener(`pointerup`,f,!0));let p=O(`gesture-pinch`,()=>{e.nodes.filter(e=>e.type===`OnGesture`||e.type===`SetScore`).forEach(d)});l.push(p),Number(e.duration)>0&&c.push(window.setTimeout(()=>{e.nodes.filter(e=>e.type===`OnTimerEnd`||e.type===`EndGame`).forEach(d),o||(o=!0,w(`${e.title||`AR Game`} timer finished. Score: ${a}`,`Game Builder`))},Number(e.duration)*1e3));let m=()=>{if(!r.parent||o)return;let e=(performance.now()-s)/1e3;i.forEach((t,n)=>{t.destroyed||(t.mesh.rotation.y+=.01+n*.001,t.mesh.position.y=.08+Math.sin(e*1.6+n)*.035)}),r.userData.frame=P(m)};return m(),{root:r,entities:i,dispose(){o=!0,yt(r.userData.frame),c.forEach(e=>window.clearTimeout(e)),l.forEach(e=>e()),r.traverse(e=>{e.geometry?.dispose?.(),e.material?.dispose?.()}),r.parent?.remove(r)}}}function Uf(e,t,n){let r=new v(.12,1),i=t/Math.max(n,1)*.78+.05,a=new b(r,new y({color:new ie().setHSL(i,.72,.55),emissive:new ie().setHSL(i,.72,.12),roughness:.25,metalness:.18})),o=t/Math.max(n,1)*Math.PI*2;return a.position.set(Math.sin(o)*.55,.08,-Math.cos(o)*.35),a.userData.entityId=e.id,a.userData.entityName=e.name,a.userData.tag=e.tag,a.castShadow=!0,a.receiveShadow=!0,{...e,mesh:a,destroyed:!1}}function Wf(e,t){let n=String(e||``).toLowerCase();return t.find(e=>String(e.name||``).toLowerCase().includes(n)||String(e.tag||``).toLowerCase().includes(n)||String(e.id||``).toLowerCase()===n)}function Gf(e,t){let n=e;for(;n;){let e=n.userData?.entityId;if(e)return t.find(t=>t.id===e);n=n.parent}return null}function Kf(){try{let e=new AudioContext,t=e.createOscillator(),n=e.createGain();t.frequency.value=660,n.gain.value=.035,t.connect(n),n.connect(e.destination),t.start(),window.setTimeout(()=>{t.stop(),e.close()},140)}catch{}}function qf(){return{id:xr(`game`),title:`Untitled AR Game`,duration:60,entities:[],nodes:[],createdAt:Date.now()}}function Jf(e){let t=hr(Mf,[]).filter(t=>t.id!==e.id);t.push(e),gr(Mf,t.slice(-20))}function Yf(){let e=document.createElement(`pre`),t=hr(Mf,[]).at(-1)||qf();return e.style.cssText=`white-space:pre-wrap;font:12px/1.4 monospace;color:rgba(255,255,255,.72);background:rgba(0,0,0,.25);padding:10px;border-radius:12px;max-height:160px;overflow:auto`,e.textContent=JSON.stringify(t,null,2),e}async function Xf(e,t={},n=0,r=1e4){let i=null;for(let a=0;a<=n;a+=1){let o=new AbortController,s=window.setTimeout(()=>o.abort(new DOMException(`Request timed out`,`AbortError`)),r);try{let n=await fetch(e,{...t,signal:o.signal});return window.clearTimeout(s),n}catch(e){if(window.clearTimeout(s),i=e,a>=n)throw e}}throw i||Error(`Request failed.`)}async function Zf(e,t={},n=0,r=1e4){let i=await Xf(e,t,n,r);if(!(i.headers.get(`content-type`)||``).includes(`application/json`)){let t=await i.text();throw Error(t||`Expected JSON response from ${e}`)}return i.json()}function Qf(e,t){if(!Array.isArray(e))return!1;let n=JSON.stringify(t);return e.some(e=>JSON.stringify(e)===n)?!1:(e.push(t),!0)}var $f=class{constructor(e){this.config=e,this.ws=null,this.connected=!1,this.reconnectTimer=0,this.pendingPatches=[],this.reconnectDelay=2e3,this.maxReconnectDelay=3e4,this.heartbeatTimer=0}connect(){return this.connectWebSocket(),this.loadConfig(),D.jarvis=this,this}async loadConfig(){try{let e=await Zf(`${this.apiBase()}/api/ar_config`,{headers:this.headers()},1,9e3);if(e.ok===!1)throw Error(e.error||`AR config failed.`);return k(`jarvis-config`,e),T(`status-omega`,`linked`),e}catch{return T(`status-omega`,`offline`),null}}connectWebSocket(){let e=this.config.wsBase||(location.protocol===`https:`?`wss://${location.host}/scene-ws`:`ws://${location.hostname}:5050`),t=cr(`omega_session`);t&&!/[?&]token=/.test(e)&&(e+=`${e.includes(`?`)?`&`:`?`}token=${encodeURIComponent(t)}`);try{this.reconnectTimer&&(clearTimeout(this.reconnectTimer),this.reconnectTimer=0),this._clearHeartbeat(),this.ws=new WebSocket(e),this.ws.onopen=()=>{this.connected=!0,clearTimeout(this.reconnectTimer),this.reconnectDelay=2e3,T(`status-omega`,`linked`),this.ws.send(JSON.stringify({type:`hello`,device_name:this.config.deviceName,source:`browser-8thwall-real-ar`})),this.flushPendingPatches(),this._startHeartbeat()},this.ws.onmessage=e=>this.onMessage(e),this.ws.onerror=()=>{this.connected&&T(`status-omega`,`ws error`)},this.ws.onclose=()=>{this.connected=!1,this._clearHeartbeat(),T(`status-omega`,`offline`),this.reconnectTimer&&clearTimeout(this.reconnectTimer);let e=this.reconnectDelay;this.reconnectDelay=Math.min(this.reconnectDelay*2,this.maxReconnectDelay),this.reconnectTimer=setTimeout(()=>this.connectWebSocket(),e)}}catch(e){C(e.message,`OMEGA WebSocket Failed`)}}_startHeartbeat(){this._clearHeartbeat(),this.heartbeatTimer=setInterval(()=>{if(!this.ws||this.ws.readyState!==WebSocket.OPEN){this._clearHeartbeat();return}try{this.ws.send(JSON.stringify({type:`ping`,ts:Date.now()}))}catch{this.ws.close()}},15e3)}_clearHeartbeat(){this.heartbeatTimer&&(clearInterval(this.heartbeatTimer),this.heartbeatTimer=0)}onMessage(e){try{let t=JSON.parse(e.data);k(`omega-message`,t),t.state&&k(`omega-scene-state`,t.state)}catch{}}async query(e){let t=await Xf(`${this.apiBase()}/api/ar_task`,{method:`POST`,headers:{"Content-Type":`application/json`,...this.headers()},body:JSON.stringify({task:e,mode:`jarvis`,device_name:this.config.deviceName})},0,9e3),n=await t.json();if(!t.ok||n.ok===!1)throw Error(n.error||`JARVIS query failed.`);return n.response||n.message||n.result||JSON.stringify(n)}async runTask(e,t=`task`){let n=await Xf(`${this.apiBase()}/api/ar_task`,{method:`POST`,headers:{"Content-Type":`application/json`,...this.headers()},body:JSON.stringify({task:e,mode:t,device_name:this.config.deviceName})},0,9e3),r=await n.json();if(!n.ok||r.ok===!1)throw Error(r.error||`Task endpoint failed.`);return k(`jarvis-task-result`,r),r}patchScene(e){let t={...e,device_name:this.config.deviceName,source:`browser-8thwall-real-ar`};return this.ws?.readyState===WebSocket.OPEN?(this.ws.send(JSON.stringify({type:`patch`,patch:t,ts:Date.now()})),Promise.resolve(!0)):(Qf(this.pendingPatches,t),Xf(`${this.apiBase()}/api/ar_scene_patch`,{method:`POST`,headers:{"Content-Type":`application/json`,...this.headers()},body:JSON.stringify(t)},1,9e3).catch(()=>null))}headers(){let e={"X-FRIDAY-Device":this.config.deviceName},t=cr(`omega_session`);return t&&(e.Authorization=`Bearer ${t}`),e}apiBase(){return String(this.config.omegaBase||``).replace(/\/+$/,``)||``}flushPendingPatches(){!this.ws||this.ws.readyState!==WebSocket.OPEN||!this.pendingPatches.length||this.pendingPatches.splice(0).forEach(e=>{try{this.ws.send(JSON.stringify({type:`patch`,patch:{...e,device_name:this.config.deviceName,source:`browser-8thwall-real-ar`},ts:Date.now()}))}catch{}})}},ep={IDLE:`idle`,LISTENING:`listening`,THINKING:`thinking`,SPEAKING:`speaking`},tp={listening:`👂`,thinking:`🧠`,speaking:`🔊`},np={listening:`LISTENING`,thinking:`THINKING`,speaking:`SPEAKING`},rp=ep.IDLE,ip=new Set;function ap(){return rp}function op(e){return ip.add(e),()=>ip.delete(e)}function sp(e){let t=String(e||``).toLowerCase();Object.values(ep).includes(t)&&t!==rp&&(rp=t,lp(),ip.forEach(e=>{try{e(rp)}catch{}}))}function cp(){let e=document.getElementById(`jarvis-assistant-state`);return e||(e=document.createElement(`div`),e.id=`jarvis-assistant-state`,e.setAttribute(`aria-live`,`polite`),Object.assign(e.style,{position:`fixed`,top:`calc(env(safe-area-inset-top, 0px) + 12px)`,left:`50%`,transform:`translateX(-50%) translateY(-8px)`,display:`flex`,alignItems:`center`,gap:`8px`,padding:`7px 14px`,borderRadius:`999px`,background:`linear-gradient(180deg, rgba(10,10,15,.82), rgba(10,10,15,.62))`,border:`1px solid rgba(0,212,255,.35)`,boxShadow:`0 6px 24px rgba(0,0,0,.45), 0 0 18px rgba(0,212,255,.22)`,backdropFilter:`blur(14px) saturate(140%)`,color:`#eaf2ff`,font:`600 11px/1 'JetBrains Mono', ui-monospace, monospace`,letterSpacing:`2px`,zIndex:`99998`,pointerEvents:`none`,opacity:`0`,transition:`opacity .28s cubic-bezier(.2,.8,.2,1), transform .28s cubic-bezier(.2,.8,.2,1)`}),e.innerHTML=`<span data-glyph style="font-size:14px;letter-spacing:0"></span><span data-label></span>`,document.body.appendChild(e),e)}function lp(){let e;try{e=cp()}catch{return}if(!e)return;let t=e.querySelector(`[data-glyph]`),n=e.querySelector(`[data-label]`);if(rp===ep.IDLE){e.style.opacity=`0`,e.style.transform=`translateX(-50%) translateY(-8px)`;return}t&&(t.textContent=tp[rp]||``),n&&(n.textContent=np[rp]||``),e.style.opacity=`1`,e.style.transform=`translateX(-50%) translateY(0)`}var up=0,dp={idle:`JARVIS`,listening:`Listening`,thinking:`Working on it`,speaking:`JARVIS`,failed:`Couldn’t answer`};function fp(e){let t=document.getElementById(`jarvis-bubble`),n=document.getElementById(`jarvis-bubble-label`);if(!t)return;let r=String(e||`idle`).toLowerCase();t.setAttribute(`data-state`,r),n&&(n.textContent=dp[r]||`JARVIS`)}var pp=!1;function mp(){if(pp)return;pp=!0,op(fp),fp(ap());let e=document.getElementById(`jarvis-bubble-close`),t=document.getElementById(`jarvis-bubble`);e&&t&&e.addEventListener(`click`,()=>{clearTimeout(up),t.classList.add(`hidden`)})}function hp(e,{speak:t=!0}={}){let n=document.getElementById(`jarvis-bubble`),r=document.getElementById(`jarvis-bubble-text`);!n||!r||(mp(),n.classList.remove(`hidden`),clearTimeout(up),_p(r,String(e||`Ready.`),()=>{clearTimeout(up),up=window.setTimeout(()=>n.classList.add(`hidden`),6e3)}),t&&gp(e))}function gp(e){try{if(!(`speechSynthesis`in window))return;window.speechSynthesis.cancel();let t=new SpeechSynthesisUtterance(String(e||``));t.rate=.92,t.pitch=.82,t.volume=.88;let n=window.speechSynthesis.getVoices();t.voice=n.find(e=>String(e.lang||``).toLowerCase()===`en-gb`)||n.find(e=>/Daniel|George|Arthur|Google UK English Male|English.*United Kingdom|UK/i.test(`${e.name} ${e.lang}`))||n.find(e=>String(e.lang||``).toLowerCase().startsWith(`en-gb`))||n.find(e=>/en/i.test(e.lang))||null;let r=()=>{ap()===ep.SPEAKING&&sp(ep.IDLE)};t.onstart=()=>sp(ep.SPEAKING),t.onend=r,t.onerror=r,window.speechSynthesis.speak(t)}catch{ap()===ep.SPEAKING&&sp(ep.IDLE)}}function _p(e,t,n){e.textContent=``;let r=0,i=()=>{e.textContent=t.slice(0,r),r+=1,r<=t.length?window.setTimeout(i,14):n?.()};i()}var vp=null,yp=0,bp=0,xp=!1,Sp=!1,Cp=!1,wp=null,Tp=`unknown`,Ep=0,Dp=``;function Op(){let e=window.SpeechRecognition||window.webkitSpeechRecognition;return e?(vp=new e,vp.continuous=!0,vp.interimResults=!1,vp.lang=navigator.language||`en-US`,vp.onresult=Ap,vp.onerror=e=>{if(e.error===`not-allowed`||e.error===`service-not-allowed`||e.error===`audio-capture`){xp=!1,Tp=`blocked`,clearTimeout(bp),C(e.error||`Speech recognition blocked.`,`JARVIS Voice`),Mp(`blocked`,{error:e.error||`blocked`});return}e.error!==`no-speech`&&C(e.error||`Speech recognition failed.`,`JARVIS Voice`),Mp(`error`,{error:e.error||`unknown`})},vp.onend=()=>{xp&&(clearTimeout(bp),bp=setTimeout(()=>void kp(),850),Mp(`ended`))},!0):(w(`SpeechRecognition is not available here. Use the JARVIS text command panel.`),!1)}async function kp(){if(!vp&&!Op())return!1;if(Cp)return!0;xp=!0,Cp=!0,await jp();try{return vp.start(),window.setTimeout(()=>{Cp=!1},350),Sp||(w(`JARVIS wake word listening is active.`),Sp=!0),!0}catch(e){return Cp=!1,clearTimeout(bp),bp=setTimeout(()=>{xp&&kp()},1200),/InvalidStateError/i.test(e?.name||e?.message||``)||w(`JARVIS voice restart pending: ${e?.message||`recognizer busy`}`),Mp(`start-failed`,{error:e?.message||`busy`}),!1}}function Ap(e){if(!e.results?.[e.resultIndex]?.isFinal)return;let t=Array.from(e.results).slice(e.resultIndex).filter(e=>e?.isFinal).map(e=>e[0]?.transcript||``).join(` `).trim();if(!t)return;let n=t.toLowerCase().replace(/\s+/g,` `).trim(),r=Date.now(),i=n.match(/(?:^|\b)(?:hey\s+)?jarvis\b[:,]?\s*(.*)$/i)||n.match(/(?:^|\b)(?:hey\s+)?friday\b[:,]?\s*(.*)$/i),a=i?.[1]?.trim()||``;if(i){if(yp=r+4200,Mp(`wake`,{wakeWindowUntil:yp}),!a){hp(`Listening.`,{speak:!1});return}}else if(r>yp)return;if(r-Ep<650)return;Ep=r;let o=a||n;!o||o===Dp||(Dp=o,k(`jarvis-command`,{text:o,source:`voice`}),Mp(`command`,{wakeWindowUntil:yp}))}async function jp(){if(wp||Tp===`blocked`||!navigator.mediaDevices?.getUserMedia)return wp;try{return wp=await navigator.mediaDevices.getUserMedia({audio:{echoCancellation:!0,noiseSuppression:!0,autoGainControl:!0,channelCount:1},video:!1}),Tp=`granted`,Mp(`mic-ready`),wp}catch(e){return Tp=[`NotAllowedError`,`SecurityError`].includes(e?.name)?`blocked`:`error`,Mp(`mic-error`,{error:e?.name||e?.message||`unknown`}),null}}function Mp(e,t={}){try{k(`VOICE_STATE`,{reason:e,enabled:xp,starting:Cp,wakeWindowUntil:yp,micPermission:Tp,hasStream:!!wp,lastCommandAt:Ep,...t})}catch{}}var Np=5,Pp=.55,Fp=.3,Ip=null,Lp=null;function Rp(){return Ip||(Ip=document.getElementById(`world-label-layer`)),Ip}function zp(e,t){let n=t?.width||0,r=t?.height||0;if(!n||!r)return null;let i=t.source?.getBoundingClientRect?.(),a=i?.width||window.innerWidth,o=i?.height||window.innerHeight;if(!a||!o)return null;let s=i?.width?i.left:0,c=i?.height?i.top:0,l=`cover`;try{l=getComputedStyle(t.source).objectFit||`cover`}catch{}let u=l===`contain`||l===`scale-down`?Math.min(a/n,o/r):Math.max(a/n,o/r),d=s+(a-n*u)/2,f=c+(o-r*u)/2;return{cx:(e.originX+e.width/2)*u+d,top:e.originY*u+f}}function Bp(e){let t=Rp();if(!t)return;let n=gt();if(!n)return;let r=new Set,i=[];for(let t of e||[]){let e=t?.categories?.[0],a=e?.categoryName,o=e?.score??0;if(!a||o<Fp||r.has(a))continue;let s=zp(t.boundingBox||{},n);if(s&&!(s.cx<0||s.cx>window.innerWidth||s.top<0||s.top>window.innerHeight)&&(r.add(a),i.push({name:a,score:o,pos:s}),i.length>=Np))break}t.replaceChildren();for(let e of i){let n=document.createElement(`span`);n.className=e.score<Pp?`world-label low`:`world-label`,n.style.left=`${e.pos.cx}px`,n.style.top=`${e.pos.top}px`;let r=document.createElement(`b`);r.textContent=e.name.charAt(0).toUpperCase()+e.name.slice(1);let i=document.createElement(`span`);i.className=`world-label-conf`;let a=document.createElement(`i`);a.style.width=`${Math.round(Math.max(0,Math.min(1,e.score))*100)}%`,i.appendChild(a),n.append(r,i),t.appendChild(n)}}function Vp(){return Lp?!0:Rp()?(Lp=N(window,`ar-object-detections`,e=>{try{Bp(e.detail)}catch(e){console.warn(`[world-labels] render skipped`,e)}}),!0):!1}var Hp=null,Up=null,Wp=!1;async function Gp(){Wp=!0;try{Hp=new globalThis.FaceMesh({locateFile:e=>`https://cdn.jsdelivr.net/npm/@mediapipe/face_mesh/${e}`}),Hp.setOptions({maxNumFaces:1,refineLandmarks:!0,minDetectionConfidence:.5,minTrackingConfidence:.5}),Hp.onResults(e=>{window.dispatchEvent(new CustomEvent(`ar-face-mesh-results`,{detail:e}))}),console.log(`[AR Vision] Face mesh initialized.`)}catch(e){Hp=null,console.warn(`[AR Vision] Face mesh unavailable, continuing without it:`,e),T(`status-tracking`,`no face mesh`)}try{let t=await e.forVisionTasks(`https://cdn.jsdelivr.net/npm/@mediapipe/tasks-vision/wasm`);Vp(),Up=await n.createFromOptions(t,{baseOptions:{modelAssetPath:`https://storage.googleapis.com/mediapipe-models/object_detector/efficientdet_lite0/float16/1/efficientdet_lite0.tflite`,delegate:`GPU`},scoreThreshold:.5,maxResults:5,runningMode:`VIDEO`}),console.log(`[AR Vision] Object detector initialized.`)}catch(e){Up=null,console.warn(`[AR Vision] Object detector unavailable, continuing without it:`,e),T(`status-tracking`,`no object detect`)}P(Kp)}async function Kp(){if(!Wp)return;let e=gt();if(e){let t=e.source;try{if(Hp&&await Hp.send({image:t}),Up){let e=Up.detectForVideo(t,performance.now());e.detections.length>0&&window.dispatchEvent(new CustomEvent(`ar-object-detections`,{detail:e.detections}))}}catch(e){console.warn(`Vision frame skipped:`,e)}}P(Kp)}var qp=.6,Jp=new Map([[`wrist`,0],[`thumb-metacarpal`,1],[`thumb-phalanx-proximal`,2],[`thumb-phalanx-distal`,3],[`thumb-tip`,4],[`index-finger-phalanx-proximal`,5],[`index-finger-phalanx-intermediate`,6],[`index-finger-phalanx-distal`,7],[`index-finger-tip`,8],[`middle-finger-phalanx-proximal`,9],[`middle-finger-phalanx-intermediate`,10],[`middle-finger-phalanx-distal`,11],[`middle-finger-tip`,12],[`ring-finger-phalanx-proximal`,13],[`ring-finger-phalanx-intermediate`,14],[`ring-finger-phalanx-distal`,15],[`ring-finger-tip`,16],[`pinky-finger-phalanx-proximal`,17],[`pinky-finger-phalanx-intermediate`,18],[`pinky-finger-phalanx-distal`,19],[`pinky-finger-tip`,20]]),Yp=!1,Xp=0,Zp=16;function Qp(e,t){let n=e?.session;if(!n)return;let r=t?.xr?.getReferenceSpace?.();if(!r)return;let i=performance.now();if(i-Xp<Zp)return;Xp=i;let a=[];for(let t of n.inputSources){if(!t.hand)continue;let n=$p(e,t.hand,r);n&&a.push(n)}if(!a.length){D.handState.hands.length&&(D.handState.hands=[],D.handState.gestures=new Map);return}Yp||(Yp=!0,F(`webXRHandTracking`,!0),k(`xr-hands-detected`,{count:a.length})),D.handState.hands=a;let o=Pc(a);D.handState.gestures=o;for(let[e,t]of o)k(`gesture-${e}`,{...t,source:`webxr-hands`})}function $p(e,t,n){let r=Array(21),i=0;for(let[a,o]of Jp){let s=t.get(a);if(!s)continue;let c=e.getJointPose?.(s,n);if(!c)continue;let l=c.transform.position;r[o]={x:.5+l.x/qp,y:.5-l.y/qp,z:l.z/qp},i+=1}return i<15||!r[0]||!r[4]||!r[8]?null:r}function em(){Yp=!1,Xp=0,D.handState.hands=[],D.handState.gestures=new Map}var Q={active:!1,binding:null,depthTexture:null,uniforms:null,patched:new WeakSet,renderer:null},tm=`
uniform sampler2D uDepthTexture;
uniform mat4 uUvTransform;
uniform float uRawValueToMeters;
uniform float uDepthActive;
varying vec4 vOcclClip;
varying float vOcclEyeDepth;
`,nm=`
if (uDepthActive > 0.5) {
vec2 ndc = (vOcclClip.xy / vOcclClip.w) * 0.5 + 0.5;
vec2 depthUv = (uUvTransform * vec4(ndc, 0.0, 1.0)).xy;
if (depthUv.x >= 0.0 && depthUv.x <= 1.0 && depthUv.y >= 0.0 && depthUv.y <= 1.0) {
float realDepth = dot(texture2D(uDepthTexture, depthUv).ra, vec2(255.0, 65280.0)) * uRawValueToMeters;
// Real surface closer than this fragment (with a small bias) → occluded.
if (realDepth > 0.0 && realDepth < vOcclEyeDepth - 0.02) discard;
}
}
`;function rm(e,t,n={}){if(n.occlusion===!1||!e||!t)return!1;if(t.depthUsage!==`gpu-optimized`||typeof globalThis.XRWebGLBinding!=`function`)return F(`depthOcclusion`,!1),!1;try{let n=e.getContext();Q.binding=new globalThis.XRWebGLBinding(t,n),Q.renderer=e;let r=new Ie;r.minFilter=u,r.magFilter=u,r.generateMipmaps=!1,r.flipY=!1,Q.depthTexture=r,Q.uniforms={uDepthTexture:{value:r},uUvTransform:{value:new a},uRawValueToMeters:{value:.001},uDepthActive:{value:0}},Q.active=!0,D.occlusion={active:!0,disable:am},F(`depthOcclusion`,!0);for(let e of D.placedObjects||[])om(e);return O(`object-placed`,e=>om(e?.object)),t.addEventListener(`end`,am,{once:!0}),w(`Depth occlusion active — virtual objects hide behind real surfaces (Quest depth sensing).`,`Occlusion`),!0}catch(e){return console.warn(`Depth occlusion init failed; continuing without it:`,e?.message||e),am(),!1}}function im(e,t){if(!(!Q.active||!e||!t))try{let e=Q.binding.getDepthInformation(t);if(!e||!e.texture){Q.uniforms.uDepthActive.value=0;return}let n=Q.renderer.properties.get(Q.depthTexture);n.__webglTexture=e.texture,n.__webglInit=!0,Q.uniforms.uUvTransform.value.fromArray(e.normDepthBufferFromNormView.matrix),Q.uniforms.uRawValueToMeters.value=e.rawValueToMeters,Q.uniforms.uDepthActive.value=1}catch{Q.uniforms.uDepthActive.value=0}}function am(){Q.active=!1,Q.uniforms&&(Q.uniforms.uDepthActive.value=0),D.occlusion&&(D.occlusion.active=!1),F(`depthOcclusion`,!1)}function om(e){!Q.active||!e?.traverse||e.traverse(e=>{if(!e.isMesh)return;let t=Array.isArray(e.material)?e.material:[e.material];for(let e of t)sm(e)})}function sm(e){if(!e||Q.patched.has(e)||!e.isMeshStandardMaterial&&!e.isMeshPhysicalMaterial&&!e.isMeshLambertMaterial&&!e.isMeshPhongMaterial)return;Q.patched.add(e);let t=e.onBeforeCompile;e.onBeforeCompile=(e,n)=>{typeof t==`function`&&t(e,n),Object.assign(e.uniforms,Q.uniforms),e.vertexShader=e.vertexShader.replace(`#include <common>`,`#include <common>
varying vec4 vOcclClip;
varying float vOcclEyeDepth;`).replace(`#include <project_vertex>`,`#include <project_vertex>
vOcclClip = gl_Position;
vOcclEyeDepth = -mvPosition.z;`),e.fragmentShader=e.fragmentShader.replace(`#include <common>`,tm+`
#include <common>`).replace(`#include <dithering_fragment>`,nm+`
#include <dithering_fragment>`)},e.needsUpdate=!0}window.THREE=pe,window.addEventListener(`deviceorientation`,e=>{if(globalThis.JARVIS_AR&&globalThis.JARVIS_AR.runtime&&globalThis.JARVIS_AR.runtime.camera){let{alpha:t,beta:n,gamma:r}=e;if(t!=null&&n!=null&&r!=null){let e=new window.THREE.Euler(Xe.degToRad(n),Xe.degToRad(t),Xe.degToRad(-r),`YXZ`);globalThis.JARVIS_AR.runtime.camera.quaternion.setFromEuler(e)}}});var $=Kt();D.config=$;try{globalThis.JARVIS_AR=D,globalThis.JarvisWebAR={state:D,start:wm,resume:Pm,pause:Fm,destroy:Im,setNativeOptions:Rm,applyNativeState:zm,command:qm,spawn:e=>k(`spawn-model`,{query:e})}}catch{}var cm=0,lm=!1,um=null,dm=!1,fm=!1,pm=!1,mm=!1,hm=null,gm=new Promise(e=>{hm=e}),_m=!1;function vm(){lm=!0,hm?.(!0),vt(cm),E(`8th Wall engine loaded.`,30),$.autoStart||at(`Engine ready`),$.autoStart&&wm()}ym();function ym(){if(mm)return;if(mm=!0,document.visibilityState===`visible`){bm();return}E(`Waiting for this tab to become visible...`,8);let e=()=>{document.visibilityState===`visible`&&(document.removeEventListener(`visibilitychange`,e),bm())};document.addEventListener(`visibilitychange`,e)}async function bm(){if(pm)return;if(document.visibilityState!==`visible`){ym();return}if(pm=!0,mt(`ar-core`,{entrypoint:`ar-core/ar-init.js`,force:!0}),ft(`booting`),A(`booting`),document.body.dataset.jarvisBoot=`booting`,D.telemetry.startedAt=performance.now(),E(`Running AR preflight audit...`,10),!Gt()){ft(`blocked`,{reason:`https-required`}),A(`blocked`,{reason:`https-required`});return}await xm($),Bm(),M(`capability-matrix`,`ready`,D.capabilities),xn(),M(`panels`,`ready`),Nl(),M(`vr`,`ready`),Xu(),Sd(),M(`media-viewer`,`ready`),Ii(),M(`spatial-audio`,`ready`),Ld(),M(`reconstruction`,`ready`),M(`physics`,`initializing`);let e=()=>{ia().then(()=>M(`physics`,`ready`)).catch(e=>{console.error(`[AR Physics] initialization failed — physics disabled:`,e),M(`physics`,`failed`,{error:String(e?.message||e)})})};typeof requestIdleCallback==`function`?requestIdleCallback(e,{timeout:5e3}):setTimeout(e,2e3),Gp(),M(`vision`,`ready`),Um(),Cm(),Vm(),await en($);try{t(async()=>{let{initVrStereoSplitScreen:e}=await import(`./ar-compositor-BL0mQ4V3.js`);return{initVrStereoSplitScreen:e}},[],import.meta.url).then(({initVrStereoSplitScreen:e})=>{let{renderer:t,scene:n,camera:r}=I();e(t,n,r),console.log(`V15 AR: Stereo split-screen mounted.`)})}catch(e){console.error(`V15 AR Stereo Mount failed:`,e)}j(`scene`,!0),M(`scene`,`ready`,{renderer:D.runtime.rendererOwner}),sn(),M(`adaptive-quality`,`ready`),zt(I(),{mode:`boot-proxy`,tier:D.telemetry.qualityTier||`medium`}),wo(),M(`models`,`ready`),Hm(),M(`jarvis`,`ready`),E(`Waiting for 8th Wall engine binary...`,22),_m||(_m=!0,window.addEventListener(`xrloaded`,vm,{once:!0})),globalThis.XR8&&(lm=!0,hm?.(!0),vt(cm),E(`8th Wall engine loaded.`,30),$.autoStart||at(`Engine ready`),$.autoStart&&wm()),cm=_t(()=>{lm||w(`8th Wall is still loading. Holding real AR start instead of silently dropping into basic camera mode.`,`8th Wall Loading`)},4500),$.command&&(D._commandBootTimer=_t(()=>qm($.command),1200)),document.body.dataset.jarvisBoot=`ready`,j(`boot`,!0),j(`ui`,!0),ft(`ready`),A(`ready`)}function xm(e={}){if(globalThis.XR8)return Promise.resolve(!0);let t=document.getElementById(`jarvis-xr-static`);return t?t.dataset.loadFailed===`true`?Sm(e):new Promise(n=>{t.addEventListener(`load`,()=>{n(!0)},{once:!0}),t.addEventListener(`error`,()=>{t.dataset.loadFailed=`true`,Sm(e).then(n)},{once:!0})}):Sm(e)}function Sm(e={}){if(globalThis.XR8)return Promise.resolve(!0);let t=String(e.xrScriptUrl||``).trim();return t?document.querySelector(`script[data-jarvis-xr-script]`)?Promise.resolve(!0):new Promise(e=>{let n=document.createElement(`script`);n.src=t,n.async=!0,n.defer=!0,n.crossOrigin=`anonymous`,n.dataset.jarvisXrScript=`true`,n.setAttribute(`data-preload-chunks`,`slam`),n.addEventListener(`load`,()=>e(!0),{once:!0}),n.addEventListener(`error`,()=>{w(`Configured 8th Wall binary failed to load. The runtime will fall back instead of hanging on a dead CDN pin.`,`8th Wall Loading`),e(!1)},{once:!0}),document.head.appendChild(n)}):Promise.resolve(!1)}function Cm(){document.getElementById(`start-ar`)?.addEventListener(`click`,e=>{let t=e.currentTarget;t.disabled=!0,t.textContent=`STARTING...`,wm()}),document.getElementById(`camerafeed`)?.addEventListener(`click`,()=>{D.started||wm()})}async function wm(){return dm||um?um:D.runtime.lifecycleState===`running`?!0:(dm=!0,mt(`ar-core`,{entrypoint:`ar-core/ar-init.js`}),ft(`starting`),A(`starting`),E(`Starting real AR camera...`,34),D._cameraAcquired=!1,um=(async()=>{try{let e=await Tm(3e4);return D._commandBootTimer&&(vt(D._commandBootTimer),D._commandBootTimer=null),e&&Em()?await Dm():e?(C(`This device or browser is not supported by the 8th Wall SLAM engine (it needs a mobile browser with motion sensors). Running the fallback tracking path instead.`,`Using fallback tracking`,{timeout:0}),await Am()):(C(`8th Wall engine binary did not load within 30 seconds. Running fallback with reduced tracking.`,`8th Wall Timeout`,{timeout:0}),await Am()),Sn(),kc().catch(e=>C(e.message,`Gesture Startup Failed`)),kp(),fn(),D.started=!0,j(`camera`,!!(D.cameraVideo||D.xrStarted||D.xrSession)),j(`tracking`,!!(D.trackingMode&&D.trackingMode!==`standby`)),ft(`running`,{trackingMode:D.trackingMode}),A(`running`,{trackingMode:D.trackingMode}),kt(`AR runtime started: ${D.trackingMode}`),!0}catch(e){D.runtime.lastError=e?.message||String(e),D.runtime.degradationReason=D.runtime.lastError,ft(`degraded`,{error:D.runtime.lastError}),A(`degraded`,{error:D.runtime.lastError}),C(e.message,`AR Startup Failed`,{timeout:0}),D._commandBootTimer&&(vt(D._commandBootTimer),D._commandBootTimer=null);let t=await Nm();return Sn(),t?(D.started=!0,j(`camera`,!0),j(`tracking`,!0),A(`degraded-running`,{trackingMode:D.trackingMode,reason:D.runtime.degradationReason}),!0):(D.started=!1,um=null,A(`failed`,{error:D.runtime.lastError}),!1)}finally{dm=!1}})(),um)}async function Tm(e){if(globalThis.XR8&&lm)return!0;E(`Waiting for 8th Wall SLAM engine...`,36);let t=new Promise(t=>_t(()=>t(!1),e));return!!(await Promise.race([gm,t])&&globalThis.XR8)}function Em(){try{let e=globalThis.XR8?.XrDevice;if(!e?.isDeviceBrowserCompatible||e.isDeviceBrowserCompatible())return!0;let t=``;try{let n=e.incompatibleReasons?e.incompatibleReasons():null,r=e.deviceEstimate?e.deviceEstimate():null;t=` (reasons: ${JSON.stringify(n)}, os: ${r?.os||`unknown`})`}catch{}return console.warn(`[AR] 8th Wall reports this device/browser is unsupported${t}. Using the fallback tracking path.`),D.runtime.degradationReason=`8thwall-device-unsupported`,!1}catch{return!0}}async function Dm(){let e=globalThis.XR8;if(!e?.GlTextureRenderer?.pipelineModule)throw Error(`XR8.GlTextureRenderer.pipelineModule() is missing.`);if(!e?.Threejs?.pipelineModule)throw Error(`XR8.Threejs.pipelineModule() is missing.`);let t=document.getElementById(`camerafeed`);if(!t)throw Error(`Camera feed canvas was not found.`);e.addCameraPipelineModule({name:`app-camera-status`,onCameraStatusChange:({status:e})=>{e===`requesting`?(E(`Allow camera access to start AR...`,40),T(`status-camera`,`requesting`)):e===`hasStream`?(E(`Camera stream acquired. Initializing SLAM...`,52),T(`status-camera`,`stream`),D.runtime.permissionState=`granted`,D._cameraAcquired=!0,j(`camera`,!0)):e===`hasVideo`?(D._cameraAcquired=!0,E(`Camera live. Tracking world points...`,76),T(`status-camera`,`live`),D.runtime.permissionState=`granted`,j(`camera`,!0),ot()):e===`failed`&&(T(`status-camera`,`failed`),D.runtime.permissionState=`denied-or-failed`,D.runtime.degradationReason=`camera failed`,A(`permission-blocked`,{source:`xr8-camera`}),C(`Camera access failed. Check browser settings and allow camera for this browser.`,`Camera Failed`,{timeout:0,linkHref:`intent://settings#Intent;scheme=android-app;end`,linkLabel:`Open Chrome Android settings`}))}});let n=[e.GlTextureRenderer.pipelineModule(),Ut.FullWindowCanvas.pipelineModule(),e.Threejs.pipelineModule(),e.XrController.pipelineModule({enableWorldPoints:!0,disableWorldTracking:!1,imageTargets:Array.isArray($.imageTargets)?$.imageTargets:[]}),...e.CameraPixelArray?.pipelineModule?[e.CameraPixelArray.pipelineModule({maxDimension:480}),Xc()]:[],Ut.AlmostThere.pipelineModule(),Ut.Loading.pipelineModule(),Ut.RuntimeError.pipelineModule(),Ad(),Xd()];D.pipelineOrder=[`app-camera-status`,`XR8.GlTextureRenderer`,...n.slice(1).map(e=>e.name)],D.trackingAPI={getTrackingQuality:pf,registerAnchor:cf,unregisterAnchor:lf,performHitTest:ff,requestRelocalization:mf},e.addCameraPipelineModules(n),e.run({canvas:t,webgl2:!0,ownRunLoop:!0,glContextConfig:{alpha:!0,preserveDrawingBuffer:!0,powerPreference:`high-performance`},cameraConfig:{direction:e.XrConfig.camera().BACK}}),D.xrStarted=!0,D.xrAvailable=!0,F(`eightWallSLAM`,!0),D.trackingMode=`8thwall-slam`,await Om(12e3),await km();let r=Pt()||I();ht(`xr8-threejs`,r,{takeover:!0,engine:`8thwall-slam`}),zt(r,{mode:`xr8-session`,session:D.xrSession,tier:D.telemetry.qualityTier||`high`,stereo:!1,depthComposition:!0,frameBudgetMs:13.5,guardianProxy:!!$.guardianProxy}),M(`xr8`,`running`,{pipelineOrder:D.pipelineOrder}),an(r.renderer,$),dn(r.scene),Ft(r),j(`tracking`,!0),document.body.dataset.jarvisTracking=`8thwall-slam`,T(`status-tracking`,`8th wall`),nn(),ot(),w(`8th Wall SLAM path started. Camera texture renderer is first in the render pipeline.`)}async function Om(e){if(D._cameraAcquired)return!0;let t=performance.now();for(;performance.now()-t<e;){if(D._cameraAcquired)return!0;if(D.runtime.permissionState===`denied-or-failed`)throw Error(`Camera access was denied or failed.`);await new Promise(e=>_t(e,250))}throw Error(`The camera did not start within ${Math.round(e/1e3)}s. The AR engine could not obtain a rear-facing camera stream.`)}async function km(e=2200){let t=0,n=performance.now();for(;performance.now()-n<e&&t<132;){try{let e=globalThis.XR8?.Threejs?.xrScene?.();if(e?.scene&&e?.camera&&e?.renderer)return e}catch{}t++,await new Promise(e=>requestAnimationFrame(e))}return t>=132&&console.warn(`Timed out without a valid XR scene — returning null.`,132),null}async function Am(){if(D.trackingMode=`webxr-fallback`,document.body.dataset.jarvisTracking=`webxr-fallback`,T(`status-tracking`,`webxr/basic`),!(`xr`in navigator&&navigator.xr))return Nm();try{if(!await navigator.xr.isSessionSupported(`immersive-ar`))return Nm();let{renderer:e}=I(),t=await Promise.race([navigator.xr.requestSession(`immersive-ar`,{requiredFeatures:[`hit-test`],optionalFeatures:[`dom-overlay`,`light-estimation`,`depth-sensing`,`local-floor`,`anchors`,`bounded-floor`,`hand-tracking`,`unbounded`],depthSensing:{usagePreference:[`gpu-optimized`],dataFormatPreference:[`luminance-alpha`]},domOverlay:{root:document.getElementById(`ui-layer`)}}),new Promise((e,t)=>_t(()=>t(Error(`WebXR session request timed out`)),5e3))]);e.xr.enabled=!0,e.xr.setSession(t),jm(e,t),Mm(e,t),rm(e,t,$);let n=await t.requestReferenceSpace(`viewer`);return D.xrHitTestSource=await t.requestHitTestSource({space:n}),D.xrSession=t,t.addEventListener(`end`,()=>{if(D.xrSession===t){D.xrSession=null,D.xrStarted=!1;try{e.setAnimationLoop(null)}catch{}em(),Mt(),D.started&&A(`degraded`,{reason:`webxr-session-ended`})}},{once:!0}),ht(`webxr-threejs`,{scene:D.scene,camera:D.camera,renderer:e},{takeover:!0,engine:`webxr-fallback`}),zt({scene:D.scene,camera:D.camera,renderer:e},{mode:`webxr-session`,session:t,stereo:!1,depthComposition:!0,source:D.cameraVideo||document.getElementById(`camerafeed`)}),M(`webxr`,`running`),F(`webXRHitTest`,!0),Nt(),e.setAnimationLoop((t,n)=>{if(n&&(D.xrFrame=n,Qp(n,e),D.occlusion?.active)){let t=e.xr.getReferenceSpace?.(),r=t?n.getViewerPose?.(t):null;r?.views?.length&&im(n,r.views[0])}let r=D.scene||D.fallbackScene,i=D.camera||D.fallbackCamera;r&&i&&e.render(r,i)}),Ft(I()),j(`camera`,!0),j(`tracking`,!0),ot(),w(`Running WebXR fallback. 8th Wall SLAM is not active in this session.`),!0}catch(e){return C(e.message,`WebXR Fallback Failed`),Nm()}}function jm(e,t){try{let n=D.scene||I()?.scene;if(!n||!e)return;let r=new we(e);D.xrEstimatedLight=r;let i=n.environment;r.addEventListener(`estimationstart`,()=>{n.add(r),i=n.environment,r.environment&&(n.environment=r.environment),D.telemetry.iblEnvironment=`xr-light-estimation`,F(`lightEstimation`,!0)}),r.addEventListener(`estimationend`,()=>{try{n.remove(r)}catch{}n.environment=i,D.telemetry.iblEnvironment=n.userData?.jarvisEnvironmentSource||`room-default`}),t.addEventListener(`end`,()=>{try{n.remove(r)}catch{}n.environment=i,D.xrEstimatedLight=null},{once:!0})}catch(e){console.warn(`XR light estimation setup failed:`,e?.message||e)}}function Mm(e,t){let n=t=>{try{let n=D.xrFrame,r=e?.xr?.getReferenceSpace?.(),i=t.inputSource,a=i?.targetRaySpace;if(!n||!r||!a)return;let o=n.getPose?.(a,r);if(!o)return;let s=o.transform.matrix,c={x:s[12],y:s[13],z:s[14]},l={x:-s[8],y:-s[9],z:-s[10]};try{i.gamepad?.hapticActuators?.[0]?.pulse?.(.4,40)}catch{}let u=Os({origin:c,direction:l});u&&(D.telemetry.lastXRSelect=u.type)}catch(e){console.warn(`XR select handling failed:`,e?.message||e)}};t.addEventListener(`select`,n),t.addEventListener(`end`,()=>{try{t.removeEventListener(`select`,n)}catch{}},{once:!0})}async function Nm(){D.trackingMode=`manual-camera`,F(`manualCamera`,!0),document.body.dataset.jarvisTracking=`manual-camera`,T(`status-tracking`,`basic camera`),E(`Starting basic camera mode...`,48);try{Lm();let e=await navigator.mediaDevices.getUserMedia({video:{facingMode:{ideal:`environment`},width:{ideal:1280},height:{ideal:720},frameRate:{ideal:30}},audio:!1}),t=document.createElement(`video`);t.srcObject=e,t.autoplay=!0,t.playsInline=!0,t.muted=!0,t.setAttribute(`playsinline`,``),t.style.cssText=`position:fixed;top:0;left:0;width:100vw;height:100vh;object-fit:cover;z-index:0;background:#000`,document.body.insertBefore(t,document.body.firstChild),await t.play(),D.cameraVideo=t,D.runtime.permissionState=`granted`;try{return ht(`fallback-three`,I(),{takeover:D.runtime.rendererOwner!==`xr8-threejs`,engine:`manual-camera`}),M(`manual-camera`,`running`),zt(I(),{mode:`manual-camera`,stereo:!1,source:D.cameraVideo||document.getElementById(`camerafeed`),frameBudgetMs:20}),Mt(),Ft(I()),T(`status-camera`,`live`),j(`camera`,!0),j(`tracking`,!0),ot(),w(`Basic camera mode is active. Surface placement uses estimated floor fallback.`),!0}catch(e){return D.runtime.permissionState=`failed`,D.runtime.degradationReason=e?.message||String(e),C(`Manual camera fallback setup failed: ${e?.message||String(e)}`,`Manual Camera Setup Failed`,{timeout:0}),Lm(),!1}}catch(e){return D.runtime.permissionState=e.name===`NotAllowedError`?`denied`:`failed`,D.runtime.degradationReason=e?.message||String(e),A(e.name===`NotAllowedError`?`permission-blocked`:`failed`,{error:D.runtime.degradationReason}),e.name===`NotAllowedError`?C(`Camera permission denied. Please allow camera access.`,`Camera Denied`,{timeout:0}):e.name===`NotFoundError`?C(`No camera found on this device.`,`Camera Missing`,{timeout:0}):C(`Camera error: ${e.message}`,`Camera Error`,{timeout:0}),!1}}function Pm(){if(D.runtime.lifecycleState===`stopped`)return!1;if(D.paused=!1,D.xrStarted)try{globalThis.XR8?.resume?.()}catch{w(`8th Wall resume was not available in this browser session.`,`Lifecycle`)}try{D.cameraVideo?.play?.()}catch{}return!D.xrStarted&&D.fallbackRenderer&&Mt(),document.body.dataset.jarvisPaused=`false`,fn(),A(D.started?`running`:`ready`,{reason:`resume`}),kt(`AR runtime resumed`),!0}function Fm(e=`manual`){if(D.paused=!0,D.xrStarted)try{globalThis.XR8?.pause?.()}catch{w(`8th Wall pause was not available in this browser session.`,`Lifecycle`)}try{D.cameraVideo?.pause?.()}catch{}return Nt(),document.body.dataset.jarvisPaused=`true`,A(`paused`,{reason:e}),kt(`AR runtime paused`),!0}async function Im(){Fm(`shutdown`),D._commandBootTimer&&(vt(D._commandBootTimer),D._commandBootTimer=null),jc(),Zl(),Nn(),hf(),Nt();try{await D.xrSession?.end?.()}catch{}try{let e=I()?.renderer;e?.xr&&await e.xr.setSession(null)}catch{}try{typeof globalThis.XR8?.clearCameraPipelineModules==`function`&&globalThis.XR8.clearCameraPipelineModules(),globalThis.XR8?.stop?.()}catch{}return Lm(),document.querySelectorAll(`#ui-layer .ar-panel, #ui-layer .panel-orb, #error-host > *, #banner-host > *`).forEach(e=>e.remove()),Vt(),pt(),um=null,kt(`AR runtime shut down`),!0}function Lm(){try{(D.cameraVideo?.srcObject)?.getTracks?.().forEach(e=>e.stop()),D.cameraVideo?.remove?.()}catch{}D.cameraVideo=null}function Rm(e={}){D.nativeOptions={...D.nativeOptions,...e&&typeof e==`object`?e:{}},document.body.dataset.jarvisNativeOptions=`applied`,D.nativeOptions.handTrackingEnabled===!1&&w(`Native options disabled hand tracking for this AR session.`,`APK Options`),(D.nativeOptions.thermalPause===!0||D.nativeOptions.thermalState===`critical`)&&(Fm(`thermal`),D.runtime.degradationReason=`thermal`,A(`thermal-paused`,{thermalState:D.nativeOptions.thermalState||`critical`}));for(let e of[`eyeTracking`,`nativeCompositor`,`truePersistentWorldAnchors`,`nativeOpenXRBridge`])Object.prototype.hasOwnProperty.call(D.nativeOptions,e)&&F(e,D.nativeOptions[e]);return Object.prototype.hasOwnProperty.call(D.nativeOptions,`truePersistentWorldAnchors`)&&F(`persistentAnchorSupport`,D.nativeOptions.truePersistentWorldAnchors),Ot(`setCompositorState`,JSON.stringify({mode:D.compositor.mode,native:D.compositor.native,passthroughBlend:D.compositor.passthroughBlend,frameBudgetMs:D.compositor.frameBudgetMs,browserManaged:!0})),k(`native-options`,D.nativeOptions),kt(`APK AR options applied`),D.nativeOptions}function zm(e={}){let t=e;try{t=typeof e==`string`?JSON.parse(e):e}catch(e){return C(e.message,`APK State Sync Failed`),!1}let n=Array.isArray(t)?t:Array.isArray(t?.objects)?t.objects:t?.ar_objects;return Array.isArray(n)&&(k(`native-ar-state`,{objects:n}),Ot(`status`,`Applied ${n.length} native AR object(s)`)),t?.ui&&typeof t.ui==`object`&&k(`native-ui-state`,t.ui),!0}function Bm(){let e=Qt();wt(e),D.runtime.browserProfile=e,F(`mediaPipeHands`,!!globalThis.Hands),F(`spatialAudio`,!!(globalThis.AudioContext||globalThis.webkitAudioContext)),F(`microphone`,!!navigator.mediaDevices?.getUserMedia),F(`speechSynthesis`,!!window.speechSynthesis),F(`voiceRecognition`,!!(globalThis.SpeechRecognition||globalThis.webkitSpeechRecognition)),F(`webXRAvailable`,!!navigator.xr),F(`webXRHitTest`,!1),F(`browserLatencyCeiling`,!0),F(`limitedSensorAccess`,!0),F(`limitedOSIntegration`,!0),F(`limitedCompositorControl`,!0),F(`persistentAnchorSupport`,!!$.truePersistentWorldAnchors),F(`backgroundExecutionLimited`,!0),F(`passthroughControlLimited`,!0),F(`spatialMemoryLimited`,!0),F(`headsetOptimizationAccessLimited`,!0),F(`webXRFragmented`,e.webXRFragmented),F(`safariWebXRLimitations`,e.limits.safariWebXRLimitations),F(`visionOSBrowserRestrictions`,e.limits.visionOSBrowserRestrictions),F(`androidBrowserInconsistency`,e.limits.androidBrowserInconsistency),F(`webViewInconsistency`,e.limits.webViewInconsistency),F(`questBrowserQuirks`,e.limits.questBrowserQuirks),F(`fullscreenEdgeCases`,e.limits.fullscreenEdgeCases),F(`orientationLockEdgeCases`,e.limits.orientationLockEdgeCases),F(`webglContextLossRisk`,e.limits.webglContextLossRisk),F(`renderLoopDuplicationRisk`,e.limits.renderLoopDuplicationRisk),F(`eyeTracking`,!!$.eyeTracking),F(`nativeCompositor`,!!$.nativeCompositor),F(`truePersistentWorldAnchors`,!!$.truePersistentWorldAnchors),F(`nativeOpenXRBridge`,!!$.nativeOpenXRBridge),F(`eyeTrackingProxy`,!0),F(`persistentSpatialMemory`,!0),F(`ultraStableAnchoring`,!0),F(`naturalWindowPlacement`,!0),F(`depthAwareImmersion`,!0),F(`environmentAwareUI`,!0),F(`headsetComfortSystems`,!0),F(`lowLatencyCompositing`,!0),document.body.dataset.jarvisCapabilityModel=`browser-web-ar-with-explicit-native-limits`,document.body.dataset.jarvisBrowserProfile=e.browser,document.body.dataset.jarvisBrowserPlatform=e.platform,document.body.dataset.jarvisBrowserLatency=String(e.latencyCeilingMs);let t=$t(e).filter(e=>/safari|visionos|android|webview|webxr-fragmented|quest/.test(e));Tt({architecture:`browser-web-ar-runtime`,experienceClass:`web-ar-experiment`,spatialRuntimeClass:e.isVisionOS?`browser-managed-visionos-shell`:e.isQuest?`quest-browser-ar-shell`:e.isSafari?`safari-webxr-shell`:e.isWebView?`embedded-webview-ar-shell`:`browser-web-ar-shell`,platformRole:e.isVisionOS?`visionos-browser`:e.isQuest?`quest-browser`:e.isAndroid?`android-browser`:e.isIOS?`ios-browser`:`desktop-browser`,spatialGapStatement:e.isVisionOS||e.isSafari||e.isWebView||e.isAndroid?`This runtime is browser-managed spatial AR, not a native headset OS, compositor, or persistent spatial shell.`:`This runtime is browser-managed spatial AR, not a unified native spatial computing runtime.`}),Et([`No single authoritative native spatial runtime exists in this codebase.`,`Browser-layer AR, XR8/WebXR, fallback cameras, and compatibility shells coexist behind one shared authority instead of a native OS compositor stack.`,`Persistent world understanding, headset compositor control, and headset-grade platform integration remain unavailable because the runtime is bounded by browser APIs and vendor binaries.`,`Lifecycle and rendering governance must therefore be centralized in the web runtime, not spread across competing engines.`].join(` `)),Dt(`Vision Pro-style browser shell implemented as far as the web stack allows: gaze proxy, hand-eye fusion, persistent spatial memory, stabilized anchoring, low-latency compositor hints, natural window placement, depth-aware immersion, environment-aware UI, and comfort systems are active; true native eye tracking, headset OS integration, and native compositor control remain outside the browser runtime.`,[`gaze proxy`,`hand-eye fusion`,`persistent spatial memory`,`ultra-stable anchoring`,`low-latency compositing proxy`,`natural window placement`,`depth-aware immersion`,`environment-aware UI`,`headset comfort systems`]),Ot(`setNativeCapabilities`,JSON.stringify({browserProfile:e,capabilities:D.capabilities,runtime:{architecture:D.runtime.architecture,spatialRuntimeClass:D.runtime.spatialRuntimeClass,platformRole:D.runtime.platformRole}})),Ot(`setGuardianState`,JSON.stringify({requested:!0,boundary:D.capabilities.guardianBoundary,platformRole:D.runtime.platformRole,source:`ar-init`})),Ot(`setOpenXRState`,JSON.stringify({supported:e.isQuest||e.isVisionOS,browserManaged:!0,platformRole:D.runtime.platformRole,compositor:D.compositor})),t.length&&(D.runtime.degradationReason=t.join(`, `),kt(`Browser limits: ${t.join(`, `)}`),e.limits.visionOSBrowserRestrictions?w(`visionOS browser support is browser-managed only. Native compositor, passthrough control, and persistent anchors stay unavailable here.`,`visionOS Browser Limits`):e.limits.safariWebXRLimitations?w(`Safari WebXR support is fragmented. Chrome Android remains the primary AR path for this runtime.`,`Safari WebXR Limits`):e.limits.webViewInconsistency?w(`Embedded WebViews can be stricter than Chrome Custom Tabs for XR, sensors, and camera permissions.`,`WebView Limits`):e.limits.questBrowserQuirks&&w(`Quest Browser fullscreen, orientation, and session behavior can be quirky; the runtime is applying extra guard rails.`,`Quest Browser Limits`))}function Vm(){fm||(fm=!0,document.addEventListener(`visibilitychange`,()=>{document.hidden?D.started&&Fm(`background-tab`):D.started&&D.runtime.lifecycleState===`paused`&&Pm()}),window.addEventListener(`pagehide`,()=>{D.started&&Fm(`pagehide`)}),window.addEventListener(`pageshow`,()=>{D.started&&D.runtime.lifecycleState===`paused`&&Pm()}))}function Hm(){let e=new $f($).connect();Op();try{globalThis.Jarvis={query:t=>e.query(t),runTask:(t,n)=>e.runTask(t,n),command:e=>qm(e)}}catch{D.jarvisGlobalBlocked=!0}O(`jarvis-command`,({text:e})=>qm(e))}function Um(){O(`VOICE_STATE`,e=>{D.spatialAudio.micPermission=e?.micPermission||D.spatialAudio.micPermission,D.spatialAudio.micReady=!!(e?.micReady||e?.enabled||e?.listening),D.spatialAudio.wakeWindowUntil=e?.wakeWindowUntil||0,D.spatialAudio.lastVoiceCommandAt=e?.lastCommandAt||D.spatialAudio.lastVoiceCommandAt,(e?.reason===`mic-error`||e?.reason===`blocked`)&&kt(`Voice mic ${e.error||e.micPermission||`blocked`}`)}),O(`open-jarvis`,Wm),O(`open-games`,Gm),O(`open-builder`,If),O(`scan-room`,()=>hp(`Scanning the room.`,{speak:!1}))}function Wm(){let e=document.createElement(`div`),t=document.createElement(`input`),n=document.createElement(`button`);t.placeholder=`Command JARVIS`,n.className=`btn-primary`,n.textContent=`Run`,n.onclick=()=>qm(t.value),t.addEventListener(`keydown`,e=>{e.key===`Enter`&&n.click()}),e.append(t,n),new bn({title:`JARVIS`,body:e,icon:`J`,width:360,height:260}).focus()}function Gm(){let e=document.createElement(`div`),t=Km(`Eternum AR`,vf),n=Km(`Ripples AR`,Cf),r=document.createElement(`input`),i=Km(`Convert Game URL`,()=>wf(r.value||`about:blank`,globalThis.Jarvis||D.jarvis));r.placeholder=`Game URL or name`,e.append(t,n,r,i),Pn(`AR Games`,e,`G`)}function Km(e,t){let n=document.createElement(`button`);return n.className=`panel-action`,n.textContent=e,n.onclick=t,n}async function qm(e){let t=String(e||``).trim();if(!t)return;let n=t.toLowerCase();sp(ep.THINKING);try{let e=n.match(/\b(open|close|toggle|rotate|spin|turn|reconfigure|rebuild|transform|rearrange|shatter|break|explode|reveal|show|hide|grab|move|drag)\b/);if(e&&/(model|door|window|screen|panel|roof|drawer|wheel|part|house|room|car|vehicle|device|custom)/.test(n)){let r=n.replace(/\b(hey\s+jarvis|jarvis)\b/gi,``).replace(/\b(open|close|toggle|rotate|spin|turn|reconfigure|rebuild|transform|rearrange|shatter|break|explode|reveal|show|hide|grab|move|drag|the|a|an|model|part|on|of|in|for|to)\b/gi,` `).replace(/\s+/g,` `).trim();k(`jarvis-model-action`,{action:e[1],target:r,command:t,source:`voice`}),hp(`Model action queued: ${e[1]}${r?` on ${r}`:``}.`,{speak:!0});return}if(/spawn|place|load|model/.test(n)){let e=n.replace(/\b(spawn|place|load|model|a|an|the|in ar)\b/g,` `).trim()||`Duck`;k(`spawn-model`,{query:e}),hp(`Model armed: ${e}. Tap a surface to place it.`,{speak:!0});return}if(/scan room|room scan|scan/.test(n)){k(`scan-room`);return}if(/reconstruct/.test(n)){let e=n.replace(`reconstruct`,``).replace(`this scene`,``).trim()||`room`;await Rd(e),hp(`Scene reconstruction complete: ${e}.`,{speak:!0});return}if(/vr mode|vr screen|headset/.test(n)){await Pl();return}if(/eternum/.test(n)){vf(),hp(`Eternum AR panel is open.`,{speak:!0});return}if(/ripples/.test(n)){Cf(),hp(`Ripples AR panel is open.`,{speak:!0});return}if(/convert .* ar|game to ar/.test(n)){await wf(t.replace(/convert|to ar|game to ar/gi,``).trim(),globalThis.Jarvis||D.jarvis);return}if(/open models|model picker/.test(n)){Do();return}if(/forge model|interactive model|3d forge|custom interactive model|build custom model|custom 3d builder/.test(n)){k(`open-model-forge`),hp(`Interactive model forge opened.`,{speak:!0});return}if(/camera kit|lens studio|snap/.test(n)){let e=document.createElement(`div`);e.style.cssText=`display:flex;flex-direction:column;gap:10px;padding:8px 0`;let t=document.createElement(`p`);t.style.cssText=`margin:0;font-size:13px;opacity:0.75;line-height:1.4`,t.textContent=`Lens Studio Camera Kit requires a Snap developer token. Enter yours below to activate the Camera Kit AR layer.`;let n=document.createElement(`label`);n.textContent=`Snap Developer Token`,n.style.cssText=`font-size:12px;font-weight:600;opacity:0.9`;let r=document.createElement(`input`);r.type=`text`,r.placeholder=`xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx`,r.style.cssText=`width:100%;box-sizing:border-box;padding:8px 10px;border-radius:6px;border:1px solid rgba(255,255,255,0.2);background:rgba(255,255,255,0.08);color:var(--text-primary);font-size:13px`,D.config.snapToken&&(r.value=D.config.snapToken);let i=document.createElement(`button`);i.className=`btn-primary`,i.textContent=`Activate Camera Kit`,i.onclick=()=>{let e=r.value.trim();if(!e){w(`Please enter a valid Snap developer token.`,`Camera Kit`);return}D.config.snapToken=e,k(`camera-kit-token-set`,{token:e}),w(`Camera Kit token saved. Reload the AR session to activate the Lens Studio layer.`,`Camera Kit`),o.close?.()};let a=document.createElement(`a`);a.href=`https://docs.snap.com/snap-kit/camera-kit/guides/tutorials/integration-guides/web#set-up-your-api-token`,a.target=`_blank`,a.rel=`noopener noreferrer`,a.textContent=`How to get a Snap developer token ↗`,a.style.cssText=`font-size:12px;color:rgba(255,255,255,0.55);text-decoration:underline`,e.append(t,n,r,i,a);let o=new bn({title:`Camera Kit`,body:e,icon:`CK`,width:360,height:300});o.focus();return}hp(await(globalThis.Jarvis||D.jarvis).query(t),{speak:!0})}catch(e){C(e.message,`JARVIS Command Failed`)}finally{ap()===ep.THINKING&&sp(ep.IDLE)}}export{zm as applyNativeState,Bt as i,Ht as n,Fm as pauseRuntime,Vt as r,Pm as resumeRuntime,Rm as setNativeOptions,Im as shutdownRuntime,Nm as startManualCameraFallback,zt as t};