@liveroom-tech/react-immersive 5.0.2 → 5.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/README.md +1030 -59
  2. package/dist/binding-builder.css +1 -1
  3. package/dist/binding-builder.js +17 -12
  4. package/dist/binding-builder.mjs +1 -1
  5. package/dist/chunk-4NLJSD3S.mjs +1 -0
  6. package/dist/chunk-B7REIGDG.mjs +1 -0
  7. package/dist/chunk-HYFJ5DYJ.mjs +1 -0
  8. package/dist/chunk-QC3NT76G.mjs +3 -0
  9. package/dist/chunk-T3M3BQ7H.mjs +32 -0
  10. package/dist/chunk-ZPK67UG7.mjs +1 -0
  11. package/dist/hosted.css +1 -1
  12. package/dist/hosted.d.mts +4 -3
  13. package/dist/hosted.d.ts +4 -3
  14. package/dist/hosted.js +16 -11
  15. package/dist/hosted.mjs +1 -1
  16. package/dist/index.css +1 -1
  17. package/dist/index.d.mts +85 -10
  18. package/dist/index.d.ts +85 -10
  19. package/dist/index.js +15 -10
  20. package/dist/index.mjs +1 -1
  21. package/dist/materialVariants-DnZe9eMC.d.mts +309 -0
  22. package/dist/materialVariants-DnZe9eMC.d.ts +309 -0
  23. package/dist/modelInfo-BYebMPdZ.d.mts +43 -0
  24. package/dist/modelInfo-XfUQO7C_.d.ts +43 -0
  25. package/dist/{ModelViewer-CbbJT85n.d.mts → modelViewerProps-CIZ2R_Fv.d.ts} +164 -43
  26. package/dist/{ModelViewer-DOexHkJC.d.ts → modelViewerProps-DoRiTZMn.d.mts} +164 -43
  27. package/dist/{objectCatalog-5W8n5xNQ.d.ts → rendererBackend-QwMzISTn.d.mts} +304 -5
  28. package/dist/{objectCatalog-5W8n5xNQ.d.mts → rendererBackend-QwMzISTn.d.ts} +304 -5
  29. package/dist/simple-model-viewer.css +1 -1
  30. package/dist/simple-model-viewer.d.mts +32 -4
  31. package/dist/simple-model-viewer.d.ts +32 -4
  32. package/dist/simple-model-viewer.js +3 -3
  33. package/dist/simple-model-viewer.mjs +1 -1
  34. package/dist/utils.d.mts +5 -4
  35. package/dist/utils.d.ts +5 -4
  36. package/dist/utils.js +1 -1
  37. package/dist/utils.mjs +1 -1
  38. package/package.json +2 -1
  39. package/dist/chunk-3GX7DOGS.mjs +0 -3
  40. package/dist/chunk-AH5NAZWX.mjs +0 -27
  41. package/dist/chunk-BGYK4Y2Y.mjs +0 -1
  42. package/dist/chunk-WFEYRUZC.mjs +0 -1
  43. package/dist/chunk-XTLSAYAQ.mjs +0 -1
  44. package/dist/modelInfo-CEmmvVCH.d.mts +0 -17
  45. package/dist/modelInfo-CEmmvVCH.d.ts +0 -17
