@imagineio/configurator-sdk 0.1.4 → 0.1.6

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/README.md CHANGED
@@ -9,14 +9,16 @@ needs an SDK release to change.
9
9
 
10
10
  The 3D stack (three / fiber / drei) is installed for you — npm 7+ adds the SDK's
11
11
  peer packages automatically at the versions the SDK is built against, so your app
12
- ends up with exactly one copy of `three`. Pin React 18 in the same command: a fresh
13
- Vite template scaffolds React 19, which the SDK's 3D stack doesn't support yet
14
- (`@react-three/fiber@8` requires React 18), so installing the SDK alone there
15
- fails with `ERESOLVE`:
12
+ ends up with exactly one copy of `three`.
16
13
 
17
14
  ```bash
18
- npm install @imagineio/configurator-sdk react@^18.2 react-dom@^18.2
19
- npm install -D @types/react@^18.3 @types/react-dom@^18.3 # the scaffold's are React 19's
15
+ npm install @imagineio/configurator-sdk
16
+ ```
17
+
18
+ To install with React 18, use this command:
19
+
20
+ ```bash
21
+ npm install @imagineio/configurator-sdk react@^18.2 react-dom@^18.2 three@~0.159.0 @react-three/fiber@^8.15 @react-three/drei@^9.88 @react-three/postprocessing@^2.16 postprocessing@~6.36.0
20
22
  ```
21
23
 
