three-live 0.0.1-alpha.0 → 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +58 -0
  3. package/dist/index.d.ts +224 -0
  4. package/dist/three-author-engine.js +297 -0
  5. package/dist/three-author.cjs +297 -0
  6. package/dist/three-author.d.ts +224 -0
  7. package/dist/three-author.js +297 -0
  8. package/dist/three-convert.cjs +291 -0
  9. package/dist/three-convert.d.ts +224 -0
  10. package/dist/three-convert.js +291 -0
  11. package/dist/three-live-animation.cjs +36 -0
  12. package/dist/three-live-animation.d.ts +224 -0
  13. package/dist/three-live-animation.js +36 -0
  14. package/dist/three-live-animation.min.js +36 -0
  15. package/dist/three-live-element.cjs +222 -0
  16. package/dist/three-live-element.d.ts +224 -0
  17. package/dist/three-live-element.js +222 -0
  18. package/dist/three-live-extras.cjs +42 -0
  19. package/dist/three-live-extras.d.ts +224 -0
  20. package/dist/three-live-extras.js +42 -0
  21. package/dist/three-live-extras.min.js +42 -0
  22. package/dist/three-live-full.cjs +341 -0
  23. package/dist/three-live-full.js +341 -0
  24. package/dist/three-live-full.min.js +341 -0
  25. package/dist/three-live-sandbox.html +157 -0
  26. package/dist/three-live-viewer.cjs +222 -0
  27. package/dist/three-live-viewer.d.ts +224 -0
  28. package/dist/three-live-viewer.js +222 -0
  29. package/dist/three-live-viewer.min.js +222 -0
  30. package/dist/three-live.cjs +299 -0
  31. package/dist/three-live.js +299 -0
  32. package/dist/three-live.min.js +299 -0
  33. package/dist/three-view.cjs +222 -0
  34. package/dist/three-view.d.ts +224 -0
  35. package/dist/three-view.js +222 -0
  36. package/dist/three-xr.cjs +291 -0
  37. package/dist/three-xr.d.ts +224 -0
  38. package/dist/three-xr.js +291 -0
  39. package/package.json +78 -6
  40. package/index.js +0 -1