package/dist/index.mjs CHANGED
@@ -1 +1 @@
1
- "use client";import{b as De,d as Ne}from"./chunk-SEESCGUS.mjs";import{a as ze}from"./chunk-MMO7KCYU.mjs";import{a as ee,b as we,c as re,d as ye,e as Ve,f as Ce,g as gt}from"./chunk-WFEYRUZC.mjs";import{b as at,j as he,r as _e,s as Oe}from"./chunk-AH5NAZWX.mjs";import"./chunk-XTLSAYAQ.mjs";import{a as ct,c as lt,g as N,o as le,r as Ue,t as dt,u as ut,v as ft,w as Fe,y as mt,z as pt}from"./chunk-BGYK4Y2Y.mjs";import"./chunk-JR557W27.mjs";import{jsx as bt}from"react/jsx-runtime";function We(e){return ze("model-viewer","ModelViewer"),bt(_e,{...Ne(e,De)})}import{useCallback as pe,useRef as Ze}from"react";import{useCallback as k,useMemo as $e,useState as ht}from"react";var Ke={baseColor:"texture",metalness:"metalnessMap",roughness:"roughnessMap",emissive:"emissiveMap",alpha:"alphaMap",normal:"normalMap",bump:"bumpMap",ao:"aoMap",displacement:"displacementMap",clearcoat:"clearcoatMap",clearcoatRoughness:"clearcoatRoughnessMap",clearcoatNormal:"clearcoatNormalMap",anisotropy:"anisotropyMap",transmission:"transmissionMap",thickness:"thicknessMap",sheenColor:"sheenColorMap",sheenRoughness:"sheenRoughnessMap",specularIntensity:"specularIntensityMap",specularColor:"specularColorMap"};function Ge(e){if(e)return Object.fromEntries(Object.entries(e).map(([t,r])=>[t,r&&typeof r=="object"?{...r}:r]))}function wt(e){return Object.fromEntries(Object.entries(e).filter(([,t])=>t.visible===!1).map(([t])=>[t,!0]))}function je(e){let[t,r]=ht(e),s=k((o,u)=>{r(a=>u===void 0?re(a,o):re(a,o,u))},[]),d=k((o,u)=>s(o,ye(u)),[s]),b=k((o,u)=>d(o,{baseColor:u}),[d]),g=k((o,u,a="baseColor")=>{let m=Ke[a],O=typeof u=="string"?{path:u}:u;s(o,{style:{material:{[m]:O}}})},[s]),p=k((o,u="baseColor")=>{let a=Ke[u];s(o,{style:{material:{[a]:void 0}}})},[s]),j=k((o,u)=>{r(a=>{let m=N(a,o);if(!m)return a;let O=Ge(a[m]?.style?.material),L=ee(a,u);if(L.length===0)return a;let U=a;for(let $ of L){let W=a[$];W&&(U===a&&(U={...a}),U[$]={...W,style:{...W.style,material:Ge(O)}})}return U})},[]),V=k(o=>s(o,{style:{material:void 0}}),[s]),y=k((o,u)=>s(o,{transform:u}),[s]),h=k(o=>s(o,{transform:void 0}),[s]),x=k((o,u)=>s(o,{metadata:u}),[s]),A=k(o=>we(t,o),[t]),v=k(o=>ee(t,o).map(u=>t[u]?.id??u),[t]),I=k(o=>{let u=N(t,o);return u?t[u]?.style?.material??null:null},[t]),E=k(o=>s(o,{visible:!1}),[s]),f=k(o=>s(o,{visible:!0}),[s]),C=k(o=>{r(u=>{let a=ee(u,o).reduce((m,O)=>{let L=u[O];return L&&m.push({ids:O,patch:{visible:L.visible===!1}}),m},[]);return re(u,a)})},[r]),M=k(()=>{r(o=>re(o,Object.keys(o),{visible:!0}))},[r]),B=$e(()=>wt(t),[t]),D=$e(()=>Object.keys(B).map(o=>t[o]?.id??o),[B,t]),H=k(o=>{let u=N(t,o);return u?t[u]?.visible===!1:!1},[t]);return{objectBindings:t,setObjectBindings:r,updateObjectBindings:s,setMaterial:d,setBaseColor:b,setTexture:g,clearTexture:p,copyMaterial:j,resetMaterial:V,getMaterial:I,setTransform:y,resetTransform:h,updateMetadata:x,selectObjectBindings:A,selectObjectBindingIds:v,hiddenObjects:B,hiddenObjectIds:D,hideObject:E,showObject:f,toggleObjectVisibility:C,isObjectHidden:H,clearHiddenObjects:M}}import{useCallback as z,useMemo as yt,useRef as Vt,useState as Ct}from"react";function Se(e){let t=Vt(null),[r,s]=Ct(()=>{let f=typeof e=="function"?e():e;return t.current=f,f}),d=z(f=>{s(C=>{let M=typeof f=="function"?f(C):f;return Ve(C,M)})},[]),b=z(()=>{let f=t.current;f&&s(f)},[]),g=z((f,C)=>{d(M=>({lighting:{lights:M.lighting.lights.map(B=>B.id===f?{...B,...C}:B)}}))},[d]),p=z(f=>{d(C=>C.lighting.lights.some(M=>M.id===f.id)?{}:{lighting:{lights:[...C.lighting.lights,Ce(f)]}})},[d]),j=z(f=>{d(C=>({lighting:{lights:C.lighting.lights.filter(M=>M.id!==f)}}))},[d]),V=z((f,C)=>g(f,{intensity:C}),[g]),y=z((f,C)=>g(f,{color:C}),[g]),h=z(f=>g(f,{visible:!0}),[g]),x=z(f=>g(f,{visible:!1}),[g]),A=z(f=>{d(C=>({lighting:{lights:C.lighting.lights.map(M=>M.id===f?{...M,visible:!M.visible}:M)}}))},[d]),v=z((f,C)=>g(f,{attachment:C,attachedToCamera:!1}),[g]),I=z(f=>g(f,{attachment:void 0}),[g]),E=yt(()=>({items:r.lighting.lights,get:f=>r.lighting.lights.find(C=>C.id===f),add:p,update:g,remove:j,setIntensity:V,setColor:y,show:h,hide:x,toggle:A,attach:v,detach:I}),[r.lighting.lights,p,g,j,V,y,h,x,A,v,I]);return{sceneConfig:r,setSceneConfig:s,updateSceneConfig:d,resetSceneConfig:b,lights:E}}import{useCallback as Be}from"react";function ve({bindings:e,scene:t,camera:r,animations:s,onAction:d}){let{objectBindings:b,updateObjectBindings:g,showObject:p,hideObject:j,toggleObjectVisibility:V}=e,y=t?.updateSceneConfig,h=r?.focusObject,x=r?.fitScene,A=r?.resetView,v=r?.setCameraTarget,I=r?.setCameraState,E=s?.play,f=s?.pause,C=s?.stop,M=s?.setSpeed,B=s?.seek,D=Be(u=>{let a=N(b,u);return a?b[a]?.actions??[]:[]},[b]),H=Be(async u=>{for(let a of u.action.effects??[]){if("objectBindings"in a){g(a.target,a.objectBindings);continue}if("sceneConfig"in a){y?.(a.sceneConfig);continue}if("visibility"in a){a.visibility==="show"?p(a.target):a.visibility==="hide"?j(a.target):V(a.target);continue}if("camera"in a){let O=a.camera;O.type==="focus-object"?await h?.(O.objectId??u.objectId):O.type==="fit-scene"?await x?.():O.type==="reset"?await A?.():O.type==="set-target"?await v?.(O.target,O.transition??!0):await I?.(O.state,O.transition??!0);continue}let m=a.animation;m.type==="play"?E?.(m.clip):m.type==="pause"?f?.():m.type==="stop"?C?.():m.type==="set-speed"?M?.(m.speed):B?.(m.time)}await d?.(u)},[x,h,j,d,f,E,A,B,M,I,v,p,C,V,g,y]),o=Be(async(u,a)=>{let m=N(b,u);if(!m)return null;let O=b[m],L=O?.actions?.find($=>$.id===a);if(!O||!L)return null;let U={objectId:m,action:L,binding:O};return await H(U),U},[H,b]);return{getActionsForObject:D,handleAction:H,runAction:o}}import{useCallback as de,useRef as Je}from"react";function Ot(e){return typeof e=="function"?e:e?.handleViewerReady??null}function Me(...e){let t=Je(null),r=Je(e);r.current=e;let s=de(p=>{t.current=p;let j=new Set;for(let V of r.current){let y=Ot(V);y&&!j.has(y)&&(j.add(y),y(p))}},[]),d=de(()=>t.current,[]),b=de(p=>{let j=t.current;return j?j.captureImage(p):Promise.reject(new Error("ModelViewer is not ready yet."))},[]),g=de(()=>{let p=t.current;return p?(p.invalidate(),!0):!1},[]);return{handleViewerReady:s,getViewer:d,captureImage:b,invalidate:g}}import{useCallback as R,useEffect as jt,useRef as G}from"react";import{Material as St,PointLight as Bt,Vector3 as vt}from"three";var Ae=["emissiveIntensity","opacity","metalness","roughness","transmission","clearcoat","clearcoatRoughness","ior","thickness"],ue=1;function fe(e){return typeof e=="string"?[e]:e}function ge(e,t=0,r=1){return Math.min(r,Math.max(t,e))}function Re(e,t){return e+Math.random()*(t-e)}function Xe([e,t],r){return e+(t-e)*r}function xe([e,t],r){return[e[0]+(t[0]-e[0])*r,e[1]+(t[1]-e[1])*r,e[2]+(t[2]-e[2])*r]}function qe(e,t){let r=ge(e);switch(t){case"ease-in":return r*r;case"ease-out":return 1-(1-r)*(1-r);case"ease-in-out":return r<.5?2*r*r:1-Math.pow(-2*r+2,2)/2;default:return r}}function Mt(e){let t=e.material;return t?(Array.isArray(t)?t:[t]).filter(r=>r instanceof St):[]}function Rt(e){let t={opacity:e.opacity,transparent:e.transparent};e.color&&(t.baseColor=`#${e.color.getHexString()}`),e.emissive&&(t.emissive=`#${e.emissive.getHexString()}`);for(let r of Ae){let s=e[r];typeof s=="number"&&(t[r]=s)}return t}function Ye(e,t){t.baseColor!==void 0&&e.color&&e.color.set(t.baseColor),t.emissive!==void 0&&e.emissive&&e.emissive.set(t.emissive);for(let r of Ae){let s=t[r];s!==void 0&&typeof e[r]=="number"&&(e[r]=s)}t.transparent!==void 0&&(e.transparent=t.transparent),e.needsUpdate=!0}function xt(e){return{position:[e.position.x,e.position.y,e.position.z],rotation:[e.rotation.x,e.rotation.y,e.rotation.z],scale:[e.scale.x,e.scale.y,e.scale.z],visible:e.visible}}function At(e,t){if(t.position&&e.position.set(...t.position),t.rotation&&e.rotation.set(...t.rotation),t.scale!==void 0){let r=typeof t.scale=="number"?[t.scale,t.scale,t.scale]:t.scale;e.scale.set(...r)}t.visible!==void 0&&(e.visible=t.visible),e.updateMatrix(),e.updateMatrixWorld(!0)}function Pe(e={}){let t=G(e);t.current=e;let r=G(null),s=G(null),d=G(null),b=G(new Map),g=G(new Map),p=G(new Map),j=G(new Map),V=R(n=>{let i=r.current;if(!i)return null;let l=N(i.objectBindings,n);return i.raw.nodes[n]??(l?i.raw.nodes[l]:null)??(i.raw.scene?Ue(i.raw.scene,n):null)??null},[]),y=R(n=>{let i=r.current;return i?typeof n=="object"&&!Array.isArray(n)?ee(i.objectBindings,n):fe(n).map(l=>N(i.objectBindings,l)??l):typeof n=="string"?[n]:Array.isArray(n)?n:[]},[]),h=R(()=>{r.current?.invalidate()},[]),x=R((n,i)=>{let l=!1;for(let c of y(n)){let w=V(c);if(w)for(let P of Mt(w))p.current.has(P)||p.current.set(P,Rt(P)),Ye(P,i),l=!0}return l},[V,y]),A=R((n,i)=>{let l=x(n,i);return l&&h(),l},[h,x]),v=R((n,i)=>{let l=!1;for(let c of y(n)){let w=V(c);w&&(j.current.has(w)||j.current.set(w,xt(w)),At(w,i),l=!0)}return l},[V,y]),I=R((n,i)=>{let l=v(n,i);return l&&h(),l},[h,v]),E=R(n=>{let i=V(n);if(!i)return null;i.updateWorldMatrix(!0,!1);let l=i.getWorldPosition(new vt);return[l.x,l.y,l.z]},[V]),f=R(n=>{let i=g.current.get(n);return i?(i.light.removeFromParent(),i.light.dispose(),g.current.delete(n),h(),!0):!1},[h]),C=R(n=>{let i=V(n.target);if(!i)return!1;let l=g.current.get(n.id),c=l?.light??new Bt;return l&&l.target!==n.target&&c.removeFromParent(),c.name=`react-immersive-runtime-light:${n.id}`,c.color.set(n.color??"#ffffff"),c.intensity=n.intensity??1,c.distance=n.distance??0,c.decay=n.decay??2,c.castShadow=n.castShadow??!1,c.position.set(...n.offset??[0,0,0]),c.parent!==i&&i.add(c),g.current.set(n.id,{light:c,target:n.target}),h(),!0},[h,V]),M=R((n,i)=>{let l=g.current.get(n);if(!l)return!1;if(i.target&&i.target!==l.target){let c=V(i.target);if(!c)return!1;l.light.removeFromParent(),c.add(l.light),l.target=i.target}return i.color!==void 0&&l.light.color.set(i.color),i.intensity!==void 0&&(l.light.intensity=i.intensity),i.distance!==void 0&&(l.light.distance=i.distance),i.decay!==void 0&&(l.light.decay=i.decay),i.offset!==void 0&&l.light.position.set(...i.offset),i.castShadow!==void 0&&(l.light.castShadow=i.castShadow),h(),!0},[h,V]),B=R((n,i)=>{let l=c=>i[c%i.length]??0;for(let c of n.materials??[])y(c.targets).forEach((w,P)=>{let S=l(P),T={};for(let K of Ae){let F=c.values[K];F&&(T[K]=Xe(F,S))}x(w,T)});for(let c of n.transforms??[])y(c.targets).forEach((w,P)=>{let S=l(P),T={};c.values.position&&(T.position=xe(c.values.position,S)),c.values.rotation&&(T.rotation=xe(c.values.rotation,S)),c.values.scale&&(T.scale=xe(c.values.scale,S)),v(w,T)});for(let c of n.lights??[])fe(c.lights).forEach((w,P)=>{let S=g.current.get(w);S&&(S.light.intensity=Xe(c.intensity,l(P)))})},[y,x,v]),D=G(()=>{}),H=G(()=>{});H.current=n=>{d.current=null;let i=!1;for(let[l,c]of b.current){c.startedAt===null&&(c.startedAt=n);let w=c.lastFrameAt??n;c.lastFrameAt=n;let P=c.override&&c.override.until>n?c.override.level:null;c.override&&P===null&&(c.override=null);let S=c.update(n,n-c.startedAt,Math.min(100,n-w),P);i=!0,S||(b.current.delete(l),c.onComplete?.())}i&&h(),b.current.size>0&&D.current()},D.current=()=>{d.current!==null||typeof requestAnimationFrame>"u"||(d.current=requestAnimationFrame(n=>H.current(n)))};let o=R(n=>(b.current.set(n.id,n),D.current(),n.id),[]),u=R((n,i={})=>{let l=i.id??`transition-${ue++}`,c=Math.max(1,i.duration??400),w=i.easing??"ease-in-out";return o({id:l,startedAt:null,lastFrameAt:null,override:null,onComplete:i.onComplete,update:(P,S,T,K)=>{let F=K??qe(S/c,w);return B(n,[F]),S<c}})},[B,o]),a=R((n,i={})=>{let l=i.id??`pulse-${ue++}`,c=Math.max(1,i.duration??1e3),w=i.minLevel??0,P=i.maxLevel??1,S=i.repeat??1/0,T=i.synchronized??!0,K=Math.max(1,...[...n.materials??[],...n.transforms??[]].map(F=>y(F.targets).length),...(n.lights??[]).map(F=>fe(F.lights).length));return o({id:l,startedAt:null,lastFrameAt:null,override:null,onComplete:i.onComplete,update:(F,te,ne,J)=>{let _=te/c,X=Array.from({length:T?1:K},(ie,Z)=>{if(J!==null)return J;let ce=_+(T?0:Z/K),Y=.5-Math.cos(ce%1*Math.PI*2)/2;return w+(P-w)*Y});return B(n,X),S===1/0||_<S}})},[B,o,y]),m=R((n,i={})=>{let l=i.id??`timeline-${ue++}`,c=i.repeat??1,w=n.map(S=>({...S,duration:Math.max(1,S.duration),hold:Math.max(0,S.hold??0)})),P=Math.max(1,w.reduce((S,T)=>S+T.duration+T.hold,0));return o({id:l,startedAt:null,lastFrameAt:null,override:null,onComplete:i.onComplete,update:(S,T,K,F)=>{if(w.length===0||c<=0)return!1;let te=T/P;if(c!==1/0&&te>=c){for(let _ of w)B(_.channels,[1]);return!1}let ne=T%P,J=0;for(let _ of w){let X=J+_.duration,ie=X+_.hold;if(ne>=X){B(_.channels,[F??1]),J=ie;continue}if(ne>=J){let Z=F??qe((ne-J)/_.duration,_.easing??"ease-in-out");B(_.channels,[Z]);break}}return!0}})},[B,o]),O=R((n,i={})=>{let l=i.id??`flicker-${ue++}`,c=i.synchronized??!0,w=i.minLevel??.15,P=i.maxLevel??1,S=i.interval??[45,160],T=typeof S=="number"?[S,S]:S,K=[Math.max(1,Math.min(...T)),Math.max(1,Math.max(...T))],F=ge(i.response??.7,.01,1),te=ge(i.blackoutChance??.08),ne=ge(i.flashChance??.12),J=i.flashLevel??1.15,_=Math.max(1,...[...n.materials??[],...n.transforms??[]].map(Y=>y(Y.targets).length),...(n.lights??[]).map(Y=>fe(Y.lights).length)),X=c?1:_,ie=Array.from({length:X},()=>w),Z=Array.from({length:X},()=>w),ce=Array.from({length:X},()=>0);return o({id:l,startedAt:null,lastFrameAt:null,override:null,onComplete:i.onComplete,update:(Y,rt,ot,ke)=>{for(let q=0;q<X;q+=1){if(ke!==null)Z[q]=ke;else if(Y>=ce[q]){let He=Math.random();Z[q]=He<te?Re(0,Math.min(.04,w)):He<te+ne?J:Re(w,P),ce[q]=Y+Re(...K)}let st=1-Math.pow(1-F,Math.max(1,ot)/16.67);ie[q]+=(Z[q]-ie[q])*st}return B(n,ie),i.duration===void 0||rt<i.duration}})},[B,o,y]),L=R((n,i,l)=>{let c=b.current.get(n);if(!c)return!1;let w=typeof performance>"u"?Date.now():performance.now();return c.override={level:i,until:w+Math.max(0,l)},D.current(),!0},[]),U=R(n=>b.current.delete(n),[]),$=R(()=>{b.current.clear(),d.current!==null&&typeof cancelAnimationFrame<"u"&&(cancelAnimationFrame(d.current),d.current=null)},[]),W=R(()=>{for(let[n,i]of p.current)Ye(n,i);p.current.clear();for(let[n,i]of j.current)n.position.set(...i.position),n.rotation.set(...i.rotation),n.scale.set(...i.scale),n.visible=i.visible,n.updateMatrix(),n.updateMatrixWorld(!0);j.current.clear();for(let n of g.current.values())n.light.removeFromParent(),n.light.dispose();g.current.clear(),h()},[h]),be=R(()=>{$(),W()},[W,$]),it=R(n=>{s.current&&s.current!==n.raw.scene&&W(),r.current=n,s.current=n.raw.scene,t.current.onViewerReady?.(n)},[W]);return jt(()=>()=>{be(),r.current=null,s.current=null},[be]),{handleViewerReady:it,setMaterial:A,setTransform:I,getWorldPosition:E,addPointLight:C,updatePointLight:M,removePointLight:f,transition:u,timeline:m,pulse:a,flicker:O,overrideEffect:L,stopEffect:U,stopAllEffects:$,resetRuntime:be}}import{useCallback as Pt,useState as Et}from"react";function Ee(){let[e,t]=Et(null),r=Pt(s=>{t(s)},[t]);return{hoveredObjectBinding:e,handleHoveredObject:r}}import{useCallback as me,useState as oe}from"react";function Te(){let[e,t]=oe(!0),[r,s]=oe(!1),[d,b]=oe(null),[g,p]=oe(null),[j,V]=oe(0),[y,h]=oe([]),x=me(E=>{p(E.bounds),V(E.objectCount),b(null),t(!1),s(!0)},[]),A=me(E=>h(E),[]),v=me(E=>{b(E),p(null),V(0),h([]),t(!1),s(!1)},[]),I=me(()=>{t(!0),s(!1),b(null),p(null),V(0),h([])},[]);return{isLoading:e,isReady:r,error:d,bounds:g,objectCount:j,objects:y,handleModelLoaded:x,handleObjectCatalog:A,handleLoadError:v,resetModelState:I}}import{useCallback as Qe,useState as Tt}from"react";function Le(e=null){let[t,r]=Tt(e),s=Qe(b=>{r(b)},[r]),d=Qe(()=>{r(null)},[]);return{selectedObjectBinding:t,setSelectedObjectBinding:r,handleObjectSelect:s,clearSelection:d}}var Lt={};function It(e={}){let t=Ze(e);t.current=e;let r=Ze(e.bindings===void 0||e.bindings==="auto"),s=je(()=>{let o=t.current.bindings;return o===void 0||o==="auto"?Lt:typeof o=="function"?o():o}),d=Se(()=>{let o=t.current.sceneConfig;return o===void 0?le:typeof o=="function"?o():o}),b=Le(),g=Ee(),p=he(e.camera),j=Te(),V=Oe(),y=Pe(),h=Me(p,y),x=ve({bindings:s,scene:d,camera:p,animations:V,onAction:e.onAction}),{setObjectBindings:A}=s,{handleObjectCatalog:v}=j,I=pe(o=>{v(o),r.current&&A(u=>{let a=Fe(o.map(m=>m.name));for(let m of Object.keys(a))u[m]&&(a[m]=u[m]);return a})},[v,A]),{handleObjectSelect:E}=b,f=pe(o=>{E(o),t.current.onObjectSelect?.(o)},[E]),{handleHoveredObject:C}=g,M=pe(o=>{C(o),t.current.onObjectHover?.(o)},[C]),{handleLoadError:B}=j,D=pe(o=>{B(o),t.current.onLoadError?.(o)},[B]),H=e.sceneConfig!==void 0||d.sceneConfig!==le;return{props:{objectBindings:s.objectBindings,onObjectBindingsChange:A,selectedObject:b.selectedObjectBinding,onObjectSelect:f,onObjectHover:M,onCameraChange:p.handleCameraChange,onViewerReady:h.handleViewerReady,onModelLoaded:j.handleModelLoaded,onLoadError:D,onObjectCatalog:I,onAnimationsReady:V.handleAnimationsReady,onAction:x.handleAction,onSceneConfigChange:d.setSceneConfig,...H?{sceneConfig:d.sceneConfig}:{}},bindings:s,selection:b,hover:g,camera:p,model:j,animations:V,actions:x,scene:d,effects:y,connection:h}}import{useMemo as kt}from"react";function Ht(e,t){return kt(()=>{if(!t)return null;let r=e[t];return r||(Object.values(e).find(s=>s.id===t||s.modelObjectId===t)??null)},[e,t])}import{useMemo as Ut}from"react";function Ft(e){return Ut(()=>Object.values(e).map(t=>t.modelObjectId),[e])}import{useCallback as se,useEffect as Ie,useRef as Q,useState as _t}from"react";function nt(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function ae(e){return typeof e=="number"&&Number.isFinite(e)}function et(e){return Array.isArray(e)&&e.length===3&&e.every(ae)}function Dt(e){return!nt(e)||!et(e.position)||!et(e.target)||e.fov!==null&&!ae(e.fov)||!ae(e.zoom)||e.zoom<=0||e.azimuthAngle!==void 0&&!ae(e.azimuthAngle)||e.polarAngle!==void 0&&!ae(e.polarAngle)?null:{position:e.position,target:e.target,fov:e.fov,zoom:e.zoom,azimuthAngle:e.azimuthAngle,polarAngle:e.polarAngle}}function Nt(e){if(!nt(e))return null;let t;if(e.camera!==void 0){let d=Dt(e.camera);if(!d)return null;t=d}let r;if(e.hidden!==void 0){if(!Array.isArray(e.hidden)||!e.hidden.every(d=>typeof d=="string"))return null;r=e.hidden}let s;if(e.selected===null||typeof e.selected=="string")s=e.selected;else if(e.selected!==void 0)return null;return{camera:t,hidden:r,selected:s}}function tt(e,t,r){let s=Object.values(t).filter(d=>d.visible===!1).map(d=>d.id);return{camera:e??void 0,hidden:s,selected:r?.id??null}}function zt({cameraState:e,setCameraState:t,objectBindings:r,onObjectBindingsChange:s,selectedObjectBinding:d,setSelectedObjectBinding:b,paramKey:g="view",debounceMs:p=400,autoSync:j=!0}){let V=Q(null),y=Q(null),h=Q(null),x=Q(null),A=Q(null),v=se(()=>{A.current!==null&&(window.clearTimeout(A.current),A.current=null),h.current=null,x.current=null},[]),I=se(()=>{let a=tt(e,r,d);return`${g}=${encodeURIComponent(JSON.stringify(a))}`},[e,r,d,g]),E=se(()=>{let a=new URL(window.location.href);return a.hash=I(),a.toString()},[I]),f=se(a=>{let m=new URL(window.location.href);m.hash=a,window.history.replaceState(null,"",m.toString()),y.current=a,V.current=new URLSearchParams(m.hash.slice(1)).get(g)},[g]),C=se(()=>{v(),f(I())},[I,v,f]),M=Q({cameraState:e,objectBindings:r,selectedObjectBinding:d});M.current={cameraState:e,objectBindings:r,selectedObjectBinding:d};let[B,D]=_t(!1);Ie(()=>{if(!j||!B){v();return}let a=M.current,m=tt(a.cameraState,a.objectBindings,a.selectedObjectBinding),O=`${g}=${encodeURIComponent(JSON.stringify(m))}`;if(O===y.current){v();return}O===h.current&&p===x.current||(v(),h.current=O,x.current=p,A.current=window.setTimeout(()=>{A.current=null,h.current=null,x.current=null,f(O)},Math.max(0,p)))},[j,e,v,p,r,g,B,d,f]),Ie(()=>v,[v]);let H=Q(null),o=Q(null),u=se(async()=>{D(!0);let a=window.location.hash.startsWith("#")?window.location.hash.slice(1):window.location.hash,m=new URLSearchParams(a).get(g);if(!m)return H.current=null,!1;if(m===V.current||m===H.current||m===o.current)return!1;let O;try{O=JSON.parse(m)}catch{return!1}let L=Nt(O);if(!L)return!1;o.current=m;try{if(L.camera&&await t(L.camera,!1),L.hidden){let U=new Set(L.hidden);s(Object.fromEntries(Object.entries(r).map(([$,W])=>[$,{...W,visible:!U.has(W.id)}])))}if(L.selected!==void 0){let U=L.selected?N(r,L.selected):null;b(U?r[U]:null)}return H.current=m,!0}finally{o.current===m&&(o.current=null)}},[r,s,g,t,b]);return Ie(()=>{let a=()=>{u().catch(()=>{})};return window.addEventListener("hashchange",a),()=>{window.removeEventListener("hashchange",a)}},[u]),{getShareUrl:E,syncUrl:C,restoreFromUrl:u}}export{ct as ACTION_CATALOG,le as DEFAULT_SCENE_CONFIG,pt as MATERIAL_BLENDING_MODES,mt as MATERIAL_SIDES,at as MODEL_VIEWER_PRESETS,We as ModelViewer,ft as buildBindingsFromNodes,ut as createDefaultBinding,gt as defineObjectBindings,lt as findCatalogAction,dt as inferType,ye as material,re as patchBindings,Ve as patchSceneConfig,Ce as sceneLight,ee as selectBindingKeys,we as selectBindings,Ht as useObjectBinding,Ft as useObjectBindingIds,je as useObjectBindings,Se as useSceneConfig,zt as useShareableViewerState,It as useViewer,ve as useViewerActions,Oe as useViewerAnimations,he as useViewerCamera,Me as useViewerConnection,Pe as useViewerEffects,Ee as useViewerHover,Te as useViewerModel,Le as useViewerSelection};
1
+ "use client";import{b as qe,d as Ye}from"./chunk-SEESCGUS.mjs";import{a as Qe}from"./chunk-MMO7KCYU.mjs";import{a as ce,b as je,c as Se,d as Be,e as It}from"./chunk-HYFJ5DYJ.mjs";import{A as et,B as ve,b as $e,c as jt,n as ye,x as Xe,y as Ze,z as Oe}from"./chunk-T3M3BQ7H.mjs";import{a as ze,b as Ge,u as We}from"./chunk-ZPK67UG7.mjs";import{A as At,C as Et,D as Tt,E as Lt,F as Je,I as kt,J as Dt,a as St,c as Bt,g as W,p as vt,q as pe,t as Ke,u as ne,v as Ce,x as Rt,y as xt,z as Pt}from"./chunk-B7REIGDG.mjs";import{a as Ot,w as Mt}from"./chunk-4NLJSD3S.mjs";import"./chunk-JR557W27.mjs";import{jsx as Ht}from"react/jsx-runtime";function le(e){return Qe("model-viewer","ModelViewer"),Ht(Xe,{...Ye(e,qe)})}import{useCallback as Ut,useEffect as tt,useMemo as nt,useRef as _t,useState as it}from"react";import{jsx as K,jsxs as rt}from"react/jsx-runtime";function ot(e){return K(ze,{labels:e.labels,children:K(Ft,{...e})})}function Ft({before:e,after:t,layout:n="slider",split:s,onSplitChange:l,reveal:h="auto",...d}){let M=Ge(),[C,p]=it(h==="auto");tt(()=>{h==="auto"&&p(!0)},[h]);let[O,m]=it(.5),A=Oe(s??O),x=Ut(I=>{let E=Oe(I);s===void 0&&m(E),l?.(E)},[s,l]),v=nt(()=>Ze(),[]);tt(()=>()=>v.detach(),[v]);let T=[e,t],_=nt(()=>[0,1].map(I=>E=>{v.attach(I,E.raw.controls,E.invalidate)}),[v]),u=T.map((I,E)=>{let{label:H,...b}=I,F={preset:"minimal",...d,...b},w=b.onViewerReady??d.onViewerReady;return{...F,onViewerReady:o=>{_[E](o),w?.(o)}}}),V=[e.label??M("compareBefore"),t.label??M("compareAfter")];(!u[0].modelUrl||!u[1].modelUrl)&&console.error("[react-immersive] CompareViewer needs a modelUrl, shared or on each side.");let R=_t(null);if(!C)return K(We,{className:"ri-compare",background:$e(d.backgroundColor,d.sceneConfig),poster:d.poster??t.poster??e.poster,onReveal:()=>p(!0)});if(n==="side-by-side")return K("div",{className:"ri-compare ri-compare--sideBySide",children:u.map((I,E)=>rt("div",{className:"ri-compare__pane",children:[K(le,{...I}),K("span",{className:"ri-compare__label",children:V[E]})]},E))});let y=`${A*100}%`;return rt("div",{ref:R,className:"ri-compare ri-compare--slider",style:{"--ri-compare-split":y},children:[K("div",{className:"ri-compare__layer",children:K(le,{...u[0]})}),K("div",{className:"ri-compare__layer ri-compare__layer--after",children:K(le,{...u[1]})}),K(et,{split:A,onSplitChange:x,labels:[V[0],V[1]],containerRef:R})]})}import{useCallback as Ve,useRef as mt}from"react";import{useCallback as k,useMemo as st,useState as Nt}from"react";var at={baseColor:"texture",metalness:"metalnessMap",roughness:"roughnessMap",emissive:"emissiveMap",alpha:"alphaMap",normal:"normalMap",bump:"bumpMap",ao:"aoMap",displacement:"displacementMap",clearcoat:"clearcoatMap",clearcoatRoughness:"clearcoatRoughnessMap",clearcoatNormal:"clearcoatNormalMap",anisotropy:"anisotropyMap",transmission:"transmissionMap",thickness:"thicknessMap",sheenColor:"sheenColorMap",sheenRoughness:"sheenRoughnessMap",specularIntensity:"specularIntensityMap",specularColor:"specularColorMap"};function ct(e){if(e)return Object.fromEntries(Object.entries(e).map(([t,n])=>[t,n&&typeof n=="object"?{...n}:n]))}function zt(e){return Object.fromEntries(Object.entries(e).filter(([,t])=>t.visible===!1).map(([t])=>[t,!0]))}function Me(e){let[t,n]=Nt(e),s=k((o,a)=>{n(g=>a===void 0?ce(g,o):ce(g,o,a))},[]),l=k((o,a)=>s(o,je(a)),[s]),h=k((o,a)=>l(o,{baseColor:a}),[l]),d=k((o,a,g="baseColor")=>{let j=at[g],S=typeof a=="string"?{path:a}:a;s(o,{style:{material:{[j]:S}}})},[s]),M=k((o,a="baseColor")=>{let g=at[a];s(o,{style:{material:{[g]:void 0}}})},[s]),C=k((o,a)=>{n(g=>{let j=W(g,o);if(!j)return g;let S=ct(g[j]?.style?.material),N=ne(g,a);if(N.length===0)return g;let q=g;for(let i of N){let r=g[i];r&&(q===g&&(q={...g}),q[i]={...r,style:{...r.style,material:ct(S)}})}return q})},[]),p=k(o=>s(o,{style:{material:void 0}}),[s]),O=k((o,a)=>s(o,{transform:a}),[s]),m=k(o=>s(o,{transform:void 0}),[s]),A=k((o,a)=>s(o,{metadata:a}),[s]),x=k((o,a)=>{n(g=>{let j=g;for(let S of ne(g,o)){let N=g[S],q=a(N.decals??[]);j===g&&(j={...g}),j[S]={...N,decals:q.length>0?q:void 0}}return j})},[]),v=k((o,a)=>{let g=a.id??`decal-${Date.now().toString(36)}-${Math.random().toString(36).slice(2,8)}`;return x(o,j=>[...j.filter(S=>S.id!==g),{...a,id:g}]),g},[x]),T=k((o,a,g)=>x(o,j=>j.map(S=>S.id===a?{...S,...g}:S)),[x]),_=k((o,a)=>x(o,g=>g.filter(j=>j.id!==a)),[x]),u=k(o=>Ce(t,o),[t]),V=k(o=>ne(t,o).map(a=>t[a]?.id??a),[t]),R=k(o=>{let a=W(t,o);return a?t[a]?.style?.material??null:null},[t]),y=k(o=>s(o,{visible:!1}),[s]),I=k(o=>s(o,{visible:!0}),[s]),E=k(o=>{n(a=>{let g=ne(a,o).reduce((j,S)=>{let N=a[S];return N&&j.push({ids:S,patch:{visible:N.visible===!1}}),j},[]);return ce(a,g)})},[n]),H=k(()=>{n(o=>ce(o,Object.keys(o),{visible:!0}))},[n]),b=st(()=>zt(t),[t]),F=st(()=>Object.keys(b).map(o=>t[o]?.id??o),[b,t]),w=k(o=>{let a=W(t,o);return a?t[a]?.visible===!1:!1},[t]);return{objectBindings:t,setObjectBindings:n,updateObjectBindings:s,setMaterial:l,setBaseColor:h,setTexture:d,clearTexture:M,copyMaterial:C,resetMaterial:p,getMaterial:R,setTransform:O,resetTransform:m,updateMetadata:A,addDecal:v,updateDecal:T,removeDecal:_,selectObjectBindings:u,selectObjectBindingIds:V,hiddenObjects:b,hiddenObjectIds:F,hideObject:y,showObject:I,toggleObjectVisibility:E,isObjectHidden:w,clearHiddenObjects:H}}import{useCallback as $,useMemo as Gt,useRef as Wt,useState as $t}from"react";function Re(e){let t=Wt(null),[n,s]=$t(()=>{let u=typeof e=="function"?e():e;return t.current=u,u}),l=$(u=>{s(V=>{let R=typeof u=="function"?u(V):u;return Se(V,R)})},[]),h=$(()=>{let u=t.current;u&&s(u)},[]),d=$((u,V)=>{l(R=>({lighting:{lights:R.lighting.lights.map(y=>y.id===u?{...y,...V}:y)}}))},[l]),M=$(u=>{l(V=>V.lighting.lights.some(R=>R.id===u.id)?{}:{lighting:{lights:[...V.lighting.lights,Be(u)]}})},[l]),C=$(u=>{l(V=>({lighting:{lights:V.lighting.lights.filter(R=>R.id!==u)}}))},[l]),p=$((u,V)=>d(u,{intensity:V}),[d]),O=$((u,V)=>d(u,{color:V}),[d]),m=$(u=>d(u,{visible:!0}),[d]),A=$(u=>d(u,{visible:!1}),[d]),x=$(u=>{l(V=>({lighting:{lights:V.lighting.lights.map(R=>R.id===u?{...R,visible:!R.visible}:R)}}))},[l]),v=$((u,V)=>d(u,{attachment:V,attachedToCamera:!1}),[d]),T=$(u=>d(u,{attachment:void 0}),[d]),_=Gt(()=>({items:n.lighting.lights,get:u=>n.lighting.lights.find(V=>V.id===u),add:M,update:d,remove:C,setIntensity:p,setColor:O,show:m,hide:A,toggle:x,attach:v,detach:T}),[n.lighting.lights,M,d,C,p,O,m,A,x,v,T]);return{sceneConfig:n,setSceneConfig:s,updateSceneConfig:l,resetSceneConfig:h,lights:_}}import{useCallback as xe}from"react";function Pe({bindings:e,scene:t,camera:n,animations:s,isolation:l,onAction:h}){let{objectBindings:d,updateObjectBindings:M,showObject:C,hideObject:p,toggleObjectVisibility:O}=e,m=t?.updateSceneConfig,A=n?.focusObject,x=n?.fitScene,v=n?.resetView,T=n?.setCameraTarget,_=n?.setCameraState,u=s?.play,V=s?.pause,R=s?.stop,y=s?.setSpeed,I=s?.seek,E=l?.handleIsolationChange,H=xe(w=>{let o=W(d,w);return o?d[o]?.actions??[]:[]},[d]),b=xe(async w=>{for(let o of w.action.effects??[]){if("objectBindings"in o){M(o.target,o.objectBindings);continue}if("sceneConfig"in o){m?.(o.sceneConfig);continue}if("isolation"in o){E?.(o.isolation);continue}if("visibility"in o){o.visibility==="show"?C(o.target):o.visibility==="hide"?p(o.target):O(o.target);continue}if("camera"in o){let g=o.camera;g.type==="focus-object"?await A?.(g.objectId??w.objectId):g.type==="fit-scene"?await x?.():g.type==="reset"?await v?.():g.type==="set-target"?await T?.(g.target,g.transition??!0):await _?.(g.state,g.transition??!0);continue}let a=o.animation;if(a.type==="play"){let{type:g,clip:j,...S}=a;u?.(j,S)}else a.type==="pause"?V?.(a.clip):a.type==="stop"?R?.(a.clip):a.type==="set-speed"?y?.(a.speed,a.clip):I?.(a.time,a.clip)}await h?.(w)},[x,A,p,h,V,u,v,I,y,_,T,E,C,R,O,M,m]),F=xe(async(w,o)=>{let a=W(d,w);if(!a)return null;let g=d[a],j=g?.actions?.find(N=>N.id===o);if(!g||!j)return null;let S={objectId:a,action:j,binding:g};return await b(S),S},[b,d]);return{getActionsForObject:H,handleAction:b,runAction:F}}import{useCallback as ue,useRef as lt}from"react";function Kt(e){return typeof e=="function"?e:e?.handleViewerReady??null}function Ae(...e){let t=lt(null),n=lt(e);n.current=e;let s=ue(C=>{t.current=C;let p=new Set;for(let O of n.current){let m=Kt(O);m&&!p.has(m)&&(p.add(m),m(C))}},[]),l=ue(()=>t.current,[]),h=ue(C=>{let p=t.current;return p?p.captureImage(C):Promise.reject(new Error("ModelViewer is not ready yet."))},[]),d=ue(()=>{let C=t.current;return C?(C.invalidate(),!0):!1},[]),M=ue(C=>{let p=t.current;return p?p.captureVideo(C):Promise.reject(new Error("ModelViewer is not ready yet."))},[]);return{handleViewerReady:s,getViewer:l,captureImage:h,captureVideo:M,invalidate:d}}import{useCallback as L,useEffect as Jt,useRef as X}from"react";import{Material as Xt,PointLight as qt,Vector3 as Yt}from"three";var Le=["emissiveIntensity","opacity","metalness","roughness","transmission","clearcoat","clearcoatRoughness","ior","thickness"],me=1;function be(e){return typeof e=="string"?[e]:e}function we(e,t=0,n=1){return Math.min(n,Math.max(t,e))}function Ee(e,t){return e+Math.random()*(t-e)}function dt([e,t],n){return e+(t-e)*n}function Te([e,t],n){return[e[0]+(t[0]-e[0])*n,e[1]+(t[1]-e[1])*n,e[2]+(t[2]-e[2])*n]}function ut(e,t){let n=we(e);switch(t){case"ease-in":return n*n;case"ease-out":return 1-(1-n)*(1-n);case"ease-in-out":return n<.5?2*n*n:1-Math.pow(-2*n+2,2)/2;default:return n}}function Qt(e){let t=e.material;return t?(Array.isArray(t)?t:[t]).filter(n=>n instanceof Xt):[]}function Zt(e){let t={opacity:e.opacity,transparent:e.transparent};e.color&&(t.baseColor=`#${e.color.getHexString()}`),e.emissive&&(t.emissive=`#${e.emissive.getHexString()}`);for(let n of Le){let s=e[n];typeof s=="number"&&(t[n]=s)}return t}function ft(e,t){t.baseColor!==void 0&&e.color&&e.color.set(t.baseColor),t.emissive!==void 0&&e.emissive&&e.emissive.set(t.emissive);for(let n of Le){let s=t[n];s!==void 0&&typeof e[n]=="number"&&(e[n]=s)}t.transparent!==void 0&&(e.transparent=t.transparent),e.needsUpdate=!0}function en(e){return{position:[e.position.x,e.position.y,e.position.z],rotation:[e.rotation.x,e.rotation.y,e.rotation.z],scale:[e.scale.x,e.scale.y,e.scale.z],visible:e.visible}}function tn(e,t){if(t.position&&e.position.set(...t.position),t.rotation&&e.rotation.set(...t.rotation),t.scale!==void 0){let n=typeof t.scale=="number"?[t.scale,t.scale,t.scale]:t.scale;e.scale.set(...n)}t.visible!==void 0&&(e.visible=t.visible),e.updateMatrix(),e.updateMatrixWorld(!0)}function Ie(e={}){let t=X(e);t.current=e;let n=X(null),s=X(null),l=X(null),h=X(new Map),d=X(new Map),M=X(new Map),C=X(new Map),p=L(i=>{let r=n.current;if(!r)return null;let f=W(r.objectBindings,i);return r.raw.nodes[i]??(f?r.raw.nodes[f]:null)??(r.raw.scene?Ke(r.raw.scene,i):null)??null},[]),O=L(i=>{let r=n.current;return r?typeof i=="object"&&!Array.isArray(i)?ne(r.objectBindings,i):be(i).map(f=>W(r.objectBindings,f)??f):typeof i=="string"?[i]:Array.isArray(i)?i:[]},[]),m=L(()=>{n.current?.invalidate()},[]),A=L((i,r)=>{let f=!1;for(let c of O(i)){let B=p(c);if(B)for(let D of Qt(B))M.current.has(D)||M.current.set(D,Zt(D)),ft(D,r),f=!0}return f},[p,O]),x=L((i,r)=>{let f=A(i,r);return f&&m(),f},[m,A]),v=L((i,r)=>{let f=!1;for(let c of O(i)){let B=p(c);B&&(C.current.has(B)||C.current.set(B,en(B)),tn(B,r),f=!0)}return f},[p,O]),T=L((i,r)=>{let f=v(i,r);return f&&m(),f},[m,v]),_=L(i=>{let r=p(i);if(!r)return null;r.updateWorldMatrix(!0,!1);let f=r.getWorldPosition(new Yt);return[f.x,f.y,f.z]},[p]),u=L(i=>{let r=d.current.get(i);return r?(r.light.removeFromParent(),r.light.dispose(),d.current.delete(i),m(),!0):!1},[m]),V=L(i=>{let r=p(i.target);if(!r)return!1;let f=d.current.get(i.id),c=f?.light??new qt;return f&&f.target!==i.target&&c.removeFromParent(),c.name=`react-immersive-runtime-light:${i.id}`,c.color.set(i.color??"#ffffff"),c.intensity=i.intensity??1,c.distance=i.distance??0,c.decay=i.decay??2,c.castShadow=i.castShadow??!1,c.position.set(...i.offset??[0,0,0]),c.parent!==r&&r.add(c),d.current.set(i.id,{light:c,target:i.target}),m(),!0},[m,p]),R=L((i,r)=>{let f=d.current.get(i);if(!f)return!1;if(r.target&&r.target!==f.target){let c=p(r.target);if(!c)return!1;f.light.removeFromParent(),c.add(f.light),f.target=r.target}return r.color!==void 0&&f.light.color.set(r.color),r.intensity!==void 0&&(f.light.intensity=r.intensity),r.distance!==void 0&&(f.light.distance=r.distance),r.decay!==void 0&&(f.light.decay=r.decay),r.offset!==void 0&&f.light.position.set(...r.offset),r.castShadow!==void 0&&(f.light.castShadow=r.castShadow),m(),!0},[m,p]),y=L((i,r)=>{let f=c=>r[c%r.length]??0;for(let c of i.materials??[])O(c.targets).forEach((B,D)=>{let P=f(D),U={};for(let J of Le){let z=c.values[J];z&&(U[J]=dt(z,P))}A(B,U)});for(let c of i.transforms??[])O(c.targets).forEach((B,D)=>{let P=f(D),U={};c.values.position&&(U.position=Te(c.values.position,P)),c.values.rotation&&(U.rotation=Te(c.values.rotation,P)),c.values.scale&&(U.scale=Te(c.values.scale,P)),v(B,U)});for(let c of i.lights??[])be(c.lights).forEach((B,D)=>{let P=d.current.get(B);P&&(P.light.intensity=dt(c.intensity,f(D)))})},[O,A,v]),I=X(()=>{}),E=X(()=>{});E.current=i=>{l.current=null;let r=!1;for(let[f,c]of h.current){c.startedAt===null&&(c.startedAt=i);let B=c.lastFrameAt??i;c.lastFrameAt=i;let D=c.override&&c.override.until>i?c.override.level:null;c.override&&D===null&&(c.override=null);let P=c.update(i,i-c.startedAt,Math.min(100,i-B),D);r=!0,P||(h.current.delete(f),c.onComplete?.())}r&&m(),h.current.size>0&&I.current()},I.current=()=>{l.current!==null||typeof requestAnimationFrame>"u"||(l.current=requestAnimationFrame(i=>E.current(i)))};let H=L(i=>(h.current.set(i.id,i),I.current(),i.id),[]),b=L((i,r={})=>{let f=r.id??`transition-${me++}`,c=Math.max(1,r.duration??400),B=r.easing??"ease-in-out";return H({id:f,startedAt:null,lastFrameAt:null,override:null,onComplete:r.onComplete,update:(D,P,U,J)=>{let z=J??ut(P/c,B);return y(i,[z]),P<c}})},[y,H]),F=L((i,r={})=>{let f=r.id??`pulse-${me++}`,c=Math.max(1,r.duration??1e3),B=r.minLevel??0,D=r.maxLevel??1,P=r.repeat??1/0,U=r.synchronized??!0,J=Math.max(1,...[...i.materials??[],...i.transforms??[]].map(z=>O(z.targets).length),...(i.lights??[]).map(z=>be(z.lights).length));return H({id:f,startedAt:null,lastFrameAt:null,override:null,onComplete:r.onComplete,update:(z,oe,se,Y)=>{let G=oe/c,Q=Array.from({length:U?1:J},(ae,re)=>{if(Y!==null)return Y;let ge=G+(U?0:re/J),te=.5-Math.cos(ge%1*Math.PI*2)/2;return B+(D-B)*te});return y(i,Q),P===1/0||G<P}})},[y,H,O]),w=L((i,r={})=>{let f=r.id??`timeline-${me++}`,c=r.repeat??1,B=i.map(P=>({...P,duration:Math.max(1,P.duration),hold:Math.max(0,P.hold??0)})),D=Math.max(1,B.reduce((P,U)=>P+U.duration+U.hold,0));return H({id:f,startedAt:null,lastFrameAt:null,override:null,onComplete:r.onComplete,update:(P,U,J,z)=>{if(B.length===0||c<=0)return!1;let oe=U/D;if(c!==1/0&&oe>=c){for(let G of B)y(G.channels,[1]);return!1}let se=U%D,Y=0;for(let G of B){let Q=Y+G.duration,ae=Q+G.hold;if(se>=Q){y(G.channels,[z??1]),Y=ae;continue}if(se>=Y){let re=z??ut((se-Y)/G.duration,G.easing??"ease-in-out");y(G.channels,[re]);break}}return!0}})},[y,H]),o=L((i,r={})=>{let f=r.id??`flicker-${me++}`,c=r.synchronized??!0,B=r.minLevel??.15,D=r.maxLevel??1,P=r.interval??[45,160],U=typeof P=="number"?[P,P]:P,J=[Math.max(1,Math.min(...U)),Math.max(1,Math.max(...U))],z=we(r.response??.7,.01,1),oe=we(r.blackoutChance??.08),se=we(r.flashChance??.12),Y=r.flashLevel??1.15,G=Math.max(1,...[...i.materials??[],...i.transforms??[]].map(te=>O(te.targets).length),...(i.lights??[]).map(te=>be(te.lights).length)),Q=c?1:G,ae=Array.from({length:Q},()=>B),re=Array.from({length:Q},()=>B),ge=Array.from({length:Q},()=>0);return H({id:f,startedAt:null,lastFrameAt:null,override:null,onComplete:r.onComplete,update:(te,Vt,yt,Fe)=>{for(let Z=0;Z<Q;Z+=1){if(Fe!==null)re[Z]=Fe;else if(te>=ge[Z]){let Ne=Math.random();re[Z]=Ne<oe?Ee(0,Math.min(.04,B)):Ne<oe+se?Y:Ee(B,D),ge[Z]=te+Ee(...J)}let Ct=1-Math.pow(1-z,Math.max(1,yt)/16.67);ae[Z]+=(re[Z]-ae[Z])*Ct}return y(i,ae),r.duration===void 0||Vt<r.duration}})},[y,H,O]),a=L((i,r,f)=>{let c=h.current.get(i);if(!c)return!1;let B=typeof performance>"u"?Date.now():performance.now();return c.override={level:r,until:B+Math.max(0,f)},I.current(),!0},[]),g=L(i=>h.current.delete(i),[]),j=L(()=>{h.current.clear(),l.current!==null&&typeof cancelAnimationFrame<"u"&&(cancelAnimationFrame(l.current),l.current=null)},[]),S=L(()=>{for(let[i,r]of M.current)ft(i,r);M.current.clear();for(let[i,r]of C.current)i.position.set(...r.position),i.rotation.set(...r.rotation),i.scale.set(...r.scale),i.visible=r.visible,i.updateMatrix(),i.updateMatrixWorld(!0);C.current.clear();for(let i of d.current.values())i.light.removeFromParent(),i.light.dispose();d.current.clear(),m()},[m]),N=L(()=>{j(),S()},[S,j]),q=L(i=>{s.current&&s.current!==i.raw.scene&&S(),n.current=i,s.current=i.raw.scene,t.current.onViewerReady?.(i)},[S]);return Jt(()=>()=>{N(),n.current=null,s.current=null},[N]),{handleViewerReady:q,setMaterial:x,setTransform:T,getWorldPosition:_,addPointLight:V,updatePointLight:R,removePointLight:u,transition:b,timeline:w,pulse:F,flicker:o,overrideEffect:a,stopEffect:g,stopAllEffects:j,resetRuntime:N}}import{useCallback as nn,useState as rn}from"react";function ke(){let[e,t]=rn(null),n=nn(s=>{t(s)},[t]);return{hoveredObjectBinding:e,handleHoveredObject:n}}import{useCallback as gt,useState as on}from"react";function De(e=null){let[t,n]=on(e),s=gt((h,d)=>n({...d,target:h}),[]),l=gt(()=>n(null),[]);return{isolation:t,isolate:s,clearIsolation:l,handleIsolationChange:n}}import{useCallback as he,useState as ie}from"react";function He(){let[e,t]=ie(!0),[n,s]=ie(!1),[l,h]=ie(null),[d,M]=ie(null),[C,p]=ie(0),[O,m]=ie([]),[A,x]=ie([]),[v,T]=ie([]),_=he(y=>{M(y.bounds),p(y.objectCount),m(y.materialVariants),x(y.materialVariantGroups),h(null),t(!1),s(!0)},[]),u=he(y=>T(y),[]),V=he(y=>{h(y),M(null),p(0),m([]),x([]),T([]),t(!1),s(!1)},[]),R=he(()=>{t(!0),s(!1),h(null),M(null),p(0),m([]),x([]),T([])},[]);return{isLoading:e,isReady:n,error:l,bounds:d,objectCount:C,materialVariants:O,materialVariantGroups:A,objects:v,handleModelLoaded:_,handleObjectCatalog:u,handleLoadError:V,resetModelState:R}}import{useCallback as pt,useState as sn}from"react";function Ue(e=null){let[t,n]=sn(e),s=pt(h=>{n(h)},[n]),l=pt(()=>{n(null)},[]);return{selectedObjectBinding:t,setSelectedObjectBinding:n,handleObjectSelect:s,clearSelection:l}}var an={};function cn(e={}){let t=mt(e);t.current=e;let n=mt(e.bindings===void 0||e.bindings==="auto"),s=Me(()=>{let b=t.current.bindings;return b===void 0||b==="auto"?an:typeof b=="function"?b():b}),l=Re(()=>{let b=t.current.sceneConfig;return b===void 0?pe:typeof b=="function"?b():b}),h=Ue(),d=ke(),M=ye(e.camera),C=He(),p=ve(),O=De(),m=Ie(),A=Ae(M,m),x=Pe({bindings:s,scene:l,camera:M,animations:p,isolation:O,onAction:e.onAction}),{setObjectBindings:v}=s,{handleObjectCatalog:T}=C,_=Ve(b=>{T(b),n.current&&v(F=>{let w=Je(b.map(o=>o.name));for(let o of Object.keys(w))F[o]&&(w[o]=F[o]);return w})},[T,v]),{handleObjectSelect:u}=h,V=Ve(b=>{u(b),t.current.onObjectSelect?.(b)},[u]),{handleHoveredObject:R}=d,y=Ve(b=>{R(b),t.current.onObjectHover?.(b)},[R]),{handleLoadError:I}=C,E=Ve(b=>{I(b),t.current.onLoadError?.(b)},[I]),H=e.sceneConfig!==void 0||l.sceneConfig!==pe;return{props:{objectBindings:s.objectBindings,onObjectBindingsChange:v,selectedObject:h.selectedObjectBinding,onObjectSelect:V,onObjectHover:y,onCameraChange:M.handleCameraChange,onViewerReady:A.handleViewerReady,onModelLoaded:C.handleModelLoaded,onLoadError:E,onObjectCatalog:_,onAnimationsReady:p.handleAnimationsReady,onAction:x.handleAction,onSceneConfigChange:l.setSceneConfig,isolation:O.isolation,onIsolationChange:O.handleIsolationChange,...H?{sceneConfig:l.sceneConfig}:{}},bindings:s,selection:h,hover:d,camera:M,model:C,animations:p,actions:x,scene:l,isolation:O,effects:m,connection:A}}import{useMemo as ln}from"react";function dn(e,t){return ln(()=>{if(!t)return null;let n=e[t];return n||(Object.values(e).find(s=>s.id===t||s.modelObjectId===t)??null)},[e,t])}import{useMemo as un}from"react";function fn(e){return un(()=>Object.values(e).map(t=>t.modelObjectId),[e])}import{useCallback as de,useEffect as _e,useRef as ee,useState as gn}from"react";function ht(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function fe(e){return typeof e=="number"&&Number.isFinite(e)}function bt(e){return Array.isArray(e)&&e.length===3&&e.every(fe)}function pn(e){return!ht(e)||!bt(e.position)||!bt(e.target)||e.fov!==null&&!fe(e.fov)||!fe(e.zoom)||e.zoom<=0||e.azimuthAngle!==void 0&&!fe(e.azimuthAngle)||e.polarAngle!==void 0&&!fe(e.polarAngle)?null:{position:e.position,target:e.target,fov:e.fov,zoom:e.zoom,azimuthAngle:e.azimuthAngle,polarAngle:e.polarAngle}}function mn(e){if(!ht(e))return null;let t;if(e.camera!==void 0){let l=pn(e.camera);if(!l)return null;t=l}let n;if(e.hidden!==void 0){if(!Array.isArray(e.hidden)||!e.hidden.every(l=>typeof l=="string"))return null;n=e.hidden}let s;if(e.selected===null||typeof e.selected=="string")s=e.selected;else if(e.selected!==void 0)return null;return{camera:t,hidden:n,selected:s}}function wt(e,t,n){let s=Object.values(t).filter(l=>l.visible===!1).map(l=>l.id);return{camera:e??void 0,hidden:s,selected:n?.id??null}}function bn(e,t){if((!!e.hidden?.length||!!e.selected)&&Object.keys(t).length===0)return null;let s={};if(e.hidden){let l=new Set(e.hidden);s.bindings=Object.fromEntries(Object.entries(t).map(([h,d])=>[h,{...d,visible:!l.has(d.id)}]))}if(e.selected!==void 0){let l=e.selected?W(t,e.selected):null;s.selected=l?t[l]:null}return s}function wn({cameraState:e,setCameraState:t,objectBindings:n,onObjectBindingsChange:s,selectedObjectBinding:l,setSelectedObjectBinding:h,paramKey:d="view",debounceMs:M=400,autoSync:C=!0}){let p=ee(null),O=ee(null),m=ee(null),A=ee(null),x=ee(null),v=de(()=>{x.current!==null&&(window.clearTimeout(x.current),x.current=null),m.current=null,A.current=null},[]),T=de(()=>{let w=wt(e,n,l);return`${d}=${encodeURIComponent(JSON.stringify(w))}`},[e,n,l,d]),_=de(()=>{let w=new URL(window.location.href);return w.hash=T(),w.toString()},[T]),u=de(w=>{let o=new URL(window.location.href);o.hash=w,window.history.replaceState(null,"",o.toString()),O.current=w,p.current=new URLSearchParams(o.hash.slice(1)).get(d)},[d]),V=de(()=>{v(),u(T())},[T,v,u]),R=ee({cameraState:e,objectBindings:n,selectedObjectBinding:l});R.current={cameraState:e,objectBindings:n,selectedObjectBinding:l};let[y,I]=gn(!1);_e(()=>{if(!C||!y){v();return}let w=R.current,o=wt(w.cameraState,w.objectBindings,w.selectedObjectBinding),a=`${d}=${encodeURIComponent(JSON.stringify(o))}`;if(a===O.current){v();return}a===m.current&&M===A.current||(v(),m.current=a,A.current=M,x.current=window.setTimeout(()=>{x.current=null,m.current=null,A.current=null,u(a)},Math.max(0,M)))},[C,e,v,M,n,d,y,l,u]),_e(()=>v,[v]);let E=ee(null),H=ee(null),b=ee(null),F=de(async()=>{let w=S=>(I(!0),S),o=window.location.hash.startsWith("#")?window.location.hash.slice(1):window.location.hash,a=new URLSearchParams(o).get(d);if(!a)return E.current=null,w(!1);if(a===H.current)return!1;if(a===p.current||a===E.current)return w(!1);let g;try{g=JSON.parse(a)}catch{return w(!1)}let j=mn(g);if(!j)return w(!1);H.current=a;try{j.camera&&b.current!==a&&(await t(j.camera,!1),b.current=a);let S=bn(j,n);return S?(S.bindings&&s(S.bindings),S.selected!==void 0&&h(S.selected),E.current=a,w(!0)):!1}finally{H.current===a&&(H.current=null)}},[n,s,d,t,h]);return _e(()=>{let w=()=>{F().catch(()=>{})};return window.addEventListener("hashchange",w),()=>{window.removeEventListener("hashchange",w)}},[F]),{getShareUrl:_,syncUrl:V,restoreFromUrl:F}}export{St as ACTION_CATALOG,ot as CompareViewer,Ot as DEFAULT_MODEL_VIEWER_LABELS,pe as DEFAULT_SCENE_CONFIG,vt as DEFAULT_SECTION_CONFIG,Dt as MATERIAL_BLENDING_MODES,kt as MATERIAL_SIDES,jt as MODEL_VIEWER_PRESETS,le as ModelViewer,At as applyIsolation,xt as applyStyleRules,Lt as buildBindingsFromNodes,Mt as chooseMaterialVariant,Rt as colorScaleValue,Tt as createDefaultBinding,It as defineObjectBindings,Bt as findCatalogAction,Et as inferType,Pt as isolatedBindingKeys,je as material,ce as patchBindings,Se as patchSceneConfig,Be as sceneLight,ne as selectBindingKeys,Ce as selectBindings,dn as useObjectBinding,fn as useObjectBindingIds,Me as useObjectBindings,Re as useSceneConfig,wn as useShareableViewerState,cn as useViewer,Pe as useViewerActions,ve as useViewerAnimations,ye as useViewerCamera,Ae as useViewerConnection,Ie as useViewerEffects,ke as useViewerHover,De as useViewerIsolation,He as useViewerModel,Ue as useViewerSelection};
@@ -0,0 +1,309 @@
1
+ /** Built-in viewer text. Override only the keys your application needs. */
2
+ declare const DEFAULT_MODEL_VIEWER_LABELS: {
3
+ readonly verifyingLicense: "Verifying License";
4
+ readonly checkingYourLicenseKey: "Checking your license key...";
5
+ readonly invalidLicense: "Invalid License";
6
+ readonly licenseHasBeenRevokedOrHasExpired: "License has been revoked or has expired";
7
+ readonly failedToLoadPleaseContactTheSiteAdministrator: "Failed to load. Please contact the site administrator.";
8
+ readonly contextRestoringTitle: "Reloading viewer…";
9
+ readonly contextLostTitle: "3D view interrupted";
10
+ readonly contextRestoringMessage: "Rebuilding the 3D view. Please wait…";
11
+ readonly contextLostMessage: "The graphics connection was interrupted. The viewer will rebuild when it returns, or you can reload it now.";
12
+ readonly reloadViewer: "Reload viewer";
13
+ readonly texturePositioningHint: "Drag to move · Scroll to zoom · Click elsewhere to finish";
14
+ readonly texturePositioningStartHint: "Double-click to move or zoom";
15
+ readonly dismiss: "Dismiss";
16
+ readonly missingUVsAreShownInMagenta: "Missing UVs are shown in magenta.";
17
+ readonly viewThisModelInARWithAppleQuickLook: "View this model in AR with Apple Quick Look";
18
+ readonly viewInAR: "View in AR";
19
+ readonly openThisExperienceOnAPhoneForAR: "Open this experience on a phone for AR";
20
+ readonly openOnPhone: "Open on phone";
21
+ readonly viewThisModelInYourSpace: "View this model in your space";
22
+ readonly viewThisModelInVR: "View this model in VR";
23
+ readonly closePhoneHandoff: "Close phone handoff";
24
+ readonly arScanCode: "Scan the code and choose AR.";
25
+ readonly qrCodeToOpenThisModelOnAPhone: "QR code to open this model on a phone";
26
+ readonly disableUVChecker: "Disable UV checker";
27
+ readonly enableUVChecker: "Enable UV checker";
28
+ readonly explodedView: "Exploded view";
29
+ readonly explodeAmount: "Explode amount";
30
+ readonly removeSectionCut: "Remove section cut";
31
+ readonly sectionCut: "Section cut";
32
+ readonly sectionAxis: "Section axis";
33
+ readonly sectionPosition: "Section position";
34
+ readonly keepTheOtherSide: "Keep the other side";
35
+ readonly pauseCinematic: "Pause cinematic";
36
+ readonly playCinematic: "Play cinematic";
37
+ readonly stopCinematicAndResetCamera: "Stop cinematic and reset camera";
38
+ readonly cancel: "Cancel";
39
+ readonly annotationCategories: "Annotation categories";
40
+ readonly annotations: "Annotations";
41
+ readonly all: "All";
42
+ readonly uncategorized: "Uncategorized";
43
+ readonly decalDragHint: "Drag the decal on the object. Release to save; Escape to cancel.";
44
+ readonly showAll: "Show all";
45
+ readonly materialVariants: "Material variants";
46
+ readonly startGuidedTour: "Start guided tour";
47
+ readonly guidedTour: "Guided Tour";
48
+ readonly previousAnnotation: "Previous annotation";
49
+ readonly previous: "Prev";
50
+ readonly stopGuidedTour: "Stop guided tour";
51
+ readonly nextAnnotation: "Next annotation";
52
+ readonly next: "Next";
53
+ readonly exitFullscreen: "Exit fullscreen";
54
+ readonly enterFullscreen: "Enter fullscreen";
55
+ readonly resetCameraView: "Reset camera view";
56
+ readonly orbitControl: "Orbit Control";
57
+ readonly pointLock: "Point Lock";
58
+ readonly cameraController: "Camera controller";
59
+ readonly cameraControllerSettings: "Camera controller settings";
60
+ readonly downloadGLB: "Download GLB";
61
+ readonly downloadPNG: "Download PNG";
62
+ readonly downloadUVLayout: "Download UV Layout";
63
+ readonly videoFormat: "Video format";
64
+ readonly auto: "Auto";
65
+ readonly recordTurntableVideo: "Record turntable video";
66
+ readonly recordCinematicVideo: "Record cinematic video";
67
+ readonly videoUnsupported: "Video recording is not supported in this browser.";
68
+ readonly downloadOptions: "Download options";
69
+ readonly exporting: "Exporting…";
70
+ readonly download: "Download";
71
+ readonly annotationTitlePlaceholder: "Title *";
72
+ readonly description: "Description";
73
+ readonly ok: "OK";
74
+ readonly arRelocate: "Relocate";
75
+ readonly tapToPlace: "Tap to place";
76
+ readonly closeAnnotation: "Close annotation";
77
+ readonly learnMore: "Learn more";
78
+ readonly stopMeasuring: "Stop measuring";
79
+ readonly startMeasuring: "Start measuring";
80
+ readonly toggleBoundingDimensions: "Toggle bounding dimensions";
81
+ readonly measurementTool: "Measurement tool";
82
+ readonly distance: "Distance";
83
+ readonly angle: "Angle";
84
+ readonly area: "Area";
85
+ readonly pointToPlane: "Point to plane";
86
+ readonly measurementSnapping: "Measurement snapping";
87
+ readonly noSnapping: "No snapping";
88
+ readonly snapAuto: "Snap: auto";
89
+ readonly snapVertex: "Snap: vertex";
90
+ readonly snapEdge: "Snap: edge";
91
+ readonly undoMeasurementPoint: "Undo measurement point";
92
+ readonly clearMeasurements: "Clear measurements";
93
+ readonly finishArea: "Finish area";
94
+ readonly openSceneObjectsPanel: "Open scene objects panel";
95
+ readonly sceneObjects: "SCENE OBJECTS";
96
+ readonly searchNodesLabels: "Search nodes, labels";
97
+ readonly closeSceneObjectsPanel: "Close scene objects panel";
98
+ readonly objectNavigator: "Objects in the 3D view";
99
+ readonly compareBefore: "Before";
100
+ readonly compareAfter: "After";
101
+ readonly compareDivider: "Comparison divider";
102
+ readonly viewIn3D: "View in 3D";
103
+ readonly objectNavigatorHint: "Arrow keys browse · Enter selects · Esc clears";
104
+ readonly selectionCleared: "Selection cleared";
105
+ readonly cameraKeyboardHelp: "3D view. Arrow keys orbit, Shift with Up or Down zooms, and W, A, S, D, Space and C move the camera.";
106
+ readonly isolate: "Isolate";
107
+ readonly hide: "Hide";
108
+ readonly show: "Show";
109
+ readonly closePanel: "Close panel";
110
+ readonly actions: "Actions";
111
+ readonly openPanel: "Open panel";
112
+ readonly close: "Close";
113
+ readonly position: "Position";
114
+ readonly decalNudgeHint: "Click to fine-tune · Hold to move";
115
+ readonly decalNudgeControls: "Move decal in small steps";
116
+ readonly text: "Text";
117
+ readonly yourText: "Your text";
118
+ readonly textToAdd: "Text to add";
119
+ readonly textColour: "Text colour";
120
+ readonly addText: "Add text";
121
+ readonly image: "Image";
122
+ readonly chooseImage: "Choose image";
123
+ readonly imageToAdd: "Image to add";
124
+ readonly added: "Added";
125
+ readonly colour: "Colour";
126
+ readonly size: "Size";
127
+ readonly turn: "Turn";
128
+ readonly rotation: "Rotation";
129
+ readonly dragTheDecalAcrossTheObjectsSurface: "Drag the decal across the object's surface";
130
+ readonly move: "Move";
131
+ readonly remove: "Remove";
132
+ readonly noneAddedYet: "None added yet";
133
+ readonly done: "Done";
134
+ readonly moveForward: "Move forward";
135
+ readonly moveLeft: "Move left";
136
+ readonly moveRight: "Move right";
137
+ readonly moveBackward: "Move backward";
138
+ readonly sceneSettings: "Scene Settings";
139
+ readonly background: "Background";
140
+ readonly backgroundColor: "Background Color";
141
+ readonly environment: "Environment";
142
+ readonly autoRotate: "Auto Rotate";
143
+ readonly lighting: "Lighting";
144
+ readonly exposure: "Exposure";
145
+ readonly ambientLightIntensity: "Ambient Light Intensity";
146
+ readonly ambientLightColor: "Ambient Light Color";
147
+ readonly directLightIntensity: "Direct Light Intensity";
148
+ readonly directLightColor: "Direct Light Color";
149
+ readonly searchObjects: "Search objects";
150
+ readonly uploadedModel: "Uploaded model";
151
+ readonly clear: "Clear";
152
+ readonly chooseModel: "Choose model";
153
+ readonly loadingModel: "Loading model...";
154
+ readonly releaseToLoadYourModel: "Release to load your model";
155
+ readonly arFindSurface: "Move your device over a flat surface";
156
+ readonly arReleaseToPlace: "Release to place";
157
+ readonly arGestureHint: "Pinch to resize · Twist to rotate";
158
+ readonly angleFirstArmHint: "Pick the first arm";
159
+ readonly angleVertexHint: "Pick the angle's vertex";
160
+ readonly angleSecondArmHint: "Pick the second arm";
161
+ readonly angleNewHint: "Pick a point to start a new angle";
162
+ readonly areaNewHint: "Pick a point to start a new area";
163
+ readonly areaCornersHint: "Pick polygon corners in order, then Finish area";
164
+ readonly pointToPlaneFaceHint: "Pick the reference face";
165
+ readonly pointToPlanePointHint: "Pick a point to measure its perpendicular distance";
166
+ readonly pointToPlaneNewHint: "Pick a face to start a new measurement";
167
+ readonly distanceHint: "Pick points on the model to measure distances";
168
+ readonly visibleEntries: "{count} visible entries";
169
+ readonly objectCount: "{count} objects";
170
+ readonly annotationMarker: "Annotation {id}: {title}";
171
+ readonly recordingVideo: "Recording video · {progress}%";
172
+ readonly isolatedObjects: "Isolated: {count} objects";
173
+ readonly largeModelWarning: "Very large model ({millions}M triangles) — it may render and move slowly on this device, and click/hover selection on the model is disabled. Use the objects panel to select parts.";
174
+ readonly preparingLargeModel: "Preparing large model ({millions}M triangles) — the first display can take a while on this device...";
175
+ readonly enterAR: "Enter AR";
176
+ readonly enterVR: "Enter VR";
177
+ readonly decalImage: "Image {index}";
178
+ readonly decalText: "Text {index}";
179
+ readonly decalAdded: "{count} added";
180
+ readonly up: "up";
181
+ readonly down: "down";
182
+ readonly left: "left";
183
+ readonly right: "right";
184
+ readonly moveDecal: "Move decal {direction}";
185
+ readonly moveDecalOnSurface: "Move {direction} on the visible surface";
186
+ readonly showAllObject: "Show all {name}";
187
+ readonly isolateObject: "Isolate {name}";
188
+ readonly isolatedObject: "Isolated: {name}";
189
+ readonly hideObject: "Hide {name}";
190
+ readonly showObject: "Show {name}";
191
+ readonly objectSelected: "{name} selected";
192
+ readonly objectNavigatorPosition: "{position} of {count}";
193
+ readonly compareDividerValue: "{before} {percent}%, {after} {rest}%";
194
+ readonly bindingMismatchOne: "1 object binding doesn't match this model";
195
+ readonly bindingMismatchMany: "{count} object bindings don't match this model";
196
+ readonly simpleLargeModelWarning: "Very large model detected ({millions}M triangles) — it may render and move slowly on this device, and click/hover selection on the model is disabled. Use the scene objects panel to select parts.";
197
+ readonly dropModelHint: "Drag and drop {formats} here";
198
+ readonly loadErrorTitle: "This model couldn't be loaded";
199
+ readonly loadErrorNotFound: "Nothing was found at this address ({status}). Check that modelUrl points to the file.";
200
+ readonly loadErrorDenied: "The server refused access to the file ({status}). Check that the file is public, or that a signed URL hasn't expired.";
201
+ readonly loadErrorStatus: "The server responded with {status} when the file was requested.";
202
+ readonly loadErrorNetwork: "The download was blocked or failed. Check that the URL is correct and, if the file is on another domain, that its server allows cross-origin requests (CORS) from this site.";
203
+ readonly loadErrorHtml: "The server sent back a web page instead of a model. There's probably no file at this path: many servers answer a missing file with their index.html.";
204
+ readonly loadErrorInvalidFile: "The file couldn't be read as {format}. Check that it's a valid {format} file.";
205
+ readonly loadErrorInvalidExplicitFormat: "The file couldn't be read as {format}. Check that it's a valid {format} file and that modelFormat matches it.";
206
+ readonly loadErrorMissingFormat: "The file couldn't be read as {format}. The URL has no file extension, so set modelFormat to the file's format.";
207
+ readonly loadErrorPointCloud: "This PLY file is a point cloud: it has points but no faces, and the viewer shows meshes. Turn it into a mesh first, for example with MeshLab or Blender.";
208
+ readonly measurementReferenceFaceRequired: "Pick a triangle face to define the reference plane.";
209
+ readonly measurementTooManyPoints: "Finish or clear this measurement before adding more points.";
210
+ readonly measurementAngleDistinct: "Pick a point away from the angle's vertex.";
211
+ readonly areaMinimumPoints: "Pick at least three points to finish the area.";
212
+ readonly areaDistinctPoints: "Area points must be distinct.";
213
+ readonly areaStraightLine: "Area points must not lie on one straight line.";
214
+ readonly areaNotPlanar: "Area points must lie on one plane.";
215
+ readonly areaEdgesCross: "Area edges must not cross or touch each other.";
216
+ readonly areaZero: "The polygon has no measurable area.";
217
+ readonly decalSurfaceMissing: "Could not find a surface on this object for the decal.";
218
+ readonly decalDirectionMissing: "No visible surface in that direction. Try another arrow or rotate the view.";
219
+ readonly fullscreenExitFailed: "Could not exit fullscreen. Press Escape to exit.";
220
+ readonly fullscreenEnterFailed: "Could not enter fullscreen. Check your browser or iframe fullscreen permissions and try again.";
221
+ readonly uvCoordinatesMissing: "This model does not contain UV coordinates.";
222
+ readonly uvExportFailed: "Could not create the UV layout archive.";
223
+ readonly videoExportFailed: "Could not export the video.";
224
+ readonly videoNotReady: "Viewer not ready for video export.";
225
+ readonly videoExitXR: "Exit the XR session before recording a video.";
226
+ readonly videoAlreadyRecording: "A video export is already in progress.";
227
+ readonly videoPathRequired: "Enable a cinematic camera path before recording it.";
228
+ readonly videoDurationInvalid: "Video duration must be greater than 0 and at most 300 seconds.";
229
+ readonly videoFrameRateInvalid: "Video frame rate must be between 1 and 60.";
230
+ readonly videoBitrateInvalid: "Video bitrate must be a positive number.";
231
+ readonly videoContextLost: "Video export stopped because the WebGL context was lost.";
232
+ readonly videoTimedOut: "Video export timed out. Keep the viewer tab visible while recording.";
233
+ readonly videoEncodingFailed: "The browser could not encode the video.";
234
+ readonly videoEmpty: "The browser produced an empty video.";
235
+ readonly videoDidNotStart: "Video recording did not start.";
236
+ readonly videoWebMUnsupported: "Video recording as WEBM is not supported in this browser.";
237
+ readonly videoMP4Unsupported: "Video recording as MP4 is not supported in this browser.";
238
+ readonly videoGIFUnsupported: "Video recording as GIF is not supported in this browser.";
239
+ readonly videoGifWidthInvalid: "GIF width must be a whole number of pixels from 16 to 4096.";
240
+ readonly environmentApartment: "apartment";
241
+ readonly environmentCity: "city";
242
+ readonly environmentDawn: "dawn";
243
+ readonly environmentForest: "forest";
244
+ readonly environmentLobby: "lobby";
245
+ readonly environmentNight: "night";
246
+ readonly environmentPark: "park";
247
+ readonly environmentStudio: "studio";
248
+ readonly environmentSunset: "sunset";
249
+ readonly environmentWarehouse: "warehouse";
250
+ readonly color: "Color";
251
+ readonly material: "Material";
252
+ readonly texturePreview: "texture preview";
253
+ readonly noTextureApplied: "No texture applied";
254
+ readonly noTextureCoordinates: "This part has no texture coordinates, so an image can't be placed on it.";
255
+ readonly replaceImage: "Replace image";
256
+ readonly uploadImage: "Upload image";
257
+ readonly removeTexture: "Remove texture";
258
+ readonly texturePosition: "Texture position";
259
+ readonly offsetX: "Offset X";
260
+ readonly offsetY: "Offset Y";
261
+ readonly confirmTexturePosition: "Confirm this texture position and exit positioning mode";
262
+ readonly donePositioning: "Done positioning";
263
+ readonly textureOffsetHint: "Double-click the object in the preview to drag its texture directly (scroll to zoom), or edit its offset numerically.";
264
+ readonly actionToggleLight: "Toggle Light";
265
+ readonly actionChangeLightColor: "Change Light Color";
266
+ readonly actionSetBrightness: "Set Brightness";
267
+ readonly actionChangeColor: "Change Color";
268
+ readonly actionChangeMaterial: "Change Material";
269
+ readonly actionToggleVisibility: "Toggle Visibility";
270
+ };
271
+ type ModelViewerLabelKey = keyof typeof DEFAULT_MODEL_VIEWER_LABELS;
272
+ /** Plain-text overrides; dynamic labels use named {placeholders}. */
273
+ type ModelViewerLabels = Partial<Record<ModelViewerLabelKey, string>>;
274
+
275
+ /**
276
+ * Whether the viewer cuts motion that starts on its own: `"user"` follows the
277
+ * visitor's `prefers-reduced-motion` setting, `"always"` and `"never"` override
278
+ * it.
279
+ */
280
+ type ReducedMotionSetting = "user" | "always" | "never";
281
+
282
+ /** One choice in a row of material variants. */
283
+ type MaterialVariantOption = {
284
+ /** The variant's name, as `sceneConfig.model.activeVariants` lists it. */
285
+ name: string;
286
+ /** The name without its group, for display: "Red" for "Paint: Red". */
287
+ label: string;
288
+ /**
289
+ * The colour of the variant's main material, as a CSS colour, when that
290
+ * material is a plain colour rather than a texture.
291
+ */
292
+ swatch?: string;
293
+ };
294
+ /**
295
+ * Variants that take turns: choosing one replaces the group's other choice.
296
+ * Variants in different groups combine, like a paint colour and a wheel style.
297
+ */
298
+ type MaterialVariantGroup = {
299
+ /** "Paint" for variants named "Paint: Red" or "Paint / Red"; null otherwise. */
300
+ name: string | null;
301
+ variants: MaterialVariantOption[];
302
+ };
303
+ /**
304
+ * The active variants after choosing `name`: it replaces any other variant of
305
+ * its group, so a paint colour swaps for another while the wheels stay.
306
+ */
307
+ declare function chooseMaterialVariant(activeVariants: readonly string[], name: string, groups: readonly MaterialVariantGroup[]): string[];
308
+
309
+ export { DEFAULT_MODEL_VIEWER_LABELS as D, type MaterialVariantGroup as M, type ReducedMotionSetting as R, type MaterialVariantOption as a, type ModelViewerLabelKey as b, type ModelViewerLabels as c, chooseMaterialVariant as d };