22
24
  (The second line matters even in a JavaScript project: create-vite scaffolds React 19
@@ -45,6 +47,8 @@ mount(document.getElementById('root'), { systemId: YOUR_SYSTEM_ID });
45
47
 
46
48
  ## Documentation
47
49
 
50
+ **https://configurator-platform.imagine.io/sdk/index.html**
51
+
48
52
  The full documentation site — Getting Started (install to a live configurator in
49
53
  five steps), theming and UI customization, placement customization, the complete
50
54
  function reference with runnable examples, the e-commerce bridge protocol, and
@@ -53,9 +57,9 @@ this package.
53
57
 
54
58
  ## Requirements
55
59
 
56
- Node ≥ 18, React 18, Vite (recommended). Peer deps (auto-installed by npm 7+):
57
- `react`, `react-dom` (React 18 only — React 19 not supported yet), `three` 0.159,
58
- `@react-three/fiber` 8, `@react-three/drei` 9. Everything else is installed as a
60
+ Node ≥ 18, React 19, Vite (recommended). Peer deps (auto-installed by npm 7+):
61
+ `react`, `react-dom` , `three` 0.185,
62
+ `@react-three/fiber` 9, `@react-three/drei` 10. Everything else is installed as a
59
63
  regular npm dependency — nothing third-party is bundled into the package itself.
60
64
 
61
65
  **Strict CSP?** Two things load at runtime from Google, not from the package: the AR
@@ -1 +1 @@
1
- import i from"node:fs";import t from"node:path";import{fileURLToPath as h}from"node:url";const g=["three","react","react-dom","@react-three/fiber","@react-three/drei","zustand"],j={".js":"text/javascript",".mjs":"text/javascript",".wasm":"application/wasm",".svg":"image/svg+xml",".json":"application/json",".txt":"text/plain",".md":"text/markdown"};function v(){const o=t.dirname(h(import.meta.url)),n=[t.resolve(o,"static"),t.resolve(o,"..","static")];return n.find(r=>i.existsSync(r))||n[0]}function y(o,n=""){let r=[],c=[];try{c=i.readdirSync(o,{withFileTypes:!0})}catch{return r}for(const s of c){const e=n?`${n}/${s.name}`:s.name;s.isDirectory()?r=r.concat(y(t.join(o,s.name),e)):r.push(e)}return r}function S(o={}){const{copyAssets:n=!0,dedupe:r=!0}=o,c=v();let s="dist";return{name:"imagine-configurator-sdk",config(){return r?{resolve:{dedupe:g}}:null},configResolved(e){s=t.resolve(e.root,e.build.outDir)},configureServer(e){if(!n)return;const a=e.config.publicDir;e.middlewares.use((m,d,u)=>{const f=decodeURIComponent((m.url||"").split("?")[0]),l=t.normalize(t.join(c,f));if(!l.startsWith(c+t.sep))return u();let p=null;try{p=i.statSync(l)}catch{return u()}if(!p.isFile())return u();try{if(a&&i.existsSync(t.join(a,f)))return u()}catch{}d.setHeader("Content-Type",j[t.extname(l).toLowerCase()]||"application/octet-stream"),i.createReadStream(l).pipe(d)})},closeBundle(){if(n)for(const e of y(c)){const a=t.join(s,e);try{if(i.existsSync(a))continue;i.mkdirSync(t.dirname(a),{recursive:!0}),i.copyFileSync(t.join(c,e),a)}catch{}}}}}export{S as default};
1
+ import n from"node:fs";import t from"node:path";import{fileURLToPath as h}from"node:url";const g=["three","react","react-dom","@react-three/fiber","@react-three/drei"],j={".js":"text/javascript",".mjs":"text/javascript",".wasm":"application/wasm",".svg":"image/svg+xml",".json":"application/json",".txt":"text/plain",".md":"text/markdown"};function v(){const o=t.dirname(h(import.meta.url)),i=[t.resolve(o,"static"),t.resolve(o,"..","static")];return i.find(r=>n.existsSync(r))||i[0]}function y(o,i=""){let r=[],c=[];try{c=n.readdirSync(o,{withFileTypes:!0})}catch{return r}for(const s of c){const e=i?`${i}/${s.name}`:s.name;s.isDirectory()?r=r.concat(y(t.join(o,s.name),e)):r.push(e)}return r}function S(o={}){const{copyAssets:i=!0,dedupe:r=!0}=o,c=v();let s="dist";return{name:"imagine-configurator-sdk",config(){return r?{resolve:{dedupe:g}}:null},configResolved(e){s=t.resolve(e.root,e.build.outDir)},configureServer(e){if(!i)return;const a=e.config.publicDir;e.middlewares.use((m,f,u)=>{const d=decodeURIComponent((m.url||"").split("?")[0]),l=t.normalize(t.join(c,d));if(!l.startsWith(c+t.sep))return u();let p=null;try{p=n.statSync(l)}catch{return u()}if(!p.isFile())return u();try{if(a&&n.existsSync(t.join(a,d)))return u()}catch{}f.setHeader("Content-Type",j[t.extname(l).toLowerCase()]||"application/octet-stream"),n.createReadStream(l).pipe(f)})},closeBundle(){if(i)for(const e of y(c)){const a=t.join(s,e);try{if(n.existsSync(a))continue;n.mkdirSync(t.dirname(a),{recursive:!0}),n.copyFileSync(t.join(c,e),a)}catch{}}}}}export{S as default};
@@ -1 +1 @@
1
- import*as o from"three";const M={ACESFilmic:o.ACESFilmicToneMapping,Reinhard:o.ReinhardToneMapping,Linear:o.LinearToneMapping,None:o.NoToneMapping,Cineon:o.CineonToneMapping},r={PCF:o.PCFSoftShadowMap,PCFSoft:o.PCFSoftShadowMap,PCFHard:o.PCFShadowMap,VSM:o.VSMShadowMap,Basic:o.BasicShadowMap},i={toneMapping:o.NoToneMapping,exposure:1,shadowMapType:o.PCFSoftShadowMap};function h(a,p){if(!a||!p)return;const n=a.tone_mapping??a.toneMapping,s=n!=null&&n!==""?M[n]:null;p.toneMapping=s??i.toneMapping;const e=a.exposure,t=e!=null&&e!==""?Number(e):NaN;if(p.toneMappingExposure=Number.isFinite(t)?t:i.exposure,a.shadows){typeof a.shadows.enabled=="boolean"&&(p.shadowMap.enabled=a.shadows.enabled);const d=a.shadows.type?r[a.shadows.type]:null;p.shadowMap.type=d??i.shadowMapType,p.shadowMap.needsUpdate=!0}}export{i as RENDERER_DEFAULTS,h as applyEnvironmentToRenderer};
1
+ import*as o from"three";const M={ACESFilmic:o.ACESFilmicToneMapping,Reinhard:o.ReinhardToneMapping,Linear:o.LinearToneMapping,None:o.NoToneMapping,Cineon:o.CineonToneMapping},r={PCF:o.PCFShadowMap,PCFSoft:o.PCFShadowMap,PCFHard:o.PCFShadowMap,VSM:o.VSMShadowMap,Basic:o.BasicShadowMap},i={toneMapping:o.NoToneMapping,exposure:1,shadowMapType:o.PCFShadowMap};function h(a,p){if(!a||!p)return;const n=a.tone_mapping??a.toneMapping,s=n!=null&&n!==""?M[n]:null;p.toneMapping=s??i.toneMapping;const e=a.exposure,t=e!=null&&e!==""?Number(e):NaN;if(p.toneMappingExposure=Number.isFinite(t)?t:i.exposure,a.shadows){typeof a.shadows.enabled=="boolean"&&(p.shadowMap.enabled=a.shadows.enabled);const d=a.shadows.type?r[a.shadows.type]:null;p.shadowMap.type=d??i.shadowMapType,p.shadowMap.needsUpdate=!0}}export{i as RENDERER_DEFAULTS,h as applyEnvironmentToRenderer};
@@ -1 +1 @@
1
- import{Fragment as le,jsx as m,jsxs as dt}from"react/jsx-runtime";import{useCallback as J,useEffect as N,useMemo as H,useRef as Mt,useState as xt,useSyncExternalStore as We}from"react";import{Html as yn,useProgress as vn}from"@react-three/drei";import _ from"./9c6c598569.js";import W from"./872c4302e0.js";import R from"./be337ddda5.js";import gt from"./d94df858ea.js";import{normalizeMaterialTargets as Pn}from"./dc2a1a0e13.js";import y from"./8f60e5059a.js";import Mn from"./60d697292c.js";import xn from"./811b403d43.js";import{useUiToggles as wn}from"./d0f9681634.js";import{ProductInstance as ce,SelectionActionPanel as Cn,FreeMovable as _n,PlacementGaps as Tn,SceneStage as Fn,SceneRoom as Gn,SceneProductsSource as On}from"./8a3a57c008.js";import An from"./205827c5c8.js";import{computeTargets as Dn,resolveTarget as Ln,resolveTargetRenderer as kn,resolveInsertSequence as zn}from"./58e6419ba8.js";import{disarmPlacement as Ye}from"./ab6c80484f.js";import{isCompatibleSlot as $e}from"./99577e3161.js";import{resolveComponent as ie,useComponentRegistry as Ke}from"./882bc739c8.js";import Rn from"./88251d6671.js";import{useLabels as En}from"./28d887bf8a.js";import{SlotHost as qn}from"./73f7d65985.js";import{ModalHost as Nn}from"./09c4973968.js";import Xn from"./6c0a2572dd.js";import Zn from"./20b0104576.js";import{getConfigState as Hn,subscribe as Qe,getVersion as Et}from"./817d930a49.js";import{getPlacementStrategy as Je}from"./281cf952fa.js";import{resolveAddMode as Vn,armPlacement as jn}from"./ab6c80484f.js";import{resolveReplaceTarget as Un}from"./4d7a0d1897.js";import{enforceCorners as Bn}from"./388cadacbd.js";import{resolvePlacementStrategyConfig as tn}from"./281cf952fa.js";import{getLabel as Wn}from"./28d887bf8a.js";import{isAddFeature as Yn}from"./8c27edda0f.js";import{usePlacementInteraction as $n}from"./4b8958aa4c.js";import{refreshCanonicalState as Kn,seedInitialState as Qn,addProduct as qt}from"./a77b15c0d6.js";import{resolveLayout as Jn,hasLayout as to,useLayoutRegistry as eo,layoutOverride as no,_publishResolvedLayoutKey as oo}from"./31ea036f5c.js";import{themeLayoutKey as so,useSystemTheme as ro}from"./5c9fd9201c.js";import"./1a2629800a.css";import{runIntent as Nt,INTENTS as Xt}from"./6d238282c1.js";function ao(){const T=gt(c=>c.sceneSelections),S=gt(c=>c.selectionOrder),g=_(c=>c.activeSceneConfigId),h=R(c=>c.defaultPresetId),f=R(c=>c.sceneConfigurations),D=R(c=>c.getSceneFeatures),b=We(Qe,Et,Et);return H(()=>{const c=g||h||Object.keys(f||{})[0],tt=c?D(c):[],V=W.getState(),v=[],et=new Set,ut=(l,L)=>{if(!l||l.id==null||et.has(String(l.id))||L>4)return;et.add(String(l.id)),v.push(l);const w=(V.features?.[l.id]||V.features?.[String(l.id)])?.childOptionSetIds||[];for(const M of w){const d=V.features?.[M]||V.features?.[String(M)];d&&ut({id:M,type:d.type,sequence:d.sequence},L+1)}};for(const l of tt)ut(l,0);const It=v.filter(l=>/finish/i.test(l.type||"")&&T[l.id]!=null).sort((l,L)=>{const X=S?.[String(l.id)]??-1,w=S?.[String(L.id)]??-1;return X!==w?X-w:(l.sequence??0)-(L.sequence??0)}),P={};for(const l of It){const L=T[l.id],X=V.options?.[L]?.value;if(X==null)continue;const w=V.features?.[l.id]||{},M=Pn(w.materialTargets??w.material_targets??w.materials);for(const d of M)P[String(d).toLowerCase()]=X}return P},[T,S,g,h,f,D,b])}function co(T,S){if(S==null)return null;const g=String(S);for(const h of Object.values(T.products||{})){const f=h?.components_configuration||h?.componentsConfiguration;if(!(!f||typeof f!="object"))for(const D of Object.values(f))for(const b of Array.isArray(D)?D:[D]){const c=b&&typeof b=="object"?b.componentId??b.component_id:b;if(c!=null&&String(c)===g)return h}}return null}function io(T){const S=gt(v=>v.sceneSelections),g=gt(v=>v.setSceneSelection),h=R(v=>v.getSceneFeatures),f=R(v=>v.sceneConfigurations),D=We(Qe,Et,Et),b=H(()=>new Set((T?h(T)||[]:[]).filter(v=>Yn(v)).map(v=>String(v.id))),[T,h,f,D]),c=Mt({}),tt=Mt(!1),V=gt(v=>v.sceneSelectionsSettled);N(()=>{if(!V){c.current={...S};return}if(!tt.current){tt.current=!0;let P=!1;for(const[l,L]of Object.entries(S||{}))L==null||!b.has(String(l))||(g(l,null),P=!0);if(P){c.current={...S};return}}const v=c.current,et=[];for(const[P,l]of Object.entries(S||{}))v[P]===l||l==null||b.has(String(P))&&et.push([P,l]);if(c.current={...S},!et.length)return;const ut=R.getState().systemId;let It=!1;return(async()=>{const P=W.getState(),l=_.getState();for(const[L,X]of et){const w=P.options?.[X];let M=w?.valueProductVariantId??w?.value_product_variant_id??w?.value_product_variant??w?.variantId??w?.variant_id??null,d=M!=null?P.getProduct?.(M):null;if(d==null){const I=w?.value??(P.optionToProducts?.[String(X)]||[])[0]??w?.product_id??w?.productId??null;d=I!=null?P.getProduct?.(I):null,d==null&&I!=null&&P.getComponent?.(I)&&(d=co(P,I)),M=d?.id??M??I}else M=d?.id??M;if(M==null){g(L,null);continue}const wt=d?.id??M,Ct=d?.placementGroup??d?.placement_group??null,Zt=d?.productGraph??d?.product_graph??null,St=d?.compatibleSlots??d?.compatible_slots??null;if(Array.isArray(St)&&St.length){const I=new Set(St.map(String));if(Object.values(l.productInstances||{}).some(ft=>{const de=P.getProduct?.(ft.variantId)||P.getProduct?.(ft.productId);return $e(d,de,P.products)})){y.getState().setPendingSlotPlacement?.({productId:wt,variantId:M,name:d?.name??d?.displayName??d?.variantName??"product",compatibleGraphIds:Array.from(I)}),g(L,null);continue}}if(Vn(ut,d)==="arm"){jn({productId:wt,variantId:M});const I=Je(),_t=typeof I?.computeTargets=="function",ft=Object.prototype.hasOwnProperty.call(I??{},"armHint")?I.armHint:Wn(_t?"placement.armedPickTarget":"placement.armedPickGap",_t?"":"Click a + between pieces to insert it.");ft&&y.getState().showInfo?.(ft),g(L,null);continue}const bt=_.getState(),pt=bt.selectedInstanceId,j=pt!=null?(bt.productInstances||{})[pt]:null,nt=j&&Number.isFinite(Number(j.sequence))?Number(j.sequence):void 0,ht=Un({placementGroup:Ct}),z=ht!=null?(bt.productInstances||{})[ht]:null,Ht=z&&Number.isFinite(Number(z.sequence))?Number(z.sequence):nt,ct=Array.isArray(z?.position)?z.position:[0,0,0];let Vt=null;try{Vt=await Nt({type:Xt.PRODUCT_ADD,productGraphId:Zt,variantId:M,placementGroup:Ct,sequence:Ht,replacePlacementId:ht??void 0},I=>qt({productGraphId:I.productGraphId,variantId:I.variantId,placementGroup:I.placementGroup,position:ct,sequence:I.sequence,replace:I.replacePlacementId!=null,replacePlacementId:I.replacePlacementId}))}catch{}if(g(L,null),It)return}})(),()=>{It=!0}},[S,b,T,g])}function lo({position:T,onClick:S}){const[g,h]=xt(!1);return m(yn,{position:T,center:!0,style:{pointerEvents:"auto"},zIndexRange:[100,0],children:m("div",{onClick:S,onPointerEnter:()=>h(!0),onPointerLeave:()=>h(!1),style:{width:22,height:22,borderRadius:"50%",background:g?"#ff8a65":"rgba(255, 87, 34, 0.85)",display:"flex",alignItems:"center",justifyContent:"center",color:"var(--bg-primary, #fff)",fontSize:13,fontWeight:"bold",boxShadow:"0 1px 4px rgba(0,0,0,0.3)",cursor:"pointer",transition:"transform 0.2s",transform:g?"scale(1.15)":"scale(1)"},children:"+"})})}function uo({isMobile:T}={}){Ke();const S=ie("SelectionActionPanel",Cn),g=_(t=>t.productInstances),h=W(t=>t.getProduct),f=W(t=>t.componentGroups),D=_(t=>t.clearSelection),b=_(t=>t.selectedInstanceId),c=_(t=>t.isFocusing),tt=y(t=>t.bootLoading),V=y(t=>t.bootDetail),v=y(t=>t.bootProgress);Ke();const et=ie("LoadingScreen",Rn),ut=En();N(()=>{if(typeof document>"u")return;const t=document.documentElement;return tt?t.setAttribute("data-scene-booting",""):t.removeAttribute("data-scene-booting"),()=>t.removeAttribute("data-scene-booting")},[tt]),N(()=>{y.getState().markUiReady?.()},[]);const It=_(t=>t.removeProductInstance),P=_(t=>t.addProductInstance),l=_(t=>t.updateInstancePosition),L=_(t=>t.updateInstanceRotation),X=_(t=>t.activeSceneConfigId),w=R(t=>t.defaultPresetId),M=R(t=>t.sceneConfigurations),d=R(t=>t.systemId),wt=R(t=>t.useTransform),Ct=y(t=>t.sceneCapabilities),Zt=y(t=>t.showWalls),St=y(t=>t.showDimensions),bt=y(t=>t.pendingSlotPlacement),pt=ao(),j=y(t=>t.hostMaterialOverrides),nt=(Hn()||{}).room||null,ht=X||w||Object.keys(M||{})[0]||null;io(ht);const[z,Ht]=xt(!0),[ct,Vt]=xt(!1),I=J(async()=>{try{await Qn()}catch{}Vt(!0)},[]),{edgeOf:_t,cornerOf:ft,isHostAnchored:de,isMovable:ue,rawFree:ho,splitReliable:fo,freeInstances:Tt,ordered:C,syntheticHosts:pe,moveInFlightRef:mo}=Mn(),Ft=H(()=>new Map(pe.map(t=>[t.hostedProductId,t])),[pe]),[ot,nn]=xt({}),jt=J((t,e,n=null)=>{const o=(r,a)=>{const i=r[a],u=e.full||null;return i&&i.width===e.width&&i.depth===e.depth&&i.height===e.height&&i.cx===e.cx&&i.cz===e.cz&&(i.full?.width??null)===(u?.width??null)&&(i.full?.height??null)===(u?.height??null)&&(i.full?.depth??null)===(u?.depth??null)?r:{...r,[a]:{width:e.width,depth:e.depth,height:e.height,cx:e.cx,cz:e.cz,full:u,forProductId:t,...e.__slots?{slots:e.__slots}:{}}}};nn(r=>{const a=o(r,t);return n!=null?o(a,`inst:${n}`):a})},[]),st=J((t,e)=>{const n=e?.id!=null?ot[`inst:${e.id}`]:null;return n&&String(n.forProductId)===String(t)?n:ot[t]||null},[ot]),he=W(t=>t.placementBoundsExcludeIds),fe=H(()=>new Set((he||[]).map(t=>String(t))),[he]),Ut=J((t,e)=>{const n=t?.componentId??e?.id??e?.componentId??null;if(n!=null&&fe.has(String(n)))return!0},[f,fe]),Y=Mt(!1),Gt=Mt(!1),k=C.length+Tt.length,Bt=H(()=>[...C,...Tt],[C,Tt]),it=k>0&&Bt.every(t=>ot[t.productId]),Ot=H(()=>Bt.filter(t=>ot[t.productId]).length,[Bt,ot]),{active:Wt,loaded:me,total:Yt}=vn(),ge=y(t=>t.isEvaluating),At=y(t=>t.isLayoutLoading),Ie=y(t=>t.bootEvaluating),Se=Mt({pieceCount:0,allMeasured:!1});Se.current={pieceCount:k,allMeasured:it};const Dt=J(()=>{const{pieceCount:t,allMeasured:e}=Se.current;t>0&&!Y.current&&!Gt.current&&(_.getState().resetCameraToDefault?.({instant:!0}),Y.current=e,Gt.current=!e)},[]);N(()=>y.subscribe((t,e)=>{e?.bootLoading&&!t.bootLoading&&Dt()}),[Dt]),N(()=>{if(!ct)return;const t=!Wt&&(Yt===0||me>=Yt),e=(it||k===0)&&t&&!ge&&!Ie,n=()=>{Dt(),Ht(!1),y.getState().endBootLoading()};if(e){let r=null;const a=setTimeout(()=>{k>0&&!Y.current&&(_.getState().resetCameraToDefault?.({instant:!0}),Y.current=!0),r=setTimeout(n,120)},780);return()=>{clearTimeout(a),r&&clearTimeout(r)}}const o=setTimeout(n,Wt?12e4:15e3);return()=>clearTimeout(o)},[ct,it,k,Ot,Wt,me,Yt,ge,Ie,Dt]);const[be,ye]=xt(!1);N(()=>{if(!z){ye(!1);return}(it&&k>0||ct&&k===0)&&ye(!0)},[it,k,ct,z]);const ve=ct?be||k===0?"Finishing up\u2026":`Loading products\u2026 ${Math.min(Ot,k)}/${k}`:"Preparing your configurator\u2026",Pe=be?100:k>0?Math.min(Math.round(Ot/k*100),92):0;N(()=>{z&&y.getState().setBootPhase(ve,Pe)},[z,ve,Pe]),N(()=>(y.setState({initialSceneLoading:z}),()=>y.setState({initialSceneLoading:!1})),[z]),N(()=>{At&&(Y.current=!1)},[At]),N(()=>{if(k===0){Y.current=!1;return}if(Y.current||z||At||!it)return;const t=setTimeout(()=>{Y.current||(_.getState().resetCameraToDefault?.({instant:!Gt.current}),Gt.current=!1,Y.current=!0)},250);return()=>clearTimeout(t)},[k,Ot,z,At,it]);const yt=Je(),mt=H(()=>C.map(t=>{const e=Ft.get(t.id);return e?{...t,productId:e.hostVariantId}:t}),[C,Ft]),Me=wt||!!M?.[ht]?.useTransform,Z=_(t=>t.pendingPlacementPiece),xe=!!Z&&typeof yt?.computeTargets=="function"&&!!kn(),lt=H(()=>{const t={getProduct:h,getDims:st,useTransform:Me,candidate:Z,openSlots:xe,config:tn()},e=yt.computeLayout?yt.computeLayout(mt,t):mt.map(()=>({position:[0,0,0],rotation:[0,0,0]})),n=Bn(e,mt,t,yt);try{import.meta.env?.DEV&&typeof window<"u"&&(window.__layoutDebug={at:Date.now(),dims:ot,items:mt.map(o=>({id:o.id,variantId:o.variantId,productId:o.productId,placementGroup:o.placementGroup,sequence:o.sequence,positionedAbove:o.positionedAbove??null,hostVariantId:o.hostVariantId??null,position:o.position,rotation:o.rotation,corner:!!o.corner})),layout:n})}catch{}return n},[yt,mt,h,st,Me,Z,xe,ot]),U=H(()=>{const e=nt?.height>0?nt.height:2.7,n=.1,o=.05,r=new Map;let a=1/0,i=-1/0,u=1/0,p=-1/0,E=0,A=!1;if(C.forEach((s,B)=>{const F=lt[B];if(!F||ue(s))return;const x=F.position||[0,0,0],G=st(s.productId,s),Q=h(s.productId),q=G?.full||G,oe=q?.height>0?q.height:Q?.height>0?Q.height*.0254:0,zt=(x[1]||0)+oe;if(zt>E&&(E=zt),(s.positionedAbove??s.positioned_above)!=null)return;const se=(x[1]||0)<=.01,Rt=-((Array.isArray(F.rotation)?F.rotation[1]:0)||0),re=G?.depth>0?G.depth:Q?.depth>0?Q.depth*.0254:.6,ae=G?.width>0?G.width:Q?.width>0?Q.width*.0254:.9,rt=Math.cos(Rt),at=Math.sin(Rt),Oe=G?.cx||0,Ae=G?.cz||0,De=x[0]+rt*Oe-at*Ae,Le=x[2]+at*Oe+rt*Ae,ke=(ae*Math.abs(rt)+re*Math.abs(at))/2,ze=(ae*Math.abs(at)+re*Math.abs(rt))/2,Re=De-ke,Ee=De+ke,qe=Le-ze,Ne=Le+ze,Xe=q?.width>0?q.width:ae,Ze=q?.depth>0?q.depth:re,He=x[0]+rt*(q?.cx||0)-at*(q?.cz||0),Ve=x[2]+at*(q?.cx||0)+rt*(q?.cz||0),je=(Xe*Math.abs(rt)+Ze*Math.abs(at))/2,Ue=(Xe*Math.abs(at)+Ze*Math.abs(rt))/2,gn=He-je,In=He+je,Sn=Ve-Ue,bn=Ve+Ue,Be=String((Math.round(Rt/(Math.PI/2))%4+4)%4),O=r.get(Be)||{heading:Rt,minX:1/0,maxX:-1/0,minZ:1/0,maxZ:-1/0,fMinX:1/0,fMaxX:-1/0,fMinZ:1/0,fMaxZ:-1/0,hasFloor:!1};O.minX=Math.min(O.minX,Re),O.maxX=Math.max(O.maxX,Ee),O.minZ=Math.min(O.minZ,qe),O.maxZ=Math.max(O.maxZ,Ne),se&&(O.fMinX=Math.min(O.fMinX,Re),O.fMaxX=Math.max(O.fMaxX,Ee),O.fMinZ=Math.min(O.fMinZ,qe),O.fMaxZ=Math.max(O.fMaxZ,Ne),O.hasFloor=!0),r.set(Be,O),a=Math.min(a,gn),i=Math.max(i,In),u=Math.min(u,Sn),p=Math.max(p,bn),A=!0}),!A)return null;const K=Math.max(e,E>0?E+.02:e),Pt=[...r.values()].map(s=>{const B=Math.sin(s.heading),F=Math.cos(s.heading),x=B,G=-F,Q=Math.abs(x)>Math.abs(G),q=s.hasFloor?s.fMinX:s.minX,oe=s.hasFloor?s.fMaxX:s.maxX,zt=s.hasFloor?s.fMinZ:s.minZ,se=s.hasFloor?s.fMaxZ:s.maxZ,Ge=Q?(x>0?oe:q)+(x>0?n/2:-n/2):(G>0?se:zt)+(G>0?n/2:-n/2);return{g:s,isSide:Q,plane:Ge}}),Lt=Pt.some(s=>s.g.hasFloor)?Pt.filter(s=>s.g.hasFloor):Pt,pn=Lt.filter(s=>s.isSide).map(s=>s.plane),hn=Lt.filter(s=>!s.isSide).map(s=>s.plane),Qt=[];for(const s of Lt){const{g:B}=s;if(s.isSide){let F=B.minZ,x=B.maxZ;for(const G of hn)F=Math.min(F,G),x=Math.max(x,G);Qt.push({cx:s.plane,cz:(F+x)/2,cy:K/2,length:x-F+o*2,thickness:n,height:K,rotY:Math.PI/2})}else{let F=B.minX,x=B.maxX;for(const G of pn)F=Math.min(F,G),x=Math.max(x,G);Qt.push({cx:(F+x)/2,cz:s.plane,cy:K/2,length:x-F+o*2,thickness:n,height:K,rotY:0})}}const kt=.4,Fe=i>a&&p>u;let Jt=a-kt,te=i+kt,ee=u-kt,ne=p+kt;for(const s of Lt){const B=Math.sin(s.g.heading),F=-Math.cos(s.g.heading);s.isSide?B<0?Jt=s.plane-n/2:te=s.plane+n/2:F<0?ee=s.plane-n/2:ne=s.plane+n/2}const fn=Fe?{cx:(Jt+te)/2,cz:(ee+ne)/2,w:te-Jt,d:ne-ee}:null,mn=Fe?{minX:a,maxX:i,minZ:u,maxZ:p,w:i-a,d:p-u,h:K,height:E>0?E:K}:null;return{segments:Qt,floor:fn,bbox:mn}},[C,lt,nt,st,h,ue]),on=Zt&&!!(U&&U.segments&&U.segments.length),sn=St&&!!(U&&U.bbox&&U.bbox.w>0),rn=(t,e)=>{const n=lt[e]||{position:[0,0,0],rotation:[0,0,0]},o=Ft.get(t.id);if(!o)return n;const r=n.position||[0,0,0],a=(Array.isArray(n.rotation)?n.rotation[1]:0)||0,i=Math.cos(a),u=Math.sin(a),p=o.offset||[0,0,0];return{position:[r[0]+(p[0]||0)*i+(p[2]||0)*u,r[1]+(p[1]||0),r[2]-(p[0]||0)*u+(p[2]||0)*i],rotation:[0,a+(o.rotDegY||0)*Math.PI/180,0]}},$=bt,vt=!!$,we=H(()=>{if(!$)return new Set;const t=h($.variantId)||h($.productId)||null,e=W.getState().products,n=new Set;for(const o of Object.values(g||{})){const r=h(o.variantId)||h(o.productId);(t?$e(t,r,e):(()=>{const i=new Set(($.compatibleGraphIds||[]).map(String)),u=r?.product_graph??r?.productGraph;return u!=null&&i.has(String(u))})())&&n.add(String(o.id))}return n},[$,g,h]),$t=J(()=>{y.getState().clearPendingSlotPlacement?.(),y.getState().clearPendingHostedProduct?.()},[]),Ce=J((t,e)=>{if(!e)return;const n=W.getState(),o=n.getProduct?.(e.variantId)||n.getProduct?.(e.productId),r=o?.productGraph??o?.product_graph??null,a=_.getState().productInstances?.[String(t)],i=o?.placementGroup??o?.placement_group??a?.placementGroup??null,u=Array.isArray(a?.position)?a.position:[0,0,0],p=a?.variantId??a?.productId??null,E=Number.isFinite(Number(a?.sequence))?Number(a.sequence):void 0;$t(),Nt({type:Xt.PRODUCT_ADD,productGraphId:r,variantId:e.variantId??e.productId,placementGroup:i,sequence:E,hostPlacementId:String(t),hostVariantId:p},A=>qt({productGraphId:A.productGraphId,variantId:A.variantId,placementGroup:A.placementGroup,position:u,sequence:A.sequence,hostPlacementId:A.hostPlacementId,hostVariantId:A.hostVariantId}).catch(()=>{}))},[$t]),Kt=J((t,e)=>{const n=W.getState(),o=n.getProduct?.(e.variantId)||n.getProduct?.(e.productId),r=o?.productGraph??o?.product_graph??null,a=o?.placementGroup??o?.placement_group??null,i=C[t-1]||C[t],u=Array.isArray(i?.position)?i.position:[0,0,0],p=C[t],E=p&&Number.isFinite(Number(p.sequence))?Number(p.sequence):void 0;Nt({type:Xt.PRODUCT_ADD,productGraphId:r,variantId:e.variantId??e.productId,placementGroup:a,sequence:E},A=>qt({productGraphId:A.productGraphId,variantId:A.variantId,placementGroup:A.placementGroup,position:u,sequence:A.sequence}).catch(()=>{}))},[C]);N(()=>{if(!Z||C.length>0)return;const t=Z;Ye(),Kt(0,t)},[Z,C.length,Kt]);const{gaps:an,onInsert:cn}=$n({systemId:d,count:C.length,positionOf:t=>lt[t]?.position||[0,0,0],insertAt:Kt}),_e=H(()=>{if(!Z)return[];const t=W.getState();return Dn(C,{candidate:Z,getProduct:e=>t.getProduct?.(e),getDims:st,config:tn(),layout:lt})},[Z,C,lt,st]),ln=J(t=>{const e=Ln(t,{candidate:Z});if(!e)return;const n=W.getState(),o=n.getProduct?.(e.variantId)||n.getProduct?.(e.productId),r=o?.productGraph??o?.product_graph??null,a=o?.placementGroup??o?.placement_group??null,i=e.transform?.position??t.position??[0,0,0],u=zn(e,t,C);Nt({type:Xt.PRODUCT_ADD,productGraphId:r,variantId:e.variantId??e.productId,placementGroup:a,anchor:e.anchor??null,sequence:u},p=>qt({productGraphId:p.productGraphId,variantId:p.variantId,placementGroup:p.placementGroup,position:i,sequence:p.sequence}).catch(()=>{})),Ye()},[Z,C]),{selectedInst:go,swapOrder:Io,panelActions:Te,priceInfo:dn}=xn(),un=wn()("selectionPanel");N(()=>{if(b==null)return;const t=g||{},e=String(b),n="__host";if(e.endsWith(n)){const o=e.slice(0,-n.length);if(t[o]||Object.values(t).some(r=>String(r?.id??r?.instanceId)===o))return}else if(t[b]||Object.values(t).some(o=>String(o?.instanceId??o?.id)===e))return;D?.()},[b,g,D]);const bo=gt(t=>t.placementPricing),yo=R(t=>t.getChannelPriceConfig);return dt(le,{children:[m(On,{onSeeded:I}),dt(Fn,{isMobile:T,camera:{position:[2.6,2.2,4],fov:45},controlsTarget:[0,.5,0],onPointerMissed:()=>D?.(),groundShadowCatcher:!0,overlay:dt(le,{children:[!vt&&Te&&un?m(S,{actions:Te,priceInfo:dn}):null,vt&&m("div",{className:"placement-mode-overlay",children:dt("div",{className:"placement-mode-overlay__content",children:[dt("span",{className:"placement-mode-overlay__text",children:["Click on a highlighted slot to place ",m("strong",{children:$?.name})]}),m("button",{type:"button",className:"placement-mode-overlay__cancel",onClick:$t,children:m("span",{className:"placement-mode-overlay__cancel-text",children:"Cancel"})})]})}),m(qn,{name:"overlay"}),tt&&m(et,{scene:!0,message:ut("loading.message","Loading your configurator\u2026"),detail:V,progress:v}),c&&m("div",{"aria-hidden":"true",style:{position:"absolute",inset:0,zIndex:30,cursor:"default"}})]}),children:[on&&m(Gn,{width:nt?.width,depth:nt?.depth,height:nt?.height??U?.bbox?.h??2.7,showCeiling:Ct?.ceiling===!0,segments:U?.segments||null,floor:U?.floor||null}),sn&&(()=>{const t=ie("SceneDimensions",Zn);return m(t,{bbox:U.bbox})})(),C.map((t,e)=>{const n=Ft.get(t.id),o=lt[e]||{position:[0,0,0],rotation:[0,0,0]};return o.hidden?null:dt("group",{children:[n&&m(ce,{instance:{id:n.id,instanceId:n.id,productId:n.hostVariantId,variantId:n.hostVariantId,position:o.position||[0,0,0],rotation:o.rotation||[0,0,0]},slotMaterials:{...pt,...j?.[n.hostedProductId]||{},...j?.[n.id]||{}},stateInstanceId:n.hostedProductId,onSelect:()=>_.getState().selectInstance(n.id),isSelected:String(b)===String(n.id),onMeasure:r=>jt(n.hostVariantId,r),footprintExcludeItem:Ut,hoverable:!0,focusable:!0},n.id),m(ce,{instance:{...t,...rn(t,e)},slotMaterials:{...pt,...j?.[t.id]||j?.[t.instanceId]||{}},onSelect:(r,a,i)=>{if(vt){we.has(String(t.id))&&Ce(t.id,$);return}_.getState().selectInstance(r,i??null)},isSelected:!vt&&String(b)===String(t.instanceId??t.id),onMeasure:r=>jt(t.productId,r,t.id),footprintExcludeItem:Ut,hoverable:!0,focusable:!0}),vt&&we.has(String(t.id))&&(()=>{const r=o.position||[0,0,0],a=st(mt[e]?.productId??t.productId,t),i=(Array.isArray(o.rotation)?o.rotation[1]:0)||0,u=Math.cos(i),p=Math.sin(i),E=a?.cx||0,A=a?.cz||0,K=a?.full?.height??a?.height,Pt=[r[0]+E*u+A*p,r[1]+(K>0?K/2:.45),r[2]-E*p+A*u];return m(lo,{position:Pt,onClick:()=>Ce(t.id,$)})})()]},t.id??t.instanceId??e)}),Tt.map((t,e)=>m(_n,{selected:b===t.id,disabled:!!t.locked,position:t.position||[0,0,0],rotationY:(Array.isArray(t.rotation)&&t.rotation[1]||0)*Math.PI/180,gizmoOffset:(()=>{const n=st(t.productId,t);return[n?.cx||0,0,n?.cz||0]})(),onCommit:({position:n,rotationY:o})=>{l(t.id,n),L(t.id,[0,o*180/Math.PI,0]),Kn({allowRevert:!0}).catch(()=>{})},children:m(ce,{instance:{...t,position:[0,0,0],rotation:[0,0,0]},slotMaterials:{...pt,...j?.[t.id]||j?.[t.instanceId]||{}},onMeasure:n=>jt(t.productId,n,t.id),footprintExcludeItem:Ut})},t.id??t.instanceId??`free-${e}`)),_e.length>0?m(An,{targets:_e,onPick:ln}):m(Tn,{gaps:an,onInsert:cn})]})]})}const en=new Set;function po(){eo();const T=R(c=>c.systemLayoutTemplate),S=R(c=>c.systemTheme),g=R(c=>c.systemThemeRecord);ro(S,g);const h=so(g)||(S?String(S).trim().toLowerCase():null);let f=T;try{const c=new URLSearchParams(window.location.search);c.has("template")?f=c.get("template"):c.has("theme")&&(f=c.get("theme"))}catch{}f=f||T||h||null;const D=no();D&&(f=D),!D&&!T&&f&&f===h&&!to(f)&&!/^theme\d+$/.test(f)&&!en.has(f)&&en.add(f),oo(f);const b=Jn(f);return dt(le,{children:[m(b,{Scene:uo,template:f}),m(Nn,{}),m(Xn,{})]})}export{uo as SharedConfiguratorScene,po as default};
1
+ import{Fragment as de,jsx as h,jsxs as lt}from"react/jsx-runtime";import{useCallback as J,useEffect as N,useMemo as H,useRef as Pt,useState as xt,useSyncExternalStore as We}from"react";import{Html as yn,useProgress as vn}from"@react-three/drei";import T from"./9c6c598569.js";import W from"./872c4302e0.js";import z from"./be337ddda5.js";import gt from"./d94df858ea.js";import{normalizeMaterialTargets as Mn}from"./dc2a1a0e13.js";import y from"./8f60e5059a.js";import Pn from"./60d697292c.js";import xn from"./811b403d43.js";import{useUiToggles as wn}from"./d0f9681634.js";import{ProductInstance as ce,SelectionActionPanel as Cn,FreeMovable as Tn,PlacementGaps as _n,SceneStage as Fn,SceneRoom as Gn,SceneProductsSource as On}from"./8a3a57c008.js";import An from"./205827c5c8.js";import{computeTargets as Dn,resolveTarget as Ln,resolveTargetRenderer as kn,resolveInsertSequence as Rn}from"./58e6419ba8.js";import{disarmPlacement as Ye}from"./ab6c80484f.js";import{applyMeasurement as zn}from"./9ce3c3df25.js";import{isCompatibleSlot as $e}from"./99577e3161.js";import{resolveComponent as ie,useComponentRegistry as Ke}from"./882bc739c8.js";import En from"./88251d6671.js";import{useLabels as qn}from"./28d887bf8a.js";import{SlotHost as Nn}from"./73f7d65985.js";import{ModalHost as Xn}from"./09c4973968.js";import Zn from"./6c0a2572dd.js";import Hn from"./20b0104576.js";import{getConfigState as Vn,subscribe as Qe,getVersion as Et}from"./817d930a49.js";import{getPlacementStrategy as Je}from"./281cf952fa.js";import{resolveAddMode as jn,armPlacement as Un}from"./ab6c80484f.js";import{resolveReplaceTarget as Bn}from"./4d7a0d1897.js";import{enforceCorners as Wn}from"./388cadacbd.js";import{resolvePlacementStrategyConfig as tn}from"./281cf952fa.js";import{getLabel as Yn}from"./28d887bf8a.js";import{isAddFeature as $n}from"./8c27edda0f.js";import{usePlacementInteraction as Kn}from"./4b8958aa4c.js";import{refreshCanonicalState as Qn,seedInitialState as Jn,addProduct as qt}from"./a77b15c0d6.js";import{resolveLayout as to,hasLayout as eo,useLayoutRegistry as no,layoutOverride as oo,_publishResolvedLayoutKey as so}from"./31ea036f5c.js";import{themeLayoutKey as ro,useSystemTheme as ao}from"./5c9fd9201c.js";import"./1a2629800a.css";import{runIntent as Nt,INTENTS as Xt}from"./6d238282c1.js";function co(){const _=gt(a=>a.sceneSelections),I=gt(a=>a.selectionOrder),f=T(a=>a.activeSceneConfigId),u=z(a=>a.defaultPresetId),p=z(a=>a.sceneConfigurations),D=z(a=>a.getSceneFeatures),S=We(Qe,Et,Et);return H(()=>{const a=f||u||Object.keys(p||{})[0],tt=a?D(a):[],V=W.getState(),v=[],et=new Set,ut=(i,L)=>{if(!i||i.id==null||et.has(String(i.id))||L>4)return;et.add(String(i.id)),v.push(i);const w=(V.features?.[i.id]||V.features?.[String(i.id)])?.childOptionSetIds||[];for(const P of w){const d=V.features?.[P]||V.features?.[String(P)];d&&ut({id:P,type:d.type,sequence:d.sequence},L+1)}};for(const i of tt)ut(i,0);const It=v.filter(i=>/finish/i.test(i.type||"")&&_[i.id]!=null).sort((i,L)=>{const X=I?.[String(i.id)]??-1,w=I?.[String(L.id)]??-1;return X!==w?X-w:(i.sequence??0)-(L.sequence??0)}),M={};for(const i of It){const L=_[i.id],X=V.options?.[L]?.value;if(X==null)continue;const w=V.features?.[i.id]||{},P=Mn(w.materialTargets??w.material_targets??w.materials);for(const d of P)M[String(d).toLowerCase()]=X}return M},[_,I,f,u,p,D,S])}function io(_,I){if(I==null)return null;const f=String(I);for(const u of Object.values(_.products||{})){const p=u?.components_configuration||u?.componentsConfiguration;if(!(!p||typeof p!="object"))for(const D of Object.values(p))for(const S of Array.isArray(D)?D:[D]){const a=S&&typeof S=="object"?S.componentId??S.component_id:S;if(a!=null&&String(a)===f)return u}}return null}function lo(_){const I=gt(v=>v.sceneSelections),f=gt(v=>v.setSceneSelection),u=z(v=>v.getSceneFeatures),p=z(v=>v.sceneConfigurations),D=We(Qe,Et,Et),S=H(()=>new Set((_?u(_)||[]:[]).filter(v=>$n(v)).map(v=>String(v.id))),[_,u,p,D]),a=Pt({}),tt=Pt(!1),V=gt(v=>v.sceneSelectionsSettled);N(()=>{if(!V){a.current={...I};return}if(!tt.current){tt.current=!0;let M=!1;for(const[i,L]of Object.entries(I||{}))L==null||!S.has(String(i))||(f(i,null),M=!0);if(M){a.current={...I};return}}const v=a.current,et=[];for(const[M,i]of Object.entries(I||{}))v[M]===i||i==null||S.has(String(M))&&et.push([M,i]);if(a.current={...I},!et.length)return;const ut=z.getState().systemId;let It=!1;return(async()=>{const M=W.getState(),i=T.getState();for(const[L,X]of et){const w=M.options?.[X];let P=w?.valueProductVariantId??w?.value_product_variant_id??w?.value_product_variant??w?.variantId??w?.variant_id??null,d=P!=null?M.getProduct?.(P):null;if(d==null){const g=w?.value??(M.optionToProducts?.[String(X)]||[])[0]??w?.product_id??w?.productId??null;d=g!=null?M.getProduct?.(g):null,d==null&&g!=null&&M.getComponent?.(g)&&(d=io(M,g)),P=d?.id??P??g}else P=d?.id??P;if(P==null){f(L,null);continue}const wt=d?.id??P,Ct=d?.placementGroup??d?.placement_group??null,Zt=d?.productGraph??d?.product_graph??null,St=d?.compatibleSlots??d?.compatible_slots??null;if(Array.isArray(St)&&St.length){const g=new Set(St.map(String));if(Object.values(i.productInstances||{}).some(ht=>{const le=M.getProduct?.(ht.variantId)||M.getProduct?.(ht.productId);return $e(d,le,M.products)})){y.getState().setPendingSlotPlacement?.({productId:wt,variantId:P,name:d?.name??d?.displayName??d?.variantName??"product",compatibleGraphIds:Array.from(g)}),f(L,null);continue}}if(jn(ut,d)==="arm"){Un({productId:wt,variantId:P});const g=Je(),Tt=typeof g?.computeTargets=="function",ht=Object.prototype.hasOwnProperty.call(g??{},"armHint")?g.armHint:Yn(Tt?"placement.armedPickTarget":"placement.armedPickGap",Tt?"":"Click a + between pieces to insert it.");ht&&y.getState().showInfo?.(ht),f(L,null);continue}const bt=T.getState(),pt=bt.selectedInstanceId,j=pt!=null?(bt.productInstances||{})[pt]:null,nt=j&&Number.isFinite(Number(j.sequence))?Number(j.sequence):void 0,mt=Bn({placementGroup:Ct}),R=mt!=null?(bt.productInstances||{})[mt]:null,Ht=R&&Number.isFinite(Number(R.sequence))?Number(R.sequence):nt,ct=Array.isArray(R?.position)?R.position:[0,0,0];let Vt=null;try{Vt=await Nt({type:Xt.PRODUCT_ADD,productGraphId:Zt,variantId:P,placementGroup:Ct,sequence:Ht,replacePlacementId:mt??void 0},g=>qt({productGraphId:g.productGraphId,variantId:g.variantId,placementGroup:g.placementGroup,position:ct,sequence:g.sequence,replace:g.replacePlacementId!=null,replacePlacementId:g.replacePlacementId}))}catch{}if(f(L,null),It)return}})(),()=>{It=!0}},[I,S,_,f])}function uo({position:_,onClick:I}){const[f,u]=xt(!1);return h(yn,{position:_,center:!0,style:{pointerEvents:"auto"},zIndexRange:[100,0],children:h("div",{onClick:I,onPointerEnter:()=>u(!0),onPointerLeave:()=>u(!1),style:{width:22,height:22,borderRadius:"50%",background:f?"#ff8a65":"rgba(255, 87, 34, 0.85)",display:"flex",alignItems:"center",justifyContent:"center",color:"var(--bg-primary, #fff)",fontSize:13,fontWeight:"bold",boxShadow:"0 1px 4px rgba(0,0,0,0.3)",cursor:"pointer",transition:"transform 0.2s",transform:f?"scale(1.15)":"scale(1)"},children:"+"})})}function po({isMobile:_}={}){Ke();const I=ie("SelectionActionPanel",Cn),f=T(t=>t.productInstances),u=W(t=>t.getProduct),p=W(t=>t.componentGroups),D=T(t=>t.clearSelection),S=T(t=>t.selectedInstanceId),a=T(t=>t.isFocusing),tt=y(t=>t.bootLoading),V=y(t=>t.bootDetail),v=y(t=>t.bootProgress);Ke();const et=ie("LoadingScreen",En),ut=qn();N(()=>{if(typeof document>"u")return;const t=document.documentElement;return tt?t.setAttribute("data-scene-booting",""):t.removeAttribute("data-scene-booting"),()=>t.removeAttribute("data-scene-booting")},[tt]),N(()=>{y.getState().markUiReady?.()},[]);const It=T(t=>t.removeProductInstance),M=T(t=>t.addProductInstance),i=T(t=>t.updateInstancePosition),L=T(t=>t.updateInstanceRotation),X=T(t=>t.activeSceneConfigId),w=z(t=>t.defaultPresetId),P=z(t=>t.sceneConfigurations),d=z(t=>t.systemId),wt=z(t=>t.useTransform),Ct=y(t=>t.sceneCapabilities),Zt=y(t=>t.showWalls),St=y(t=>t.showDimensions),bt=y(t=>t.pendingSlotPlacement),pt=co(),j=y(t=>t.hostMaterialOverrides),nt=(Vn()||{}).room||null,mt=X||w||Object.keys(P||{})[0]||null;lo(mt);const[R,Ht]=xt(!0),[ct,Vt]=xt(!1),g=J(async()=>{try{await Jn()}catch{}Vt(!0)},[]),{edgeOf:Tt,cornerOf:ht,isHostAnchored:le,isMovable:ue,rawFree:ho,splitReliable:fo,freeInstances:_t,ordered:C,syntheticHosts:pe,moveInFlightRef:go}=Pn(),Ft=H(()=>new Map(pe.map(t=>[t.hostedProductId,t])),[pe]),[ot,nn]=xt({}),jt=J((t,n,e=null,o=e)=>{nn(r=>zn(r,t,n,e,o))},[]),st=J((t,n)=>{const e=n?.id!=null?ot[`inst:${n.id}`]:null;return e&&String(e.forProductId)===String(t)?e:ot[t]||null},[ot]),me=W(t=>t.placementBoundsExcludeIds),he=H(()=>new Set((me||[]).map(t=>String(t))),[me]),Ut=J((t,n)=>{const e=t?.componentId??n?.id??n?.componentId??null;if(e!=null&&he.has(String(e)))return!0},[p,he]),Y=Pt(!1),Gt=Pt(!1),k=C.length+_t.length,Bt=H(()=>[...C,..._t],[C,_t]),it=k>0&&Bt.every(t=>ot[t.productId]),Ot=H(()=>Bt.filter(t=>ot[t.productId]).length,[Bt,ot]),{active:Wt,loaded:fe,total:Yt}=vn(),ge=y(t=>t.isEvaluating),At=y(t=>t.isLayoutLoading),Ie=y(t=>t.bootEvaluating),Se=Pt({pieceCount:0,allMeasured:!1});Se.current={pieceCount:k,allMeasured:it};const Dt=J(()=>{const{pieceCount:t,allMeasured:n}=Se.current;t>0&&!Y.current&&!Gt.current&&(T.getState().resetCameraToDefault?.({instant:!0}),Y.current=n,Gt.current=!n)},[]);N(()=>y.subscribe((t,n)=>{n?.bootLoading&&!t.bootLoading&&Dt()}),[Dt]),N(()=>{if(!ct)return;const t=!Wt&&(Yt===0||fe>=Yt),n=(it||k===0)&&t&&!ge&&!Ie,e=()=>{Dt(),Ht(!1),y.getState().endBootLoading()};if(n){let r=null;const c=setTimeout(()=>{k>0&&!Y.current&&(T.getState().resetCameraToDefault?.({instant:!0}),Y.current=!0),r=setTimeout(e,120)},780);return()=>{clearTimeout(c),r&&clearTimeout(r)}}const o=setTimeout(e,Wt?12e4:15e3);return()=>clearTimeout(o)},[ct,it,k,Ot,Wt,fe,Yt,ge,Ie,Dt]);const[be,ye]=xt(!1);N(()=>{if(!R){ye(!1);return}(it&&k>0||ct&&k===0)&&ye(!0)},[it,k,ct,R]);const ve=ct?be||k===0?"Finishing up\u2026":`Loading products\u2026 ${Math.min(Ot,k)}/${k}`:"Preparing your configurator\u2026",Me=be?100:k>0?Math.min(Math.round(Ot/k*100),92):0;N(()=>{R&&y.getState().setBootPhase(ve,Me)},[R,ve,Me]),N(()=>(y.setState({initialSceneLoading:R}),()=>y.setState({initialSceneLoading:!1})),[R]),N(()=>{At&&(Y.current=!1)},[At]),N(()=>{if(k===0){Y.current=!1;return}if(Y.current||R||At||!it)return;const t=setTimeout(()=>{Y.current||(T.getState().resetCameraToDefault?.({instant:!Gt.current}),Gt.current=!1,Y.current=!0)},250);return()=>clearTimeout(t)},[k,Ot,R,At,it]);const yt=Je(),ft=H(()=>C.map(t=>{const n=Ft.get(t.id);return n?{...t,productId:n.hostVariantId}:t}),[C,Ft]),Pe=wt||!!P?.[mt]?.useTransform,Z=T(t=>t.pendingPlacementPiece),xe=!!Z&&typeof yt?.computeTargets=="function"&&!!kn(),dt=H(()=>{const t={getProduct:u,getDims:st,useTransform:Pe,candidate:Z,openSlots:xe,config:tn()},n=yt.computeLayout?yt.computeLayout(ft,t):ft.map(()=>({position:[0,0,0],rotation:[0,0,0]})),e=Wn(n,ft,t,yt);try{import.meta.env?.DEV&&typeof window<"u"&&(window.__layoutDebug={at:Date.now(),dims:ot,items:ft.map(o=>({id:o.id,variantId:o.variantId,productId:o.productId,placementGroup:o.placementGroup,sequence:o.sequence,positionedAbove:o.positionedAbove??null,hostVariantId:o.hostVariantId??null,position:o.position,rotation:o.rotation,corner:!!o.corner})),layout:e})}catch{}return e},[yt,ft,u,st,Pe,Z,xe,ot]),U=H(()=>{const n=nt?.height>0?nt.height:2.7,e=.1,o=.05,r=new Map;let c=1/0,m=-1/0,b=1/0,l=-1/0,E=0,A=!1;if(C.forEach((s,B)=>{const F=dt[B];if(!F||ue(s))return;const x=F.position||[0,0,0],G=st(s.productId,s),Q=u(s.productId),q=G?.full||G,oe=q?.height>0?q.height:Q?.height>0?Q.height*.0254:0,Rt=(x[1]||0)+oe;if(Rt>E&&(E=Rt),(s.positionedAbove??s.positioned_above)!=null)return;const se=(x[1]||0)<=.01,zt=-((Array.isArray(F.rotation)?F.rotation[1]:0)||0),re=G?.depth>0?G.depth:Q?.depth>0?Q.depth*.0254:.6,ae=G?.width>0?G.width:Q?.width>0?Q.width*.0254:.9,rt=Math.cos(zt),at=Math.sin(zt),Oe=G?.cx||0,Ae=G?.cz||0,De=x[0]+rt*Oe-at*Ae,Le=x[2]+at*Oe+rt*Ae,ke=(ae*Math.abs(rt)+re*Math.abs(at))/2,Re=(ae*Math.abs(at)+re*Math.abs(rt))/2,ze=De-ke,Ee=De+ke,qe=Le-Re,Ne=Le+Re,Xe=q?.width>0?q.width:ae,Ze=q?.depth>0?q.depth:re,He=x[0]+rt*(q?.cx||0)-at*(q?.cz||0),Ve=x[2]+at*(q?.cx||0)+rt*(q?.cz||0),je=(Xe*Math.abs(rt)+Ze*Math.abs(at))/2,Ue=(Xe*Math.abs(at)+Ze*Math.abs(rt))/2,gn=He-je,In=He+je,Sn=Ve-Ue,bn=Ve+Ue,Be=String((Math.round(zt/(Math.PI/2))%4+4)%4),O=r.get(Be)||{heading:zt,minX:1/0,maxX:-1/0,minZ:1/0,maxZ:-1/0,fMinX:1/0,fMaxX:-1/0,fMinZ:1/0,fMaxZ:-1/0,hasFloor:!1};O.minX=Math.min(O.minX,ze),O.maxX=Math.max(O.maxX,Ee),O.minZ=Math.min(O.minZ,qe),O.maxZ=Math.max(O.maxZ,Ne),se&&(O.fMinX=Math.min(O.fMinX,ze),O.fMaxX=Math.max(O.fMaxX,Ee),O.fMinZ=Math.min(O.fMinZ,qe),O.fMaxZ=Math.max(O.fMaxZ,Ne),O.hasFloor=!0),r.set(Be,O),c=Math.min(c,gn),m=Math.max(m,In),b=Math.min(b,Sn),l=Math.max(l,bn),A=!0}),!A)return null;const K=Math.max(n,E>0?E+.02:n),Mt=[...r.values()].map(s=>{const B=Math.sin(s.heading),F=Math.cos(s.heading),x=B,G=-F,Q=Math.abs(x)>Math.abs(G),q=s.hasFloor?s.fMinX:s.minX,oe=s.hasFloor?s.fMaxX:s.maxX,Rt=s.hasFloor?s.fMinZ:s.minZ,se=s.hasFloor?s.fMaxZ:s.maxZ,Ge=Q?(x>0?oe:q)+(x>0?e/2:-e/2):(G>0?se:Rt)+(G>0?e/2:-e/2);return{g:s,isSide:Q,plane:Ge}}),Lt=Mt.some(s=>s.g.hasFloor)?Mt.filter(s=>s.g.hasFloor):Mt,pn=Lt.filter(s=>s.isSide).map(s=>s.plane),mn=Lt.filter(s=>!s.isSide).map(s=>s.plane),Qt=[];for(const s of Lt){const{g:B}=s;if(s.isSide){let F=B.minZ,x=B.maxZ;for(const G of mn)F=Math.min(F,G),x=Math.max(x,G);Qt.push({cx:s.plane,cz:(F+x)/2,cy:K/2,length:x-F+o*2,thickness:e,height:K,rotY:Math.PI/2})}else{let F=B.minX,x=B.maxX;for(const G of pn)F=Math.min(F,G),x=Math.max(x,G);Qt.push({cx:(F+x)/2,cz:s.plane,cy:K/2,length:x-F+o*2,thickness:e,height:K,rotY:0})}}const kt=.4,Fe=m>c&&l>b;let Jt=c-kt,te=m+kt,ee=b-kt,ne=l+kt;for(const s of Lt){const B=Math.sin(s.g.heading),F=-Math.cos(s.g.heading);s.isSide?B<0?Jt=s.plane-e/2:te=s.plane+e/2:F<0?ee=s.plane-e/2:ne=s.plane+e/2}const hn=Fe?{cx:(Jt+te)/2,cz:(ee+ne)/2,w:te-Jt,d:ne-ee}:null,fn=Fe?{minX:c,maxX:m,minZ:b,maxZ:l,w:m-c,d:l-b,h:K,height:E>0?E:K}:null;return{segments:Qt,floor:hn,bbox:fn}},[C,dt,nt,st,u,ue]),on=Zt&&!!(U&&U.segments&&U.segments.length),sn=St&&!!(U&&U.bbox&&U.bbox.w>0),rn=(t,n)=>{const e=dt[n]||{position:[0,0,0],rotation:[0,0,0]},o=Ft.get(t.id);if(!o)return e;const r=e.position||[0,0,0],c=(Array.isArray(e.rotation)?e.rotation[1]:0)||0,m=Math.cos(c),b=Math.sin(c),l=o.offset||[0,0,0];return{position:[r[0]+(l[0]||0)*m+(l[2]||0)*b,r[1]+(l[1]||0),r[2]-(l[0]||0)*b+(l[2]||0)*m],rotation:[0,c+(o.rotDegY||0)*Math.PI/180,0]}},$=bt,vt=!!$,we=H(()=>{if(!$)return new Set;const t=u($.variantId)||u($.productId)||null,n=W.getState().products,e=new Set;for(const o of Object.values(f||{})){const r=u(o.variantId)||u(o.productId);(t?$e(t,r,n):(()=>{const m=new Set(($.compatibleGraphIds||[]).map(String)),b=r?.product_graph??r?.productGraph;return b!=null&&m.has(String(b))})())&&e.add(String(o.id))}return e},[$,f,u]),$t=J(()=>{y.getState().clearPendingSlotPlacement?.(),y.getState().clearPendingHostedProduct?.()},[]),Ce=J((t,n)=>{if(!n)return;const e=W.getState(),o=e.getProduct?.(n.variantId)||e.getProduct?.(n.productId),r=o?.productGraph??o?.product_graph??null,c=T.getState().productInstances?.[String(t)],m=o?.placementGroup??o?.placement_group??c?.placementGroup??null,b=Array.isArray(c?.position)?c.position:[0,0,0],l=c?.variantId??c?.productId??null,E=Number.isFinite(Number(c?.sequence))?Number(c.sequence):void 0;$t(),Nt({type:Xt.PRODUCT_ADD,productGraphId:r,variantId:n.variantId??n.productId,placementGroup:m,sequence:E,hostPlacementId:String(t),hostVariantId:l},A=>qt({productGraphId:A.productGraphId,variantId:A.variantId,placementGroup:A.placementGroup,position:b,sequence:A.sequence,hostPlacementId:A.hostPlacementId,hostVariantId:A.hostVariantId}).catch(()=>{}))},[$t]),Kt=J((t,n)=>{const e=W.getState(),o=e.getProduct?.(n.variantId)||e.getProduct?.(n.productId),r=o?.productGraph??o?.product_graph??null,c=o?.placementGroup??o?.placement_group??null,m=C[t-1]||C[t],b=Array.isArray(m?.position)?m.position:[0,0,0],l=C[t],E=l&&Number.isFinite(Number(l.sequence))?Number(l.sequence):void 0;Nt({type:Xt.PRODUCT_ADD,productGraphId:r,variantId:n.variantId??n.productId,placementGroup:c,sequence:E},A=>qt({productGraphId:A.productGraphId,variantId:A.variantId,placementGroup:A.placementGroup,position:b,sequence:A.sequence}).catch(()=>{}))},[C]);N(()=>{if(!Z||C.length>0)return;const t=Z;Ye(),Kt(0,t)},[Z,C.length,Kt]);const{gaps:an,onInsert:cn}=Kn({systemId:d,count:C.length,positionOf:t=>dt[t]?.position||[0,0,0],insertAt:Kt}),Te=H(()=>{if(!Z)return[];const t=W.getState();return Dn(C,{candidate:Z,getProduct:n=>t.getProduct?.(n),getDims:st,config:tn(),layout:dt})},[Z,C,dt,st]),dn=J(t=>{const n=Ln(t,{candidate:Z});if(!n)return;const e=W.getState(),o=e.getProduct?.(n.variantId)||e.getProduct?.(n.productId),r=o?.productGraph??o?.product_graph??null,c=o?.placementGroup??o?.placement_group??null,m=n.transform?.position??t.position??[0,0,0],b=Rn(n,t,C);Nt({type:Xt.PRODUCT_ADD,productGraphId:r,variantId:n.variantId??n.productId,placementGroup:c,anchor:n.anchor??null,sequence:b},l=>qt({productGraphId:l.productGraphId,variantId:l.variantId,placementGroup:l.placementGroup,position:m,sequence:l.sequence}).catch(()=>{})),Ye()},[Z,C]),{selectedInst:Io,swapOrder:So,panelActions:_e,priceInfo:ln}=xn(),un=wn()("selectionPanel");N(()=>{if(S==null)return;const t=f||{},n=String(S),e="__host";if(n.endsWith(e)){const o=n.slice(0,-e.length);if(t[o]||Object.values(t).some(r=>String(r?.id??r?.instanceId)===o))return}else if(t[S]||Object.values(t).some(o=>String(o?.instanceId??o?.id)===n))return;D?.()},[S,f,D]);const yo=gt(t=>t.placementPricing),vo=z(t=>t.getChannelPriceConfig);return lt(de,{children:[h(On,{onSeeded:g}),lt(Fn,{isMobile:_,camera:{position:[2.6,2.2,4],fov:45},controlsTarget:[0,.5,0],onPointerMissed:()=>D?.(),groundShadowCatcher:!0,overlay:lt(de,{children:[!vt&&_e&&un?h(I,{actions:_e,priceInfo:ln}):null,vt&&h("div",{className:"placement-mode-overlay",children:lt("div",{className:"placement-mode-overlay__content",children:[lt("span",{className:"placement-mode-overlay__text",children:["Click on a highlighted slot to place ",h("strong",{children:$?.name})]}),h("button",{type:"button",className:"placement-mode-overlay__cancel",onClick:$t,children:h("span",{className:"placement-mode-overlay__cancel-text",children:"Cancel"})})]})}),h(Nn,{name:"overlay"}),tt&&h(et,{scene:!0,message:ut("loading.message","Loading your configurator\u2026"),detail:V,progress:v}),a&&h("div",{"aria-hidden":"true",style:{position:"absolute",inset:0,zIndex:30,cursor:"default"}})]}),children:[on&&h(Gn,{width:nt?.width,depth:nt?.depth,height:nt?.height??U?.bbox?.h??2.7,showCeiling:Ct?.ceiling===!0,segments:U?.segments||null,floor:U?.floor||null}),sn&&(()=>{const t=ie("SceneDimensions",Hn);return h(t,{bbox:U.bbox})})(),C.map((t,n)=>{const e=Ft.get(t.id),o=dt[n]||{position:[0,0,0],rotation:[0,0,0]};return o.hidden?null:lt("group",{children:[e&&h(ce,{instance:{id:e.id,instanceId:e.id,productId:e.hostVariantId,variantId:e.hostVariantId,position:o.position||[0,0,0],rotation:o.rotation||[0,0,0]},slotMaterials:{...pt,...j?.[e.hostedProductId]||{},...j?.[e.id]||{}},stateInstanceId:e.hostedProductId,onSelect:()=>T.getState().selectInstance(e.id),isSelected:String(S)===String(e.id),onMeasure:r=>jt(e.hostVariantId,r,null,e.id),footprintExcludeItem:Ut,hoverable:!0,focusable:!0},e.id),h(ce,{instance:{...t,...rn(t,n)},slotMaterials:{...pt,...j?.[t.id]||j?.[t.instanceId]||{}},onSelect:(r,c,m)=>{if(vt){we.has(String(t.id))&&Ce(t.id,$);return}T.getState().selectInstance(r,m??null)},isSelected:!vt&&String(S)===String(t.instanceId??t.id),onMeasure:r=>jt(t.productId,r,t.id),footprintExcludeItem:Ut,hoverable:!0,focusable:!0}),vt&&we.has(String(t.id))&&(()=>{const r=o.position||[0,0,0],c=st(ft[n]?.productId??t.productId,t),m=(Array.isArray(o.rotation)?o.rotation[1]:0)||0,b=Math.cos(m),l=Math.sin(m),E=c?.cx||0,A=c?.cz||0,K=c?.full?.height??c?.height,Mt=[r[0]+E*b+A*l,r[1]+(K>0?K/2:.45),r[2]-E*l+A*b];return h(uo,{position:Mt,onClick:()=>Ce(t.id,$)})})()]},t.id??t.instanceId??n)}),_t.map((t,n)=>h(Tn,{selected:S===t.id,disabled:!!t.locked,position:t.position||[0,0,0],rotationY:(Array.isArray(t.rotation)&&t.rotation[1]||0)*Math.PI/180,gizmoOffset:(()=>{const e=st(t.productId,t);return[e?.cx||0,0,e?.cz||0]})(),onCommit:({position:e,rotationY:o})=>{i(t.id,e),L(t.id,[0,o*180/Math.PI,0]),Qn({allowRevert:!0}).catch(()=>{})},children:h(ce,{instance:{...t,position:[0,0,0],rotation:[0,0,0]},slotMaterials:{...pt,...j?.[t.id]||j?.[t.instanceId]||{}},onMeasure:e=>jt(t.productId,e,t.id),footprintExcludeItem:Ut})},t.id??t.instanceId??`free-${n}`)),Te.length>0?h(An,{targets:Te,onPick:dn}):h(_n,{gaps:an,onInsert:cn})]})]})}const en=new Set;function mo(){no();const _=z(a=>a.systemLayoutTemplate),I=z(a=>a.systemTheme),f=z(a=>a.systemThemeRecord);ao(I,f);const u=ro(f)||(I?String(I).trim().toLowerCase():null);let p=_;try{const a=new URLSearchParams(window.location.search);a.has("template")?p=a.get("template"):a.has("theme")&&(p=a.get("theme"))}catch{}p=p||_||u||null;const D=oo();D&&(p=D),!D&&!_&&p&&p===u&&!eo(p)&&!/^theme\d+$/.test(p)&&!en.has(p)&&en.add(p),so(p);const S=to(p);return lt(de,{children:[h(S,{Scene:po,template:p}),h(Xn,{}),h(Zn,{})]})}export{po as SharedConfiguratorScene,mo as default};
@@ -0,0 +1 @@
1
+ const g=(l,t)=>{const h=t.full||null;return!!l&&l.width===t.width&&l.depth===t.depth&&l.height===t.height&&l.cx===t.cx&&l.cz===t.cz&&(l.full?.width??null)===(h?.width??null)&&(l.full?.height??null)===(h?.height??null)&&(l.full?.depth??null)===(h?.depth??null)},a=(l,t,h)=>({width:l.width,depth:l.depth,height:l.height,cx:l.cx,cz:l.cz,full:l.full||null,forProductId:t,...h!=null?{ownerId:h}:{},...l.__slots?{slots:l.__slots}:{}});function _(l,t,h,e=null,f=e){let n=l;const u=l[t];if((!u||u.ownerId==null||f==null||String(u.ownerId)===String(f))&&!g(u,h)&&(n={...n,[t]:a(h,t,f)}),e!=null){const o=`inst:${e}`;g(n[o],h)||(n={...n,[o]:a(h,t,e)})}return n}export{_ as applyMeasurement};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@imagineio/configurator-sdk",
3
- "version": "0.1.4",
3
+ "version": "0.1.6",
4
4
  "description": "Configurator SDK — backend Configuration Engine client, state stores, shared 3D scene primitives, and pluggable placement (strategy + type). Drives every configurator (kitchen, sectional, …) from one self-contained surface.",
5
5
  "license": "SEE LICENSE IN LICENSE.md",
6
6
  "type": "module",
@@ -36,26 +36,28 @@
36
36
  "verify:publish": "node build/verify-publish.mjs"
37
37
  },