@@ -0,0 +1,291 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2026 Google LLC
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+ "use strict";var Fe=Object.defineProperty;var ft=Object.getOwnPropertyDescriptor;var dt=Object.getOwnPropertyNames;var pt=Object.prototype.hasOwnProperty;var bt=(n,e)=>{for(var t in e)Fe(n,t,{get:e[t],enumerable:!0})},yt=(n,e,t,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of dt(e))!pt.call(n,r)&&r!==t&&Fe(n,r,{get:()=>e[r],enumerable:!(i=ft(e,r))||i.enumerable});return n};var gt=n=>yt(Fe({},"__esModule",{value:!0}),n);var Ut={};bt(Ut,{WebXRSessionManager:()=>Pe,activateAR:()=>_t,buildUSDZZip:()=>De,calculateCRC32:()=>Ve,createSceneViewerIntent:()=>ht,createUSDZBlob:()=>Xe,generateUSDA:()=>Ne,generateUSDZ:()=>Ge,getARCapabilities:()=>qe,getAvailableARModes:()=>Ft,getBestARMode:()=>Lt,glbToUSDZ:()=>Oe,isQuickLookSupported:()=>ze,isSceneViewerSupported:()=>We,isWebXRSupported:()=>$e,launchQuickLook:()=>He,launchSceneViewer:()=>mt});module.exports=gt(Ut);var Me="__THREE_LIVE_REGISTRY__";function de(){let n=typeof globalThis<"u"?globalThis:{};if(!n[Me]){let e={plugins:[],decoders:new Map};try{Object.defineProperty(n,Me,{value:e,writable:!1,configurable:!1,enumerable:!1})}catch{n[Me]=e}}return n[Me]}var K=de().plugins;function Ye(n){let e=de().plugins;e.some(t=>t.name===n.name)||e.push(n)}function Ke(){return de().plugins}function Z(){let n=new Float32Array(16);return n[0]=1,n[5]=1,n[10]=1,n[15]=1,n}function Te(n,e,t,i,r){let s=1/Math.tan(e/2);n.fill(0),n[0]=s/t,n[5]=s,n[11]=-1;let u=1/(i-r);return n[10]=(r+i)*u,n[14]=2*r*i*u,n}function we(n,e,t,i){let[r,s,u]=e,[l,c,o]=i,[a,f,d]=t,p=r-a,h=s-f,x=u-d,b=Math.hypot(p,h,x);b<=1e-5?(p=0,h=0,x=1):(p/=b,h/=b,x/=b);let S=c*x-o*h,P=o*p-l*x,E=l*h-c*p;b=Math.hypot(S,P,E),b<=1e-5?(S=0,P=0,E=0):(S/=b,P/=b,E/=b);let R=h*E-x*P,g=x*S-p*E,T=p*P-h*S;return b=Math.hypot(R,g,T),b<=1e-5?(R=0,g=0,T=0):(R/=b,g/=b,T/=b),n[0]=S,n[1]=R,n[2]=p,n[3]=0,n[4]=P,n[5]=g,n[6]=h,n[7]=0,n[8]=E,n[9]=T,n[10]=x,n[11]=0,n[12]=-(S*r+P*s+E*u),n[13]=-(R*r+g*s+T*u),n[14]=-(p*r+h*s+x*u),n[15]=1,n}function ue(n,e,t){let i=e[0],r=e[1],s=e[2],u=e[3],l=e[4],c=e[5],o=e[6],a=e[7],f=e[8],d=e[9],p=e[10],h=e[11],x=e[12],b=e[13],S=e[14],P=e[15],E=t[0],R=t[1],g=t[2],T=t[3];return n[0]=E*i+R*l+g*f+T*x,n[1]=E*r+R*c+g*d+T*b,n[2]=E*s+R*o+g*p+T*S,n[3]=E*u+R*a+g*h+T*P,E=t[4],R=t[5],g=t[6],T=t[7],n[4]=E*i+R*l+g*f+T*x,n[5]=E*r+R*c+g*d+T*b,n[6]=E*s+R*o+g*p+T*S,n[7]=E*u+R*a+g*h+T*P,E=t[8],R=t[9],g=t[10],T=t[11],n[8]=E*i+R*l+g*f+T*x,n[9]=E*r+R*c+g*d+T*b,n[10]=E*s+R*o+g*p+T*S,n[11]=E*u+R*a+g*h+T*P,E=t[12],R=t[13],g=t[14],T=t[15],n[12]=E*i+R*l+g*f+T*x,n[13]=E*r+R*c+g*d+T*b,n[14]=E*s+R*o+g*p+T*S,n[15]=E*u+R*a+g*h+T*P,n}function Ze(n,e,t,i){let r=e[0],s=e[1],u=e[2],l=e[3],c=r+r,o=s+s,a=u+u,f=r*c,d=r*o,p=r*a,h=s*o,x=s*a,b=u*a,S=l*c,P=l*o,E=l*a,R=i[0],g=i[1],T=i[2];return n[0]=(1-(h+b))*R,n[1]=(d+E)*R,n[2]=(p-P)*R,n[3]=0,n[4]=(d-E)*g,n[5]=(1-(f+b))*g,n[6]=(x+S)*g,n[7]=0,n[8]=(p+P)*T,n[9]=(x-S)*T,n[10]=(1-(f+h))*T,n[11]=0,n[12]=t[0],n[13]=t[1],n[14]=t[2],n[15]=1,n}function he(n,e){let t=e[0],i=e[1],r=e[2],s=e[4],u=e[5],l=e[6],c=e[8],o=e[9],a=e[10],f=a*u-l*o,d=-a*s+l*c,p=o*s-u*c,h=t*f+i*d+r*p;return h&&(h=1/h,n[0]=f*h,n[1]=(-a*i+r*o)*h,n[2]=(l*i-r*u)*h,n[3]=d*h,n[4]=(a*t-r*c)*h,n[5]=(-l*t+r*s)*h,n[6]=p*h,n[7]=(-o*t+i*c)*h,n[8]=(u*t-i*s)*h),n}function je(n,e){let t=e[0],i=e[1],r=e[2],s=e[3],u=e[4],l=e[5],c=e[6],o=e[7],a=e[8],f=e[9],d=e[10],p=e[11],h=e[12],x=e[13],b=e[14],S=e[15],P=t*l-i*u,E=t*c-r*u,R=t*o-s*u,g=i*c-r*l,T=i*o-s*l,m=r*o-s*c,v=a*x-f*h,y=a*b-d*h,w=a*S-p*h,C=f*b-d*x,I=f*S-p*x,A=d*S-p*b,F=P*A-E*I+R*C+g*w-T*y+m*v;return F?(F=1/F,n[0]=(l*A-c*I+o*C)*F,n[1]=(r*I-i*A-s*C)*F,n[2]=(x*m-b*T+S*g)*F,n[3]=(d*T-f*m-p*g)*F,n[4]=(c*w-u*A-o*y)*F,n[5]=(t*A-r*w+s*y)*F,n[6]=(b*R-h*m-S*E)*F,n[7]=(a*m-d*R+p*E)*F,n[8]=(u*I-l*w+o*v)*F,n[9]=(i*w-t*I-s*v)*F,n[10]=(h*T-x*R+S*P)*F,n[11]=(f*R-a*T-p*P)*F,n[12]=(l*y-u*C-c*v)*F,n[13]=(t*C-i*y+r*v)*F,n[14]=(x*E-h*g-b*P)*F,n[15]=(a*g-f*E+d*P)*F,n):null}function Le(n,e,t,i,r){let s=r[0]*e+r[4]*t+r[8]*i+r[12],u=r[1]*e+r[5]*t+r[9]*i+r[13],l=r[2]*e+r[6]*t+r[10]*i+r[14],c=r[3]*e+r[7]*t+r[11]*i+r[15],o=c!==0?1/c:1;n[0]=s*o,n[1]=u*o,n[2]=l*o}function Qe(n,e,t,i,r,s,u,l,c,o,a,f,d,p,h,x,b=0){let S=o-u,P=a-l,E=f-c,R=d-u,g=p-l,T=h-c,m=r*T-s*g,v=s*R-i*T,y=i*g-r*R,w=S*m+P*v+E*y;if(w>-1e-7&&w<1e-7)return!1;let C=1/w,I=n-u,A=e-l,F=t-c,_=C*(I*m+A*v+F*y);if(_<-b||_>1+b)return!1;let D=A*E-F*P,W=F*S-I*E,H=I*P-A*S,j=C*(i*D+r*W+s*H);if(j<-b||_+j>1+b)return!1;let O=C*(R*D+g*W+T*H);if(O>1e-4&&O<x.distance){x.distance=O,x.point=[n+i*O,e+r*O,t+s*O];let q=P*T-E*g,X=E*R-S*T,N=S*g-P*R,$=Math.hypot(q,X,N)||1;return x.normal=[q/$,X/$,N/$],!0}return!1}function Re(n,e){let t=Array.isArray(n?.nodes)?n.nodes.length:0,i=[];for(let a=0;a<t;a++)i.push(Z());if(t===0)return i;let r=new Set;for(let a of n.nodes)if(Array.isArray(a.children))for(let f of a.children)r.add(f);let s=new Set,u=128,l=(a,f,d=0)=>{if(d>u||a<0||a>=t||s.has(a))return;s.add(a);let p=n.nodes[a];if(!p)return;let h=Z();if(e&&e[a])h.set(e[a]);else if(p.matrix&&p.matrix.length===16)h.set(p.matrix);else{let b=p.translation||[0,0,0],S=p.rotation||[0,0,0,1],P=p.scale||[1,1,1];Ze(h,S,b,P)}let x=i[a];if(f?ue(x,f,h):x.set(h),Array.isArray(p.children))for(let b of p.children)typeof b=="number"&&l(b,x,d+1)},c=[],o=n.scenes&&n.scenes[n.scene!==void 0?n.scene:0];if(o&&Array.isArray(o.nodes))c.push(...o.nodes);else for(let a=0;a<t;a++)r.has(a)||c.push(a);for(let a of c)l(a,null);for(let a=0;a<t;a++)!r.has(a)&&!c.includes(a)&&l(a,null);return i}function vt(n){return new TextDecoder().decode(n)}var tt=de().decoders;function xt(n,e){tt.set(n.toLowerCase(),e)}function ye(n){return tt.get(n.toLowerCase())}function nt(n){let e=ArrayBuffer.isView(n)?n.buffer.slice(n.byteOffset,n.byteOffset+n.byteLength):n,t=new DataView(e);if(e.byteLength<12)throw new Error(`Invalid GLB buffer size: ${e.byteLength} bytes`);let i=t.getUint32(0,!0);if(i!==1179937895){let d=t.getUint8(0);throw d===123||d===32||d===10||d===13?new Error("[three-live] Multi-file JSON .gltf is not supported for performance reasons. Please pack your asset into a single binary .glb file."):new Error(`Invalid GLB magic: 0x${i.toString(16)}`)}let r=t.getUint32(4,!0);if(r!==2)throw new Error(`Unsupported GLB version: ${r}`);let s=t.getUint32(8,!0),u=12,l=null,c=null;for(;u+8<=s&&u+8<=e.byteLength;){let d=t.getUint32(u,!0),p=t.getUint32(u+4,!0),h=u+8;if(h+d>e.byteLength)throw new Error(`Truncated GLB chunk: required ${h+d} bytes, buffer has ${e.byteLength}`);if(p===1313821514){let x=new Uint8Array(e,h,d),b=vt(x);l=JSON.parse(b,(S,P)=>S==="__proto__"||S==="constructor"||S==="prototype"?void 0:P)}else p===5130562&&(c=e.slice(h,h+d));u=h+d}if(!l)throw new Error("Missing JSON chunk in GLB");let o=l.extensionsRequired||[];if(o.includes("KHR_draco_mesh_compression")&&!ye("draco"))throw new Error("Model requires KHR_draco_mesh_compression. Register a decoder via ThreeLiveElement.registerDecoder('draco', decoder).");if(o.includes("EXT_meshopt_compression")&&!ye("meshopt"))throw new Error("Model requires EXT_meshopt_compression. Register a decoder via ThreeLiveElement.registerDecoder('meshopt', decoder).");if(o.includes("KHR_texture_basisu")&&!ye("ktx2"))throw new Error("Model requires KHR_texture_basisu. Register a decoder via ThreeLiveElement.registerDecoder('ktx2', decoder).");let a=c||new ArrayBuffer(0),f={gltf:l,bin:a,animations:[]};for(let d of K)d.onParseGLB?.(f);return f}function Mt(n){return typeof n=="object"&&n!==null&&"gltf"in n&&typeof n.gltf=="object"&&n.gltf!==null&&"bin"in n&&(n.bin instanceof ArrayBuffer||ArrayBuffer.isView(n.bin))}function ge(n){if(Mt(n))return n;if(n instanceof ArrayBuffer||ArrayBuffer.isView(n))return nt(n);throw new TypeError("Invalid 3D model input: expected GLBData ({ gltf, bin }) or binary GLB (ArrayBuffer / ArrayBufferView).")}var it=`#version 300 es
18
+ layout(location=0) in vec3 aPosition;
19
+ layout(location=1) in vec3 aNormal;
20
+ layout(location=2) in vec2 aUV;
21
+ uniform mat4 uMVP,uModel;
22
+ uniform mat3 uNormalMatrix;
23
+ uniform vec4 uUvTransform;
24
+ out vec3 vNormal,vWorldPos;
25
+ out vec2 vUV;
26
+ void main(){
27
+ vec3 rawN=uNormalMatrix*aNormal;
28
+ vNormal=length(rawN)>1e-5?normalize(rawN):vec3(0.0);
29
+ vec4 world=uModel*vec4(aPosition,1.0);
30
+ vWorldPos=world.xyz;
31
+ vec2 scaleUV=uUvTransform.zw;
32
+ if(scaleUV.x==0.0&&scaleUV.y==0.0)scaleUV=vec2(1.0);
33
+ vUV=aUV*scaleUV+uUvTransform.xy;
34
+ gl_Position=uMVP*vec4(aPosition,1.0);
35
+ }`,rt=`#version 300 es
36
+ precision highp float;
37
+ in vec3 vNormal,vWorldPos;
38
+ in vec2 vUV;
39
+ uniform vec4 uBaseColor;
40
+ uniform float uMetallic,uRoughness,uEmissive,uEnvIntensity;
41
+ uniform vec2 uClearcoat;
42
+ uniform vec3 uCameraPos,uAmbientColor;
43
+ uniform sampler2D uBaseColorTexture,uMetallicRoughnessTexture,uNormalTexture,uOcclusionTexture,uEnvironmentMap,uXrDepthTex;
44
+ uniform int uHasTexture,uHasMetallicRoughnessTexture,uHasNormalTexture,uHasOcclusionTexture,uHasEnvironmentMap,uXrDepthEnabled,uXrDepthFormat;
45
+ uniform float uNormalScale,uOcclusionStrength,uXrRawValueToMeters;
46
+ uniform mat4 uXrDepthUVTransform;
47
+ uniform vec2 uViewportSize;
48
+ uniform vec4 uViewport;
49
+ uniform vec3 uCameraFwd;
50
+ uniform int uToneMapping,uNumDirLights,uNumPointLights;
51
+ uniform vec3 uDirLightDir[2],uDirLightColor[2],uPointLightPos[2],uPointLightColor[2];
52
+ out vec4 fragColor;
53
+
54
+ vec2 envBRDF(float r,float n){
55
+ vec4 c0=vec4(-1.0,-0.0275,-0.572,0.022),c1=vec4(1.0,0.0425,1.04,-0.04);
56
+ vec4 rv=r*c0+c1;
57
+ float a=min(rv.x*rv.x,exp2(-9.28*n))*rv.x+rv.y;
58
+ return vec2(-1.04,1.04)*a+rv.zw;
59
+ }
60
+
61
+ vec3 F_SchlickRoughness(vec3 F0,float r,float n){
62
+ return F0+(max(vec3(1.0-r),F0)-F0)*pow(clamp(1.0-n,0.0,1.0),5.0);
63
+ }
64
+
65
+ vec3 getStudioRadiance(vec3 R,float r){
66
+ vec3 kd=normalize(vec3(0.0,1.0,0.35));
67
+ float ki=pow(max(dot(R,kd),0.0),mix(96.0,1.5,r))*mix(2.4,0.5,r);
68
+ vec3 fd=normalize(vec3(-0.85,0.45,-0.35));
69
+ float fi=pow(max(dot(R,fd),0.0),mix(36.0,1.2,r))*mix(1.3,0.35,r);
70
+ float ri=pow(clamp(1.0-abs(R.y),0.0,1.0),3.5)*mix(0.55,0.22,r);
71
+ vec3 ag=mix(vec3(0.06,0.06,0.08),vec3(0.48,0.50,0.55),R.y*0.5+0.5);
72
+ return ag+vec3(1.0,0.98,0.94)*ki+vec3(0.85,0.92,1.0)*fi+vec3(0.65,0.72,0.85)*ri;
73
+ }
74
+
75
+ vec3 perturbNormal(vec3 N,vec3 V,vec2 uv,sampler2D normalMap,float scale){
76
+ vec3 mapNormal=texture(normalMap,uv).xyz*2.0-1.0;
77
+ mapNormal.xy*=scale;
78
+ vec3 dp1=dFdx(vWorldPos);
79
+ vec3 dp2=dFdy(vWorldPos);
80
+ vec2 duv1=dFdx(uv);
81
+ vec2 duv2=dFdy(uv);
82
+ vec3 dp2perp=cross(dp2,N);
83
+ vec3 dp1perp=cross(N,dp1);
84
+ vec3 T=dp2perp*duv1.x+dp1perp*duv2.x;
85
+ vec3 B=dp2perp*duv1.y+dp1perp*duv2.y;
86
+ float invmax=inversesqrt(max(dot(T,T),dot(B,B)));
87
+ return normalize(mat3(T*invmax,B*invmax,N)*normalize(mapNormal));
88
+ }
89
+
90
+ vec2 equirectangularUV(vec3 dir){
91
+ vec3 d=normalize(dir);
92
+ float u=atan(d.z,d.x)*0.15915494309+0.5;
93
+ float v=asin(clamp(d.y,-1.0,1.0))*0.31830988618+0.5;
94
+ return vec2(u,1.0-v);
95
+ }
96
+
97
+ vec3 neutralToneMapping(vec3 color){
98
+ const float startCompression=0.76;
99
+ const float desaturation=0.15;
100
+ float x=min(color.r,min(color.g,color.b));
101
+ float offset=x<0.08?x-6.25*x*x:0.04;
102
+ color-=offset;
103
+ float peak=max(color.r,max(color.g,color.b));
104
+ if(peak<startCompression)return color;
105
+ const float d=1.0-startCompression;
106
+ float newPeak=1.0-d*d/(peak+d-startCompression);
107
+ color*=newPeak/peak;
108
+ float g=1.0-1.0/(desaturation*(peak-newPeak)+1.0);
109
+ return mix(color,newPeak*vec3(1.0),g);
110
+ }
111
+
112
+ vec3 applyToneMapping(vec3 color,int mode){
113
+ if(mode==0)return neutralToneMapping(color);
114
+ if(mode==1)return color/(color+vec3(1.0));
115
+ return color;
116
+ }
117
+
118
+ void main(){
119
+ vec4 base=uBaseColor;
120
+ if(uHasTexture==1)base*=texture(uBaseColorTexture,vUV);
121
+ if(length(vNormal)<1e-4&&uHasTexture==1){
122
+ vec3 unlit=base.rgb+vec3(uEmissive*0.35,uEmissive*0.5,uEmissive*0.7);
123
+ fragColor=vec4(unlit,base.a);
124
+ return;
125
+ }
126
+ vec3 N=length(vNormal)<1e-4?normalize(cross(dFdx(vWorldPos),dFdy(vWorldPos))):normalize(vNormal);
127
+ if(!gl_FrontFacing)N=-N;
128
+ vec3 V=normalize(uCameraPos-vWorldPos);
129
+ if(uHasNormalTexture==1){
130
+ N=perturbNormal(N,V,vUV,uNormalTexture,uNormalScale);
131
+ }
132
+
133
+ float metallic=uMetallic;
134
+ float roughness=uRoughness;
135
+ if(uHasMetallicRoughnessTexture==1){
136
+ vec4 mr=texture(uMetallicRoughnessTexture,vUV);
137
+ roughness*=mr.g;
138
+ metallic*=mr.b;
139
+ }
140
+ roughness=clamp(roughness,0.04,1.0);
141
+ metallic=clamp(metallic,0.0,1.0);
142
+
143
+ float occ=1.0;
144
+ if(uHasOcclusionTexture==1){
145
+ occ=mix(1.0,texture(uOcclusionTexture,vUV).r,uOcclusionStrength);
146
+ }
147
+
148
+ float gloss=1.0-roughness;
149
+ float specExp=mix(16.0,256.0,gloss*gloss);
150
+ float specWeight=mix(0.22*gloss,1.0,metallic);
151
+ vec3 directLight=vec3(0.0);
152
+ for(int i=0;i<2;i++){
153
+ if(i>=uNumDirLights)break;
154
+ vec3 L=normalize(uDirLightDir[i]);
155
+ float NdotL=max(dot(N,L),0.0);
156
+ vec3 H=normalize(L+V);
157
+ float NoH=max(dot(N,H),0.0);
158
+ float spec=pow(NoH,specExp)*specWeight+uClearcoat.x*pow(NoH,mix(64.0,512.0,1.0-uClearcoat.y))*0.35;
159
+ directLight+=(base.rgb*NdotL*0.75+vec3(spec))*uDirLightColor[i];
160
+ }
161
+ for(int i=0;i<2;i++){
162
+ if(i>=uNumPointLights)break;
163
+ vec3 toLight=uPointLightPos[i]-vWorldPos;
164
+ float dist=length(toLight);
165
+ vec3 L=toLight/max(dist,0.0001);
166
+ float atten=1.0/(1.0+0.09*dist+0.032*dist*dist);
167
+ float NdotL=max(dot(N,L),0.0);
168
+ vec3 H=normalize(L+V);
169
+ float NoH=max(dot(N,H),0.0);
170
+ float spec=pow(NoH,specExp)*specWeight+uClearcoat.x*pow(NoH,mix(64.0,512.0,1.0-uClearcoat.y))*0.35;
171
+ directLight+=(base.rgb*NdotL*0.75+vec3(spec))*uPointLightColor[i]*atten;
172
+ }
173
+
174
+ vec3 R=reflect(-V,N);
175
+ float NoV=clamp(dot(N,V),0.001,1.0);
176
+ vec3 F0=mix(vec3(0.04),base.rgb,metallic);
177
+ vec3 F=F_SchlickRoughness(F0,roughness,NoV);
178
+ vec2 brdf=envBRDF(roughness,NoV);
179
+
180
+ vec3 specularIBL;
181
+ vec3 envDiffuse;
182
+ if(uHasEnvironmentMap==1){
183
+ specularIBL=texture(uEnvironmentMap,equirectangularUV(R)).rgb*(F*brdf.x+brdf.y);
184
+ envDiffuse=texture(uEnvironmentMap,equirectangularUV(N)).rgb;
185
+ }else{
186
+ specularIBL=getStudioRadiance(R,roughness)*(F*brdf.x+brdf.y);
187
+ envDiffuse=mix(vec3(0.10,0.10,0.12),vec3(0.52,0.54,0.58),N.y*0.5+0.5);
188
+ }
189
+
190
+ vec3 kD=(vec3(1.0)-F)*(1.0-metallic);
191
+ vec3 diffuseIBL=kD*base.rgb*(uAmbientColor+envDiffuse*0.5)*occ;
192
+ vec3 color=directLight+(diffuseIBL+specularIBL)*uEnvIntensity+vec3(uEmissive*0.35,uEmissive*0.5,uEmissive*0.7);
193
+ if(uClearcoat.x>0.0){
194
+ vec3 ccF=F_SchlickRoughness(vec3(0.04),uClearcoat.y,NoV)*uClearcoat.x;
195
+ color=color*(vec3(1.0)-ccF)+getStudioRadiance(R,uClearcoat.y)*ccF*uEnvIntensity;
196
+ }
197
+ color=applyToneMapping(color,uToneMapping);
198
+ float outAlpha=base.a;
199
+ if(uXrDepthEnabled==1){
200
+ vec2 normViewUV=vec2((gl_FragCoord.x-uViewport.x)/max(uViewport.z,1.0),1.0-(gl_FragCoord.y-uViewport.y)/max(uViewport.w,1.0));
201
+ vec2 depthUV=(uXrDepthUVTransform*vec4(normViewUV,0.0,1.0)).xy;
202
+ if(depthUV.x>=0.0&&depthUV.x<=1.0&&depthUV.y>=0.0&&depthUV.y<=1.0){
203
+ vec4 depthSample=texture(uXrDepthTex,depthUV);
204
+ float rawDepth=uXrDepthFormat==1?depthSample.r:(depthSample.r*255.0+depthSample.a*65280.0);
205
+ float realDepth=rawDepth*uXrRawValueToMeters;
206
+ float virtDepth=dot(uCameraFwd,uCameraFwd)>0.5?dot(vWorldPos-uCameraPos,uCameraFwd):length(uCameraPos-vWorldPos);
207
+ if(rawDepth>0.0&&(uXrDepthFormat==1||rawDepth<65500.0)&&realDepth>0.15&&realDepth<20.0&&virtDepth>realDepth+0.02){
208
+ float occAlpha=1.0-smoothstep(0.0,0.035,virtDepth-realDepth-0.02);
209
+ outAlpha*=occAlpha;
210
+ if(outAlpha<0.01)discard;
211
+ }
212
+ }
213
+ }
214
+ fragColor=vec4(color,outAlpha);
215
+ }`,Tt=`#version 300 es
216
+ layout(location=0) in vec3 aPosition;
217
+ uniform mat4 uMVP;
218
+ void main(){gl_Position=uMVP*vec4(aPosition,1.0);}`,wt=`#version 300 es
219
+ precision highp float;
220
+ uniform vec4 uColorId;
221
+ out vec4 fragColor;
222
+ void main(){fragColor=uColorId;}`;function Je(n,e,t){let i=n.createShader(e);if(n.shaderSource(i,t),n.compileShader(i),!n.getShaderParameter(i,35713)){let r=n.getShaderInfoLog(i);throw n.deleteShader(i),new Error(`Shader compile error: ${r}`)}return i}function Ie(n,e,t){let i=Je(n,35633,e),r=Je(n,35632,t),s=n.createProgram();if(n.attachShader(s,i),n.attachShader(s,r),n.linkProgram(s),!n.getProgramParameter(s,35714)){let u=n.getProgramInfoLog(s);throw n.deleteProgram(s),new Error(`Program link error: ${u}`)}return s}function _e(n,e,t){let i={};for(let r of t)i[r]=n.getUniformLocation(e,r);return i}var st=["uMVP","uModel","uNormalMatrix","uUvTransform","uBaseColor","uMetallic","uRoughness","uClearcoat","uEmissive","uCameraPos","uBaseColorTexture","uHasTexture","uMetallicRoughnessTexture","uHasMetallicRoughnessTexture","uNormalTexture","uHasNormalTexture","uNormalScale","uOcclusionTexture","uHasOcclusionTexture","uOcclusionStrength","uToneMapping","uEnvironmentMap","uHasEnvironmentMap","uAmbientColor","uNumDirLights","uDirLightDir","uDirLightColor","uNumPointLights","uPointLightPos","uPointLightColor","uEnvIntensity","uXrDepthTex","uXrDepthEnabled","uXrDepthFormat","uXrRawValueToMeters","uXrDepthUVTransform","uViewportSize","uViewport","uCameraFwd"];function Rt(n){if(typeof n!="string")return null;let e=n.trim();if(!e||/[\x00-\x1f\x7f]/.test(e))return null;let t=e.toLowerCase();return t.startsWith("data:")?/^data:image\/(png|jpeg|jpg|webp|ktx2|avif)(;|,)/i.test(e)?e:null:t.startsWith("https://")||t.startsWith("blob:")?e:t.startsWith("//")||/^[a-z][a-z0-9+.-]*:/i.test(e)||/(^|[\\/])\.\.([\\/]|$)/.test(e)?null:e}function Ce(n,e,t,i,r,s,u){if(i===void 0||!e.accessors?.[i])return null;let l=e.accessors[i],c=e.bufferViews[l.bufferView],o=(c.byteOffset||0)+(l.byteOffset||0),a=c.byteStride&&c.byteStride>s*4?c.byteStride>>2:s,f;if(a===s)f=new Float32Array(t,o,l.count*s);else{f=new Float32Array(l.count*s);let p=new Float32Array(t,c.byteOffset||0,Math.floor(c.byteLength/4)),h=(l.byteOffset||0)>>2;for(let x=0;x<l.count;x++){let b=h+x*a;for(let S=0;S<s;S++)f[x*s+S]=p[b+S]}}let d=n.createBuffer();return u.push(d),n.bindBuffer(34962,d),n.bufferData(34962,f,35044),n.enableVertexAttribArray(r),n.vertexAttribPointer(r,s,5126,!1,0,0),f}var Gt=Object.freeze({maxMeshes:1e3,maxTextures:64,maxVertices:1e6,maxIndices:3e6}),at=Object.freeze({maxMeshes:1/0,maxTextures:1/0,maxVertices:1/0,maxIndices:1/0});function et(n,e,t=at,i){if(!e||!e.gltf)throw new Error("Invalid GLBData passed to buildGpuScene: missing gltf object.");let{gltf:r,bin:s}=e,u=[],l=Re(r),c=[];if(Array.isArray(r.nodes))for(let v=0;v<r.nodes.length;v++){let y=r.nodes[v];y.mesh!==void 0&&r.meshes&&r.meshes[y.mesh]&&c.push({node:y,nodeIdx:v,meshIdx:y.mesh})}let o=c.length>0?c:(r.meshes||[]).map((v,y)=>({node:v,nodeIdx:-1,meshIdx:y})),a=[];if(Array.isArray(e.lights)&&e.lights.length>0)a.push(...e.lights);else if(r.extensions?.KHR_lights_punctual?.lights){let v=r.extensions.KHR_lights_punctual.lights;for(let y of v){let w=y.type==="directional"?"directional":y.type==="point"?"point":"ambient";a.push({type:w,color:y.color||[1,1,1],intensity:y.intensity!==void 0?y.intensity:1})}}if(a.length===0&&(a.push({type:"ambient",color:[1,1,1],intensity:.35}),a.push({type:"directional",color:[1,1,1],intensity:.85,direction:[.5,1,.8]})),o.length>t.maxMeshes)throw new Error(`SecurityError: GLB scene exceeds host mesh limit (${t.maxMeshes}). Found: ${o.length}`);let f=[];if(r.textures&&r.images){if(r.textures.length>t.maxTextures)throw new Error(`SecurityError: GLB scene exceeds host texture limit (${t.maxTextures}). Found: ${r.textures.length}`);for(let v=0;v<r.textures.length;v++){let y=r.textures[v],w=r.images[y.source];if(w){let C=n.createTexture();if(n.bindTexture(3553,C),n.texImage2D(3553,0,6408,1,1,0,6408,5121,new Uint8Array([255,255,255,255])),n.texParameteri(3553,10242,10497),n.texParameteri(3553,10243,10497),n.texParameteri(3553,10241,9729),n.texParameteri(3553,10240,9729),w.bufferView!==void 0){let I=r.bufferViews[w.bufferView],A=s.slice(I.byteOffset||0,(I.byteOffset||0)+I.byteLength),F=new Blob([A],{type:w.mimeType||"image/png"});typeof createImageBitmap=="function"&&createImageBitmap(F).then(_=>{n.bindTexture(3553,C),n.texImage2D(3553,0,6408,6408,5121,_),n.generateMipmap(3553),i?.()}).catch(()=>{})}else if(w.uri){let I=Rt(w.uri);if(I){let A=new Image;A.crossOrigin="anonymous",A.referrerPolicy="no-referrer",A.onload=()=>{n.bindTexture(3553,C),n.texImage2D(3553,0,6408,6408,5121,A),n.generateMipmap(3553),i?.()},A.src=I}else console.warn("[Three-Live Security] Blocked unsafe glTF image URI:",w.uri)}f.push(C)}else f.push(null)}}let d=[1/0,1/0,1/0],p=[-1/0,-1/0,-1/0],h=0,x=0;for(let v=0;v<o.length;v++){let y=o[v],w=r.meshes[y.meshIdx],C=y.nodeIdx>=0?l[y.nodeIdx]:Z(),I=new Float32Array(9);he(I,C);let A={name:y.node.name||w.name||`Mesh_${y.meshIdx}`,nodeIndex:y.nodeIdx,transform:C,normalMatrix:I,primitives:[],extras:y.node.extras||w.extras};for(let F of w.primitives||[]){if(F.extensions?.KHR_draco_mesh_compression){let G=ye("draco");G&&G.decodePrimitive(r,F,s)}let _=[],D=n.createVertexArray();n.bindVertexArray(D);let W=r.accessors[F.attributes.POSITION],H=Number(W?.count??0);if(!Number.isFinite(H)||H<0||h+H>t.maxVertices)throw new Error(`SecurityError: GLB scene exceeds host vertex limit (${t.maxVertices}).`);if(h+=H,W?.min&&W?.max)for(let G=0;G<3;G++){let se=C[12+G],be=C[12+G];for(let fe=0;fe<3;fe++){let ve=C[fe*4+G]*W.min[fe],xe=C[fe*4+G]*W.max[fe];se+=ve<xe?ve:xe,be+=ve>xe?ve:xe}se<d[G]&&(d[G]=se),be>p[G]&&(p[G]=be)}let j=Ce(n,r,s,F.attributes.POSITION,0,3,_);Ce(n,r,s,F.attributes.NORMAL,1,3,_),Ce(n,r,s,F.attributes.TEXCOORD_0,2,2,_);let O=0,q=5123,X=null;if(F.indices!==void 0){let G=r.accessors[F.indices],be=(r.bufferViews[G.bufferView].byteOffset||0)+(G.byteOffset||0);if(O=Number(G.count??0),!Number.isFinite(O)||O<0||x+O>t.maxIndices)throw new Error(`SecurityError: GLB scene exceeds host index limit (${t.maxIndices}).`);x+=O,q=G.componentType===5125?5125||5125:5123||5123;let fe=n.createBuffer();_.push(fe),n.bindBuffer(34963,fe),G.componentType===5125?(X=new Uint32Array(s,be,G.count),n.bufferData(34963,X,35044)):(X=new Uint16Array(s,be,G.count),n.bufferData(34963,X,35044))}else O=W.count;let N={};for(let G of K)if(G.onBuildPrimitiveVAO){let se=G.onBuildPrimitiveVAO(n,D,F,r,s);se&&(N[G.name]=se)}n.bindVertexArray(null);let $=r.materials&&F.material!==void 0?r.materials[F.material]:null,M=it,L=rt,B=!1;for(let G of K)if(G.onResolveShader){let se=G.onResolveShader(F,$,M,L);se&&(M=se.vs,L=se.fs,B=!0)}let k=B?Ie(n,M,L):null,ie=k?_e(n,k,st):null,Y=$?.pbrMetallicRoughness,Q=Y?.baseColorFactor||[.8,.8,.8,1],re=Y?.metallicFactor??.1,te=Y?.roughnessFactor??.5,U=$?.extensions?.KHR_materials_clearcoat,z=U?U.clearcoatFactor??1:0,oe=Math.max(.04,U?.clearcoatRoughnessFactor??.04),ne=Y?.baseColorTexture!==void 0&&f[Y.baseColorTexture.index]?f[Y.baseColorTexture.index]:null,J=Y?.metallicRoughnessTexture!==void 0&&f[Y.metallicRoughnessTexture.index]?f[Y.metallicRoughnessTexture.index]:null,ee=$?.normalTexture!==void 0&&f[$.normalTexture.index]?f[$.normalTexture.index]:null,me=$?.normalTexture?.scale??1,ae=$?.occlusionTexture!==void 0&&f[$.occlusionTexture.index]?f[$.occlusionTexture.index]:null,ce=$?.occlusionTexture?.strength??1,le=!!($?.extensions?.KHR_materials_transmission||N.materials?.isTransmissive);A.primitives.push({vao:D,indexCount:O,indexType:q,baseColor:Q,metallic:re,roughness:te,clearcoat:z,clearcoatRoughness:oe,positions:j,indices:X,texture:ne,metallicRoughnessTexture:J,normalTexture:ee,occlusionTexture:ae,normalScale:me,occlusionStrength:ce,buffers:_,materialIndex:F.material,pluginData:N,customProgram:k,customUniforms:ie,isTransmissive:le})}u.push(A)}isFinite(d[0])||(d=[-1,-1,-1]),isFinite(p[0])||(p=[1,1,1]);let b=[(d[0]+p[0])/2,(d[1]+p[1])/2,(d[2]+p[2])/2],S=p[0]-d[0],P=p[1]-d[1],E=p[2]-d[2],R=Math.max(Math.hypot(S,P,E)/2,.5),g=[d[0],d[1],d[2]],T=[p[0],p[1],p[2]],m=e.animations;if(!m){for(let v of K)if(v.onParseGLB?.(e),e.animations){m=e.animations;break}}return m||(m=[]),{meshes:u,bounds:{center:b,radius:R,min:g,max:T},lights:a,animations:m,worldMatrices:l}}var Ae=class{constructor(e,t,i){this.meshes=[];this.backdropMeshes=[];this.bounds={center:[0,0,0],radius:1,min:[-1,-1,-1],max:[1,1,1]};this.lights=[];this.modelRootMatrix=Z();this.clearColor=[0,0,0,0];this.envIntensity=1;this.shadowIntensity=0;this.shadowSoftness=.5;this.toneMapping="neutral";this.environmentTexture=null;this.animations=[];this.currentClip=null;this.animationTime=0;this.isPlayingAnimation=!1;this.autoplay=!1;this.animationName="";this.gltf=null;this.worldMatrices=[];this.initialNodeTransforms=[];this.projMatrix=Z();this.viewMatrix=Z();this.modelMatrix=Z();this.mvpMatrix=Z();this.normalMatrix=new Float32Array(9);this.initialTheta=.6;this.initialPhi=.35;this.initialDistance=null;this.customDistance=!1;this.distanceMode="auto";this.initialCustomTarget=null;this.customTarget=null;this.fov=Math.PI/4;this.minTheta=-1/0;this.maxTheta=1/0;this.minPhi=-Math.PI*.48;this.maxPhi=Math.PI*.48;this.minDistanceLimit=null;this.maxDistanceLimit=null;this.activePointers=new Map;this.isPanning=!1;this.targetTheta=.6;this.currTheta=.6;this.targetPhi=.35;this.currPhi=.35;this.targetDistance=3;this.currDistance=3;this.autoRotate=!1;this.autoRotateSpeed=Math.PI/6;this.autoRotateDelay=3e3;this.lastInteractionTime=-1/0;this.turntableRotation=0;this.isPointerDown=!1;this.interactive=!0;this.skyboxTexture=null;this.lastPointerX=0;this.lastPointerY=0;this.totalDragDist=0;this.selectedMeshName="";this.pickFbo=null;this.pickTexture=null;this.pickDepth=null;this.pickFboWidth=0;this.pickFboHeight=0;this.animFrameId=null;this.isVisible=!0;this.xrSessionActive=!1;this.lastTime=0;this.lastReportedTheta=-999;this.lastReportedPhi=-999;this.lastReportedZoom=-999;this.boundPointerDown=null;this.boundPointerMove=null;this.boundPointerUp=null;this.boundWheel=null;this.boundKeyDown=null;this.boundContextMenu=null;this.boundSetCamera=null;this.boundResetCamera=null;this.stereoSBS=!1;this.renderErrorReported=!1;this.xrDepthState={enabled:!1,texture:null,uvTransform:Z(),rawValueToMeters:.001,format:0};this.container=e;let r,s;if(t&&typeof t.getContext=="function"?(r=t,s=i):(s=t,r=s?.canvas),!r){let c=e.querySelector("canvas");c||(c=document.createElement("canvas"),c.style.width="100%",c.style.height="100%",c.style.display="block",c.style.touchAction="none",e.prepend(c)),r=c}this.canvas=r,this.opts=s||{},this.opts.clearColor&&(this.clearColor=this.opts.clearColor);let u=typeof window<"u"&&typeof window.matchMedia=="function"&&window.matchMedia("(prefers-reduced-motion: reduce)").matches;this.opts.autoRotate!==void 0?this.autoRotate=this.opts.autoRotate&&!u:u&&(this.autoRotate=!1),this.opts.autoRotateSpeed!==void 0&&(this.autoRotateSpeed=this.opts.autoRotateSpeed),this.opts.autoRotateDelay!==void 0&&(this.autoRotateDelay=Math.max(0,Number(this.opts.autoRotateDelay)||0)),this.opts.exposure!==void 0&&(this.envIntensity=Math.max(0,Number(this.opts.exposure))),this.opts.camera&&this.setInitialCamera(this.opts.camera.theta,this.opts.camera.phi,this.opts.camera.distance,this.opts.camera.zoom),this.opts.shadowIntensity!==void 0&&(this.shadowIntensity=Math.max(0,Math.min(1,Number(this.opts.shadowIntensity)||0))),this.opts.shadowSoftness!==void 0&&(this.shadowSoftness=Math.max(0,Math.min(1,Number(this.opts.shadowSoftness)||0))),this.opts.toneMapping!==void 0&&(this.toneMapping=this.opts.toneMapping),this.opts.autoplay!==void 0&&(this.autoplay=this.opts.autoplay),this.opts.animationName!==void 0&&(this.animationName=this.opts.animationName),this.opts.fieldOfView!==void 0&&(this.fov=this.opts.fieldOfView*Math.PI/180),this.opts.distanceMode!==void 0&&(this.distanceMode=this.opts.distanceMode),this.opts.cameraTarget!==void 0&&(this.setTarget(this.opts.cameraTarget[0],this.opts.cameraTarget[1],this.opts.cameraTarget[2]),this.initialCustomTarget=[...this.opts.cameraTarget]),(this.opts.minCameraOrbit||this.opts.maxCameraOrbit)&&this.setOrbitLimits({minTheta:this.opts.minCameraOrbit?.theta,maxTheta:this.opts.maxCameraOrbit?.theta,minPhi:this.opts.minCameraOrbit?.phi,maxPhi:this.opts.maxCameraOrbit?.phi,minDistance:this.opts.minCameraOrbit?.distance,maxDistance:this.opts.maxCameraOrbit?.distance});let l=r.getContext("webgl2",{antialias:!0,alpha:!0,xrCompatible:!0});if(!l)throw new Error("WebGL2 not supported");this.gl=l,this.renderProg=Ie(l,it,rt),this.pickProg=Ie(l,Tt,wt),this.uRender=_e(l,this.renderProg,st),this.uPick=_e(l,this.pickProg,["uMVP","uColorId"]),this.setupPickingFbo(),this.setupEvents(),this.opts.environmentImage&&this.setEnvironmentImage(this.opts.environmentImage).catch(()=>{}),typeof requestAnimationFrame<"u"&&this.opts.autoStart!==!1&&this.start()}static registerDecoder(e,t){xt(e,t)}static getDecoder(e){return ye(e)}setupPickingFbo(){let e=this.gl;if(typeof e.createFramebuffer!="function")return;this.pickFbo=e.createFramebuffer(),this.pickTexture=e.createTexture(),this.pickDepth=e.createRenderbuffer();let t=Math.max(1,this.canvas.width),i=Math.max(1,this.canvas.height);this.pickFboWidth=t,this.pickFboHeight=i,e.bindTexture(3553,this.pickTexture),e.texImage2D(3553,0,6408,t,i,0,6408,5121,null),e.texParameteri(3553,10241,9728),e.texParameteri(3553,10240,9728),e.bindRenderbuffer(36161,this.pickDepth),e.renderbufferStorage(36161,33189,t,i),e.bindFramebuffer(36160,this.pickFbo),e.framebufferTexture2D(36160,36064,3553,this.pickTexture,0),e.framebufferRenderbuffer(36160,36096,36161,this.pickDepth),e.bindFramebuffer(36160,null)}resizePickingFbo(e,t){if(!this.pickFbo)return;let i=this.gl,r=Math.max(1,e),s=Math.max(1,t);this.pickFboWidth=r,this.pickFboHeight=s,i.bindTexture(3553,this.pickTexture),i.texImage2D(3553,0,6408,r,s,0,6408,5121,null),i.bindRenderbuffer(36161,this.pickDepth),i.renderbufferStorage(36161,33189,r,s)}loadGLBData(e,t){let{meshes:i,bounds:r,lights:s,animations:u,worldMatrices:l}=et(this.gl,e,t,()=>this.render());if(this.disposeMeshGpuResources(),this.meshes=i,this.bounds=r,this.turntableRotation=0,this.updateTurntableMatrix(),this.lights=s,this.animations=u||[],this.worldMatrices=l||[],this.gltf=e.gltf,this.initialNodeTransforms=[],Array.isArray(e.gltf?.nodes))for(let o of e.gltf.nodes)this.initialNodeTransforms.push({t:o.translation?[o.translation[0],o.translation[1],o.translation[2]]:[0,0,0],r:o.rotation?[o.rotation[0],o.rotation[1],o.rotation[2],o.rotation[3]]:[0,0,0,1],s:o.scale?[o.scale[0],o.scale[1],o.scale[2]]:[1,1,1]});this.autoplay&&this.animations.length>0&&this.playAnimation(this.animationName||void 0);for(let o of K)o.onLoadModel?.(this,this.gltf);this.customDistance||(this.initialDistance=this.distanceMode==="absolute"?3:r.radius*2.5,this.targetDistance=this.initialDistance,this.currDistance=this.initialDistance);let c=e.exposure??e.environmentIntensity??e.gltf?.extras?.exposure??e.gltf?.extras?.environmentIntensity??e.gltf?.asset?.extras?.exposure??e.gltf?.asset?.extras?.environmentIntensity;c!==void 0&&(this.envIntensity=Math.max(0,Number(c))),this.container&&typeof this.container.hasAttribute=="function"&&this.container.hasAttribute("poster")&&this.container.removeAttribute("poster"),this.resize(),this.update(0),this.render(),this.animFrameId===null&&typeof requestAnimationFrame<"u"&&this.opts.autoStart!==!1&&this.start()}loadGLB(e){this.loadGLBData(nt(e))}clearScene(){this.disposeMeshGpuResources(),this.lights=[],this.animations=[],this.currentClip=null,this.isPlayingAnimation=!1,this.worldMatrices=[],this.gltf=null,this.initialNodeTransforms=[],this.turntableRotation=0,this.updateTurntableMatrix(),this.gl&&this.render()}loadModel(e){this.loadGLBData(ge(e))}setBackdropGLB(e,t){if(this.disposeMeshListGpuResources(this.backdropMeshes),this.backdropMeshes=[],!e){this.update(0),this.render();return}let i=ge(e),{meshes:r}=et(this.gl,i,at,()=>this.render());if(t)for(let s of r)s.transform[12]+=t[0],s.transform[13]+=t[1],s.transform[14]+=t[2],he(s.normalMatrix,s.transform);this.backdropMeshes=r,this.update(0),this.render()}setClearColor(e,t,i,r=1){this.clearColor=[e,t,i,r]}updateMeshTransforms(e){for(let t=0;t<this.meshes.length;t++){let i=this.meshes[t],r;e instanceof Map?r=e.get(i.name)??e.get(t):Array.isArray(e)?r=e[t]:e&&typeof e=="object"&&(Object.prototype.hasOwnProperty.call(e,i.name)?r=e[i.name]:Object.prototype.hasOwnProperty.call(e,t)&&(r=e[t])),r&&r.length===16&&(i.transform.set(r),he(i.normalMatrix,i.transform))}}bindLights(e=this.uRender){let t=this.gl,i=[.28,.28,.28],r=[],s=[],u=[],l=[];for(let c of this.lights){let o=c.color||[1,1,1],a=c.intensity!==void 0?c.intensity:1;if(c.type==="ambient")i=[o[0]*a,o[1]*a,o[2]*a];else if(c.type==="directional"&&r.length<6){let f=c.direction||[.5,1,.8];r.push(f[0],f[1],f[2]),s.push(o[0]*a,o[1]*a,o[2]*a)}else if(c.type==="point"&&u.length<6){let f=c.position||[0,0,0];u.push(f[0],f[1],f[2]),l.push(o[0]*a,o[1]*a,o[2]*a)}}r.length===0&&(r.push(.5,1,.8),s.push(1,1,1)),t.uniform3fv(e.uAmbientColor,i),t.uniform1i(e.uNumDirLights,r.length/3),r.length>0&&(t.uniform3fv(e.uDirLightDir,r),t.uniform3fv(e.uDirLightColor,s)),t.uniform1i(e.uNumPointLights,u.length/3),u.length>0&&(t.uniform3fv(e.uPointLightPos,u),t.uniform3fv(e.uPointLightColor,l)),t.uniform1f(e.uEnvIntensity,this.envIntensity)}setExposure(e){this.envIntensity=Math.max(0,Number(e))}getExposure(){return this.envIntensity}setShadow(e,t){this.shadowIntensity=Math.max(0,Math.min(1,Number(e)||0)),t!==void 0&&(this.shadowSoftness=Math.max(0,Math.min(1,Number(t)||0)))}getShadowIntensity(){return this.shadowIntensity}getShadowSoftness(){return this.shadowSoftness}setToneMapping(e){this.toneMapping=e}getToneMapping(){return this.toneMapping}async setEnvironmentImage(e){for(let t of K)if(t.setEnvironmentImage){await t.setEnvironmentImage(this,e);return}}async setSkyboxImage(e){for(let t of K)if(t.setSkyboxImage){await t.setSkyboxImage(this,e);return}}setInteractive(e){this.interactive=e}isInteractive(){return this.interactive}getCameraOrbit(){let e=this.currTheta,t=this.currPhi,i=this.currDistance;return{theta:e,phi:t,radius:i,toString(){return`${e.toFixed(4)}rad ${t.toFixed(4)}rad ${i.toFixed(4)}m`}}}getCameraTarget(){let e=this.customTarget||this.bounds.center;return{x:e[0],y:e[1],z:e[2],toString(){return`${e[0].toFixed(4)}m ${e[1].toFixed(4)}m ${e[2].toFixed(4)}m`}}}jumpCameraToGoal(){this.currTheta=this.targetTheta,this.currPhi=this.targetPhi,this.currDistance=this.targetDistance,this.update(0),this.render()}getModelMaterials(){let e=this.gltf?.materials?.length?this.gltf.materials:[{name:"DefaultMaterial",pbrMetallicRoughness:{}}];return e.map((t,i)=>{let r=this.meshes.flatMap(a=>a.primitives.filter(f=>f.materialIndex===i||e.length===1&&f.materialIndex===void 0)),s=r[0],u=s?[...s.baseColor]:t.pbrMetallicRoughness?.baseColorFactor||[.8,.8,.8,1],l=s?s.metallic:t.pbrMetallicRoughness?.metallicFactor??.1,c=s?s.roughness:t.pbrMetallicRoughness?.roughnessFactor??.5,o={baseColorFactor:u,metallicFactor:l,roughnessFactor:c,setBaseColorFactor:a=>{let f=[a[0],a[1],a[2],a[3]??1];o.baseColorFactor=f,t.pbrMetallicRoughness&&(t.pbrMetallicRoughness.baseColorFactor=f);for(let d of r)d.baseColor=f;this.render()},setMetallicFactor:a=>{o.metallicFactor=a,t.pbrMetallicRoughness&&(t.pbrMetallicRoughness.metallicFactor=a);for(let f of r)f.metallic=a;this.render()},setRoughnessFactor:a=>{o.roughnessFactor=a,t.pbrMetallicRoughness&&(t.pbrMetallicRoughness.roughnessFactor=a);for(let f of r)f.roughness=a;this.render()}};return{name:t.name||`Material_${i}`,pbrMetallicRoughness:o}})}playAnimation(e){if(this.animations.length!==0){if(e){let t=this.animations.find(i=>i.name===e);t&&(this.currentClip=t)}else this.currentClip||(this.currentClip=this.animations[0]);this.isPlayingAnimation=!0}}pauseAnimation(){this.isPlayingAnimation=!1}getAvailableAnimations(){return this.animations.map(e=>e.name)}setAutoplay(e){this.autoplay=e,e?this.playAnimation(this.animationName||void 0):this.pauseAnimation()}setAnimationName(e){this.animationName=e,(this.isPlayingAnimation||this.autoplay)&&this.playAnimation(e)}evaluateAnimation(e){for(let t of K)if(t.evaluateAnimation){t.evaluateAnimation(this,e);return}}setTarget(e,t,i){this.customTarget=[e,t,i],this.gl&&(this.meshes.length>0||this.backdropMeshes.length>0)&&(this.update(0),this.render())}getTarget(){return this.customTarget?[...this.customTarget]:null}setFieldOfView(e){let t=Math.max(10,Math.min(90,e));this.fov=t*Math.PI/180}getFieldOfView(){return this.fov*180/Math.PI}setDistanceMode(e){if(this.distanceMode=e,!this.customDistance){let t=this.clampDistance(this.distanceMode==="absolute"?3:this.bounds.radius*2.5);this.initialDistance=t,this.targetDistance=t,this.currDistance=t,this.gl&&(this.meshes.length>0||this.backdropMeshes.length>0)&&(this.update(0),this.render())}}getDistanceMode(){return this.distanceMode}setOrbitLimits(e){e.minTheta!==void 0&&(this.minTheta=e.minTheta*Math.PI/180),e.maxTheta!==void 0&&(this.maxTheta=e.maxTheta*Math.PI/180),e.minPhi!==void 0&&(this.minPhi=Math.max(-Math.PI*.48,e.minPhi*Math.PI/180)),e.maxPhi!==void 0&&(this.maxPhi=Math.min(Math.PI*.48,e.maxPhi*Math.PI/180)),e.minDistance!==void 0&&(this.minDistanceLimit=e.minDistance),e.maxDistance!==void 0&&(this.maxDistanceLimit=e.maxDistance),this.targetTheta=this.clampTheta(this.targetTheta),this.targetPhi=this.clampPhi(this.targetPhi),this.targetDistance=this.clampDistance(this.targetDistance)}getOrbitLimits(){return{minTheta:isFinite(this.minTheta)?this.minTheta*180/Math.PI:void 0,maxTheta:isFinite(this.maxTheta)?this.maxTheta*180/Math.PI:void 0,minPhi:this.minPhi*180/Math.PI,maxPhi:this.maxPhi*180/Math.PI,minDistance:this.minDistanceLimit!==null?this.minDistanceLimit:void 0,maxDistance:this.maxDistanceLimit!==null?this.maxDistanceLimit:void 0}}clampTheta(e){return Math.max(this.minTheta,Math.min(this.maxTheta,e))}clampPhi(e){return Math.max(this.minPhi,Math.min(this.maxPhi,e))}clampDistance(e){let t=this.minDistanceLimit!==null?this.minDistanceLimit:this.bounds?this.bounds.radius*.5:.1,i=this.maxDistanceLimit!==null?this.maxDistanceLimit:this.bounds?this.bounds.radius*8:100;return Math.max(t,Math.min(i,e))}setCamera(e,t,i,r){e!==void 0&&(this.targetTheta=this.clampTheta(e*Math.PI/180)),t!==void 0&&(this.targetPhi=this.clampPhi(t*Math.PI/180)),i!==void 0&&i>0&&(this.targetDistance=this.clampDistance(i)),r!==void 0&&r>0&&(this.targetDistance=this.clampDistance(this.bounds.radius*2.5/r))}setInitialCamera(e,t,i,r){if(e!==void 0&&(this.initialTheta=this.clampTheta(e*Math.PI/180),this.targetTheta=this.initialTheta,this.currTheta=this.initialTheta),t!==void 0&&(this.initialPhi=this.clampPhi(t*Math.PI/180),this.targetPhi=this.initialPhi,this.currPhi=this.initialPhi),i!==void 0&&i>0){let s=this.clampDistance(i);this.initialDistance=s,this.customDistance=!0,this.targetDistance=s,this.currDistance=s}else if(r!==void 0&&r>0){let s=this.clampDistance(this.bounds.radius*2.5/r);this.initialDistance=s,this.customDistance=!0,this.targetDistance=s,this.currDistance=s}else{this.customDistance=!1;let s=this.clampDistance(this.distanceMode==="absolute"?3:this.bounds.radius*2.5);this.initialDistance=s,this.targetDistance=s,this.currDistance=s}this.gl&&(this.meshes.length>0||this.backdropMeshes.length>0)&&(this.update(0),this.render())}resetCamera(){this.targetTheta=this.clampTheta(this.initialTheta),this.targetPhi=this.clampPhi(this.initialPhi),this.initialDistance!==null?this.targetDistance=this.clampDistance(this.initialDistance):this.targetDistance=this.clampDistance(this.bounds.radius*2.5),this.initialCustomTarget?this.customTarget=[...this.initialCustomTarget]:this.customTarget=null,this.turntableRotation=0,this.updateTurntableMatrix()}projectPointToScreen(e,t){let i=Z();ue(i,this.projMatrix,this.viewMatrix);let[r,s,u]=e,l=t?t[0]:0,c=t?t[1]:0,o=t?t[2]:0,a=this.modelRootMatrix;a&&(r=a[0]*e[0]+a[4]*e[1]+a[8]*e[2]+a[12],s=a[1]*e[0]+a[5]*e[1]+a[9]*e[2]+a[13],u=a[2]*e[0]+a[6]*e[1]+a[10]*e[2]+a[14],t&&(l=a[0]*t[0]+a[4]*t[1]+a[8]*t[2],c=a[1]*t[0]+a[5]*t[1]+a[9]*t[2],o=a[2]*t[0]+a[6]*t[1]+a[10]*t[2]));let f=i[0]*r+i[4]*s+i[8]*u+i[12],d=i[1]*r+i[5]*s+i[9]*u+i[13],p=i[2]*r+i[6]*s+i[10]*u+i[14],h=i[3]*r+i[7]*s+i[11]*u+i[15];if(h<=1e-4)return{x:0,y:0,z:1,visible:!1};let x=f/h,b=d/h,S=p/h,P=this.canvas.getBoundingClientRect(),E=P.width||this.canvas.clientWidth||this.canvas.width||300,R=P.height||this.canvas.clientHeight||this.canvas.height||150,g=(x*.5+.5)*E,T=(-b*.5+.5)*R,m=x>=-1.1&&x<=1.1&&b>=-1.1&&b<=1.1&&S>=-1&&S<=1;if(m&&t){let v=this.customTarget||this.bounds.center,y=v[0]+this.currDistance*Math.cos(this.currPhi)*Math.sin(this.currTheta),w=v[1]+this.currDistance*Math.sin(this.currPhi),C=v[2]+this.currDistance*Math.cos(this.currPhi)*Math.cos(this.currTheta),I=[r-y,s-w,u-C];l*I[0]+c*I[1]+o*I[2]>.05&&(m=!1)}return{x:g,y:T,z:S,visible:m}}setSelectedMesh(e){this.selectedMeshName=e||""}setupEvents(){let e=this.canvas;this.boundContextMenu=t=>{t.preventDefault()},e.addEventListener("contextmenu",this.boundContextMenu),this.boundPointerDown=t=>{this.interactive&&(this.isPointerDown=!0,this.lastInteractionTime=typeof performance<"u"?performance.now():Date.now(),this.lastPointerX=t.clientX,this.lastPointerY=t.clientY,this.totalDragDist=0,this.activePointers.set(t.pointerId,{x:t.clientX,y:t.clientY}),this.isPanning=t.button===2||t.shiftKey||this.activePointers.size===2,e.setPointerCapture(t.pointerId))},e.addEventListener("pointerdown",this.boundPointerDown),this.boundPointerMove=t=>{if(!this.isPointerDown||!this.interactive)return;this.lastInteractionTime=typeof performance<"u"?performance.now():Date.now();let i=this.activePointers.get(t.pointerId)||{x:this.lastPointerX,y:this.lastPointerY},r=t.clientX-i.x,s=t.clientY-i.y;if(this.activePointers.set(t.pointerId,{x:t.clientX,y:t.clientY}),this.lastPointerX=t.clientX,this.lastPointerY=t.clientY,this.totalDragDist+=Math.hypot(r,s),this.isPanning||t.button===2||t.shiftKey||this.activePointers.size===2){let u=[this.viewMatrix[0],this.viewMatrix[4],this.viewMatrix[8]],l=[this.viewMatrix[1],this.viewMatrix[5],this.viewMatrix[9]],c=this.customTarget?[...this.customTarget]:[...this.bounds.center],o=this.currDistance/Math.max(e.clientHeight||300,1)*1.5;c[0]+=(-r*u[0]+s*l[0])*o,c[1]+=(-r*u[1]+s*l[1])*o,c[2]+=(-r*u[2]+s*l[2])*o,this.customTarget=c}else this.targetTheta=this.clampTheta(this.targetTheta-r*.008),this.targetPhi=this.clampPhi(this.targetPhi+s*.008)},e.addEventListener("pointermove",this.boundPointerMove),this.boundPointerUp=t=>{this.lastInteractionTime=typeof performance<"u"?performance.now():Date.now(),this.activePointers.delete(t.pointerId),this.activePointers.size===0?(this.isPointerDown=!1,this.isPanning=!1):this.activePointers.size===1&&(this.isPanning=!1);try{e.releasePointerCapture(t.pointerId)}catch{}if(this.totalDragDist<5&&t.button===0){let i=e.getBoundingClientRect(),r=Math.floor((t.clientX-i.left)*(e.width/Math.max(i.width,1))),s=Math.floor((t.clientY-i.top)*(e.height/Math.max(i.height,1)));this.performMeshPick(r,s,!0)}},e.addEventListener("pointerup",this.boundPointerUp),this.boundWheel=t=>{if(!this.interactive)return;t.preventDefault(),this.lastInteractionTime=typeof performance<"u"?performance.now():Date.now();let i=Math.exp(t.deltaY*.001);this.targetDistance=this.clampDistance(this.targetDistance*i)},e.addEventListener("wheel",this.boundWheel,{passive:!1}),this.boundSetCamera=t=>{let i=t.detail||{};i.reset?this.resetCamera():this.setCamera(i.theta,i.phi,i.distance,i.zoom)},this.container.addEventListener("setCamera",this.boundSetCamera),this.boundResetCamera=()=>{this.resetCamera()},this.container.addEventListener("resetCamera",this.boundResetCamera),e.tabIndex!==void 0&&e.tabIndex<0&&(e.tabIndex=0),e.getAttribute?.("role")||e.setAttribute?.("role","region"),e.getAttribute?.("aria-label")||e.setAttribute?.("aria-label","Interactive 3D model viewport"),this.boundKeyDown=t=>{if(!this.interactive)return;let i=typeof performance<"u"?performance.now():Date.now();switch(t.key){case"ArrowLeft":this.lastInteractionTime=i,this.targetTheta=this.clampTheta(this.targetTheta-.1),t.preventDefault();break;case"ArrowRight":this.lastInteractionTime=i,this.targetTheta=this.clampTheta(this.targetTheta+.1),t.preventDefault();break;case"ArrowUp":this.lastInteractionTime=i,this.targetPhi=this.clampPhi(this.targetPhi+.08),t.preventDefault();break;case"ArrowDown":this.lastInteractionTime=i,this.targetPhi=this.clampPhi(this.targetPhi-.08),t.preventDefault();break;case"+":case"=":{this.lastInteractionTime=i,this.targetDistance=this.clampDistance(this.targetDistance*.9),t.preventDefault();break}case"-":case"_":{this.lastInteractionTime=i,this.targetDistance=this.clampDistance(this.targetDistance*1.1),t.preventDefault();break}case"Home":this.lastInteractionTime=i,this.resetCamera(),t.preventDefault();break}},e.addEventListener("keydown",this.boundKeyDown)}teardownEvents(){let e=this.canvas;this.boundContextMenu&&(e.removeEventListener("contextmenu",this.boundContextMenu),this.boundContextMenu=null),this.boundPointerDown&&(e.removeEventListener("pointerdown",this.boundPointerDown),this.boundPointerDown=null),this.boundPointerMove&&(e.removeEventListener("pointermove",this.boundPointerMove),this.boundPointerMove=null),this.boundPointerUp&&(e.removeEventListener("pointerup",this.boundPointerUp),this.boundPointerUp=null),this.boundWheel&&(e.removeEventListener("wheel",this.boundWheel),this.boundWheel=null),this.boundKeyDown&&(e.removeEventListener("keydown",this.boundKeyDown),this.boundKeyDown=null),this.boundSetCamera&&(this.container.removeEventListener("setCamera",this.boundSetCamera),this.boundSetCamera=null),this.boundResetCamera&&(this.container.removeEventListener("resetCamera",this.boundResetCamera),this.boundResetCamera=null)}raycastFromScreenPoint(e,t){let i=this.canvas,r=i.getBoundingClientRect(),s=i.width||300,u=i.height||300,l=r.width>0?Math.floor((e-r.left)*(s/r.width)):Math.floor(e),c=r.height>0?Math.floor((t-r.top)*(u/r.height)):Math.floor(t);return this.performMeshPick(l,c,!1)}performMeshPick(e,t,i=!0){if(this.meshes.length===0)return null;let r=this.gl,s=Math.max(1,this.canvas.width||300),u=Math.max(1,this.canvas.height||300);e=this.mapStereoPickX(e,s);let l=Z();ue(l,this.projMatrix,this.viewMatrix);let c=[],o=Math.max(0,Math.min(s-1,e)),a=Math.max(0,Math.min(u-1,u-1-t));if(this.pickFbo&&r&&!this.xrSessionActive){(this.pickFboWidth!==s||this.pickFboHeight!==u)&&this.resizePickingFbo(s,u),r.bindFramebuffer(36160,this.pickFbo),r.viewport(0,0,s,u),r.enable(2929),r.clearColor(0,0,0,0),r.clear(16384|256),r.useProgram(this.pickProg);for(let m=0;m<this.meshes.length;m++){let v=this.meshes[m];if(v.visible===!1||v.isPluginMesh)continue;let y=m+1,w=(y&255)/255,C=(y>>8&255)/255,I=(y>>16&255)/255;r.uniform4f(this.uPick.uColorId,w,C,I,1),ue(this.modelMatrix,this.modelRootMatrix,v.transform),ue(this.mvpMatrix,l,this.modelMatrix),r.uniformMatrix4fv(this.uPick.uMVP,!1,this.mvpMatrix);for(let A of v.primitives)r.bindVertexArray(A.vao),r.drawElements(4,A.indexCount,A.indexType,0)}let g=new Uint8Array(4);r.readPixels(o,a,1,1,6408,5121,g),r.bindFramebuffer(36160,null);let T=g[0]+(g[1]<<8)+(g[2]<<16);T>0&&T<=this.meshes.length&&(c=[this.meshes[T-1]])}c.length===0&&(c=this.meshes.filter(g=>g.visible!==!1));let f=null,d=1/0,p=[0,0,0],h=[0,1,0],x=this.customTarget||this.bounds.center,b=x[0]+this.currDistance*Math.cos(this.currPhi)*Math.sin(this.currTheta),S=x[1]+this.currDistance*Math.sin(this.currPhi),P=x[2]+this.currDistance*Math.cos(this.currPhi)*Math.cos(this.currTheta);for(let g of c){ue(this.modelMatrix,this.modelRootMatrix,g.transform),ue(this.mvpMatrix,l,this.modelMatrix);let T=Z();if(!je(T,this.mvpMatrix))continue;let m=(o+.5)/s*2-1,v=(a+.5)/u*2-1,y=[0,0,0],w=[0,0,0];Le(y,m,v,-1,T),Le(w,m,v,1,T);let C=w[0]-y[0],I=w[1]-y[1],A=w[2]-y[2],F=Math.hypot(C,I,A)||1,_=C/F,D=I/F,W=A/F,H={distance:1/0,point:[0,0,0],normal:[0,1,0]};if((O=>{for(let q of g.primitives){if(!q.positions)continue;let X=q.positions,N=q.indices,$=Math.floor(N?N.length/3:X.length/9);for(let M=0;M<$;M++){let L=N?N[M*3]:M*3,B=N?N[M*3+1]:M*3+1,k=N?N[M*3+2]:M*3+2;Qe(y[0],y[1],y[2],_,D,W,X[L*3],X[L*3+1],X[L*3+2],X[B*3],X[B*3+1],X[B*3+2],X[k*3],X[k*3+1],X[k*3+2],H,O)}}})(1e-4),isFinite(H.distance)){let O=H.point[0],q=H.point[1],X=H.point[2],N=this.modelMatrix,$=N[0]*O+N[4]*q+N[8]*X+N[12],M=N[1]*O+N[5]*q+N[9]*X+N[13],L=N[2]*O+N[6]*q+N[10]*X+N[14],B=$-b,k=M-S,ie=L-P,Y=Math.hypot(B,k,ie);if(Y<d){he(this.normalMatrix,this.modelMatrix);let Q=this.normalMatrix,re=H.normal[0],te=H.normal[1],U=H.normal[2],z=Q[0]*re+Q[3]*te+Q[6]*U,oe=Q[1]*re+Q[4]*te+Q[7]*U,ne=Q[2]*re+Q[5]*te+Q[8]*U,J=Math.hypot(z,oe,ne)||1;z/=J,oe/=J,ne/=J,z*B+oe*k+ne*ie>0&&(z=-z,oe=-oe,ne=-ne),f=g,d=Math.round(Y*1e3)/1e3,p=[Math.round($*1e3)/1e3,Math.round(M*1e3)/1e3,Math.round(L*1e3)/1e3],h=[Math.round(z*1e3)/1e3,Math.round(oe*1e3)/1e3,Math.round(ne*1e3)/1e3]}}}if(!f)return null;let R={meshIndex:this.meshes.indexOf(f),meshName:f.name,nodeIndex:f.nodeIndex,distance:d,hitPoint:p,normal:h,screenX:e,screenY:t};if(i){for(let g of K)g.onMeshSelect?.(this,R);this.opts.onMeshClick&&this.opts.onMeshClick(R),typeof CustomEvent<"u"&&typeof this.container.dispatchEvent=="function"&&this.container.dispatchEvent(new CustomEvent("meshClick",{bubbles:!0,detail:R}))}return R}mapStereoPickX(e,t){if(!this.stereoSBS||this.xrSessionActive||t<2)return e;let i=Math.max(1,Math.floor(t*.5)),r=e>=i,s=r?e-i:e,u=r?Math.max(1,t-i):i,l=(s+.5)/u*2-1;return Math.floor((l*.5+1)*.5*t)}setStereoSBS(e){this.stereoSBS=!!e,this.xrSessionActive||(this.syncCameraMatrices(),this.render())}syncCameraMatrices(){let e=Math.max(1,this.canvas.width||1)/Math.max(1,this.canvas.height||1),t=this.backdropMeshes.length>0?Math.max(this.bounds.radius*20,120):Math.max(this.bounds.radius*20,10);Te(this.projMatrix,this.fov,e,.1,t);let i=this.customTarget||this.bounds.center,r=i[0]+this.currDistance*Math.cos(this.currPhi)*Math.sin(this.currTheta),s=i[1]+this.currDistance*Math.sin(this.currPhi),u=i[2]+this.currDistance*Math.cos(this.currPhi)*Math.cos(this.currTheta);we(this.viewMatrix,[r,s,u],i,[0,1,0]),ue(this.mvpMatrix,this.projMatrix,this.viewMatrix),he(this.normalMatrix,this.modelMatrix)}resize(){let e=Math.min((typeof window<"u"?window.devicePixelRatio:1)||1,2),t=this.canvas.getBoundingClientRect(),i=Math.max(1,Math.floor(t.width*e)),r=Math.max(1,Math.floor(t.height*e));this.canvas.width!==i||this.canvas.height!==r?(this.canvas.width=i,this.canvas.height=r,this.resizePickingFbo(i,r),this.xrSessionActive||this.syncCameraMatrices()):!this.xrSessionActive&&this.projMatrix[0]===0&&this.syncCameraMatrices()}getGLContext(){return this.gl}setXRSessionActive(e){let t=this.xrSessionActive;if(this.xrSessionActive=e,t&&!e){this.xrDepthState.enabled=!1;for(let i of K)i.onXRSessionEnd?.(this);if(this.lastTime=typeof performance<"u"?performance.now():Date.now(),this.updateTurntableMatrix(),this.isVisible)try{this.resize(),this.syncCameraMatrices(),this.render()}catch(i){this.reportRenderError(i)}}}reportRenderError(e){this.renderErrorReported||(this.renderErrorReported=!0,typeof console<"u"&&console.warn("[three-live] render frame failed:",e))}stepXRUpdate(e){for(let t of K)t.onUpdate?.(this,e)}start(){if(this.animFrameId!==null)return;this.lastTime=typeof performance<"u"?performance.now():Date.now();let e=t=>{if(this.animFrameId===null)return;let i=Math.min(Math.max((t-this.lastTime)/1e3,0),.1);if(this.lastTime=t,this.isVisible&&!this.xrSessionActive)try{this.resize(),this.update(i),this.render()}catch(r){this.reportRenderError(r)}this.animFrameId!==null&&(this.animFrameId=requestAnimationFrame(e))};this.animFrameId=requestAnimationFrame(e)}stop(){this.animFrameId!==null&&(cancelAnimationFrame(this.animFrameId),this.animFrameId=null)}setAutoRotate(e){this.autoRotate=e}getAutoRotate(){return this.autoRotate}setAutoRotateSpeed(e){this.autoRotateSpeed=e}getAutoRotateSpeed(){return this.autoRotateSpeed}setAutoRotateDelay(e){this.autoRotateDelay=Math.max(0,Number(e)||0)}getAutoRotateDelay(){return this.autoRotateDelay}resetTurntableRotation(e=0){this.turntableRotation=Number(e)||0,this.updateTurntableMatrix(),this.render()}updateTurntableMatrix(){let e=Math.cos(this.turntableRotation),t=Math.sin(this.turntableRotation),i=this.bounds.center[0],r=this.bounds.center[2],s=this.modelRootMatrix;s[0]=e,s[1]=0,s[2]=-t,s[3]=0,s[4]=0,s[5]=1,s[6]=0,s[7]=0,s[8]=t,s[9]=0,s[10]=e,s[11]=0,s[12]=i-(e*i+t*r),s[13]=0,s[14]=r-(-t*i+e*r),s[15]=1}setVisible(e){this.isVisible=e}update(e){for(let u of K)u.onUpdate?.(this,e);let t=typeof performance<"u"?performance.now():Date.now();if(!this.isPointerDown&&this.autoRotate&&t-this.lastInteractionTime>=this.autoRotateDelay){this.turntableRotation+=this.autoRotateSpeed*e,this.updateTurntableMatrix();for(let u of K)u.onCameraChange?.(this,this.container)}this.currTheta+=(this.targetTheta-this.currTheta)*.12,this.currPhi+=(this.targetPhi-this.currPhi)*.12,this.currDistance+=(this.targetDistance-this.currDistance)*.12,this.syncCameraMatrices();let i=Math.round((this.currTheta*180/Math.PI%360+360)%360),r=Math.round(this.currPhi*180/Math.PI),s=Math.round(this.bounds.radius*2.5/this.currDistance*100)/100;if(Math.abs(i-this.lastReportedTheta)>=1||Math.abs(r-this.lastReportedPhi)>=1||Math.abs(s-this.lastReportedZoom)>=.02){this.lastReportedTheta=i,this.lastReportedPhi=r,this.lastReportedZoom=s;let u={theta:i,phi:r,zoom:s,distance:Math.round(this.currDistance*100)/100};this.opts.onCameraChange&&this.opts.onCameraChange(u),typeof CustomEvent<"u"&&typeof this.container.dispatchEvent=="function"&&this.container.dispatchEvent(new CustomEvent("cameraChange",{bubbles:!0,detail:u}))}}renderXRView(e,t,i,r,s=!0,u=0){this.onBeforeRenderXRView&&this.onBeforeRenderXRView(e);let l=e?.transform?.inverse?.matrix||this.viewMatrix,c=e?.projectionMatrix||this.projMatrix,o=e?.transform?.position,a=o?[o.x,o.y,o.z]:[0,1.6,0];t?this.modelRootMatrix.set(t):i&&t&&this.modelRootMatrix.set(t),this.render({viewMatrix:l,projMatrix:c,eyePos:a,viewport:r,eye:e?.eye||"none",clear:u>0?!1:e?.eye!=="right",isAR:s})}render(e){if(!e&&this.stereoSBS){let R=Math.max(2,this.canvas.width||2),g=Math.max(1,this.canvas.height||1),T=Math.max(1,Math.floor(R*.5)),m=Math.max(1,R-T),v=this.backdropMeshes.length>0?Math.max(this.bounds.radius*20,120):Math.max(this.bounds.radius*20,10),y=this.customTarget||this.bounds.center,w=y[0]+this.currDistance*Math.cos(this.currPhi)*Math.sin(this.currTheta),C=y[1]+this.currDistance*Math.sin(this.currPhi),I=y[2]+this.currDistance*Math.cos(this.currPhi)*Math.cos(this.currTheta),A=Math.cos(this.currTheta),F=-Math.sin(this.currTheta),_=.032,D=Z(),W=Z(),H=[w-A*_,C,I-F*_],j=[y[0]-A*_*.25,y[1],y[2]-F*_*.25];Te(D,this.fov,T/g,.1,v),we(W,H,j,[0,1,0]);let O=Z(),q=Z(),X=[w+A*_,C,I+F*_],N=[y[0]+A*_*.25,y[1],y[2]+F*_*.25];Te(O,this.fov,m/g,.1,v),we(q,X,N,[0,1,0]),this.render({viewMatrix:W,projMatrix:D,eyePos:H,viewport:[0,0,T,g],eye:"left",clear:!0,isAR:!1}),this.render({viewMatrix:q,projMatrix:O,eyePos:X,viewport:[T,0,m,g],eye:"right",clear:!1,isAR:!1}),this.gl.viewport(0,0,R,g);return}let t=this.gl,i=0,r=0,s=this.canvas.width,u=this.canvas.height;e?.viewport?(i=e.viewport[0],r=e.viewport[1],s=e.viewport[2],u=e.viewport[3],t.viewport(i,r,s,u)):t.viewport(0,0,this.canvas.width,this.canvas.height),t.enable(2929),(!e||e.clear!==!1)&&(e?.isAR?t.clearColor(0,0,0,0):t.clearColor(this.clearColor[0],this.clearColor[1],this.clearColor[2],this.clearColor[3]),t.clear(16384|256));let l=Z(),c=e?.viewMatrix??this.viewMatrix;ue(l,e?.projMatrix??this.projMatrix,c);let o=[-c[2],-c[6],-c[10]],a=this.toneMapping==="reinhard"?1:this.toneMapping==="none"?2:0,f=this.customTarget||this.bounds.center,d=e?e.eyePos[0]:f[0]+this.currDistance*Math.cos(this.currPhi)*Math.sin(this.currTheta),p=e?e.eyePos[1]:f[1]+this.currDistance*Math.sin(this.currPhi),h=e?e.eyePos[2]:f[2]+this.currDistance*Math.cos(this.currPhi)*Math.cos(this.currTheta);for(let R of K)R.onBeforeDrawScene?.(this,t,l,[d,p,h],a);let x=e?.isAR?0:this.backdropMeshes.length;if(this.meshes.length===0&&x===0)return;let b=e?.eye||"none",S=!1,P=x>0?[...this.backdropMeshes,...this.meshes]:this.meshes,E=R=>{for(let g=0;g<P.length;g++){let T=P[g];if(T.visible===!1)continue;let m=this.selectedMeshName!==""&&T.name===this.selectedMeshName;g<x||T.worldSpace===!0||T.name==="__xr_reticle__"?this.modelMatrix.set(T.transform):ue(this.modelMatrix,this.modelRootMatrix,T.transform),ue(this.mvpMatrix,l,this.modelMatrix),he(T.normalMatrix,this.modelMatrix);let v=T.extras?.xr?.stereo||T.userData?.xr?.stereo,y=0,w=0,C=1,I=1;v==="sbs"?(C=.5,y=b==="right"?.5:0):v==="ou"&&(I=.5,w=b==="right"?.5:0);for(let A of T.primitives){let F=!!A.isTransmissive;if(!R&&F){S=!0;continue}if(R&&!F)continue;let _=A.customProgram||this.renderProg,D=A.customUniforms||this.uRender;t.useProgram(_),t.uniform1i(D.uToneMapping,a),t.uniform1f(D.uEnvIntensity,this.envIntensity),t.uniform3f(D.uCameraPos,d,p,h),D.uCameraFwd&&t.uniform3f(D.uCameraFwd,o[0],o[1],o[2]),t.uniform1f(D.uEmissive,m?1:0),t.uniformMatrix4fv(D.uMVP,!1,this.mvpMatrix),t.uniformMatrix4fv(D.uModel,!1,this.modelMatrix),t.uniformMatrix3fv(D.uNormalMatrix,!1,T.normalMatrix),D.uUvTransform&&t.uniform4f(D.uUvTransform,y,w,C,I),D.uViewportSize&&t.uniform2f(D.uViewportSize,Math.max(1,s),Math.max(1,u)),D.uViewport&&t.uniform4f(D.uViewport,i,r,Math.max(1,s),Math.max(1,u)),this.xrDepthState.enabled&&this.xrDepthState.texture?(t.activeTexture(33989),t.bindTexture(3553,this.xrDepthState.texture),D.uXrDepthTex&&t.uniform1i(D.uXrDepthTex,5),D.uXrDepthEnabled&&t.uniform1i(D.uXrDepthEnabled,1),D.uXrDepthFormat&&t.uniform1i(D.uXrDepthFormat,this.xrDepthState.format||0),D.uXrRawValueToMeters&&t.uniform1f(D.uXrRawValueToMeters,this.xrDepthState.rawValueToMeters),D.uXrDepthUVTransform&&t.uniformMatrix4fv(D.uXrDepthUVTransform,!1,this.xrDepthState.uvTransform)):D.uXrDepthEnabled&&t.uniform1i(D.uXrDepthEnabled,0),this.environmentTexture?(t.activeTexture(33988),t.bindTexture(3553,this.environmentTexture),t.uniform1i(D.uEnvironmentMap,4),t.uniform1i(D.uHasEnvironmentMap,1)):t.uniform1i(D.uHasEnvironmentMap,0),this.bindLights(D);for(let W of K)W.onBeforeDrawPrimitive?.(t,_,A,T,this.worldMatrices||[],this.gltf);t.uniform4fv(D.uBaseColor,A.baseColor),t.uniform1f(D.uMetallic,A.metallic),t.uniform1f(D.uRoughness,A.roughness),D.uClearcoat&&t.uniform2f(D.uClearcoat,A.clearcoat??0,A.clearcoatRoughness??.04),A.texture?(t.activeTexture(33984),t.bindTexture(3553,A.texture),t.uniform1i(D.uBaseColorTexture,0),t.uniform1i(D.uHasTexture,1)):t.uniform1i(D.uHasTexture,0),A.metallicRoughnessTexture?(t.activeTexture(33985),t.bindTexture(3553,A.metallicRoughnessTexture),t.uniform1i(D.uMetallicRoughnessTexture,1),t.uniform1i(D.uHasMetallicRoughnessTexture,1)):t.uniform1i(D.uHasMetallicRoughnessTexture,0),A.normalTexture?(t.activeTexture(33986),t.bindTexture(3553,A.normalTexture),t.uniform1i(D.uNormalTexture,2),t.uniform1i(D.uHasNormalTexture,1),t.uniform1f(D.uNormalScale,A.normalScale)):t.uniform1i(D.uHasNormalTexture,0),A.occlusionTexture?(t.activeTexture(33987),t.bindTexture(3553,A.occlusionTexture),t.uniform1i(D.uOcclusionTexture,3),t.uniform1i(D.uHasOcclusionTexture,1),t.uniform1f(D.uOcclusionStrength,A.occlusionStrength)):t.uniform1i(D.uHasOcclusionTexture,0),t.bindVertexArray(A.vao),t.drawElements(4,A.indexCount,A.indexType,0)}}};if(E(!1),S){for(let R of K)R.onBeforeTransmissivePass?.(t,this);E(!0)}for(let R of K)R.onAfterRender?.(t,this,l)}disposeMeshListGpuResources(e){let t=this.gl;for(let i of e)for(let r of i.primitives){if(r.vao&&t.deleteVertexArray(r.vao),r.buffers)for(let s of r.buffers)t.deleteBuffer(s);r.texture&&t.deleteTexture(r.texture),r.metallicRoughnessTexture&&t.deleteTexture(r.metallicRoughnessTexture),r.normalTexture&&t.deleteTexture(r.normalTexture),r.occlusionTexture&&t.deleteTexture(r.occlusionTexture),r.customProgram&&t.deleteProgram(r.customProgram)}}disposeMeshGpuResources(){this.disposeMeshListGpuResources(this.meshes),this.meshes=[]}disposeGpuResources(){let e=this.gl;this.disposeMeshGpuResources(),this.disposeMeshListGpuResources(this.backdropMeshes),this.backdropMeshes=[];for(let t of K)t.onDestroy?.(e,this);this.environmentTexture&&(e.deleteTexture(this.environmentTexture),this.environmentTexture=null),this.renderProg&&e.deleteProgram(this.renderProg),this.pickProg&&e.deleteProgram(this.pickProg),this.pickFbo&&e.deleteFramebuffer(this.pickFbo),this.pickTexture&&e.deleteTexture(this.pickTexture),this.pickDepth&&e.deleteRenderbuffer(this.pickDepth),this.pickFbo=null,this.pickTexture=null,this.pickDepth=null}dispose(){this.stop(),this.teardownEvents(),this.disposeGpuResources()}destroy(){this.dispose()}};Ae.registerPlugin=Ye,Ae.getRegisteredPlugins=Ke;function ke(n){return new TextEncoder().encode(n)}function At(n,e){n.updateMatrixWorld(!0);let t=[];return n.traverse(i=>{if(i.geometry){let r=i.geometry,s=r.attributes.position;if(!s||s.count===0)return;let u=s.count,l=new Float32Array(u*3),c=i.matrixWorld.elements;for(let m=0;m<u;m++){let v=s.getX(m),y=s.getY(m),w=s.getZ(m);l[m*3]=c[0]*v+c[4]*y+c[8]*w+c[12],l[m*3+1]=c[1]*v+c[5]*y+c[9]*w+c[13],l[m*3+2]=c[2]*v+c[6]*y+c[10]*w+c[14]}let o;if(r.attributes.normal){let m=r.attributes.normal;o=new Float32Array(u*3);let v=new Float32Array(9);he(v,c);for(let y=0;y<u;y++){let w=m.getX(y),C=m.getY(y),I=m.getZ(y),A=v[0]*w+v[3]*C+v[6]*I,F=v[1]*w+v[4]*C+v[7]*I,_=v[2]*w+v[5]*C+v[8]*I,D=Math.hypot(A,F,_)||1;o[y*3]=A/D,o[y*3+1]=F/D,o[y*3+2]=_/D}}let a;if(r.attributes.uv){let m=r.attributes.uv;a=new Float32Array(u*2);for(let v=0;v<u;v++)a[v*2]=m.getX(v),a[v*2+1]=m.getY(v)}let f;if(r.index)f=r.index.array;else{f=u>65535?new Uint32Array(u):new Uint16Array(u);for(let m=0;m<u;m++)f[m]=m}let d="DefaultMaterial",p=[.8,.8,.8],h=.5,x=.1,b=0,S=0,P=1.5,E=1,R=[0,0,0];if(i.material){let m=i.material;d=m.name||`Material_${t.length}`,m.color&&(p=[m.color.r,m.color.g,m.color.b]),typeof m.roughness=="number"&&(h=m.roughness),typeof m.metalness=="number"&&(x=m.metalness),typeof m.clearcoat=="number"&&(b=m.clearcoat),typeof m.clearcoatRoughness=="number"&&(S=m.clearcoatRoughness),typeof m.ior=="number"&&(P=m.ior);let v=typeof m.opacity=="number"?m.opacity:1,y=typeof m.transmission=="number"?m.transmission:0;if(E=v*(1-y),m.emissive&&(m.emissive.r>0||m.emissive.g>0||m.emissive.b>0)){let w=m.emissiveIntensity??1;R=[m.emissive.r*w,m.emissive.g*w,m.emissive.b*w]}}let g,T=e?.animateCallback||e?.animateFn||(typeof n.userData?.animate=="function"?n.userData.animate:typeof n.__animateFn=="function"?n.__animateFn:typeof globalThis.animate=="function"?globalThis.animate:void 0);if(typeof T=="function"){let m=e?.duration??4,v=e?.fps??4,y=Math.max(2,Math.round(m*v)+1),w=[],C=[],I=[],A=[],F=[i.position.x,i.position.y,i.position.z],_=[i.quaternion.x,i.quaternion.y,i.quaternion.z,i.quaternion.w],D=[i.scale.x,i.scale.y,i.scale.z],W=!1;for(let H=0;H<y;H++){let j=H/(y-1)*m;w.push(j);try{T(j)}catch{}C.push([i.position.x,i.position.y,i.position.z]),I.push([i.quaternion.x,i.quaternion.y,i.quaternion.z,i.quaternion.w]),A.push([i.scale.x,i.scale.y,i.scale.z]),(Math.abs(i.position.x-F[0])>1e-4||Math.abs(i.position.y-F[1])>1e-4||Math.abs(i.position.z-F[2])>1e-4||Math.abs(i.quaternion.x-_[0])>1e-4||Math.abs(i.quaternion.y-_[1])>1e-4||Math.abs(i.quaternion.z-_[2])>1e-4||Math.abs(i.quaternion.w-_[3])>1e-4||Math.abs(i.scale.x-D[0])>1e-4)&&(W=!0)}i.position.set(F[0],F[1],F[2]),i.quaternion.set(_[0],_[1],_[2],_[3]),i.scale.set(D[0],D[1],D[2]),W&&(g={times:w,translations:C,rotations:I,scales:A})}t.push({name:i.name||`Mesh_${t.length}`,positions:l,indices:f,normals:o,uvs:a,materialName:d,color:p,roughness:h,metallic:x,clearcoat:b,clearcoatRoughness:S,ior:P,opacity:E,emissiveColor:R,xrTraits:i.userData?.xr,timeSamples:g})}}),t}function ut(n){let e=[],t=n.gltf,i=n.bin,r=i instanceof ArrayBuffer?i:i.buffer.slice(i.byteOffset,i.byteOffset+i.byteLength),s=t.accessors||[],u=t.bufferViews||[],l=t.materials||[],c=t.meshes||[],o=t.nodes||[];function a(p){let h=s[p];if(!h)throw new Error(`Accessor ${p} not found`);let x=u[h.bufferView||0],b=(x.byteOffset||0)+(h.byteOffset||0),S=x.byteLength||0,P=r.slice(b,b+S);return{acc:h,buffer:P}}let f=new Map;if(o.length>0){let p=Re(t);for(let h=0;h<p.length;h++)f.set(h,p[h])}function d(p,h,x,b){let S=c[p];if(!S)return;let P=new Float32Array(9);he(P,h);for(let E=0;E<(S.primitives||[]).length;E++){let R=S.primitives[E],g=R.attributes?.POSITION;if(g===void 0)continue;let{acc:T,buffer:m}=a(g),v=new Float32Array(m,0,T.count*3),y=new Float32Array(v.length);for(let M=0;M<T.count;M++){let L=v[M*3],B=v[M*3+1],k=v[M*3+2];y[M*3]=h[0]*L+h[4]*B+h[8]*k+h[12],y[M*3+1]=h[1]*L+h[5]*B+h[9]*k+h[13],y[M*3+2]=h[2]*L+h[6]*B+h[10]*k+h[14]}let w,C=R.attributes?.NORMAL;if(C!==void 0){let{acc:M,buffer:L}=a(C),B=new Float32Array(L,0,M.count*3);w=new Float32Array(B.length);for(let k=0;k<M.count;k++){let ie=B[k*3],Y=B[k*3+1],Q=B[k*3+2],re=P[0]*ie+P[3]*Y+P[6]*Q,te=P[1]*ie+P[4]*Y+P[7]*Q,U=P[2]*ie+P[5]*Y+P[8]*Q,z=Math.hypot(re,te,U)||1;w[k*3]=re/z,w[k*3+1]=te/z,w[k*3+2]=U/z}}let I,A=R.attributes?.TEXCOORD_0;if(A!==void 0){let{acc:M,buffer:L}=a(A);I=new Float32Array(L,0,M.count*2)}let F;if(R.indices!==void 0){let{acc:M,buffer:L}=a(R.indices);M.componentType===5125?F=new Uint32Array(L,0,M.count):F=new Uint16Array(L,0,M.count);let B=T.count;for(let k of F)if(k>=B)throw new Error(`SecurityError: Index buffer value (${k}) out of vertex bounds [0, ${B}).`)}else{let M=T.count;F=M>65535?new Uint32Array(M):new Uint16Array(M);for(let L=0;L<M;L++)F[L]=L}let _="DefaultMaterial",D=[.8,.8,.8],W=.5,H=.1,j=0,O=0,q=1.5,X=1,N=[0,0,0];if(R.material!==void 0&&l[R.material]){let M=l[R.material];_=M.name||`Material_${R.material}`;let L=M.pbrMetallicRoughness||{},B=1;Array.isArray(L.baseColorFactor)&&(D=[L.baseColorFactor[0],L.baseColorFactor[1],L.baseColorFactor[2]],typeof L.baseColorFactor[3]=="number"&&(B=L.baseColorFactor[3])),typeof L.roughnessFactor=="number"&&(W=L.roughnessFactor),typeof L.metallicFactor=="number"&&(H=L.metallicFactor),Array.isArray(M.emissiveFactor)&&M.emissiveFactor.length>=3&&(N=[M.emissiveFactor[0],M.emissiveFactor[1],M.emissiveFactor[2]]);let k=M.extensions||{};k.KHR_materials_clearcoat&&(j=k.KHR_materials_clearcoat.clearcoatFactor??0,O=k.KHR_materials_clearcoat.clearcoatRoughnessFactor??0),k.KHR_materials_ior&&typeof k.KHR_materials_ior.ior=="number"&&(q=k.KHR_materials_ior.ior);let ie=k.KHR_materials_transmission?.transmissionFactor??0;X=B*(1-ie)}let $=(S.primitives||[]).length>1?`${x}_p${E}`:x;e.push({name:$,positions:y,indices:F,normals:w,uvs:I,materialName:_,color:D,roughness:W,metallic:H,clearcoat:j,clearcoatRoughness:O,ior:q,opacity:X,emissiveColor:N,xrTraits:b?.xr||S.extras?.xr})}}if(o.length>0)for(let p=0;p<o.length;p++){let h=o[p];if(h.mesh!==void 0&&h.mesh<c.length){let x=f.get(p)||Z(),b=h.name||c[h.mesh].name||`Node_${p}`;d(h.mesh,x,b,h.extras)}}else{let p=Z();for(let h=0;h<c.length;h++){let x=c[h].name||`Mesh_${h}`;d(h,p,x,c[h].extras)}}return e}function Ue(n,e){if(!n||typeof n!="string")return e;let t=n.replace(/[^A-Za-z0-9_]/g,"_");return/^[0-9]/.test(t)&&(t="_"+t),t||e}function ot(n){return String(n??"").replace(/[\x00-\x1f\x7f]/g,"").replace(/\\/g,"\\\\").replace(/"/g,'\\"')}function V(n){if(!Number.isFinite(n)||Math.abs(n)<1e-7)return"0";let e=Number(n.toFixed(5)).toString();return e.indexOf(".")===-1?`${e}.0`:e}function ct(n){let e=n.length/3,t=new Array(e);for(let i=0;i<e;i++)t[i]=`(${V(n[i*3])}, ${V(n[i*3+1])}, ${V(n[i*3+2])})`;return t.join(", ")}function Et(n,e){let t=new Array(e);for(let i=0;i<e;i++)t[i]=`(${V(n[i*2])}, ${V(1-n[i*2+1])})`;return t.join(", ")}function Dt(n){return Array.from(n).join(", ")}function Be(n){let e=new Map;for(let c of n){let o=Ue(c.materialName,"DefaultMaterial");e.has(o)||e.set(o,{color:c.color||[.8,.8,.8],roughness:c.roughness??.5,metallic:c.metallic??0,clearcoat:c.clearcoat??0,clearcoatRoughness:c.clearcoatRoughness??0,ior:c.ior??1.5,opacity:c.opacity??1,emissiveColor:c.emissiveColor||[0,0,0]})}let t=0,i=null;for(let c of n){if(c.timeSamples&&c.timeSamples.times.length>0){let o=c.timeSamples.times[c.timeSamples.times.length-1];o>t&&(t=o)}c.xrTraits?.anchor&&!i&&(i=c.xrTraits.anchor==="vertical"||c.xrTraits.anchor==="wall"?"vertical":"horizontal")}let r="";t>0&&(r=`startTimeCode = 0
223
+ endTimeCode = ${V(t)}
224
+ timeCodesPerSecond = 1.0
225
+ `);let s="";i&&(s=`uniform token preliminary:anchoring:type = "plane"
226
+ uniform token preliminary:planeAnchoring:alignment = "${i}"
227
+ `);let u=`#usda 1.0
228
+ (
229
+ defaultPrim = "Root"
230
+ metersPerUnit = 1.0
231
+ upAxis = "Y"
232
+ ${r})
233
+
234
+ def Xform "Root" (
235
+ kind = "component"
236
+ )
237
+ {
238
+ ${s}def Scope "Materials"
239
+ {
240
+ `;for(let[c,o]of e.entries()){let[a,f,d]=o.color,[p,h,x]=o.emissiveColor,b="";o.clearcoat>0&&(b+=`float inputs:clearcoat = ${V(o.clearcoat)}
241
+ `,b+=`float inputs:clearcoatRoughness = ${V(o.clearcoatRoughness)}
242
+ `),o.ior!==1.5&&(b+=`float inputs:ior = ${V(o.ior)}
243
+ `),o.opacity<1&&(b+=`float inputs:opacity = ${V(o.opacity)}
244
+ `),(p>0||h>0||x>0)&&(b+=`color3f inputs:emissiveColor = (${V(p)}, ${V(h)}, ${V(x)})
245
+ `),u+=`def Material "${c}"
246
+ {
247
+ def Shader "PBRShader"
248
+ {
249
+ uniform token info:id = "UsdPreviewSurface"
250
+ color3f inputs:diffuseColor = (${V(a)}, ${V(f)}, ${V(d)})
251
+ float inputs:metallic = ${V(o.metallic)}
252
+ float inputs:roughness = ${V(o.roughness)}
253
+ ${b}token outputs:surface
254
+ }
255
+ token outputs:surface.connect = </Root/Materials/${c}/PBRShader.outputs:surface>
256
+ }
257
+ `}u+=`}
258
+ def Scope "Meshes"
259
+ {
260
+ `;let l=new Set;for(let c=0;c<n.length;c++){let o=n[c],a=o.positions.length/3,f=1/0,d=1/0,p=1/0,h=-1/0,x=-1/0,b=-1/0;for(let m=0;m<a;m++){let v=o.positions[m*3],y=o.positions[m*3+1],w=o.positions[m*3+2];v<f&&(f=v),v>h&&(h=v),y<d&&(d=y),y>x&&(x=y),w<p&&(p=w),w>b&&(b=w)}isFinite(f)||(f=d=p=-1,h=x=b=1);let S=Math.floor(o.indices.length/3),P=Ue(o.materialName,"DefaultMaterial"),E=Ue(o.name,`Mesh_${c}`);l.has(E)&&(E=`${E}_${c}`),l.add(E);let R=S>0?S===1?"3":"3, ".repeat(S-1)+"3":"",g=o.xrTraits,T="";if(g){let m=[];g.physics&&g.physics!=="none"&&m.push('prepend apiSchemas = ["PhysicsBodyAPI", "PhysicsCollisionAPI"]');let v=de().xrTraitSerializer?.usdLines(g,ot)??[];if(!v.length)for(let y of["grab","billboard","follow","anchor","physics"]){let w=y==="follow"&&typeof g.follow=="object"?g.follow.mode??"head":g[y];w!==void 0&&v.push(`string ${y} = "${ot(w)}"`)}v.length>0&&m.push(`customData = {
261
+ dictionary xr = {
262
+ ${v.join(`
263
+ `)}
264
+ }
265
+ }`),m.length>0&&(T=` (
266
+ ${m.join(`
267
+ `)}
268
+ )`)}if(u+=`def Mesh "${E}"${T}
269
+ {
270
+ `,g?.physics&&g.physics!=="none"){let m=g.physics==="static"?"true":"false";u+=`bool physics:rigidBodyEnabled = true
271
+ bool physics:kinematicEnabled = ${m}
272
+ bool physics:collisionEnabled = true
273
+ `}if(o.timeSamples&&o.timeSamples.times.length>0){let m=o.timeSamples,v=m.times.map((C,I)=>{let A=m.translations?.[I]||[0,0,0];return`${V(C)}: (${V(A[0])}, ${V(A[1])}, ${V(A[2])})`}).join(", "),y=m.times.map((C,I)=>{let A=m.rotations?.[I]||[0,0,0,1];return`${V(C)}: (${V(A[3])}, ${V(A[0])}, ${V(A[1])}, ${V(A[2])})`}).join(", "),w=m.times.map((C,I)=>{let A=m.scales?.[I]||[1,1,1];return`${V(C)}: (${V(A[0])}, ${V(A[1])}, ${V(A[2])})`}).join(", ");u+=`double3 xformOp:translate.timeSamples = { ${v} }
274
+ quatf xformOp:orient.timeSamples = { ${y} }
275
+ double3 xformOp:scale.timeSamples = { ${w} }
276
+ uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:orient", "xformOp:scale"]
277
+ `}u+=`float3[] extent = [(${V(f)}, ${V(d)}, ${V(p)}), (${V(h)}, ${V(x)}, ${V(b)})]
278
+ int[] faceVertexCounts = [${R}]
279
+ int[] faceVertexIndices = [${Dt(o.indices)}]
280
+ point3f[] points = [${ct(o.positions)}]
281
+ `,o.normals&&o.normals.length===o.positions.length&&(u+=`normal3f[] normals = [${ct(o.normals)}] (
282
+ interpolation = "vertex"
283
+ )
284
+ `),o.uvs&&o.uvs.length===a*2&&(u+=`texCoord2f[] primvars:st = [${Et(o.uvs,a)}] (
285
+ interpolation = "vertex"
286
+ )
287
+ `),u+=`rel material:binding = </Root/Materials/${P}>
288
+ }
289
+ `}return u+=`}
290
+ }
291
+ `,u}function Ne(n,e){if(n&&typeof n.traverse=="function"){let r=At(n,e);return Be(r)}let t=ge(n),i=ut(t);return Be(i)}var Ee=null;function Ve(n){if(!Ee){Ee=new Uint32Array(256);for(let t=0;t<256;t++){let i=t;for(let r=0;r<8;r++)i=i&1?3988292384^i>>>1:i>>>1;Ee[t]=i}}let e=4294967295;for(let t=0;t<n.length;t++)e=Ee[(e^n[t])&255]^e>>>8;return(e^4294967295)>>>0}function De(n){let e=[],t=0,i=[];for(let a of n){let f=ke(a.filename),d=Ve(a.data),p=a.data.length,h=30+f.length,x=t+h,b=0,S=x%64;S!==0&&(b=64-S);let P=new Uint8Array(h+b),E=new DataView(P.buffer);E.setUint32(0,67324752,!0),E.setUint16(4,20,!0),E.setUint16(6,0,!0),E.setUint16(8,0,!0),E.setUint16(10,0,!0),E.setUint16(12,0,!0),E.setUint32(14,d,!0),E.setUint32(18,p,!0),E.setUint32(22,p,!0),E.setUint16(26,f.length,!0),E.setUint16(28,b,!0),P.set(f,30),b>0&&P.fill(0,30+f.length),e.push({offset:t,size:p,crc:d,filenameBytes:f,entry:a}),i.push(P),i.push(a.data),t+=P.length+a.data.length}let r=t;for(let a of e){let f=new Uint8Array(46+a.filenameBytes.length),d=new DataView(f.buffer);d.setUint32(0,33639248,!0),d.setUint16(4,20,!0),d.setUint16(6,20,!0),d.setUint16(8,0,!0),d.setUint16(10,0,!0),d.setUint16(12,0,!0),d.setUint16(14,0,!0),d.setUint32(16,a.crc,!0),d.setUint32(20,a.size,!0),d.setUint32(24,a.size,!0),d.setUint16(28,a.filenameBytes.length,!0),d.setUint16(30,0,!0),d.setUint16(32,0,!0),d.setUint16(34,0,!0),d.setUint16(36,0,!0),d.setUint32(38,0,!0),d.setUint32(42,a.offset,!0),f.set(a.filenameBytes,46),i.push(f),t+=f.length}let s=t-r,u=new Uint8Array(22),l=new DataView(u.buffer);l.setUint32(0,101010256,!0),l.setUint16(4,0,!0),l.setUint16(6,0,!0),l.setUint16(8,e.length,!0),l.setUint16(10,e.length,!0),l.setUint32(12,s,!0),l.setUint32(16,r,!0),l.setUint16(20,0,!0),i.push(u),t+=22;let c=new Uint8Array(t),o=0;for(let a of i)c.set(a,o),o+=a.length;return c}function St(n){let e=Ne(n),t=ke(e);return De([{filename:"model.usda",data:t}])}function Oe(n){let e=ge(n),t=ut(e),i=Be(t),r=ke(i);return De([{filename:"model.usda",data:r}])}function Ge(n){return n&&typeof n.toUSDZ=="function"?n.toUSDZ():n&&typeof n.traverse=="function"?St(n):Oe(n)}function Xe(n){let e=Ge(n);return new Blob([e],{type:"model/vnd.usdz+zip"})}function ze(){if(typeof window>"u"||typeof navigator>"u")return!1;let n=navigator.userAgent||"";if(!(/iPad|iPhone|iPod/.test(n)||navigator.platform==="MacIntel"&&navigator.maxTouchPoints>1))return!1;let t=document.createElement("a");return t.relList!==void 0&&t.relList.supports!==void 0&&t.relList.supports("ar")}function We(){if(typeof navigator>"u")return!1;let n=navigator.userAgent||"";return/android/i.test(n)}async function $e(){if(typeof navigator>"u")return!1;let n=navigator;if(!n.xr||typeof n.xr.isSessionSupported!="function")return!1;try{return await n.xr.isSessionSupported("immersive-ar")?!0:await n.xr.isSessionSupported("immersive-vr")}catch{return!1}}async function Ft(){let n=[];return await $e()&&n.push("webxr"),ze()&&n.push("quick-look"),We()&&n.push("scene-viewer"),n}async function Lt(){return(await qe()).bestMode}async function qe(){let[n,e,t]=await Promise.all([$e(),Promise.resolve(ze()),Promise.resolve(We())]),i=[];e&&i.push("quick-look"),n&&i.push("webxr"),t&&i.push("scene-viewer");let r=null;return e?r="quick-look":n?r="webxr":t&&(r="scene-viewer"),{webxr:n,quickLook:e,sceneViewer:t,availableModes:i,bestMode:r}}function He(n,e={}){if(typeof document>"u")throw new Error("launchQuickLook requires a browser DOM environment");let t,i=!1;if(typeof n=="string"){if(t=Ct(n),!t)throw new Error("[XR-Live Security] Quick Look URL is empty.")}else t=URL.createObjectURL(n),i=!0;let r=[];if(e.allowScale===!1&&r.push("allowsContentScaling=0"),e.canonicalWebPageUrl){let l=Se(e.canonicalWebPageUrl,!1);l&&r.push(`canonicalWebPageURL=${encodeURIComponent(l)}`)}e.checkoutTitle&&r.push(`checkoutTitle=${encodeURIComponent(e.checkoutTitle)}`),e.checkoutSubtitle&&r.push(`checkoutSubtitle=${encodeURIComponent(e.checkoutSubtitle)}`),e.price&&r.push(`price=${encodeURIComponent(e.price)}`),r.length>0&&(t+=`#${r.join("&")}`);let s=document.createElement("a");s.setAttribute("rel","ar"),s.setAttribute("href",t);let u=document.createElement("img");u.setAttribute("src","data:image/svg+xml;utf8,<svg/>"),u.style.display="none",s.appendChild(u),document.body.appendChild(s),s.click(),setTimeout(()=>{document.body.removeChild(s),i&&URL.revokeObjectURL(t.split("#")[0])},3e3)}function Se(n,e=!1){if(typeof n!="string")return"";let t=n.replace(/[\x00-\x1f\x7f]+/g,"").trim();if(!t)return"";if(/^[\\/]{2}/.test(t))throw new Error(`[XR-Live Security] Rejected protocol-relative URL in Scene Viewer intent: ${t.slice(0,32)}`);let i=t.toLowerCase();if(i.startsWith("https://")||i.startsWith("http://")||e&&i.startsWith("blob:")||!/^[a-z][a-z0-9+.-]*:/i.test(t))return t;throw new Error(`[XR-Live Security] Rejected unsafe URL scheme in Scene Viewer intent: ${t.slice(0,32)}`)}function Ct(n){try{return Se(n,!0)}catch{throw new Error(`[XR-Live Security] Rejected unsafe URL scheme in Quick Look launch: ${(n||"").trim().slice(0,32)}`)}}function ht(n,e={}){let t=Se(n,!0),i=e.mode||"ar_preferred",r=new URLSearchParams({file:t,mode:i,resizable:e.resizable!==!1?"true":"false",enable_vertical_placement:e.enableVerticalPlacement?"true":"false"});return e.title&&r.set("title",e.title),e.link&&r.set("link",Se(e.link,!1)),`intent://arvr.google.com/scene-viewer/1.0?${r.toString()}#Intent;scheme=https;package=com.google.ar.core;action=android.intent.action.VIEW;end;`}function mt(n,e={}){if(typeof window>"u")throw new Error("launchSceneViewer requires a browser environment");let t=ht(n,e);window.location.href=t}var pe=null;function It(n,e){let i=new Float32Array(144),r=new Float32Array(24*6),s=new Float32Array(24*4),u=new Uint16Array(24*6);for(let f=0;f<24;f++){let d=f/24*Math.PI*2,p=Math.cos(d),h=Math.sin(d),x=f*2,b=x+1,S=(f+1)%24*2;i[x*3]=p*.11,i[x*3+1]=.002,i[x*3+2]=h*.11,i[b*3]=p*.145,i[b*3+1]=.002,i[b*3+2]=h*.145,r[x*3+1]=r[b*3+1]=1,u.set([x,S,b,b,S,S+1],f*6)}let l=n.createVertexArray();n.bindVertexArray(l);let c=(f,d,p)=>{let h=n.createBuffer();return n.bindBuffer(34962,h),n.bufferData(34962,f,35044),n.enableVertexAttribArray(d),n.vertexAttribPointer(d,p,5126,!1,0,0),h},o=[c(i,0,3),c(r,1,3),c(s,2,2)],a=n.createBuffer();return o.push(a),n.bindBuffer(34963,a),n.bufferData(34963,u,35044),n.bindVertexArray(null),{name:"__xr_reticle__",nodeIndex:-1,worldSpace:!0,visible:!1,transform:new Float32Array([1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]),normalMatrix:new Float32Array([1,0,0,0,1,0,0,0,1]),primitives:[{vao:l,indexCount:u.length,indexType:5123,baseColor:e&&e.length>=3?[e[0],e[1],e[2],e[3]??.95]:[.22,.74,.97,.95],metallic:0,roughness:.2,positions:i,indices:u,texture:null,metallicRoughnessTexture:null,normalTexture:null,occlusionTexture:null,normalScale:1,occlusionStrength:1,buffers:o}]}}function lt(n,e,t,i,r){let s=Math.cos(i),u=Math.sin(i),l=Math.max(.01,r);n.fill(0),n[0]=l*s,n[2]=-l*u,n[5]=l,n[8]=l*u,n[10]=l*s,n[12]=e[0]-l*(s*t[0]+u*t[2]),n[13]=e[1]-l*t[1],n[14]=e[2]-l*(-u*t[0]+s*t[2]),n[15]=1}var Pe=class{constructor(e={}){this.s=null;this.placed=!1;this.placedMat=new Float32Array([1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]);this.cleanFn=null;this.opts=e}isSessionActive(){return this.s!==null}hasPlacedModel(){return this.placed}getPlacedMatrix(){return this.placedMat}async start(e,t){if(typeof navigator>"u"||!navigator.xr)throw new Error("WebXR is not supported on this browser.");pe&&pe!==this&&pe.isSessionActive()&&await pe.stop().catch(()=>{});let i=navigator.xr,r=this.opts,s=t||e?.container,u=String(s?.tagName||"").toLowerCase()==="xr-live",l=e?.bounds,c=Number(l?.radius)||1,o=Array.isArray(l?.center)?l.center:[0,0,0],a=Array.isArray(l?.min)?l.min:[-.5,-.5,-.5],f=typeof navigator<"u"&&navigator.userAgent||"",d=/Android|iPhone|iPad|iPod/i.test(f)&&!/Quest|Oculus|Pico|Vision/i.test(f),p=u?r.arScale==="fixed"?1:d?.55:1:r.arScale==="fixed"?1:c>.45?.3/c:c<.05?.12/Math.max(c,.001):1,h=u?[0,-.25,0]:[o[0]||0,r.arPlacement==="wall"?o[1]:a[1]??0,o[2]||0],x="immersive-ar";try{await i.isSessionSupported("immersive-ar")||(x="immersive-vr")}catch{x="immersive-vr"}let b=s?.querySelector?.('[slot="ar-overlay"]')||null,S=!1,P=null,E=()=>{S&&b?.parentNode&&b.parentNode.removeChild(b),b=null,P=null,S=!1};if(x==="immersive-ar"){if(b)b.addEventListener?.("beforexrselect",M=>M.preventDefault());else if(typeof document<"u"&&document.body&&typeof document.createElement=="function"){let M=document.createElement("div");M.style.cssText="position:fixed;inset:0;pointer-events:none;background:transparent!important;z-index:2147483647;font-family:system-ui,sans-serif;user-select:none";let L=document.createElement("button");L.type="button",L.textContent="\u2715 Exit AR",L.style.cssText="position:absolute;top:max(16px,env(safe-area-inset-top,16px));right:16px;pointer-events:auto;padding:8px 14px;border-radius:99px;border:1px solid rgba(255,255,255,.3);background:rgba(15,23,42,.8);color:#f8fafc;font:600 13px system-ui,sans-serif",L.addEventListener("beforexrselect",B=>B.preventDefault()),L.addEventListener("click",B=>{B.stopPropagation(),this.stop().catch(()=>{})}),P=document.createElement("div"),P.style.cssText="position:absolute;bottom:max(28px,env(safe-area-inset-bottom,28px));left:50%;transform:translateX(-50%);padding:8px 15px;border-radius:99px;border:1px solid rgba(56,189,248,.4);background:rgba(15,23,42,.82);color:#f8fafc;font:500 12.5px system-ui,sans-serif;text-align:center;max-width:88vw",P.textContent="Move phone to detect a surface \u2022 Tap to place",M.appendChild(L),M.appendChild(P),document.body.appendChild(M),b=M,S=!0}}let R=new Set(r.optionalFeatures||["local","local-floor","hit-test","light-estimation"]),g={requiredFeatures:r.requiredFeatures?[...r.requiredFeatures]:[],optionalFeatures:Array.from(R)};b&&(R.add("dom-overlay"),g.optionalFeatures=Array.from(R),g.domOverlay={root:b});for(let M of K)M.onConfigureXRSessionInit?.(s,g);Array.isArray(g.optionalFeatures)&&g.optionalFeatures.includes("dom-overlay")&&!g.domOverlay?.root&&(g.optionalFeatures=g.optionalFeatures.filter(M=>M!=="dom-overlay"));let T=M=>{let L=String(M?.name||"");return L==="NotAllowedError"||L==="SecurityError"};try{this.s=await i.requestSession(x,g)}catch(M){if(E(),T(M))throw r.onError?.(M),M;try{this.s=await i.requestSession(x,{requiredFeatures:[],optionalFeatures:["local","hit-test"]})}catch(L){if(T(L))throw r.onError?.(L),L;try{this.s=await i.requestSession(x)}catch(B){throw r.onError?.(B),B}}}let m=this.s;pe=this,this.placed=!1;let v=null,y=null,w=null,C=null,I=null,A=[0,-.25,-1.2],F=[0,-.25,-1.2],_=new Float32Array(16),D=!1,W=1,H=0,j=!1,O=null,q=null,X=0,N=null,$=()=>{pe===this&&(pe=null),N?.(),N=null;try{y?.cancel?.()}catch{}if(y=null,w){let M=e?.meshes;if(Array.isArray(M)){let B=M.indexOf(w);B!==-1&&M.splice(B,1)}let L=e.getGLContext?.()||e?.gl;if(L)for(let B of w.primitives||[]){L.deleteVertexArray?.(B.vao);for(let k of B.buffers||[])L.deleteBuffer?.(k)}w=null}e?.setXRSessionActive?.(!1),E(),this.s=null,this.placed=!1,this.cleanFn=null};this.cleanFn=$,m.addEventListener("end",()=>{$(),r.onExit?.()}),m.addEventListener("select",()=>{if(!this.placed){let M=I||A;F=[M[0],M[1],M[2]],lt(this.placedMat,F,h,H,p*W),this.placed=!0,w&&(w.visible=!1),P&&(P.textContent="Placed \u2022 Drag to move \u2022 Pinch to scale"),r.onPlaced?.(this.placedMat)}});try{let M=e.getGLContext?.()||e?.gl;M&&typeof M.makeXRCompatible=="function"&&await M.makeXRCompatible();let L=typeof XRWebGLLayer<"u"?XRWebGLLayer:globalThis?.XRWebGLLayer;M&&typeof L=="function"&&typeof m.updateRenderState=="function"&&m.updateRenderState({baseLayer:new L(m,M,{alpha:!0})});try{v=await m.requestReferenceSpace("local")}catch{try{v=await m.requestReferenceSpace("local-floor")}catch{v=await m.requestReferenceSpace("viewer")}}let B=await m.requestReferenceSpace("viewer").catch(()=>v);if(typeof m.requestHitTestSource=="function"&&B&&(y=await m.requestHitTestSource({space:B}).catch(()=>null)),x==="immersive-ar"&&M&&typeof M.createVertexArray=="function"&&Array.isArray(e.meshes)&&(w=It(M,r.reticleColor),e.meshes.push(w)),typeof window<"u"&&typeof window.addEventListener=="function"){let ie=U=>Math.hypot(U.touches[1].clientX-U.touches[0].clientX,U.touches[1].clientY-U.touches[0].clientY),Y=U=>Math.atan2(U.touches[1].clientY-U.touches[0].clientY,U.touches[1].clientX-U.touches[0].clientX),Q=U=>{this.s&&(U.touches.length===1&&this.placed?j=!0:U.touches.length>=2&&(j=!1,O=ie(U),q=Y(U)))},re=U=>{if(!this.s||U.touches.length<2)return;let z=ie(U),oe=Y(U);if(O&&O>4&&r.arScale!=="fixed"&&(W=Math.max(.15,Math.min(6,W*(z/O)))),q!==null){let ne=oe-q;ne>Math.PI&&(ne-=Math.PI*2),ne<-Math.PI&&(ne+=Math.PI*2),H-=ne}O=z,q=oe},te=U=>{(!U.touches||U.touches.length===0)&&(j=!1),(!U.touches||U.touches.length<2)&&(O=null,q=null)};window.addEventListener("touchstart",Q,{passive:!0}),window.addEventListener("touchmove",re,{passive:!0}),window.addEventListener("touchend",te,{passive:!0}),window.addEventListener("touchcancel",te,{passive:!0}),N=()=>{window.removeEventListener("touchstart",Q),window.removeEventListener("touchmove",re),window.removeEventListener("touchend",te),window.removeEventListener("touchcancel",te)}}e.setXRSessionActive?.(!0);let k=(ie,Y)=>{if(this.s!==m)return;m.requestAnimationFrame(k);let Q=X>0?Math.min(Math.max((ie-X)/1e3,0),.1):1/60;X=ie,e?.stepXRUpdate?.(Q);let re=Y.getViewerPose(v);if(!re)return;let te=re.views?.[0];if(!D&&te?.transform){let J=te.transform.position,ee=te.transform.matrix,me=J?.x??(ee?ee[12]:0),ae=J?.y??(ee?ee[13]:0),ce=J?.z??(ee?ee[14]:0),le=ee?-ee[8]:0,G=ee?-ee[10]:-1,se=Math.hypot(le,G);se>1e-4?(le/=se,G/=se):(le=0,G=-1),A=[me+le*1.2,ae-.25,ce+G*1.2],H=Math.atan2(-le,-G),D=!0}if(y&&typeof Y.getHitTestResults=="function"&&(!this.placed||j)){let J=Y.getHitTestResults(y)||[],ee=!1;for(let me of J){let ae=me.getPose(v);if(ae?.transform?.matrix){let ce=ae.transform.matrix,le=ce[5];if(r.arPlacement==="wall"&&Math.abs(le)>.35||r.arPlacement==="floor"&&Math.abs(le)<.65)continue;C||(C=new Float32Array(16)),C.set(ce),I=[ce[12],ce[13],ce[14]],this.placed&&j&&(F=[ce[12],ce[13],ce[14]]),w&&(w.visible=!this.placed||j,w.transform.set(ce)),!this.placed&&P&&(P.textContent="Surface found \u2022 Tap to place \u2022 Pinch to scale"),r.onHit?.(C),ee=!0;break}}!ee&&w&&(w.visible=!1)}lt(_,this.placed?F:I||A,h,H,p*W),this.placed&&this.placedMat.set(_),e.modelRootMatrix&&e.modelRootMatrix.set(_);for(let J of K)J.onXRFrame?.(e,m,Y,v);let U=e.getGLContext?.()||e?.gl,z=m.renderState?.baseLayer;U&&z&&z.framebuffer!==void 0&&U.bindFramebuffer(36160,z.framebuffer);let oe=x==="immersive-ar",ne=re.views||[];for(let J=0;J<ne.length;J++){let ee=ne[J];if(typeof e.renderXRView=="function"){let me;if(z&&typeof z.getViewport=="function"){let ae=z.getViewport(ee);ae&&ae.width>0&&ae.height>0&&(me=[ae.x,ae.y,ae.width,ae.height])}else z?.framebufferWidth>0&&z?.framebufferHeight>0&&(me=[0,0,z.framebufferWidth,z.framebufferHeight]);e.renderXRView(ee,_,this.placed,me,oe,J)}}U&&z&&z.framebuffer&&U.bindFramebuffer(36160,null)};m.requestAnimationFrame(k)}catch(M){throw typeof m.end=="function"&&await m.end().catch(()=>{}),$(),r.onError?.(M),M}}async stop(){let e=this.s;if(e)try{await e.end()}catch{}finally{this.cleanFn?.()}else this.cleanFn?.()}};async function _t(n){let e=await qe(),t=n.preferredModes||["quick-look","webxr","scene-viewer"],i=null;for(let l of t)if(e.availableModes.includes(l)){i=l;break}if(i||(i=e.bestMode),!i)return{mode:"quick-look",success:!1,error:new Error("No augmented reality viewing mode is supported on this device.")};let r={...n.quickLookOptions,allowScale:n.arScale==="fixed"?!1:n.quickLookOptions?.allowScale},s={...n.sceneViewerOptions,resizable:n.arScale==="fixed"?!1:n.sceneViewerOptions?.resizable,enableVerticalPlacement:n.arPlacement==="wall"?!0:n.sceneViewerOptions?.enableVerticalPlacement},u={...n.webXROptions,arScale:n.arScale||n.webXROptions?.arScale,arPlacement:n.arPlacement||n.webXROptions?.arPlacement};try{if(i==="quick-look"){let l;if(n.model instanceof Blob&&n.model.type==="model/vnd.usdz+zip")l=n.model;else{if(typeof n.model=="string")return He(n.model,r),{mode:"quick-look",success:!0};l=Xe(n.model)}return He(l,r),{mode:"quick-look",success:!0}}if(i==="scene-viewer"){let l=n.glbUrl||(typeof n.model=="string"?n.model:null);if(!l)throw new Error("Scene Viewer requires a hosted GLB URL (glbUrl option).");return mt(l,s),{mode:"scene-viewer",success:!0}}if(i==="webxr"){if(!n.view)throw new Error("WebXR AR mode requires an active ThreeView instance.");let l=new Pe(u);return await l.start(n.view,n.element),{mode:"webxr",success:!0,session:l}}}catch(l){return{mode:i,success:!1,error:l}}return{mode:i,success:!1,error:new Error(`Unhandled AR mode: ${i}`)}}