@liveroom-tech/react-immersive 5.2.0 → 6.0.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.
- package/LICENSE +10 -6
- package/README.md +106 -3856
- package/dist/binding-builder.css +1 -1
- package/dist/binding-builder.d.mts +5 -1
- package/dist/binding-builder.d.ts +5 -1
- package/dist/binding-builder.js +67 -17
- package/dist/binding-builder.mjs +1 -1
- package/dist/chunk-2JFUMJUP.mjs +1 -0
- package/dist/chunk-4JMJALRO.mjs +2 -0
- package/dist/chunk-OTSCPJWF.mjs +1 -0
- package/dist/chunk-P2JZ5Z7I.mjs +1 -0
- package/dist/chunk-UGPR4EPP.mjs +81 -0
- package/dist/chunk-V7WZUWJ5.mjs +1 -0
- package/dist/chunk-WWUWEPFK.mjs +3 -0
- package/dist/hosted.css +1 -1
- package/dist/hosted.d.mts +48 -19
- package/dist/hosted.d.ts +48 -19
- package/dist/hosted.js +66 -16
- package/dist/hosted.mjs +1 -1
- package/dist/index.css +1 -1
- package/dist/index.d.mts +78 -12
- package/dist/index.d.ts +78 -12
- package/dist/index.js +65 -15
- package/dist/index.mjs +1 -1
- package/dist/{materialVariants-DnZe9eMC.d.mts → modelFileResolver-Co7j1tdQ.d.mts} +125 -27
- package/dist/{materialVariants-DnZe9eMC.d.ts → modelFileResolver-Co7j1tdQ.d.ts} +125 -27
- package/dist/modelViewerProps-BibuMND7.d.ts +1988 -0
- package/dist/modelViewerProps-Ce4-wb57.d.mts +1988 -0
- package/dist/{publicProps-tJuWZgT3.d.ts → publicProps-BaJHCDa_.d.mts} +7 -0
- package/dist/{publicProps-tJuWZgT3.d.mts → publicProps-CP18d_mt.d.ts} +7 -0
- package/dist/simple-model-viewer.d.mts +2 -4
- package/dist/simple-model-viewer.d.ts +2 -4
- package/dist/simple-model-viewer.js +3 -3
- package/dist/simple-model-viewer.mjs +1 -1
- package/dist/utils.d.mts +62 -4
- package/dist/utils.d.ts +62 -4
- package/dist/utils.js +2 -1
- package/dist/utils.mjs +1 -1
- package/package.json +2 -1
- package/dist/chunk-4NLJSD3S.mjs +0 -1
- package/dist/chunk-B7REIGDG.mjs +0 -1
- package/dist/chunk-HYFJ5DYJ.mjs +0 -1
- package/dist/chunk-QC3NT76G.mjs +0 -3
- package/dist/chunk-SEESCGUS.mjs +0 -1
- package/dist/chunk-T3M3BQ7H.mjs +0 -32
- package/dist/chunk-ZPK67UG7.mjs +0 -1
- package/dist/modelInfo-BYebMPdZ.d.mts +0 -43
- package/dist/modelInfo-XfUQO7C_.d.ts +0 -43
- package/dist/modelViewerProps-CIZ2R_Fv.d.ts +0 -569
- package/dist/modelViewerProps-DoRiTZMn.d.mts +0 -569
- package/dist/rendererBackend-QwMzISTn.d.mts +0 -903
- package/dist/rendererBackend-QwMzISTn.d.ts +0 -903
package/dist/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
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};
|
|
1
|
+
"use client";import{c as he}from"./chunk-2JFUMJUP.mjs";import"./chunk-MMO7KCYU.mjs";import{a as pe,b as He,c as _e,d as Ne,e as gn}from"./chunk-P2JZ5Z7I.mjs";import{I as ut,J as gt,K as De,L as ft,M as qe,N as yn,c as Ee,g as lt,i as en}from"./chunk-UGPR4EPP.mjs";import{a as st,b as at,y as ct}from"./chunk-OTSCPJWF.mjs";import{Aa as Qt,Ba as tn,Da as nn,Ha as le,Ia as Le,K as Se,Ka as on,L as Oe,La as sn,M as kt,Ma as an,N as Ut,Na as cn,Oa as ln,Pa as dn,Qa as un,R as re,Ra as dt,S as Te,U as Dt,Ua as ke,V as Ht,Va as Ue,Wa as fn,Xa as pn,Ya as mn,Za as bn,_a as wn,da as _t,e as ot,f as At,fa as Nt,g as Pt,ha as qt,ia as Ft,j as Et,ja as Kt,k as Tt,ka as Gt,l as It,la as $t,m as ee,ma as zt,na as Wt,oa as Yt,pa as fe,qa as ye,ra as Ie,wa as Xt,xa as Jt}from"./chunk-4JMJALRO.mjs";import{L as rn,j as Lt,q as Zt}from"./chunk-V7WZUWJ5.mjs";import"./chunk-JR557W27.mjs";import{useCallback as hn,useEffect as je,useMemo as Be,useRef as Fe,useState as me}from"react";import{jsx as ie,jsxs as Ke}from"react/jsx-runtime";var Vn=Object.freeze({});function pt(e){return ie(st,{labels:e.labels,children:ie(Cn,{...e})})}function Cn({before:e,after:t,layout:i="slider",split:s,onSplitChange:g,reveal:y="auto",semanticComparison:l=!1,showComparisonOutlines:A,onComparisonOutlinesChange:B,onComparisonChange:O,linkSections:v,...m}){let k=at(),[E,C]=me(y==="auto");je(()=>{y==="auto"&&C(!0)},[y]);let[h,b]=me(.5),[f,S]=me(!0),x=A??f,j=R=>{A===void 0&&S(R),B?.(R)},q=De(s??h),X=hn(R=>{let P=De(R);s===void 0&&b(P),g?.(P)},[s,g]),_=Fe([null,null]),[V,J]=me([null,null]),[N,a]=me(null),[r,c]=me(null),u=[{...m,...e},{...m,...t}];je(()=>a(null),[u[0].sceneConfig?.section,u[1].sceneConfig?.section]);let w=R=>{let P=u[R].objectBindings;return P&&typeof P=="object"?P:V[R]?.url===u[R].modelUrl?V[R].bindings:Vn},L=w(0),$=w(1),n=Be(()=>l?ke({objectBindings:L,sceneConfig:u[0].sceneConfig},{objectBindings:$,sceneConfig:u[1].sceneConfig},typeof l=="object"?l:{}):null,[l,L,$,u[0].sceneConfig,u[1].sceneConfig]),o=n?JSON.stringify(n):"",p=Fe(null);je(()=>{n&&p.current!==o&&(p.current=o,O?.(n))},[n,o,O]);let d=n?.objects.find(R=>R.id===r),M=Be(()=>n?[Ue(n,"before",r),Ue(n,"after",r)]:null,[n,r]),I=Be(()=>gt(),[]);je(()=>()=>I.detach(),[I]);let T=[e,t],D=Be(()=>[0,1].map(R=>(P,W)=>{_.current[R]=P,J(K=>K[R]?.bindings===P.objectBindings&&K[R]?.url===W?K:K.map((G,we)=>we===R?{url:W,bindings:P.objectBindings}:G)),I.attach(R,P.raw.controls,P.invalidate)}),[I]),z=T.map((R,P)=>{let{label:W,...K}=R,G={preset:"minimal",...m,...K},we=K.onViewerReady??m.onViewerReady;return{...G,...v??!!l?{sceneConfig:{...G.sceneConfig,section:N??u[1].sceneConfig?.section??Se},onSceneConfigChange:oe=>{a(oe.section??Se),(K.onSceneConfigChange??m.onSceneConfigChange)?.(oe)}}:{},...M?{comparisonHighlights:x?M[P]:void 0,selectedObject:P===0?d?.beforeKey?L[d.beforeKey]:null:d?.afterKey?$[d.afterKey]:null}:{},onObjectSelect:oe=>{if((K.onObjectSelect??m.onObjectSelect)?.(oe),n){let Ce=n.objects.find(Z=>(P===0?Z.beforeObjectId:Z.afterObjectId)===oe?.modelObjectId);c(Ce?.id??null)}},onViewerReady:oe=>{D[P](oe,G.modelUrl),we?.(oe)}}}),F=[e.label??k("compareBefore"),t.label??k("compareAfter")];(!z[0].modelUrl||!z[1].modelUrl)&&console.error("[react-immersive] CompareViewer needs a modelUrl, shared or on each side.");let ce=Fe(null),Q=n?ie(ut,{showOutlines:x,onShowOutlinesChange:j,report:n,selected:r,onSelect:R=>{c(R.id);let P=R.afterObjectId?1:0,W=_.current[P],K=P===1?R.afterObjectId:R.beforeObjectId,G=K?W?.raw.nodes[K]:null;W&&G&&(I.setLeader(P),W.raw.controls.fitToBox(G,!0),W.invalidate())},onClear:()=>c(null)}):null;if(!E)return ie(ct,{className:"ri-compare",background:lt(m.backgroundColor,m.sceneConfig),poster:m.poster??t.poster??e.poster,onReveal:()=>C(!0)});if(i==="side-by-side")return Ke("div",{className:"ri-compare ri-compare--sideBySide",children:[z.map((R,P)=>Ke("div",{className:"ri-compare__pane",children:[ie(he,{...R}),ie("span",{className:"ri-compare__label",children:F[P]})]},P)),Q]});let Y=`${q*100}%`;return Ke("div",{ref:ce,className:"ri-compare ri-compare--slider",style:{"--ri-compare-split":Y},children:[ie("div",{className:"ri-compare__layer",children:ie(he,{...z[0]})}),ie("div",{className:"ri-compare__layer ri-compare__layer--after",children:ie(he,{...z[1]})}),Q,ie(ft,{split:q,onSplitChange:X,labels:[F[0],F[1]],containerRef:ce})]})}import{useCallback as Ae,useRef as jt}from"react";import{useCallback as H,useMemo as mt,useState as Sn}from"react";var bt={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 wt(e){if(e)return Object.fromEntries(Object.entries(e).map(([t,i])=>[t,i&&typeof i=="object"?{...i}:i]))}function On(e){return Object.fromEntries(Object.entries(e).filter(([,t])=>t.visible===!1).map(([t])=>[t,!0]))}function Ge(e){let[t,i]=Sn(e),s=H((a,r)=>{i(c=>r===void 0?pe(c,a):pe(c,a,r))},[]),g=H((a,r)=>s(a,He(r)),[s]),y=H((a,r)=>g(a,{baseColor:r}),[g]),l=H((a,r,c="baseColor")=>{let u=bt[c],w=typeof r=="string"?{path:r}:r;s(a,{style:{material:{[u]:w}}})},[s]),A=H((a,r="baseColor")=>{let c=bt[r];s(a,{style:{material:{[c]:void 0}}})},[s]),B=H((a,r)=>{i(c=>{let u=ee(c,a);if(!u)return c;let w=wt(c[u]?.style?.material),L=le(c,r);if(L.length===0)return c;let $=c;for(let n of L){let o=c[n];o&&($===c&&($={...c}),$[n]={...o,style:{...o.style,material:wt(w)}})}return $})},[]),O=H(a=>s(a,{style:{material:void 0}}),[s]),v=H((a,r)=>s(a,{transform:r}),[s]),m=H(a=>s(a,{transform:void 0}),[s]),k=H((a,r)=>s(a,{metadata:r}),[s]),E=H((a,r)=>{i(c=>{let u=c;for(let w of le(c,a)){let L=c[w],$=r(L.decals??[]);u===c&&(u={...c}),u[w]={...L,decals:$.length>0?$:void 0}}return u})},[]),C=H((a,r)=>{let c=r.id??`decal-${Date.now().toString(36)}-${Math.random().toString(36).slice(2,8)}`;return E(a,u=>[...u.filter(w=>w.id!==c),{...r,id:c}]),c},[E]),h=H((a,r,c)=>E(a,u=>u.map(w=>w.id===r?{...w,...c}:w)),[E]),b=H((a,r)=>E(a,c=>c.filter(u=>u.id!==r)),[E]),f=H(a=>Le(t,a),[t]),S=H(a=>le(t,a).map(r=>t[r]?.id??r),[t]),x=H(a=>{let r=ee(t,a);return r?t[r]?.style?.material??null:null},[t]),j=H(a=>s(a,{visible:!1}),[s]),q=H(a=>s(a,{visible:!0}),[s]),X=H(a=>{i(r=>{let c=le(r,a).reduce((u,w)=>{let L=r[w];return L&&u.push({ids:w,patch:{visible:L.visible===!1}}),u},[]);return pe(r,c)})},[i]),_=H(()=>{i(a=>pe(a,Object.keys(a),{visible:!0}))},[i]),V=mt(()=>On(t),[t]),J=mt(()=>Object.keys(V).map(a=>t[a]?.id??a),[V,t]),N=H(a=>{let r=ee(t,a);return r?t[r]?.visible===!1:!1},[t]);return{objectBindings:t,setObjectBindings:i,updateObjectBindings:s,setMaterial:g,setBaseColor:y,setTexture:l,clearTexture:A,copyMaterial:B,resetMaterial:O,getMaterial:x,setTransform:v,resetTransform:m,updateMetadata:k,addDecal:C,updateDecal:h,removeDecal:b,selectObjectBindings:f,selectObjectBindingIds:S,hiddenObjects:V,hiddenObjectIds:J,hideObject:j,showObject:q,toggleObjectVisibility:X,isObjectHidden:N,clearHiddenObjects:_}}import{useCallback as te,useMemo as jn,useRef as Bn,useState as vn}from"react";function $e(e){let t=Bn(null),[i,s]=vn(()=>{let f=typeof e=="function"?e():e;return t.current=f,f}),g=te(f=>{s(S=>{let x=typeof f=="function"?f(S):f;return _e(S,x)})},[]),y=te(()=>{let f=t.current;f&&s(f)},[]),l=te((f,S)=>{g(x=>({lighting:{lights:x.lighting.lights.map(j=>j.id===f?{...j,...S}:j)}}))},[g]),A=te(f=>{g(S=>S.lighting.lights.some(x=>x.id===f.id)?{}:{lighting:{lights:[...S.lighting.lights,Ne(f)]}})},[g]),B=te(f=>{g(S=>({lighting:{lights:S.lighting.lights.filter(x=>x.id!==f)}}))},[g]),O=te((f,S)=>l(f,{intensity:S}),[l]),v=te((f,S)=>l(f,{color:S}),[l]),m=te(f=>l(f,{visible:!0}),[l]),k=te(f=>l(f,{visible:!1}),[l]),E=te(f=>{g(S=>({lighting:{lights:S.lighting.lights.map(x=>x.id===f?{...x,visible:!x.visible}:x)}}))},[g]),C=te((f,S)=>l(f,{attachment:S,attachedToCamera:!1}),[l]),h=te(f=>l(f,{attachment:void 0}),[l]),b=jn(()=>({items:i.lighting.lights,get:f=>i.lighting.lights.find(S=>S.id===f),add:A,update:l,remove:B,setIntensity:O,setColor:v,show:m,hide:k,toggle:E,attach:C,detach:h}),[i.lighting.lights,A,l,B,O,v,m,k,E,C,h]);return{sceneConfig:i,setSceneConfig:s,updateSceneConfig:g,resetSceneConfig:y,lights:b}}import{useCallback as ze}from"react";function We({bindings:e,scene:t,camera:i,animations:s,isolation:g,onAction:y}){let{objectBindings:l,updateObjectBindings:A,showObject:B,hideObject:O,toggleObjectVisibility:v}=e,m=t?.updateSceneConfig,k=i?.focusObject,E=i?.fitScene,C=i?.resetView,h=i?.setCameraTarget,b=i?.setCameraState,f=s?.play,S=s?.pause,x=s?.stop,j=s?.setSpeed,q=s?.seek,X=g?.handleIsolationChange,_=ze(N=>{let a=ee(l,N);return a?l[a]?.actions??[]:[]},[l]),V=ze(async N=>{for(let a of N.action.effects??[]){if("objectBindings"in a){A(a.target,a.objectBindings);continue}if("sceneConfig"in a){m?.(a.sceneConfig);continue}if("isolation"in a){X?.(a.isolation);continue}if("visibility"in a){a.visibility==="show"?B(a.target):a.visibility==="hide"?O(a.target):v(a.target);continue}if("camera"in a){let c=a.camera;c.type==="focus-object"?await k?.(c.objectId??N.objectId):c.type==="fit-scene"?await E?.():c.type==="reset"?await C?.():c.type==="set-target"?await h?.(c.target,c.transition??!0):await b?.(c.state,c.transition??!0);continue}let r=a.animation;if(r.type==="play"){let{type:c,clip:u,...w}=r;f?.(u,w)}else r.type==="pause"?S?.(r.clip):r.type==="stop"?x?.(r.clip):r.type==="set-speed"?j?.(r.speed,r.clip):q?.(r.time,r.clip)}await y?.(N)},[E,k,O,y,S,f,C,q,j,b,h,X,B,x,v,A,m]),J=ze(async(N,a)=>{let r=ee(l,N);if(!r)return null;let c=l[r],u=c?.actions?.find(L=>L.id===a);if(!c||!u)return null;let w={objectId:r,action:u,binding:c};return await V(w),w},[V,l]);return{getActionsForObject:_,handleAction:V,runAction:J}}import{useCallback as Ve,useRef as yt}from"react";function Mn(e){return typeof e=="function"?e:e?.handleViewerReady??null}function Ye(...e){let t=yt(null),i=yt(e);i.current=e;let s=Ve(B=>{t.current=B;let O=new Set;for(let v of i.current){let m=Mn(v);m&&!O.has(m)&&(O.add(m),m(B))}},[]),g=Ve(()=>t.current,[]),y=Ve(B=>{let O=t.current;return O?O.captureImage(B):Promise.reject(new Error("ModelViewer is not ready yet."))},[]),l=Ve(()=>{let B=t.current;return B?(B.invalidate(),!0):!1},[]),A=Ve(B=>{let O=t.current;return O?O.captureVideo(B):Promise.reject(new Error("ModelViewer is not ready yet."))},[]);return{handleViewerReady:s,getViewer:g,captureImage:y,captureVideo:A,invalidate:l}}import{useCallback as U,useEffect as Rn,useRef as se}from"react";import{Material as xn,PointLight as An,Vector3 as Pn}from"three";var Qe=["emissiveIntensity","opacity","metalness","roughness","transmission","clearcoat","clearcoatRoughness","ior","thickness"],ve=1;function Me(e){return typeof e=="string"?[e]:e}function Re(e,t=0,i=1){return Math.min(i,Math.max(t,e))}function Xe(e,t){return e+Math.random()*(t-e)}function ht([e,t],i){return e+(t-e)*i}function Je([e,t],i){return[e[0]+(t[0]-e[0])*i,e[1]+(t[1]-e[1])*i,e[2]+(t[2]-e[2])*i]}function Vt(e,t){let i=Re(e);switch(t){case"ease-in":return i*i;case"ease-out":return 1-(1-i)*(1-i);case"ease-in-out":return i<.5?2*i*i:1-Math.pow(-2*i+2,2)/2;default:return i}}function En(e){let t=e.material;return t?(Array.isArray(t)?t:[t]).filter(i=>i instanceof xn):[]}function Tn(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 i of Qe){let s=e[i];typeof s=="number"&&(t[i]=s)}return t}function Ct(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 i of Qe){let s=t[i];s!==void 0&&typeof e[i]=="number"&&(e[i]=s)}t.transparent!==void 0&&(e.transparent=t.transparent),e.needsUpdate=!0}function In(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 Ln(e,t){if(t.position&&e.position.set(...t.position),t.rotation&&e.rotation.set(...t.rotation),t.scale!==void 0){let i=typeof t.scale=="number"?[t.scale,t.scale,t.scale]:t.scale;e.scale.set(...i)}t.visible!==void 0&&(e.visible=t.visible),e.updateMatrix(),e.updateMatrixWorld(!0)}function Ze(e={}){let t=se(e);t.current=e;let i=se(null),s=se(null),g=se(null),y=se(new Map),l=se(new Map),A=se(new Map),B=se(new Map),O=U(n=>{let o=i.current;if(!o)return null;let p=ee(o.objectBindings,n);return o.raw.nodes[n]??(p?o.raw.nodes[p]:null)??(o.raw.scene?ot(o.raw.scene,n):null)??null},[]),v=U(n=>{let o=i.current;return o?typeof n=="object"&&!Array.isArray(n)?le(o.objectBindings,n):Me(n).map(p=>ee(o.objectBindings,p)??p):typeof n=="string"?[n]:Array.isArray(n)?n:[]},[]),m=U(()=>{i.current?.invalidate()},[]),k=U((n,o)=>{let p=!1;for(let d of v(n)){let M=O(d);if(M)for(let I of En(M))A.current.has(I)||A.current.set(I,Tn(I)),Ct(I,o),p=!0}return p},[O,v]),E=U((n,o)=>{let p=k(n,o);return p&&m(),p},[m,k]),C=U((n,o)=>{let p=!1;for(let d of v(n)){let M=O(d);M&&(B.current.has(M)||B.current.set(M,In(M)),Ln(M,o),p=!0)}return p},[O,v]),h=U((n,o)=>{let p=C(n,o);return p&&m(),p},[m,C]),b=U(n=>{let o=O(n);if(!o)return null;o.updateWorldMatrix(!0,!1);let p=o.getWorldPosition(new Pn);return[p.x,p.y,p.z]},[O]),f=U(n=>{let o=l.current.get(n);return o?(o.light.removeFromParent(),o.light.dispose(),l.current.delete(n),m(),!0):!1},[m]),S=U(n=>{let o=O(n.target);if(!o)return!1;let p=l.current.get(n.id),d=p?.light??new An;return p&&p.target!==n.target&&d.removeFromParent(),d.name=`react-immersive-runtime-light:${n.id}`,d.color.set(n.color??"#ffffff"),d.intensity=n.intensity??1,d.distance=n.distance??0,d.decay=n.decay??2,d.castShadow=n.castShadow??!1,d.position.set(...n.offset??[0,0,0]),d.parent!==o&&o.add(d),l.current.set(n.id,{light:d,target:n.target}),m(),!0},[m,O]),x=U((n,o)=>{let p=l.current.get(n);if(!p)return!1;if(o.target&&o.target!==p.target){let d=O(o.target);if(!d)return!1;p.light.removeFromParent(),d.add(p.light),p.target=o.target}return o.color!==void 0&&p.light.color.set(o.color),o.intensity!==void 0&&(p.light.intensity=o.intensity),o.distance!==void 0&&(p.light.distance=o.distance),o.decay!==void 0&&(p.light.decay=o.decay),o.offset!==void 0&&p.light.position.set(...o.offset),o.castShadow!==void 0&&(p.light.castShadow=o.castShadow),m(),!0},[m,O]),j=U((n,o)=>{let p=d=>o[d%o.length]??0;for(let d of n.materials??[])v(d.targets).forEach((M,I)=>{let T=p(I),D={};for(let z of Qe){let F=d.values[z];F&&(D[z]=ht(F,T))}k(M,D)});for(let d of n.transforms??[])v(d.targets).forEach((M,I)=>{let T=p(I),D={};d.values.position&&(D.position=Je(d.values.position,T)),d.values.rotation&&(D.rotation=Je(d.values.rotation,T)),d.values.scale&&(D.scale=Je(d.values.scale,T)),C(M,D)});for(let d of n.lights??[])Me(d.lights).forEach((M,I)=>{let T=l.current.get(M);T&&(T.light.intensity=ht(d.intensity,p(I)))})},[v,k,C]),q=se(()=>{}),X=se(()=>{});X.current=n=>{g.current=null;let o=!1;for(let[p,d]of y.current){d.startedAt===null&&(d.startedAt=n);let M=d.lastFrameAt??n;d.lastFrameAt=n;let I=d.override&&d.override.until>n?d.override.level:null;d.override&&I===null&&(d.override=null);let T=d.update(n,n-d.startedAt,Math.min(100,n-M),I);o=!0,T||(y.current.delete(p),d.onComplete?.())}o&&m(),y.current.size>0&&q.current()},q.current=()=>{g.current!==null||typeof requestAnimationFrame>"u"||(g.current=requestAnimationFrame(n=>X.current(n)))};let _=U(n=>(y.current.set(n.id,n),q.current(),n.id),[]),V=U((n,o={})=>{let p=o.id??`transition-${ve++}`,d=Math.max(1,o.duration??400),M=o.easing??"ease-in-out";return _({id:p,startedAt:null,lastFrameAt:null,override:null,onComplete:o.onComplete,update:(I,T,D,z)=>{let F=z??Vt(T/d,M);return j(n,[F]),T<d}})},[j,_]),J=U((n,o={})=>{let p=o.id??`pulse-${ve++}`,d=Math.max(1,o.duration??1e3),M=o.minLevel??0,I=o.maxLevel??1,T=o.repeat??1/0,D=o.synchronized??!0,z=Math.max(1,...[...n.materials??[],...n.transforms??[]].map(F=>v(F.targets).length),...(n.lights??[]).map(F=>Me(F.lights).length));return _({id:p,startedAt:null,lastFrameAt:null,override:null,onComplete:o.onComplete,update:(F,ce,ue,Q)=>{let Y=ce/d,R=Array.from({length:D?1:z},(P,W)=>{if(Q!==null)return Q;let K=Y+(D?0:W/z),G=.5-Math.cos(K%1*Math.PI*2)/2;return M+(I-M)*G});return j(n,R),T===1/0||Y<T}})},[j,_,v]),N=U((n,o={})=>{let p=o.id??`timeline-${ve++}`,d=o.repeat??1,M=n.map(T=>({...T,duration:Math.max(1,T.duration),hold:Math.max(0,T.hold??0)})),I=Math.max(1,M.reduce((T,D)=>T+D.duration+D.hold,0));return _({id:p,startedAt:null,lastFrameAt:null,override:null,onComplete:o.onComplete,update:(T,D,z,F)=>{if(M.length===0||d<=0)return!1;let ce=D/I;if(d!==1/0&&ce>=d){for(let Y of M)j(Y.channels,[1]);return!1}let ue=D%I,Q=0;for(let Y of M){let R=Q+Y.duration,P=R+Y.hold;if(ue>=R){j(Y.channels,[F??1]),Q=P;continue}if(ue>=Q){let W=F??Vt((ue-Q)/Y.duration,Y.easing??"ease-in-out");j(Y.channels,[W]);break}}return!0}})},[j,_]),a=U((n,o={})=>{let p=o.id??`flicker-${ve++}`,d=o.synchronized??!0,M=o.minLevel??.15,I=o.maxLevel??1,T=o.interval??[45,160],D=typeof T=="number"?[T,T]:T,z=[Math.max(1,Math.min(...D)),Math.max(1,Math.max(...D))],F=Re(o.response??.7,.01,1),ce=Re(o.blackoutChance??.08),ue=Re(o.flashChance??.12),Q=o.flashLevel??1.15,Y=Math.max(1,...[...n.materials??[],...n.transforms??[]].map(G=>v(G.targets).length),...(n.lights??[]).map(G=>Me(G.lights).length)),R=d?1:Y,P=Array.from({length:R},()=>M),W=Array.from({length:R},()=>M),K=Array.from({length:R},()=>0);return _({id:p,startedAt:null,lastFrameAt:null,override:null,onComplete:o.onComplete,update:(G,we,oe,Ce)=>{for(let Z=0;Z<R;Z+=1){if(Ce!==null)W[Z]=Ce;else if(G>=K[Z]){let it=Math.random();W[Z]=it<ce?Xe(0,Math.min(.04,M)):it<ce+ue?Q:Xe(M,I),K[Z]=G+Xe(...z)}let xt=1-Math.pow(1-F,Math.max(1,oe)/16.67);P[Z]+=(W[Z]-P[Z])*xt}return j(n,P),o.duration===void 0||we<o.duration}})},[j,_,v]),r=U((n,o,p)=>{let d=y.current.get(n);if(!d)return!1;let M=typeof performance>"u"?Date.now():performance.now();return d.override={level:o,until:M+Math.max(0,p)},q.current(),!0},[]),c=U(n=>y.current.delete(n),[]),u=U(()=>{y.current.clear(),g.current!==null&&typeof cancelAnimationFrame<"u"&&(cancelAnimationFrame(g.current),g.current=null)},[]),w=U(()=>{for(let[n,o]of A.current)Ct(n,o);A.current.clear();for(let[n,o]of B.current)n.position.set(...o.position),n.rotation.set(...o.rotation),n.scale.set(...o.scale),n.visible=o.visible,n.updateMatrix(),n.updateMatrixWorld(!0);B.current.clear();for(let n of l.current.values())n.light.removeFromParent(),n.light.dispose();l.current.clear(),m()},[m]),L=U(()=>{u(),w()},[w,u]),$=U(n=>{s.current&&s.current!==n.raw.scene&&w(),i.current=n,s.current=n.raw.scene,t.current.onViewerReady?.(n)},[w]);return Rn(()=>()=>{L(),i.current=null,s.current=null},[L]),{handleViewerReady:$,setMaterial:E,setTransform:h,getWorldPosition:b,addPointLight:S,updatePointLight:x,removePointLight:f,transition:V,timeline:N,pulse:J,flicker:a,overrideEffect:r,stopEffect:c,stopAllEffects:u,resetRuntime:L}}import{useCallback as kn,useState as Un}from"react";function et(){let[e,t]=Un(null),i=kn(s=>{t(s)},[t]);return{hoveredObjectBinding:e,handleHoveredObject:i}}import{useCallback as St,useState as Dn}from"react";function tt(e=null){let[t,i]=Dn(e),s=St((y,l)=>i({...l,target:y}),[]),g=St(()=>i(null),[]);return{isolation:t,isolate:s,clearIsolation:g,handleIsolationChange:i}}import{useCallback as xe,useState as de}from"react";function nt(){let[e,t]=de(!0),[i,s]=de(!1),[g,y]=de(null),[l,A]=de(null),[B,O]=de(0),[v,m]=de([]),[k,E]=de([]),[C,h]=de([]),b=xe(j=>{A(j.bounds),O(j.objectCount),m(j.materialVariants),E(j.materialVariantGroups),y(null),t(!1),s(!0)},[]),f=xe(j=>h(j),[]),S=xe(j=>{y(j),A(null),O(0),m([]),E([]),h([]),t(!1),s(!1)},[]),x=xe(()=>{t(!0),s(!1),y(null),A(null),O(0),m([]),E([]),h([])},[]);return{isLoading:e,isReady:i,error:g,bounds:l,objectCount:B,materialVariants:v,materialVariantGroups:k,objects:C,handleModelLoaded:b,handleObjectCatalog:f,handleLoadError:S,resetModelState:x}}import{useCallback as Ot,useState as Hn}from"react";function rt(e=null){let[t,i]=Hn(e),s=Ot(y=>{i(y)},[i]),g=Ot(()=>{i(null)},[]);return{selectedObjectBinding:t,setSelectedObjectBinding:i,handleObjectSelect:s,clearSelection:g}}var _n={};function Nn(e={}){let t=jt(e);t.current=e;let i=jt(e.bindings===void 0||e.bindings==="auto"),s=Ge(()=>{let V=t.current.bindings;return V===void 0||V==="auto"?_n:typeof V=="function"?V():V}),g=$e(()=>{let V=t.current.sceneConfig;return V===void 0?Oe:typeof V=="function"?V():V}),y=rt(),l=et(),A=Ee(e.camera),B=nt(),O=qe(),v=tt(),m=Ze(),k=Ye(A,m),E=We({bindings:s,scene:g,camera:A,animations:O,isolation:v,onAction:e.onAction}),{setObjectBindings:C}=s,{handleObjectCatalog:h}=B,b=Ae(V=>{h(V),i.current&&C(J=>{let N=dt(V.map(a=>a.name));for(let a of Object.keys(N))J[a]&&(N[a]=J[a]);return N})},[h,C]),{handleObjectSelect:f}=y,S=Ae(V=>{f(V),t.current.onObjectSelect?.(V)},[f]),{handleHoveredObject:x}=l,j=Ae(V=>{x(V),t.current.onObjectHover?.(V)},[x]),{handleLoadError:q}=B,X=Ae(V=>{q(V),t.current.onLoadError?.(V)},[q]),_=e.sceneConfig!==void 0||g.sceneConfig!==Oe;return{props:{objectBindings:s.objectBindings,onObjectBindingsChange:C,selectedObject:y.selectedObjectBinding,onObjectSelect:S,onObjectHover:j,onCameraChange:A.handleCameraChange,onViewerReady:k.handleViewerReady,onModelLoaded:B.handleModelLoaded,onLoadError:X,onObjectCatalog:b,onAnimationsReady:O.handleAnimationsReady,onAction:E.handleAction,onSceneConfigChange:g.setSceneConfig,isolation:v.isolation,onIsolationChange:v.handleIsolationChange,..._?{sceneConfig:g.sceneConfig}:{}},bindings:s,selection:y,hover:l,camera:A,model:B,animations:O,actions:E,scene:g,isolation:v,effects:m,connection:k}}import{useMemo as qn}from"react";function Fn(e,t){return qn(()=>{if(!t)return null;let i=e[t];return i||(Object.values(e).find(s=>s.id===t||s.modelObjectId===t)??null)},[e,t])}import{useMemo as Kn}from"react";function Gn(e){return Kn(()=>Object.values(e).map(t=>t.modelObjectId),[e])}import{useCallback as ne,useEffect as Pe,useRef as ae,useState as $n}from"react";function zn(e,t){if(!e.objectBindings&&(!!e.hidden?.length||!!e.selected)&&Object.keys(t).length===0)return null;let s={};if(e.objectBindings)s.bindings=e.objectBindings;else if(e.hidden){let g=new Set(e.hidden);s.bindings=Object.fromEntries(Object.entries(t).map(([y,l])=>[y,{...l,visible:!g.has(l.id)}]))}if(e.selected!==void 0){let g=e.objectBindings??t,y=e.selected?ee(g,e.selected):null;s.selected=y?g[y]:null}return s}function Bt(e){return JSON.stringify(e&&{modelUrl:e.modelUrl,activeModelId:e.activeModelId,tilesetUrl:e.tilesetUrl,mergeModels:e.mergeModels,models:e.models?.map(({id:t,url:i,mergeModels:s})=>({id:t,url:i,mergeModels:s}))})}function Wn(e){let t=ae(e);t.current=e;let i=e.paramKey??"view",s=`${i}Id`,[g,y]=$n(!1),l=ae(null),A=ae(null),B=ae(null),O=ae(null),v=ae(null),m=ae(null),k=ae(null),E=ae(null),C=ae(!0),h=ne(r=>{let c=r instanceof Error?r:new Error(String(r));t.current.onError?t.current.onError(c):k.current!==c.message&&console.warn("[react-immersive]",c.message),k.current=c.message},[]),b=ne(()=>{v.current!==null&&clearTimeout(v.current),v.current=null},[]);Pe(()=>(C.current=!0,()=>{C.current=!1,b()}),[b]);let f=ne(()=>{let r=t.current,c=(r.mode??(r.configuration?"configuration":"view"))==="configuration";return{version:1,camera:r.cameraState??void 0,hidden:Object.values(r.objectBindings).filter(u=>u.visible===!1).map(u=>u.id),selected:r.selectedObjectBinding?.id??null,...c?{objectBindings:r.objectBindings,configuration:r.configuration}:{}}},[]),S=ne(()=>ye(f(),typeof window>"u"?void 0:window.location.href),[f]),x=ne(()=>Ie(f(),typeof window>"u"?void 0:window.location.href),[f]),j=ne((r,c,u=window.location.href)=>{let w=new URL(u),L=new URLSearchParams(w.hash.slice(1));if(L.delete(i),L.delete(s),L.set(c?s:i,r),w.hash=L.toString(),!c&&w.href.length>(t.current.maxUrlLength??65536))throw new Error("Viewer configuration is too large for an inline link. Save JSON instead, or configure storage for createShareUrl(). Uploaded images can make links large.");return w.href},[i,s]),q=ne(()=>j(fe(S()),!1),[S,j]),X=ne(async()=>{let r=window.location.href,c=t.current.storage,u=await x();if(!c)return j(fe(u),!1,r);let w=await c.save(u);if(typeof w!="string"||!w.trim()||w.length>2048)throw new Error("Viewer state storage returned an invalid id.");return j(w,!0,r)},[x,j]),_=ne(()=>{if(b(),l.current||m.current)return;let r=q();window.history.replaceState(null,"",r),O.current=`inline:${new URL(r).hash}`},[b,q]),V=ne(async()=>{let r=l.current;if(!r||A.current||!C.current)return!1;A.current=r,b();try{let c=t.current,u=r.state;if(u.configuration&&!r.configurationApplied){if(!c.onConfigurationChange)throw new Error("Restoring a full viewer configuration requires onConfigurationChange.");return r.configurationApplied=!0,c.onConfigurationChange(u.configuration),!1}if(u.configuration&&Bt(c.configuration)!==Bt(u.configuration)||c.isReady===!1)return!1;if(u.camera&&!r.cameraApplied){if(!await c.setCameraState(u.camera,!1)||l.current!==r||!C.current)return!1;r.cameraApplied=!0}c=t.current;let w=zn(u,c.objectBindings);return!w||l.current!==r?!1:(w.bindings&&c.onObjectBindingsChange(w.bindings),w.selected!==void 0&&c.setSelectedObjectBinding(w.selected),l.current=null,B.current=r.key,y(!0),!0)}catch(c){throw l.current===r&&(l.current=null),y(!1),c}finally{A.current=null,l.current&&l.current!==r&&C.current&&V().catch(h)}},[b,h]),J=ne(async r=>{let c=ye(r,window.location.href);b(),E.current=null,m.current=null;let u=new URLSearchParams(window.location.hash.slice(1));return O.current=u.has(i)?`inline:${window.location.hash}`:u.has(s)?`stored:${s}:${u.get(s)}`:null,B.current=null,l.current={key:`manual:${fe(c)}`,origin:"manual",state:c,configurationApplied:!1,cameraApplied:!1},y(!1),V()},[V,b,i,s]),N=ne(async()=>{let r=new URLSearchParams(window.location.hash.slice(1)),c=r.get(i),u=r.get(s),w=c!==null?`inline:${window.location.hash}`:u!==null?`stored:${s}:${u}`:null;if(!w)return E.current=null,m.current=null,l.current?.origin==="manual"?V():(l.current=null,B.current=null,y(!0),!1);if(w===O.current||w===B.current)return l.current?.origin==="manual"?V():!1;if(l.current?.key===w)return V();b(),y(!1),E.current=w,l.current=null;let L=c;if(c===null){let n=t.current.storage;if(!n)throw new Error("This shared link requires a viewer state storage adapter.");(!m.current||m.current.key!==w)&&(m.current={key:w,promise:n.load(u)});let o=m.current;try{L=await o.promise}finally{m.current===o&&(m.current=null)}if(E.current!==w||!C.current)return!1;let p=l.current;if(p?.key===w||B.current===w)return p?V():!1}let $;try{$=ye(L,window.location.href)}catch(n){throw n}return l.current={key:w,origin:"url",state:$,configurationApplied:!1,cameraApplied:!1},V()},[V,b,s,i]);Pe(()=>{l.current&&V().catch(h)}),Pe(()=>{let r=()=>{N().catch(h)};return window.addEventListener("hashchange",r),()=>window.removeEventListener("hashchange",r)},[N,h]);let a=null;if(e.autoSync!==!1&&g&&!l.current&&!m.current)try{a=fe(S())}catch{}return Pe(()=>{if(e.autoSync===!1||!g||l.current||m.current){b();return}if(a===null){try{S()}catch(r){h(r)}return}return v.current=setTimeout(()=>{v.current=null;try{_()}catch(r){h(r)}},Math.max(0,e.debounceMs??400)),b},[a,e.autoSync,e.debounceMs,g,b,S,_,h]),{getState:S,getStateAsync:x,restoreState:J,getShareUrl:q,createShareUrl:X,syncUrl:_,restoreFromUrl:N}}import{useCallback as ge,useState as vt}from"react";var Yn={};function Mt(){return`asset-${globalThis.crypto.randomUUID()}`}function Xn(e){let[t,i]=vt(e),[s,g]=vt(()=>e[0]?re(e[0]):""),y=t.find(C=>re(C)===s)??t[0],l=y?re(y):"",A=ge(C=>{i(h=>h.map(b=>re(b)===l?{...b,objectBindings:C}:b))},[l]),B=ge(C=>{i(h=>h.map(b=>re(b)===l?{...b,sceneConfig:C}:b))},[l]),O=ge(C=>g(h=>{let b=t.find(f=>f.url===C);return b?re(b):h}),[t]),v=ge(C=>{let h={...C,id:C.id??Mt()};return i(b=>{if(b.some(f=>re(f)===h.id))throw new Error("Asset instance ID already exists.");return[...b,h]}),h.id},[]),m=ge(C=>{let h=t.find(j=>re(j)===C);if(!h)return null;let b=structuredClone(h);b.id=Mt(),b.sceneConfig?.measurements&&(b.sceneConfig.measurements.items=b.sceneConfig.measurements.items.map(j=>({...j,modelId:b.id}))),b.label=`${h.label??"Asset"} copy`;let[f,S,x]=h.transform?.position??[0,0,0];return b.transform={...b.transform,position:[f+1,S,x]},i(j=>[...j,b]),b.id},[t]),k=ge(C=>{i(h=>h.filter(b=>re(b)!==C))},[]),E=ge((C,h)=>{let b=Te(h);i(f=>f.map(S=>re(S)===C?{...S,transform:b}:S))},[]);return{modelUrl:y?.url??"",models:t,activeModelId:l,onModelChange:O,onActiveModelChange:g,objectBindings:Yn,onObjectBindingsChange:A,sceneConfig:y?.sceneConfig,onSceneConfigChange:B,addModel:v,duplicateModel:m,removeModel:k,updateModelTransform:E}}import{useCallback as be,useEffect as Jn,useState as Qn,useSyncExternalStore as Zn}from"react";var er={sequenceId:null,time:0,duration:0,status:"stopped",previewing:!1,ready:!1,issues:[]},tr=()=>()=>{},Rt=()=>er;function nr(){let[e,t]=Qn(null),i=Zn(e?.subscribe??tr,e?.getState??Rt,Rt);Jn(()=>()=>e?.stop(),[e]);let s=be(g=>t(g),[]);return{controls:e,playback:i,handleSequencesReady:s,play:be(g=>e?.play(g)??!1,[e]),pause:be(()=>e?.pause(),[e]),stop:be(()=>e?.stop(),[e]),seek:be(g=>e?.seek(g)??!1,[e]),select:be(g=>e?.select(g)??!1,[e])}}export{tn as ACTION_CATALOG,yn as AssetDiagnosticsPanel,pt as CompareViewer,Lt as DEFAULT_MODEL_VIEWER_LABELS,Oe as DEFAULT_SCENE_CONFIG,Se as DEFAULT_SECTION_CONFIG,pn as MATERIAL_BLENDING_MODES,fn as MATERIAL_SIDES,Yt as MAX_VIEWER_STATE_BYTES,_t as MEASUREMENT_UNITS,en as MODEL_VIEWER_PRESETS,he as ModelViewer,Pt as SEQUENCE_EASINGS,At as SEQUENCE_OBJECT_PROPERTIES,cn as applyIsolation,sn as applyStyleRules,un as buildBindingsFromNodes,qt as calibrateMeasurements,rn as chooseMaterialVariant,mn as collectObjectHierarchy,on as colorScaleValue,ke as compareViewerConfigurations,bn as copyBindingStyle,Xt as createARHandoffUrl,dn as createDefaultBinding,gn as defineObjectBindings,Qt as exportConfiguredUSDZ,nn as findCatalogAction,Ht as groundAsset,ln as inferType,Zt as inspectAsset,an as isolatedBindingKeys,He as material,Kt as measurementResult,Nt as measurementScale,Ft as measurementValue,zt as measurementsToCsv,Te as parseAssetTransform,Gt as parseMeasurements,kt as parseSectionConfig,Wt as parseSelectionSets,Et as parseSequences,ye as parseViewerState,wn as pasteBindingStyle,pe as patchBindings,_e as patchSceneConfig,Ie as prepareViewerState,Jt as readARHandoffUrl,Tt as sampleSequenceTrack,Ne as sceneLight,Ut as sectionSnapshot,le as selectBindingKeys,Le as selectBindings,$t as serializeMeasurements,fe as serializeViewerState,Dt as snapAssetToGrid,It as upsertSequenceKeyframe,Fn as useObjectBinding,Gn as useObjectBindingIds,Ge as useObjectBindings,$e as useSceneConfig,Wn as useShareableViewerState,Nn as useViewer,We as useViewerActions,qe as useViewerAnimations,Ee as useViewerCamera,Ye as useViewerConnection,Ze as useViewerEffects,et as useViewerHover,tt as useViewerIsolation,nt as useViewerModel,Xn as useViewerModels,rt as useViewerSelection,nr as useViewerSequences};
|
|
@@ -1,3 +1,55 @@
|
|
|
1
|
+
/** One choice in a row of material variants. */
|
|
2
|
+
type MaterialVariantOption = {
|
|
3
|
+
/** The variant's name, as `sceneConfig.model.activeVariants` lists it. */
|
|
4
|
+
name: string;
|
|
5
|
+
/** The name without its group, for display: "Red" for "Paint: Red". */
|
|
6
|
+
label: string;
|
|
7
|
+
/**
|
|
8
|
+
* The colour of the variant's main material, as a CSS colour, when that
|
|
9
|
+
* material is a plain colour rather than a texture.
|
|
10
|
+
*/
|
|
11
|
+
swatch?: string;
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* Variants that take turns: choosing one replaces the group's other choice.
|
|
15
|
+
* Variants in different groups combine, like a paint colour and a wheel style.
|
|
16
|
+
*/
|
|
17
|
+
type MaterialVariantGroup = {
|
|
18
|
+
/** "Paint" for variants named "Paint: Red" or "Paint / Red"; null otherwise. */
|
|
19
|
+
name: string | null;
|
|
20
|
+
variants: MaterialVariantOption[];
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* The active variants after choosing `name`: it replaces any other variant of
|
|
24
|
+
* its group, so a paint colour swaps for another while the wheels stay.
|
|
25
|
+
*/
|
|
26
|
+
declare function chooseMaterialVariant(activeVariants: readonly string[], name: string, groups: readonly MaterialVariantGroup[]): string[];
|
|
27
|
+
|
|
28
|
+
type ViewerModelBounds = {
|
|
29
|
+
min: [number, number, number];
|
|
30
|
+
max: [number, number, number];
|
|
31
|
+
center: [number, number, number];
|
|
32
|
+
size: [number, number, number];
|
|
33
|
+
};
|
|
34
|
+
/** What `onModelLoaded` reports about a model that finished loading. */
|
|
35
|
+
type ViewerModelInfo = {
|
|
36
|
+
/** Bounds in world space, where the viewer placed the model. */
|
|
37
|
+
bounds: ViewerModelBounds;
|
|
38
|
+
/** Number of meshes in the loaded scene. */
|
|
39
|
+
objectCount: number;
|
|
40
|
+
/**
|
|
41
|
+
* Names of the glTF material variants (KHR_materials_variants) the model
|
|
42
|
+
* offers, in file order; empty when it has none. Show them by setting
|
|
43
|
+
* `sceneConfig.model.activeVariants`.
|
|
44
|
+
*/
|
|
45
|
+
materialVariants: string[];
|
|
46
|
+
/**
|
|
47
|
+
* The same variants as option groups, with their display labels and
|
|
48
|
+
* swatches. One variant from each group can show at once.
|
|
49
|
+
*/
|
|
50
|
+
materialVariantGroups: MaterialVariantGroup[];
|
|
51
|
+
};
|
|
52
|
+
|
|
1
53
|
/** Built-in viewer text. Override only the keys your application needs. */
|
|
2
54
|
declare const DEFAULT_MODEL_VIEWER_LABELS: {
|
|
3
55
|
readonly verifyingLicense: "Verifying License";
|
|
@@ -15,6 +67,27 @@ declare const DEFAULT_MODEL_VIEWER_LABELS: {
|
|
|
15
67
|
readonly dismiss: "Dismiss";
|
|
16
68
|
readonly missingUVsAreShownInMagenta: "Missing UVs are shown in magenta.";
|
|
17
69
|
readonly viewThisModelInARWithAppleQuickLook: "View this model in AR with Apple Quick Look";
|
|
70
|
+
readonly sequencePlayer: "Sequence player";
|
|
71
|
+
readonly sequenceSelect: "Sequence";
|
|
72
|
+
readonly sequencePlay: "Play sequence";
|
|
73
|
+
readonly sequencePause: "Pause sequence";
|
|
74
|
+
readonly sequenceStop: "Stop and restore scene";
|
|
75
|
+
readonly sequencePlayhead: "Sequence playhead";
|
|
76
|
+
readonly sequenceTime: "Sequence time";
|
|
77
|
+
readonly sequenceIssues: "Unavailable sequence targets";
|
|
78
|
+
readonly arConfiguredButton: "AR handoff";
|
|
79
|
+
readonly arConfiguredTitle: "Take this configuration to AR";
|
|
80
|
+
readonly arConfiguredDescription: "Your current materials, visible models and placements are included.";
|
|
81
|
+
readonly arSnapshotStale: "Updating AR to include your latest changes…";
|
|
82
|
+
readonly arPreparing: "Preparing your scene…";
|
|
83
|
+
readonly arRefresh: "Refresh AR";
|
|
84
|
+
readonly arRetry: "Try again";
|
|
85
|
+
readonly arExportDetails: "Export details";
|
|
86
|
+
readonly arPrepare: "Prepare AR";
|
|
87
|
+
readonly arPrepareAgain: "Prepare again";
|
|
88
|
+
readonly arDownloadUSDZ: "Download USDZ for iPhone/iPad";
|
|
89
|
+
readonly arScanConfigured: "Scan to open this configuration on your phone.";
|
|
90
|
+
readonly arOpenConfiguredLink: "Open configuration link";
|
|
18
91
|
readonly viewInAR: "View in AR";
|
|
19
92
|
readonly openThisExperienceOnAPhoneForAR: "Open this experience on a phone for AR";
|
|
20
93
|
readonly openOnPhone: "Open on phone";
|
|
@@ -58,6 +131,10 @@ declare const DEFAULT_MODEL_VIEWER_LABELS: {
|
|
|
58
131
|
readonly cameraController: "Camera controller";
|
|
59
132
|
readonly cameraControllerSettings: "Camera controller settings";
|
|
60
133
|
readonly downloadGLB: "Download GLB";
|
|
134
|
+
readonly downloadGLBDescription: "All visible models, material edits and animations in one file. No annotations or separate editor model slots. Duplicate mesh names may change on reimport.";
|
|
135
|
+
readonly downloadCombinedGLB: "Download as one GLB";
|
|
136
|
+
readonly downloadSeparateGLBs: "Download separate GLBs";
|
|
137
|
+
readonly downloadSeparateGLBsDescription: "One GLB file per model";
|
|
61
138
|
readonly downloadPNG: "Download PNG";
|
|
62
139
|
readonly downloadUVLayout: "Download UV Layout";
|
|
63
140
|
readonly videoFormat: "Video format";
|
|
@@ -83,6 +160,8 @@ declare const DEFAULT_MODEL_VIEWER_LABELS: {
|
|
|
83
160
|
readonly angle: "Angle";
|
|
84
161
|
readonly area: "Area";
|
|
85
162
|
readonly pointToPlane: "Point to plane";
|
|
163
|
+
readonly wrap: "Circumference (Edge)";
|
|
164
|
+
readonly wrapHorizontal: "Circumference (Horizontal)";
|
|
86
165
|
readonly measurementSnapping: "Measurement snapping";
|
|
87
166
|
readonly noSnapping: "No snapping";
|
|
88
167
|
readonly snapAuto: "Snap: auto";
|
|
@@ -91,6 +170,35 @@ declare const DEFAULT_MODEL_VIEWER_LABELS: {
|
|
|
91
170
|
readonly undoMeasurementPoint: "Undo measurement point";
|
|
92
171
|
readonly clearMeasurements: "Clear measurements";
|
|
93
172
|
readonly finishArea: "Finish area";
|
|
173
|
+
readonly savedMeasurements: "Saved measurements ({count})";
|
|
174
|
+
readonly noSavedMeasurements: "No saved measurements yet. Pick points in the preview, then save a measurement here.";
|
|
175
|
+
readonly measurementFiles: "Import / export";
|
|
176
|
+
readonly measurementSourceUnit: "Model units";
|
|
177
|
+
readonly measurementDisplayUnit: "Display units";
|
|
178
|
+
readonly measurementName: "Measurement name";
|
|
179
|
+
readonly measurementNamePlaceholder: "e.g. Door width";
|
|
180
|
+
readonly saveMeasurement: "Save measurement";
|
|
181
|
+
readonly knownMeasurementDistance: "Known distance";
|
|
182
|
+
readonly calibrationUnit: "Calibration unit";
|
|
183
|
+
readonly calibrateMeasurement: "Calibrate";
|
|
184
|
+
readonly measurementCalibrationHint: "Pick two distance points, enter their known length, then calibrate.";
|
|
185
|
+
readonly measurementCalibratedScale: "Calibrated: 1 model unit = {scale} m";
|
|
186
|
+
readonly resetMeasurementCalibration: "Reset calibration";
|
|
187
|
+
readonly showSavedMeasurement: "Show {name}";
|
|
188
|
+
readonly renameSavedMeasurement: "Rename {name}";
|
|
189
|
+
readonly deleteSavedMeasurement: "Delete {name}";
|
|
190
|
+
readonly exportMeasurementJson: "Export JSON";
|
|
191
|
+
readonly exportMeasurementCsv: "Export CSV";
|
|
192
|
+
readonly importMeasurementJson: "Import JSON";
|
|
193
|
+
readonly measurementReady: "Ready";
|
|
194
|
+
readonly measurementApproximate: "Approximate LOD";
|
|
195
|
+
readonly measurementModelChanged: "Different model";
|
|
196
|
+
readonly measurementObjectMissing: "Object unavailable";
|
|
197
|
+
readonly measurementGeometryChanged: "Geometry changed — measure again";
|
|
198
|
+
readonly measurementPoseChanged: "Pose changed — measure again";
|
|
199
|
+
readonly measurementObjectHidden: "Object hidden";
|
|
200
|
+
readonly measurementInvalid: "Invalid measurement";
|
|
201
|
+
readonly measurementWaiting: "Waiting for model";
|
|
94
202
|
readonly openSceneObjectsPanel: "Open scene objects panel";
|
|
95
203
|
readonly sceneObjects: "SCENE OBJECTS";
|
|
96
204
|
readonly searchNodesLabels: "Search nodes, labels";
|
|
@@ -165,6 +273,8 @@ declare const DEFAULT_MODEL_VIEWER_LABELS: {
|
|
|
165
273
|
readonly pointToPlanePointHint: "Pick a point to measure its perpendicular distance";
|
|
166
274
|
readonly pointToPlaneNewHint: "Pick a face to start a new measurement";
|
|
167
275
|
readonly distanceHint: "Pick points on the model to measure distances";
|
|
276
|
+
readonly wrapHint: "Click a point on the surface to measure its circumference, following the surface (best for limbs)";
|
|
277
|
+
readonly wrapHorizontalHint: "Click a point to measure a level circumference around it (best for the torso/waist)";
|
|
168
278
|
readonly visibleEntries: "{count} visible entries";
|
|
169
279
|
readonly objectCount: "{count} objects";
|
|
170
280
|
readonly annotationMarker: "Annotation {id}: {title}";
|
|
@@ -272,6 +382,19 @@ type ModelViewerLabelKey = keyof typeof DEFAULT_MODEL_VIEWER_LABELS;
|
|
|
272
382
|
/** Plain-text overrides; dynamic labels use named {placeholders}. */
|
|
273
383
|
type ModelViewerLabels = Partial<Record<ModelViewerLabelKey, string>>;
|
|
274
384
|
|
|
385
|
+
/**
|
|
386
|
+
* When a viewer starts its 3D view on its own. `"lazy"` waits until it's on
|
|
387
|
+
* or near the screen and shares the page's live 3D views with the other lazy
|
|
388
|
+
* viewers, so a page of viewers stays within the browser's limit. `"eager"`
|
|
389
|
+
* starts at once and keeps its view.
|
|
390
|
+
*/
|
|
391
|
+
type ViewerLoading = "lazy" | "eager";
|
|
392
|
+
/**
|
|
393
|
+
* Whether the 3D view starts on its own (`"auto"`) or waits on the poster
|
|
394
|
+
* until the visitor asks for it with a "View in 3D" button (`"interaction"`).
|
|
395
|
+
*/
|
|
396
|
+
type ViewerReveal = "auto" | "interaction";
|
|
397
|
+
|
|
275
398
|
/**
|
|
276
399
|
* Whether the viewer cuts motion that starts on its own: `"user"` follows the
|
|
277
400
|
* visitor's `prefers-reduced-motion` setting, `"always"` and `"never"` override
|
|
@@ -279,31 +402,6 @@ type ModelViewerLabels = Partial<Record<ModelViewerLabelKey, string>>;
|
|
|
279
402
|
*/
|
|
280
403
|
type ReducedMotionSetting = "user" | "always" | "never";
|
|
281
404
|
|
|
282
|
-
|
|
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[];
|
|
405
|
+
type ModelFormat = "glb" | "gltf" | "obj" | "fbx" | "usdz" | "stl" | "ply";
|
|
308
406
|
|
|
309
|
-
export { DEFAULT_MODEL_VIEWER_LABELS as D, type MaterialVariantGroup as M, type ReducedMotionSetting as R, type MaterialVariantOption as a, type
|
|
407
|
+
export { DEFAULT_MODEL_VIEWER_LABELS as D, type MaterialVariantGroup as M, type ReducedMotionSetting as R, type ViewerLoading as V, type MaterialVariantOption as a, type ModelFormat as b, type ModelViewerLabelKey as c, type ModelViewerLabels as d, type ViewerModelBounds as e, type ViewerModelInfo as f, type ViewerReveal as g, chooseMaterialVariant as h };
|
|
@@ -1,3 +1,55 @@
|
|
|
1
|
+
/** One choice in a row of material variants. */
|
|
2
|
+
type MaterialVariantOption = {
|
|
3
|
+
/** The variant's name, as `sceneConfig.model.activeVariants` lists it. */
|
|
4
|
+
name: string;
|
|
5
|
+
/** The name without its group, for display: "Red" for "Paint: Red". */
|
|
6
|
+
label: string;
|
|
7
|
+
/**
|
|
8
|
+
* The colour of the variant's main material, as a CSS colour, when that
|
|
9
|
+
* material is a plain colour rather than a texture.
|
|
10
|
+
*/
|
|
11
|
+
swatch?: string;
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* Variants that take turns: choosing one replaces the group's other choice.
|
|
15
|
+
* Variants in different groups combine, like a paint colour and a wheel style.
|
|
16
|
+
*/
|
|
17
|
+
type MaterialVariantGroup = {
|
|
18
|
+
/** "Paint" for variants named "Paint: Red" or "Paint / Red"; null otherwise. */
|
|
19
|
+
name: string | null;
|
|
20
|
+
variants: MaterialVariantOption[];
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* The active variants after choosing `name`: it replaces any other variant of
|
|
24
|
+
* its group, so a paint colour swaps for another while the wheels stay.
|
|
25
|
+
*/
|
|
26
|
+
declare function chooseMaterialVariant(activeVariants: readonly string[], name: string, groups: readonly MaterialVariantGroup[]): string[];
|
|
27
|
+
|
|
28
|
+
type ViewerModelBounds = {
|
|
29
|
+
min: [number, number, number];
|
|
30
|
+
max: [number, number, number];
|
|
31
|
+
center: [number, number, number];
|
|
32
|
+
size: [number, number, number];
|
|
33
|
+
};
|
|
34
|
+
/** What `onModelLoaded` reports about a model that finished loading. */
|
|
35
|
+
type ViewerModelInfo = {
|
|
36
|
+
/** Bounds in world space, where the viewer placed the model. */
|
|
37
|
+
bounds: ViewerModelBounds;
|
|
38
|
+
/** Number of meshes in the loaded scene. */
|
|
39
|
+
objectCount: number;
|
|
40
|
+
/**
|
|
41
|
+
* Names of the glTF material variants (KHR_materials_variants) the model
|
|
42
|
+
* offers, in file order; empty when it has none. Show them by setting
|
|
43
|
+
* `sceneConfig.model.activeVariants`.
|
|
44
|
+
*/
|
|
45
|
+
materialVariants: string[];
|
|
46
|
+
/**
|
|
47
|
+
* The same variants as option groups, with their display labels and
|
|
48
|
+
* swatches. One variant from each group can show at once.
|
|
49
|
+
*/
|
|
50
|
+
materialVariantGroups: MaterialVariantGroup[];
|
|
51
|
+
};
|
|
52
|
+
|
|
1
53
|
/** Built-in viewer text. Override only the keys your application needs. */
|
|
2
54
|
declare const DEFAULT_MODEL_VIEWER_LABELS: {
|
|
3
55
|
readonly verifyingLicense: "Verifying License";
|
|
@@ -15,6 +67,27 @@ declare const DEFAULT_MODEL_VIEWER_LABELS: {
|
|
|
15
67
|
readonly dismiss: "Dismiss";
|
|
16
68
|
readonly missingUVsAreShownInMagenta: "Missing UVs are shown in magenta.";
|
|
17
69
|
readonly viewThisModelInARWithAppleQuickLook: "View this model in AR with Apple Quick Look";
|
|
70
|
+
readonly sequencePlayer: "Sequence player";
|
|
71
|
+
readonly sequenceSelect: "Sequence";
|
|
72
|
+
readonly sequencePlay: "Play sequence";
|
|
73
|
+
readonly sequencePause: "Pause sequence";
|
|
74
|
+
readonly sequenceStop: "Stop and restore scene";
|
|
75
|
+
readonly sequencePlayhead: "Sequence playhead";
|
|
76
|
+
readonly sequenceTime: "Sequence time";
|
|
77
|
+
readonly sequenceIssues: "Unavailable sequence targets";
|
|
78
|
+
readonly arConfiguredButton: "AR handoff";
|
|
79
|
+
readonly arConfiguredTitle: "Take this configuration to AR";
|
|
80
|
+
readonly arConfiguredDescription: "Your current materials, visible models and placements are included.";
|
|
81
|
+
readonly arSnapshotStale: "Updating AR to include your latest changes…";
|
|
82
|
+
readonly arPreparing: "Preparing your scene…";
|
|
83
|
+
readonly arRefresh: "Refresh AR";
|
|
84
|
+
readonly arRetry: "Try again";
|
|
85
|
+
readonly arExportDetails: "Export details";
|
|
86
|
+
readonly arPrepare: "Prepare AR";
|
|
87
|
+
readonly arPrepareAgain: "Prepare again";
|
|
88
|
+
readonly arDownloadUSDZ: "Download USDZ for iPhone/iPad";
|
|
89
|
+
readonly arScanConfigured: "Scan to open this configuration on your phone.";
|
|
90
|
+
readonly arOpenConfiguredLink: "Open configuration link";
|
|
18
91
|
readonly viewInAR: "View in AR";
|
|
19
92
|
readonly openThisExperienceOnAPhoneForAR: "Open this experience on a phone for AR";
|
|
20
93
|
readonly openOnPhone: "Open on phone";
|
|
@@ -58,6 +131,10 @@ declare const DEFAULT_MODEL_VIEWER_LABELS: {
|
|
|
58
131
|
readonly cameraController: "Camera controller";
|
|
59
132
|
readonly cameraControllerSettings: "Camera controller settings";
|
|
60
133
|
readonly downloadGLB: "Download GLB";
|
|
134
|
+
readonly downloadGLBDescription: "All visible models, material edits and animations in one file. No annotations or separate editor model slots. Duplicate mesh names may change on reimport.";
|
|
135
|
+
readonly downloadCombinedGLB: "Download as one GLB";
|
|
136
|
+
readonly downloadSeparateGLBs: "Download separate GLBs";
|
|
137
|
+
readonly downloadSeparateGLBsDescription: "One GLB file per model";
|
|
61
138
|
readonly downloadPNG: "Download PNG";
|
|
62
139
|
readonly downloadUVLayout: "Download UV Layout";
|
|
63
140
|
readonly videoFormat: "Video format";
|
|
@@ -83,6 +160,8 @@ declare const DEFAULT_MODEL_VIEWER_LABELS: {
|
|
|
83
160
|
readonly angle: "Angle";
|
|
84
161
|
readonly area: "Area";
|
|
85
162
|
readonly pointToPlane: "Point to plane";
|
|
163
|
+
readonly wrap: "Circumference (Edge)";
|
|
164
|
+
readonly wrapHorizontal: "Circumference (Horizontal)";
|
|
86
165
|
readonly measurementSnapping: "Measurement snapping";
|
|
87
166
|
readonly noSnapping: "No snapping";
|
|
88
167
|
readonly snapAuto: "Snap: auto";
|
|
@@ -91,6 +170,35 @@ declare const DEFAULT_MODEL_VIEWER_LABELS: {
|
|
|
91
170
|
readonly undoMeasurementPoint: "Undo measurement point";
|
|
92
171
|
readonly clearMeasurements: "Clear measurements";
|
|
93
172
|
readonly finishArea: "Finish area";
|
|
173
|
+
readonly savedMeasurements: "Saved measurements ({count})";
|
|
174
|
+
readonly noSavedMeasurements: "No saved measurements yet. Pick points in the preview, then save a measurement here.";
|
|
175
|
+
readonly measurementFiles: "Import / export";
|
|
176
|
+
readonly measurementSourceUnit: "Model units";
|
|
177
|
+
readonly measurementDisplayUnit: "Display units";
|
|
178
|
+
readonly measurementName: "Measurement name";
|
|
179
|
+
readonly measurementNamePlaceholder: "e.g. Door width";
|
|
180
|
+
readonly saveMeasurement: "Save measurement";
|
|
181
|
+
readonly knownMeasurementDistance: "Known distance";
|
|
182
|
+
readonly calibrationUnit: "Calibration unit";
|
|
183
|
+
readonly calibrateMeasurement: "Calibrate";
|
|
184
|
+
readonly measurementCalibrationHint: "Pick two distance points, enter their known length, then calibrate.";
|
|
185
|
+
readonly measurementCalibratedScale: "Calibrated: 1 model unit = {scale} m";
|
|
186
|
+
readonly resetMeasurementCalibration: "Reset calibration";
|
|
187
|
+
readonly showSavedMeasurement: "Show {name}";
|
|
188
|
+
readonly renameSavedMeasurement: "Rename {name}";
|
|
189
|
+
readonly deleteSavedMeasurement: "Delete {name}";
|
|
190
|
+
readonly exportMeasurementJson: "Export JSON";
|
|
191
|
+
readonly exportMeasurementCsv: "Export CSV";
|
|
192
|
+
readonly importMeasurementJson: "Import JSON";
|
|
193
|
+
readonly measurementReady: "Ready";
|
|
194
|
+
readonly measurementApproximate: "Approximate LOD";
|
|
195
|
+
readonly measurementModelChanged: "Different model";
|
|
196
|
+
readonly measurementObjectMissing: "Object unavailable";
|
|
197
|
+
readonly measurementGeometryChanged: "Geometry changed — measure again";
|
|
198
|
+
readonly measurementPoseChanged: "Pose changed — measure again";
|
|
199
|
+
readonly measurementObjectHidden: "Object hidden";
|
|
200
|
+
readonly measurementInvalid: "Invalid measurement";
|
|
201
|
+
readonly measurementWaiting: "Waiting for model";
|
|
94
202
|
readonly openSceneObjectsPanel: "Open scene objects panel";
|
|
95
203
|
readonly sceneObjects: "SCENE OBJECTS";
|
|
96
204
|
readonly searchNodesLabels: "Search nodes, labels";
|
|
@@ -165,6 +273,8 @@ declare const DEFAULT_MODEL_VIEWER_LABELS: {
|
|
|
165
273
|
readonly pointToPlanePointHint: "Pick a point to measure its perpendicular distance";
|
|
166
274
|
readonly pointToPlaneNewHint: "Pick a face to start a new measurement";
|
|
167
275
|
readonly distanceHint: "Pick points on the model to measure distances";
|
|
276
|
+
readonly wrapHint: "Click a point on the surface to measure its circumference, following the surface (best for limbs)";
|
|
277
|
+
readonly wrapHorizontalHint: "Click a point to measure a level circumference around it (best for the torso/waist)";
|
|
168
278
|
readonly visibleEntries: "{count} visible entries";
|
|
169
279
|
readonly objectCount: "{count} objects";
|
|
170
280
|
readonly annotationMarker: "Annotation {id}: {title}";
|
|
@@ -272,6 +382,19 @@ type ModelViewerLabelKey = keyof typeof DEFAULT_MODEL_VIEWER_LABELS;
|
|
|
272
382
|
/** Plain-text overrides; dynamic labels use named {placeholders}. */
|
|
273
383
|
type ModelViewerLabels = Partial<Record<ModelViewerLabelKey, string>>;
|
|
274
384
|
|
|
385
|
+
/**
|
|
386
|
+
* When a viewer starts its 3D view on its own. `"lazy"` waits until it's on
|
|
387
|
+
* or near the screen and shares the page's live 3D views with the other lazy
|
|
388
|
+
* viewers, so a page of viewers stays within the browser's limit. `"eager"`
|
|
389
|
+
* starts at once and keeps its view.
|
|
390
|
+
*/
|
|
391
|
+
type ViewerLoading = "lazy" | "eager";
|
|
392
|
+
/**
|
|
393
|
+
* Whether the 3D view starts on its own (`"auto"`) or waits on the poster
|
|
394
|
+
* until the visitor asks for it with a "View in 3D" button (`"interaction"`).
|
|
395
|
+
*/
|
|
396
|
+
type ViewerReveal = "auto" | "interaction";
|
|
397
|
+
|
|
275
398
|
/**
|
|
276
399
|
* Whether the viewer cuts motion that starts on its own: `"user"` follows the
|
|
277
400
|
* visitor's `prefers-reduced-motion` setting, `"always"` and `"never"` override
|
|
@@ -279,31 +402,6 @@ type ModelViewerLabels = Partial<Record<ModelViewerLabelKey, string>>;
|
|
|
279
402
|
*/
|
|
280
403
|
type ReducedMotionSetting = "user" | "always" | "never";
|
|
281
404
|
|
|
282
|
-
|
|
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[];
|
|
405
|
+
type ModelFormat = "glb" | "gltf" | "obj" | "fbx" | "usdz" | "stl" | "ply";
|
|
308
406
|
|
|
309
|
-
export { DEFAULT_MODEL_VIEWER_LABELS as D, type MaterialVariantGroup as M, type ReducedMotionSetting as R, type MaterialVariantOption as a, type
|
|
407
|
+
export { DEFAULT_MODEL_VIEWER_LABELS as D, type MaterialVariantGroup as M, type ReducedMotionSetting as R, type ViewerLoading as V, type MaterialVariantOption as a, type ModelFormat as b, type ModelViewerLabelKey as c, type ModelViewerLabels as d, type ViewerModelBounds as e, type ViewerModelInfo as f, type ViewerReveal as g, chooseMaterialVariant as h };
|