38
38
  "dependencies": {
39
- "@copilotkit/react-core": "^1.51.3",
40
- "@copilotkit/react-ui": "^1.51.3",
41
- "@gltf-transform/core": "4.3",
42
- "@gltf-transform/extensions": "4.3",
43
- "@react-three/postprocessing": "2.16",
39
+ "@copilotkit/react-core": "1.59.5",
40
+ "@copilotkit/react-ui": "1.59.5",
41
+ "@gltf-transform/core": "^4.5.1",
42
+ "@gltf-transform/extensions": "^4.5.1",
43
+ "lucide-react": "^0.525.0",
44
44
  "html2canvas": "^1.4.1",
45
45
  "jspdf": "^4.2.1",
46
- "postprocessing": "6.36",
47
46
  "qrcode": "^1.5.4",
48
47
  "qrcode.react": "^4.2.0",
49
- "uuid": "^11.1.1",
50
- "zustand": "^4.4.7"
48
+ "uuid": "^14.0.3",
49
+ "zustand": "^5.0.16"
51
50
  },
52
51
  "peerDependencies": {
53
- "@react-three/drei": "^9.88.0",
54
- "@react-three/fiber": "^8.15.0",
55
- "react": "^18.2.0",
56
- "react-dom": "^18.2.0",
57
- "three": "^0.159.0"
52
+ "@react-three/drei": "^9.88.0 || ^10.7.0",
53
+ "@react-three/fiber": "^8.15.0 || ^9.6.0",
54
+ "@react-three/postprocessing": "^2.16.0 || ^3.2.0",
55
+ "postprocessing": "^6.36.0",
56
+ "react": "^18.2.0 || ^19.0.0",
57
+ "react-dom": "^18.2.0 || ^19.0.0",
58
+ "three": ">=0.159.0 <0.187.0"
58
59
  },
60
+ "peerDependenciesComment": "Two supported lines, picked by the consumer's React: React 19 -> fiber 9 / drei 10 / @react-three/postprocessing 3; React 18 -> fiber 8 / drei 9 / @react-three/postprocessing 2. Recommended three on BOTH lines is 0.186 (drei 9 / fiber 8 accept it; one three means one HDRI prefilter and one lighting result - 0.159 lights the same HDR visibly differently, its PMREM was rewritten in r16x). The original React 18 stack (three 0.159) stays installable by naming it, with postprocessing pinned ~6.36 because 6.39+ needs three >=0.168. The || operator only widens what is ACCEPTED: npm resolves each range to its highest match independently, so an empty project gets the React 19 line and a React 18 project must name its whole line in one install command (README). The two postprocessing packages are peers, not dependencies, because their major follows the React line; the dist bundles import both dynamically and leave them external.",
59
61
  "devDependencies": {
60
62
  "javascript-obfuscator": "^5.7.0",
61
63
  "tsup": "^8.5.1",