@solumflow-app/product-configurator 0.3.0 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.js +2 -2
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import {e,g,f,b,k,c,d,a,o,l,i,h,n}from'./chunk-ATEH2U7F.js';import {b as b$1}from'./chunk-RNTBO6KY.js';import {lazy,useMemo,useState,useSyncExternalStore,Suspense,useRef,useEffect,useId}from'react';import {jsxs,jsx}from'react/jsx-runtime';var X="#b8b4ad",Pe=1e-6;function W(n){let{structure:e,value:t,selection:o}=n,a$1=[],l$1=new Map(e.parameters.map(r=>[r.key,r])),m=new Map(e.materials.map(r=>[r.code,r]));for(let r of Object.keys(o.values))l$1.has(r)||a$1.push(a(["values",r],"configurator.unknownParam",{key:r}));let s=e.presets?t.presets.map(r=>({code:r.code,label:r.label,productId:r.productId})):[],c=null;o.preset!==void 0&&(c=s.find(r=>r.code===o.preset)??null,c||a$1.push(a(["preset"],"configurator.presetNotOffered",{code:o.preset}))),!c&&e.presets?.required&&(c=s[0]??null);let u=c?t.presets.find(r=>r.code===c?.code)?.values??{}:{},p=new Set(e.presets?.sets??[]),f=new Map,v={},d$1=r=>{let g=f.get(r.param),w=g?.visible?g.value:null;switch(r.op){case "eq":return w===r.value;case "neq":return w!==r.value;case "in":return Array.isArray(r.value)&&r.value.includes(w);case "gte":return typeof w=="number"&&w>=r.value;case "lte":return typeof w=="number"&&w<=r.value}};for(let r of l(e)){let g=l$1.get(r);if(!g)continue;let w=e.rules.filter(S=>S.param===r),i=w.filter(S=>S.kind==="visible").every(S=>d$1(S.when)),b=o.values[r],h=["values",r],I={key:r,kind:g.kind,label:g.label,tab:g.tab};if(g.kind==="number"){let S=t.numbers[r]??{min:g.min,max:g.max,default:g.min},C=S.min,P=S.max;for(let H of w){if(H.kind!=="limit")continue;let K=d(H.formula,v);if(!K.ok){a$1.push(a(["rules",e.rules.indexOf(H)],`configurator.${K.code}`));continue}H.bound==="min"?C=Math.max(C,K.value):P=Math.min(P,K.value);}C>P&&(a$1.push(a(h,"configurator.emptyRange",{key:r,min:C,max:P})),P=C);let j=p.has(r)?u[r]:void 0,B=pe(S.default,C,P);j!==void 0?B=j:i&&b!==void 0&&(typeof b!="number"?a$1.push(a(h,"configurator.expectedNumber",{key:r})):b<C||b>P?(a$1.push(a(h,"configurator.outOfRange",{key:r,min:C,max:P})),B=pe(b,C,P)):Oe(b,g.step)?B=b:a$1.push(a(h,"configurator.offStep",{key:r,step:g.step}))),v[r]=B,f.set(r,{...I,visible:i,value:B,min:C,max:P,step:g.step,unit:g.unit,fixed:j!==void 0,settled:j===void 0&&C===P});continue}if(g.kind==="toggle"){let S=t.toggles[r]??{offered:true,default:false};i=i&&S.offered;let C=S.default;i&&b!==void 0&&(typeof b!="boolean"?a$1.push(a(h,"configurator.expectedBoolean",{key:r})):C=b);let P=i&&C;v[r]=P?1:0,f.set(r,{...I,visible:i,value:P});continue}let A=new Set(w.filter(S=>S.kind==="exclude"&&d$1(S.when)).flatMap(S=>S.kind==="exclude"?S.codes:[])),$,J;if(g.kind==="choice"){let S=e.choiceLists.find(P=>P.key===g.list),C=t.choices[g.list];$=(S?.options??[]).filter(P=>C?.options[P.code]!==void 0&&!A.has(P.code)).map(P=>({code:P.code,label:P.label,priceCents:C?.options[P.code]?.priceCents??null})),J=C?.default;}else {let S=t.materials[r];$=(S?.offered??[]).map(C=>m.get(C)).filter(C=>C!==void 0).filter(C=>!A.has(C.code)).map(C=>({code:C.code,label:C.label,priceCents:C.priceGroup?t.priceGroups[C.priceGroup]??null:0,material:C})),J=S?.default;}i=i&&$.length>0;let ne=$.find(S=>S.code===J)?.code??$[0]?.code??null;i&&b!==void 0&&(typeof b!="string"||!$.some(S=>S.code===b)?a$1.push(a(h,"configurator.optionNotOffered",{key:r,code:String(b)})):ne=b),f.set(r,{...I,visible:i,value:i?ne:null,options:$,settled:$.length===1});}let y=e.parameters.map(r=>f.get(r.key)).filter(r=>r!==void 0),x={};for(let r of e.geometry.inputs){let g=f.get(r.binding.param);g&&(g.kind==="number"?x[r.name]=g.value:g.kind==="toggle"?x[r.name]=g.value===true?1:0:g.kind==="choice"&&(x[r.name]=typeof g.value=="string"?r.binding.map?.[g.value]??0:0));}let k={};for(let r of e.geometry.slots){let g=null;if(r.param){let w=f.get(r.param);g=w?.options?.find(i=>i.code===w.value)?.material??null;}else r.material&&(g=m.get(r.material)??null);k[r.name]={color:g?.color??r.color??X,material:g,grain:r.grain??"horizontal"};}let M={values:{}};for(let r of y)r.visible&&!r.fixed&&r.value!==null&&(M.values[r.key]=r.value);return c&&(M.preset=c.code),{configuration:{parameters:y,byKey:Object.fromEntries(f),presets:s,preset:c,inputs:x,slots:k,selection:M},issues:a$1}}function me(n){let e={};for(let t of n.parameters)t.kind==="choice"&&t.visible&&typeof t.value=="string"&&(e[t.key]=t.value);return {choices:e,preset:n.preset?.code}}function pe(n,e,t){return Math.min(t,Math.max(e,n))}function Oe(n,e){let t=n/e;return Math.abs(t-Math.round(t))<Pe}var _e=1;function V(n){let{structure:e,value:t,tax:o}=n,{configuration:a$1,issues:l}=W(n);if(l.length>0)return {ok:false,issues:l,configuration:a$1};let m=[],s={};for(let d of a$1.parameters)d.kind==="number"?s[d.key]=d.value:d.kind==="toggle"&&(s[d.key]=d.value===true?1:0);let c$1=[{key:"base",label:"base",amountCents:t.basePriceCents}],u=(d$1,y)=>{if(d$1===void 0)return 1;let x=d(d$1,s);return x.ok?x.value<0?(m.push(a(y,"configurator.negativeMultiplier")),null):x.value:(m.push(a(y,`configurator.${x.code}`)),null)};if(e.priceRules.forEach((d$1,y)=>{let x=["priceRules",y];if(d$1.kind==="formula"){let g=Object.fromEntries(e.amounts.map(I=>[I.key,t.amounts[I.key]])),w=c(d$1.formula);if(w.ok&&w.names.some(I=>I in g&&g[I]==null)){c$1.push({key:d$1.key,label:d$1.label,amountCents:null});return}let b={...s};for(let[I,A]of Object.entries(g))typeof A=="number"&&(b[I]=A);let h=d(d$1.formula,b);if(!h.ok){m.push(a([...x,"formula"],`configurator.${h.code}`));return}if(h.value<0){m.push(a([...x,"formula"],"configurator.negativeAmount"));return}de(c$1,d$1.key,d$1.label,Math.round(h.value));return}let k=a$1.byKey[d$1.param];if(!k?.visible)return;let M;if(d$1.kind==="toggle"){if(k.value!==true)return;M=t.amounts[d$1.amount]??null;}else {let g=k.options?.find(w=>w.code===k.value);if(!g)return;M=g.priceCents;}if(M===null){c$1.push({key:d$1.key,label:d$1.label,amountCents:null});return}let r=u(d$1.multiplier,[...x,"multiplier"]);r!==null&&de(c$1,d$1.key,d$1.label,Math.round(M*r));}),m.length>0)return {ok:false,issues:m,configuration:a$1};let p=t.basePriceCents===null?"open":c$1.some(d=>d.amountCents===null)?"partial":"priced",f=c$1.reduce((d,y)=>d+(y.amountCents??0),0),v=p==="open"?null:Me(f,o);return {ok:true,configuration:a$1,quote:{engineVersion:_e,state:p,lines:c$1,netCents:v?.netCents??null,taxCents:v?.taxCents??null,totalCents:v?.totalCents??null,taxPercentage:o.taxPercentage,pricesIncludeTax:o.pricesIncludeTax}}}function de(n,e,t,o){o!==0&&n.push({key:e,label:t,amountCents:o});}function Me(n,e){let t=e.taxPercentage>0?e.taxPercentage:0;if(e.pricesIncludeTax){let a=Math.round(n*t/(100+t));return {netCents:n-a,taxCents:a,totalCents:n}}let o=Math.round(n*t/100);return {netCents:n,taxCents:o,totalCents:n+o}}function ge(n,e,t={choices:{}}){let o=[],a$1=[],l={...n.constants};for(let u of n.inputs){let p=e[u.name];if(p===void 0||!Number.isFinite(p)){o.push(a(["inputs",u.name],"configurator.inputMissing",{name:u.name}));continue}l[u.name]=p;}if(o.length>0)return {ok:false,issues:o};for(let u of i(n.root))l[u.name]=fe(u.node,t)===void 0?0:1;let m=(u,p,f)=>{let v=d(u,p);return v.ok?v.value:(o.push(v.code==="formula_unknown_name"?a(f,"configurator.unknownName",{name:v.name}):a(f,`configurator.${v.code}`)),null)},s=(u,p,f,v,d)=>{for(let y of u){if(o.length>0)return;let x=[...f,y.id];if(y.visible!==void 0){let i=m(y.visible,p,[...x,"visible"]);if(i===null||i<=0)continue}if(y.type==="repeat"){if(d+1>b.repeatDepth){o.push(a(x,"configurator.repeatTooDeep",{max:b.repeatDepth}));return}let i=m(y.count,p,[...x,"count"]);if(i===null)return;if(!Number.isInteger(i)||i<0||i>b.repeatCount){o.push(a([...x,"count"],"configurator.repeatCountInvalid",{count:i,max:b.repeatCount}));return}let b$1=y.index??"i";for(let h=0;h<i;h+=1)s(y.children,{...p,[b$1]:h},[...x,h],`${v}[${h}]`,d+1);continue}let k=y.size.map((i,b)=>m(i,p,[...x,"size",b])),M=y.at.map((i,b)=>m(i,p,[...x,"at",b]));if(k.includes(null)||M.includes(null))return;let r=k.findIndex(i=>i<0);if(r>=0){o.push(a([...x,"size",r],"configurator.negativeMeasure",{value:k[r]}));return}let g=fe(y,t);if(y.type==="model"&&g===void 0)continue;let w={};for(let[i,b]of Object.entries(y.params??{})){let h=m(b,p,[...x,"params",i]);if(h===null)return;w[i]=h;}if(a$1.push({key:`${y.id}${v}`,id:y.id,type:y.type,slot:y.slot,size:k,at:M,params:w,...g===void 0?{}:{model:g}}),a$1.length>b.expandedParts){o.push(a(["root"],"configurator.tooManyParts",{max:b.expandedParts}));return}}};s(n.root,l,["root"],"",0);let c=[];for(let u of n.annotations){let p=["annotations",u.id],f=m(u.from,l,[...p,"from"]),v=m(u.to,l,[...p,"to"]),d=m(u.at,l,[...p,"at"]);f===null||v===null||d===null||c.push({id:u.id,axis:u.axis,from:f,to:v,at:d,label:u.label??null,length:Math.abs(v-f)});}return o.length>0?{ok:false,issues:o}:{ok:true,geometry:{parts:a$1,dimensions:c,bounds:Ie(a$1)}}}function Ie(n){if(n.length===0)return {min:[0,0,0],max:[0,0,0]};let e=[1/0,1/0,1/0],t=[-1/0,-1/0,-1/0];for(let o of n)for(let a=0;a<3;a+=1)e[a]=Math.min(e[a],o.at[a]),t[a]=Math.max(t[a],o.at[a]+o.size[a]);return {min:e,max:t}}function fe(n,e){if(n.follows===void 0)return n.model;let t=n.follows===h?e.preset:e.choices[n.follows];return t===void 0?void 0:n.models?.[t]}var G={tabsLabel:"Onderdelen van de configurator",presetNone:"Geen keuze",switchOn:"Aan",switchOff:"Uit",unitMm:"mm",unitCount:"stuks",surchargePrefix:"+",optionOnRequest:"op aanvraag",priceHeading:"Prijs",priceIncludingTax:"incl. btw",priceFrom:"vanaf",priceInPartOnRequest:"deels op aanvraag",priceOnRequest:"prijs op aanvraag",priceUnavailable:"Prijs nog niet te berekenen",sketchTitle:"Maatschets",sketchUnavailable:"Deze combinatie kan niet getekend worden.",sceneLoading:"3D-weergave laden\u2026",sceneLabel:"3D-weergave van de configuratie",cameraControls:"Beeld verschuiven en zoomen",cameraLeft:"Beeld naar links",cameraRight:"Beeld naar rechts",cameraUp:"Beeld omhoog",cameraDown:"Beeld omlaag",cameraZoomIn:"Inzoomen",cameraZoomOut:"Uitzoomen",cameraReset:"Beeld herstellen"};var $e=`
1
+ import {e,g,f,b,k,c,d,a,o,l,i,h,n}from'./chunk-ATEH2U7F.js';import {b as b$1}from'./chunk-RNTBO6KY.js';import {lazy,useMemo,useState,useSyncExternalStore,Suspense,useRef,useEffect,useId}from'react';import {jsxs,jsx}from'react/jsx-runtime';var X="#b8b4ad",_e=1e-6;function W(n){let{structure:e,value:t,selection:o}=n,r=[],l$1=new Map(e.parameters.map(a=>[a.key,a])),m=new Map(e.materials.map(a=>[a.code,a]));for(let a$1 of Object.keys(o.values))l$1.has(a$1)||r.push(a(["values",a$1],"configurator.unknownParam",{key:a$1}));let s=e.presets?t.presets.map(a=>({code:a.code,label:a.label,productId:a.productId})):[],u=null;o.preset!==void 0&&(u=s.find(a=>a.code===o.preset)??null,u||r.push(a(["preset"],"configurator.presetNotOffered",{code:o.preset}))),!u&&e.presets?.required&&(u=s[0]??null);let c=u?t.presets.find(a=>a.code===u?.code)?.values??{}:{},p=new Set(e.presets?.sets??[]),f=new Map,v={},d$1=a=>{let g=f.get(a.param),N=g?.visible?g.value:null;switch(a.op){case "eq":return N===a.value;case "neq":return N!==a.value;case "in":return Array.isArray(a.value)&&a.value.includes(N);case "gte":return typeof N=="number"&&N>=a.value;case "lte":return typeof N=="number"&&N<=a.value}};for(let a$1 of l(e)){let g=l$1.get(a$1);if(!g)continue;let N=e.rules.filter(R=>R.param===a$1),i=N.filter(R=>R.kind==="visible").every(R=>d$1(R.when)),b=o.values[a$1],h=["values",a$1],I={key:a$1,kind:g.kind,label:g.label,tab:g.tab};if(g.kind==="number"){let R=t.numbers[a$1]??{min:g.min,max:g.max,default:g.min},C=R.min,P=R.max;for(let H of N){if(H.kind!=="limit")continue;let K=d(H.formula,v);if(!K.ok){r.push(a(["rules",e.rules.indexOf(H)],`configurator.${K.code}`));continue}H.bound==="min"?C=Math.max(C,K.value):P=Math.min(P,K.value);}C>P&&(r.push(a(h,"configurator.emptyRange",{key:a$1,min:C,max:P})),P=C);let j=p.has(a$1)?c[a$1]:void 0,B=pe(R.default,C,P);j!==void 0?B=j:i&&b!==void 0&&(typeof b!="number"?r.push(a(h,"configurator.expectedNumber",{key:a$1})):b<C||b>P?(r.push(a(h,"configurator.outOfRange",{key:a$1,min:C,max:P})),B=pe(b,C,P)):Me(b,g.step)?B=b:r.push(a(h,"configurator.offStep",{key:a$1,step:g.step}))),v[a$1]=B,f.set(a$1,{...I,visible:i,value:B,min:C,max:P,step:g.step,unit:g.unit,fixed:j!==void 0,settled:j===void 0&&C===P});continue}if(g.kind==="toggle"){let R=t.toggles[a$1]??{offered:true,default:false};i=i&&R.offered;let C=R.default;i&&b!==void 0&&(typeof b!="boolean"?r.push(a(h,"configurator.expectedBoolean",{key:a$1})):C=b);let P=i&&C;v[a$1]=P?1:0,f.set(a$1,{...I,visible:i,value:P});continue}let A=new Set(N.filter(R=>R.kind==="exclude"&&d$1(R.when)).flatMap(R=>R.kind==="exclude"?R.codes:[])),L,J;if(g.kind==="choice"){let R=e.choiceLists.find(P=>P.key===g.list),C=t.choices[g.list];L=(R?.options??[]).filter(P=>C?.options[P.code]!==void 0&&!A.has(P.code)).map(P=>({code:P.code,label:P.label,priceCents:C?.options[P.code]?.priceCents??null})),J=C?.default;}else {let R=t.materials[a$1];L=(R?.offered??[]).map(C=>m.get(C)).filter(C=>C!==void 0).filter(C=>!A.has(C.code)).map(C=>({code:C.code,label:C.label,priceCents:C.priceGroup?t.priceGroups[C.priceGroup]??null:0,material:C})),J=R?.default;}i=i&&L.length>0;let ne=L.find(R=>R.code===J)?.code??L[0]?.code??null;i&&b!==void 0&&(typeof b!="string"||!L.some(R=>R.code===b)?r.push(a(h,"configurator.optionNotOffered",{key:a$1,code:String(b)})):ne=b),f.set(a$1,{...I,visible:i,value:i?ne:null,options:L,settled:L.length===1});}let y=e.parameters.map(a=>f.get(a.key)).filter(a=>a!==void 0),x={};for(let a of e.geometry.inputs){let g=f.get(a.binding.param);g&&(g.kind==="number"?x[a.name]=g.value:g.kind==="toggle"?x[a.name]=g.value===true?1:0:g.kind==="choice"&&(x[a.name]=typeof g.value=="string"?a.binding.map?.[g.value]??0:0));}let S={};for(let a of e.geometry.slots){let g=null;if(a.param){let N=f.get(a.param);g=N?.options?.find(i=>i.code===N.value)?.material??null;}else a.material&&(g=m.get(a.material)??null);S[a.name]={color:g?.color??a.color??X,material:g,grain:a.grain==="vertical"?"vertical":"horizontal"};}let M={values:{}};for(let a of y)a.visible&&!a.fixed&&a.value!==null&&(M.values[a.key]=a.value);return u&&(M.preset=u.code),{configuration:{parameters:y,byKey:Object.fromEntries(f),presets:s,preset:u,inputs:x,slots:S,selection:M},issues:r}}function me(n){let e={};for(let t of n.parameters)t.kind==="choice"&&t.visible&&typeof t.value=="string"&&(e[t.key]=t.value);return {choices:e,preset:n.preset?.code}}function pe(n,e,t){return Math.min(t,Math.max(e,n))}function Me(n,e){let t=n/e;return Math.abs(t-Math.round(t))<_e}var Ie=1;function V(n){let{structure:e,value:t,tax:o}=n,{configuration:r,issues:l}=W(n);if(l.length>0)return {ok:false,issues:l,configuration:r};let m=[],s={};for(let d of r.parameters)d.kind==="number"?s[d.key]=d.value:d.kind==="toggle"&&(s[d.key]=d.value===true?1:0);let u=[{key:"base",label:"base",amountCents:t.basePriceCents}],c$1=(d$1,y)=>{if(d$1===void 0)return 1;let x=d(d$1,s);return x.ok?x.value<0?(m.push(a(y,"configurator.negativeMultiplier")),null):x.value:(m.push(a(y,`configurator.${x.code}`)),null)};if(e.priceRules.forEach((d$1,y)=>{let x=["priceRules",y];if(d$1.kind==="formula"){let g=Object.fromEntries(e.amounts.map(I=>[I.key,t.amounts[I.key]])),N=c(d$1.formula);if(N.ok&&N.names.some(I=>I in g&&g[I]==null)){u.push({key:d$1.key,label:d$1.label,amountCents:null});return}let b={...s};for(let[I,A]of Object.entries(g))typeof A=="number"&&(b[I]=A);let h=d(d$1.formula,b);if(!h.ok){m.push(a([...x,"formula"],`configurator.${h.code}`));return}if(h.value<0){m.push(a([...x,"formula"],"configurator.negativeAmount"));return}de(u,d$1.key,d$1.label,Math.round(h.value));return}let S=r.byKey[d$1.param];if(!S?.visible)return;let M;if(d$1.kind==="toggle"){if(S.value!==true)return;M=t.amounts[d$1.amount]??null;}else {let g=S.options?.find(N=>N.code===S.value);if(!g)return;M=g.priceCents;}if(M===null){u.push({key:d$1.key,label:d$1.label,amountCents:null});return}let a$1=c$1(d$1.multiplier,[...x,"multiplier"]);a$1!==null&&de(u,d$1.key,d$1.label,Math.round(M*a$1));}),m.length>0)return {ok:false,issues:m,configuration:r};let p=t.basePriceCents===null?"open":u.some(d=>d.amountCents===null)?"partial":"priced",f=u.reduce((d,y)=>d+(y.amountCents??0),0),v=p==="open"?null:Le(f,o);return {ok:true,configuration:r,quote:{engineVersion:Ie,state:p,lines:u,netCents:v?.netCents??null,taxCents:v?.taxCents??null,totalCents:v?.totalCents??null,taxPercentage:o.taxPercentage,pricesIncludeTax:o.pricesIncludeTax}}}function de(n,e,t,o){o!==0&&n.push({key:e,label:t,amountCents:o});}function Le(n,e){let t=e.taxPercentage>0?e.taxPercentage:0;if(e.pricesIncludeTax){let r=Math.round(n*t/(100+t));return {netCents:n-r,taxCents:r,totalCents:n}}let o=Math.round(n*t/100);return {netCents:n,taxCents:o,totalCents:n+o}}function ge(n,e,t={choices:{}}){let o=[],r=[],l={...n.constants};for(let c of n.inputs){let p=e[c.name];if(p===void 0||!Number.isFinite(p)){o.push(a(["inputs",c.name],"configurator.inputMissing",{name:c.name}));continue}l[c.name]=p;}if(o.length>0)return {ok:false,issues:o};for(let c of i(n.root))l[c.name]=fe(c.node,t)===void 0?0:1;let m=(c,p,f)=>{let v=d(c,p);return v.ok?v.value:(o.push(v.code==="formula_unknown_name"?a(f,"configurator.unknownName",{name:v.name}):a(f,`configurator.${v.code}`)),null)},s=(c,p,f,v,d)=>{for(let y of c){if(o.length>0)return;let x=[...f,y.id];if(y.visible!==void 0){let i=m(y.visible,p,[...x,"visible"]);if(i===null||i<=0)continue}if(y.type==="repeat"){if(d+1>b.repeatDepth){o.push(a(x,"configurator.repeatTooDeep",{max:b.repeatDepth}));return}let i=m(y.count,p,[...x,"count"]);if(i===null)return;if(!Number.isInteger(i)||i<0||i>b.repeatCount){o.push(a([...x,"count"],"configurator.repeatCountInvalid",{count:i,max:b.repeatCount}));return}let b$1=y.index??"i";for(let h=0;h<i;h+=1)s(y.children,{...p,[b$1]:h},[...x,h],`${v}[${h}]`,d+1);continue}let S=y.size.map((i,b)=>m(i,p,[...x,"size",b])),M=y.at.map((i,b)=>m(i,p,[...x,"at",b]));if(S.includes(null)||M.includes(null))return;let a$1=S.findIndex(i=>i<0);if(a$1>=0){o.push(a([...x,"size",a$1],"configurator.negativeMeasure",{value:S[a$1]}));return}let g=fe(y,t);if(y.type==="model"&&g===void 0)continue;let N={};for(let[i,b]of Object.entries(y.params??{})){let h=m(b,p,[...x,"params",i]);if(h===null)return;N[i]=h;}if(r.push({key:`${y.id}${v}`,id:y.id,type:y.type,slot:y.slot,size:S,at:M,params:N,...g===void 0?{}:{model:g}}),r.length>b.expandedParts){o.push(a(["root"],"configurator.tooManyParts",{max:b.expandedParts}));return}}};s(n.root,l,["root"],"",0);let u=[];for(let c of n.annotations){let p=["annotations",c.id],f=m(c.from,l,[...p,"from"]),v=m(c.to,l,[...p,"to"]),d=m(c.at,l,[...p,"at"]);f===null||v===null||d===null||u.push({id:c.id,axis:c.axis,from:f,to:v,at:d,label:c.label??null,length:Math.abs(v-f)});}return o.length>0?{ok:false,issues:o}:{ok:true,geometry:{parts:r,dimensions:u,bounds:$e(r)}}}function $e(n){if(n.length===0)return {min:[0,0,0],max:[0,0,0]};let e=[1/0,1/0,1/0],t=[-1/0,-1/0,-1/0];for(let o of n)for(let r=0;r<3;r+=1)e[r]=Math.min(e[r],o.at[r]),t[r]=Math.max(t[r],o.at[r]+o.size[r]);return {min:e,max:t}}function fe(n,e){if(n.follows===void 0)return n.model;let t=n.follows===h?e.preset:e.choices[n.follows];return t===void 0?void 0:n.models?.[t]}var G={tabsLabel:"Onderdelen van de configurator",presetNone:"Geen keuze",switchOn:"Aan",switchOff:"Uit",unitMm:"mm",unitCount:"stuks",surchargePrefix:"+",optionOnRequest:"op aanvraag",priceHeading:"Prijs",priceIncludingTax:"incl. btw",priceFrom:"vanaf",priceInPartOnRequest:"deels op aanvraag",priceOnRequest:"prijs op aanvraag",priceUnavailable:"Prijs nog niet te berekenen",sketchTitle:"Maatschets",sketchUnavailable:"Deze combinatie kan niet getekend worden.",sceneLoading:"3D-weergave laden\u2026",sceneLabel:"3D-weergave van de configuratie",cameraControls:"Beeld verschuiven en zoomen",cameraLeft:"Beeld naar links",cameraRight:"Beeld naar rechts",cameraUp:"Beeld omhoog",cameraDown:"Beeld omlaag",cameraZoomIn:"Inzoomen",cameraZoomOut:"Uitzoomen",cameraReset:"Beeld herstellen"};var Te=`
2
2
  .pc-scope{
3
3
  --_fg:var(--pc-fg,currentColor);--_bg:var(--pc-bg,transparent);
4
4
  --_surface:var(--pc-surface,color-mix(in srgb,currentColor 6%,transparent));
@@ -55,4 +55,4 @@ import {e,g,f,b,k,c,d,a,o,l,i,h,n}from'./chunk-ATEH2U7F.js';import {b as b$1}fro
55
55
  .pc-price-total{font-size:26px;font-weight:700}
56
56
  .pc-price-note{color:var(--_muted);font-size:13px}
57
57
  .pc-hidden{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}
58
- `;function U(){return jsx("style",{href:"product-configurator",precedence:"default",children:$e})}function be(n,e,t){let o=n%100===0;return new Intl.NumberFormat(e,{style:"currency",currency:t,minimumFractionDigits:o?0:2,maximumFractionDigits:o?0:2}).format(n/100)}function he(n,e){let{min:t,max:o,step:a}=e,l=s=>Math.round(s*1e6)/1e6,m=Math.round(n/a)*a;return m<t&&(m=Math.ceil(t/a)*a),m>o&&(m=Math.floor(o/a)*a),l(Math.min(o,Math.max(t,m)))}function ve(n){let{structure:e,configuration:t,quote:o,onSelectionChange:a,locale:l="nl-NL",currency:m="EUR",disabled:s=false,className:c}=n,u={...G,...n.labels},p=useId(),f=useRef({}),v=e.presets&&t.presets.length>0?e.presets.tab:null,d=e.tabs.filter(i=>i.key===v||t.parameters.some(b=>b.tab===i.key&&ye(b))),[y,x]=useState(d[0]?.key),k=d.find(i=>i.key===y)??d[0],M=i=>be(i,l,m),r=(i,b)=>{a?.({...t.selection,values:{...t.selection.values,[i]:b}});},g=i=>{let{preset:b,...h}=t.selection;a?.(i===""?h:{...h,preset:i});},w=(i,b)=>{let h=i.key==="ArrowRight"?1:i.key==="ArrowLeft"?-1:0,I=d.length-1,A=i.key==="Home"?0:i.key==="End"?I:(b+h+d.length)%d.length;if(h===0&&i.key!=="Home"&&i.key!=="End")return;i.preventDefault();let $=d[A];$&&(x($.key),f.current[$.key]?.focus());};return jsxs("div",{className:["pc-panel","pc-scope",c].filter(Boolean).join(" "),children:[jsx(U,{}),d.length>1?jsx("div",{role:"tablist","aria-label":u.tabsLabel,className:"pc-tabs",children:d.map((i,b)=>jsx("button",{ref:h=>{f.current[i.key]=h;},type:"button",role:"tab",id:`${p}-tab-${i.key}`,"aria-selected":i.key===k?.key,"aria-controls":`${p}-panel-${i.key}`,tabIndex:i.key===k?.key?0:-1,className:"pc-tab",onClick:()=>x(i.key),onKeyDown:h=>w(h,b),children:i.label},i.key))}):null,k?jsxs("fieldset",{role:d.length>1?"tabpanel":void 0,id:`${p}-panel-${k.key}`,"aria-labelledby":d.length>1?`${p}-tab-${k.key}`:void 0,className:"pc-fields",disabled:s,children:[e.presets&&v===k.key?jsxs("div",{className:"pc-field",children:[jsx("label",{className:"pc-label",htmlFor:`${p}-preset`,children:e.presets.label}),jsxs("select",{id:`${p}-preset`,className:"pc-control",value:t.preset?.code??"",onChange:i=>g(i.target.value),children:[e.presets.required?null:jsx("option",{value:"",children:u.presetNone}),t.presets.map(i=>jsx("option",{value:i.code,children:i.label},i.code))]})]}):null,t.parameters.filter(i=>ye(i)&&i.tab===k.key).map(i=>jsx(Ae,{id:`${p}-${i.key}`,parameter:i,labels:u,money:M,onChange:b=>r(i.key,b)},i.key))]}):null,jsx(ze,{quote:o,labels:u,money:M})]})}function Ae(n){let{id:e,parameter:t,labels:o,money:a,onChange:l}=n;if(t.kind==="number"){let s={min:t.min??0,max:t.max??0,step:t.step??1},c=t.value,u=t.unit==="count"?o.unitCount:o.unitMm,p=f=>{Number.isFinite(f)&&l(he(f,s));};return jsxs("div",{className:"pc-field",children:[jsxs("label",{className:"pc-label",htmlFor:`${e}-range`,children:[t.label,jsxs("small",{children:[c," ",u]})]}),jsxs("div",{className:"pc-number",children:[jsx("input",{id:`${e}-range`,className:"pc-control",type:"range",min:s.min,max:s.max,step:s.step,value:c,disabled:t.fixed,onChange:f=>p(f.target.valueAsNumber)}),jsxs("span",{children:[jsx("label",{className:"pc-hidden",htmlFor:`${e}-number`,children:`${t.label} (${u})`}),jsx("input",{id:`${e}-number`,className:"pc-control",type:"number",inputMode:"numeric",min:s.min,max:s.max,step:s.step,defaultValue:c,readOnly:t.fixed,onBlur:f=>p(f.target.valueAsNumber),onKeyDown:f=>{f.key==="Enter"&&p(f.currentTarget.valueAsNumber);}},c)]})]})]})}if(t.kind==="toggle")return jsx("div",{className:"pc-field",children:jsxs("label",{className:"pc-switch",htmlFor:e,children:[jsx("input",{id:e,type:"checkbox",checked:t.value===true,onChange:s=>l(s.target.checked)}),jsx("span",{className:"pc-label",children:t.label})]})});let m=t.options??[];if(t.kind==="material"){let s=m.find(c=>c.code===t.value);return jsxs("fieldset",{className:"pc-field",children:[jsxs("legend",{className:"pc-label",children:[t.label,s?jsx("small",{children:s.label}):null]}),jsx("div",{className:"pc-swatches",children:m.map(c=>jsxs("label",{className:"pc-choice",title:c.label,children:[jsx("input",{type:"radio",name:e,value:c.code,checked:c.code===t.value,onChange:()=>l(c.code)}),jsx("span",{className:"pc-swatch",style:{backgroundColor:c.material?.color,backgroundImage:c.material?.texture?`url("${c.material.texture}")`:void 0},children:jsx("span",{className:"pc-hidden",children:c.label})})]},c.code))})]})}return jsxs("fieldset",{className:"pc-field",children:[jsx("legend",{className:"pc-label",children:t.label}),jsx("div",{className:"pc-choices",children:m.map(s=>jsxs("label",{className:"pc-choice",children:[jsx("input",{type:"radio",name:e,value:s.code,checked:s.code===t.value,onChange:()=>l(s.code)}),jsxs("span",{children:[s.label,jsx("small",{children:De(s,o,a)})]})]},s.code))})]})}function De(n,e,t){return n.priceCents===null?e.optionOnRequest:n.priceCents>0?`${e.surchargePrefix} ${t(n.priceCents)}`:""}function ze(n){let{quote:e,labels:t,money:o}=n,a,l=null;return e?e.state==="open"||e.totalCents===null?a=t.priceOnRequest:e.state==="partial"?(a=`${t.priceFrom} ${o(e.totalCents)}`,l=`${t.priceInPartOnRequest}, ${t.priceIncludingTax}`):(a=o(e.totalCents),l=t.priceIncludingTax):a=t.priceUnavailable,jsxs("div",{className:"pc-price","aria-live":"polite","data-quote-state":e?.state??"none",children:[jsx("span",{className:"pc-price-heading",children:t.priceHeading}),jsx("span",{className:"pc-price-total",children:a}),l?jsx("span",{className:"pc-price-note",children:l}):null]})}function ye(n){return n.visible&&!n.settled}function xe(n){let{geometry:e,slots:t={},labels:o=G,className:a}=n,l=Ve(e),m=Math.max(l.width,l.height)/42,s=[...e.parts].sort((u,p)=>u.at[2]+u.size[2]-(p.at[2]+p.size[2])),c=u=>l.top-u;return jsxs("div",{className:["pc-sketch","pc-scope",a].filter(Boolean).join(" "),children:[jsx(U,{}),jsxs("svg",{role:"img","aria-label":o.sketchTitle,viewBox:`${l.left} 0 ${l.width} ${l.height}`,preserveAspectRatio:"xMidYMid meet",children:[jsx("title",{children:o.sketchTitle}),s.map(u=>jsx(Fe,{part:u,slot:t[u.slot],y:c},u.key)),e.dimensions.map(u=>jsx(Ue,{dimension:u,unit:o.unitMm,fontSize:m,y:c},u.id))]})]})}function Fe(n$1){let{part:e,slot:t,y:o}=n$1,[a,l]=e.size,m=e.at[0],s=o(e.at[1]+l),c=t?n(t):null,u={className:"pc-sketch-part",fill:t?.color??X,fillOpacity:c?.transparent?.35:1,"data-part":e.key};if(e.type==="niche_panel"){let f=b$1(e),v=o(e.at[1]+f.y+f.height),d=`M${m} ${s}h${a}v${l}h${-a}Z`,y=f.width>0&&f.height>0?`M${m+f.x} ${v}h${f.width}v${f.height}h${-f.width}Z`:"";return jsx("path",{...u,d:d+y,fillRule:"evenodd"})}let p=e.type==="stadium_prism"?Math.min(a,l)/2:0;return jsx("rect",{...u,x:m,y:s,width:a,height:l,rx:p,ry:p})}function Ue(n){let{dimension:e,unit:t,fontSize:o,y:a}=n,l=o*.5,m=`${e.label?`${e.label} `:""}${Be(e.length)} ${t}`,s=Math.min(e.from,e.to),c=Math.max(e.from,e.to);if(e.axis==="x"){let f=a(e.at);return jsxs("g",{"data-dimension":e.id,children:[jsx("path",{className:"pc-sketch-line",d:`M${s} ${f}H${c}M${s} ${f-l}v${l*2}M${c} ${f-l}v${l*2}`}),jsx("text",{className:"pc-sketch-text",x:(s+c)/2,y:f-l*1.4,fontSize:o,children:m})]})}let u=e.at,p=a((s+c)/2);return jsxs("g",{"data-dimension":e.id,children:[jsx("path",{className:"pc-sketch-line",d:`M${u} ${a(s)}V${a(c)}M${u-l} ${a(s)}h${l*2}M${u-l} ${a(c)}h${l*2}`}),jsx("text",{className:"pc-sketch-text",x:u-l*1.4,y:p,fontSize:o,transform:`rotate(-90 ${u-l*1.4} ${p})`,children:m})]})}function Be(n){return String(Math.round(n*10)/10)}function Ve(n){let e=1/0,t=-1/0,o=1/0,a=-1/0,l=(s,c,u,p)=>{e=Math.min(e,s),t=Math.max(t,c),o=Math.min(o,u),a=Math.max(a,p);};for(let s of n.parts)l(s.at[0],s.at[0]+s.size[0],s.at[1],s.at[1]+s.size[1]);for(let s of n.dimensions){let c=Math.min(s.from,s.to),u=Math.max(s.from,s.to);s.axis==="x"?l(c,u,s.at,s.at):l(s.at,s.at,c,u);}if(!Number.isFinite(e))return {left:0,top:1e3,width:1e3,height:1e3};let m=Math.max(t-e,a-o)*.08;return {left:e-m,top:a+m,width:t-e+m*2,height:a-o+m*2}}var Q;function Ce(){if(Q!==void 0)return Q;try{let n=document.createElement("canvas");Q=!!(n.getContext("webgl2")??n.getContext("webgl"));}catch{Q=false;}return Q}function ke(n){let{children:e,placeholder:t=null,minHeight:o=280,rootMargin:a="200px",className:l}=n,m=useRef(null),[s,c]=useState(false);return useEffect(()=>{let u=m.current;if(s||!u)return;if(typeof IntersectionObserver>"u"){c(true);return}let p=new IntersectionObserver(f=>{f.some(v=>v.isIntersecting)&&(c(true),p.disconnect());},{rootMargin:a});return p.observe(u),()=>p.disconnect()},[s,a]),jsx("div",{ref:m,className:l,style:s?void 0:{minHeight:o},children:s?e:t})}var Je=lazy(()=>import('./configurator-scene-3ABIR55G.js').then(n=>({default:n.ConfiguratorScene}))),Xe=()=>()=>{},et={values:{}};function te(n){let{structure:e,value:t,tax:o$1,initialSelection:a,onChange:l,locale:m,currency:s,interactive:c=true,className:u}=n,p=useMemo(()=>({...G,...n.labels}),[n.labels]),f=i=>W({structure:e,value:t,selection:i}).configuration.selection,[v,d]=useState(()=>f(a??et)),y=useSyncExternalStore(Xe,Ce,()=>null),x=useMemo(()=>V({structure:e,value:t,selection:v,tax:o$1}),[e,t,v,o$1]),{configuration:k}=x,M=x.ok?x.quote:null,r=useMemo(()=>ge(e.geometry,k.inputs,me(k)),[e.geometry,k]),g=i=>{let b=f(i),h=V({structure:e,value:t,selection:b,tax:o$1});d(b),l?.(b,h.ok?h.quote:null);},w=r.ok?jsx(xe,{geometry:r.geometry,slots:k.slots,labels:p}):jsx("p",{className:"pc-scene-note",children:p.sketchUnavailable});return jsxs("div",{className:["pc-root","pc-scope",u].filter(Boolean).join(" "),children:[jsx(U,{}),jsxs("div",{className:"pc-visual",children:[y&&r.ok?jsx(ke,{className:"pc-scene",placeholder:jsx("p",{className:"pc-scene-note",children:p.sceneLoading}),children:jsx(o,{fallback:null,children:jsx(Suspense,{fallback:jsx("p",{className:"pc-scene-note",children:p.sceneLoading}),children:jsx("div",{role:"region","aria-label":p.sceneLabel,style:{position:"absolute",inset:0},children:jsx(Je,{geometry:r.geometry,slots:k.slots,camera:e.geometry.camera,lighting:e.scene?.lighting,edges:e.scene?.edges,cameraLabels:p,interactive:c})})})})}):null,w]}),jsx(ve,{structure:e,configuration:k,quote:M,onSelectionChange:g,labels:p,locale:m,currency:s,disabled:!c})]})}var tt=e.number().int().min(0).max(1e8),Y=tt.nullable(),Re=e.strictObject({basePriceCents:Y,numbers:e.record(f,e.strictObject({min:e.number().finite(),max:e.number().finite(),default:e.number().finite()})).default({}),choices:e.record(f,e.strictObject({options:e.record(g,e.strictObject({priceCents:Y})),default:g.optional()})).default({}),materials:e.record(f,e.strictObject({offered:e.array(g).max(b.materials),default:g.optional()})).default({}),toggles:e.record(f,e.strictObject({offered:e.boolean(),default:e.boolean()})).default({}),priceGroups:e.record(g,Y).default({}),amounts:e.record(f,Y).default({}),presets:e.array(e.strictObject({code:g,label:e.string().trim().min(1).max(80),productId:e.string().uuid().nullable(),values:e.record(f,e.number().finite())})).max(b.presets).default([])});var q=class extends Error{constructor(t,o){super(o);this.reason=t;this.name="ConfiguratorFieldError";}};function ot(n,e){let t=n.fields[e];if(t==null)throw new q("missing",`The product has no public configurator under "${e}". Make the field public in the object builder.`);if(typeof t=="object"&&"configurator"in t&&!("structure"in t))throw new q("listing",`"${e}" is the listing's flag. Fetch the product itself (getProduct) to draw its configurator.`);let o=t,a=k.safeParse(o.structure),l=Re.safeParse(o.value),m=o.tax;if(!a.success||!l.success||typeof o.structureHash!="string"||typeof o.valueHash!="string"||typeof m?.taxPercentage!="number"||typeof m.pricesIncludeTax!="boolean")throw new q("invalid",`"${e}" does not read as a configurator. Update @solumflow-app/product-configurator.`);return {structure:a.data,value:l.data,tax:{taxPercentage:m.taxPercentage,pricesIncludeTax:m.pricesIncludeTax},structureHash:o.structureHash,valueHash:o.valueHash}}function we(n,e,t,o){return {attribute:n,selection:t,structureHash:e,expected:{state:o.state,totalCents:o.totalCents}}}var at="Aanvragen";function fn(n){let{product:e,attribute:t,onChange:o,onSubmit:a}=n,l=useMemo(()=>ot(e,t),[e,t]),[m,s]=useState(()=>{let u=n.initialSelection??{values:{}},p=V({structure:l.structure,value:l.value,selection:u,tax:l.tax});return {selection:p.configuration.selection,quote:p.ok?p.quote:null}}),c=m.quote?we(t,l.structureHash,m.selection,m.quote):null;return jsxs("div",{className:n.className,children:[jsx(te,{structure:l.structure,value:l.value,tax:l.tax,initialSelection:n.initialSelection,labels:n.labels,locale:n.locale,currency:n.currency,onChange:(u,p)=>{s({selection:u,quote:p}),o?.({selection:u,quote:p,payload:p?we(t,l.structureHash,u,p):null});}}),a?jsx("button",{type:"button",className:"pc-submit",disabled:c===null,onClick:()=>{c&&a(c);},children:n.submitLabel??at}):null]})}export{q as ConfiguratorFieldError,G as DEFAULT_CONFIGURATOR_LABELS,fn as ProductConfigurator,ot as readConfigurator,we as toConfigurationPayload};
58
+ `;function U(){return jsx("style",{href:"product-configurator",precedence:"default",children:Te})}function be(n,e,t){let o=n%100===0;return new Intl.NumberFormat(e,{style:"currency",currency:t,minimumFractionDigits:o?0:2,maximumFractionDigits:o?0:2}).format(n/100)}function he(n,e){let{min:t,max:o,step:r}=e,l=s=>Math.round(s*1e6)/1e6,m=Math.round(n/r)*r;return m<t&&(m=Math.ceil(t/r)*r),m>o&&(m=Math.floor(o/r)*r),l(Math.min(o,Math.max(t,m)))}function ve(n){let{structure:e,configuration:t,quote:o,onSelectionChange:r,locale:l="nl-NL",currency:m="EUR",disabled:s=false,className:u}=n,c={...G,...n.labels},p=useId(),f=useRef({}),v=e.presets&&t.presets.length>0?e.presets.tab:null,d=e.tabs.filter(i=>i.key===v||t.parameters.some(b=>b.tab===i.key&&ye(b))),[y,x]=useState(d[0]?.key),S=d.find(i=>i.key===y)??d[0],M=i=>be(i,l,m),a=(i,b)=>{r?.({...t.selection,values:{...t.selection.values,[i]:b}});},g=i=>{let{preset:b,...h}=t.selection;r?.(i===""?h:{...h,preset:i});},N=(i,b)=>{let h=i.key==="ArrowRight"?1:i.key==="ArrowLeft"?-1:0,I=d.length-1,A=i.key==="Home"?0:i.key==="End"?I:(b+h+d.length)%d.length;if(h===0&&i.key!=="Home"&&i.key!=="End")return;i.preventDefault();let L=d[A];L&&(x(L.key),f.current[L.key]?.focus());};return jsxs("div",{className:["pc-panel","pc-scope",u].filter(Boolean).join(" "),children:[jsx(U,{}),d.length>1?jsx("div",{role:"tablist","aria-label":c.tabsLabel,className:"pc-tabs",children:d.map((i,b)=>jsx("button",{ref:h=>{f.current[i.key]=h;},type:"button",role:"tab",id:`${p}-tab-${i.key}`,"aria-selected":i.key===S?.key,"aria-controls":`${p}-panel-${i.key}`,tabIndex:i.key===S?.key?0:-1,className:"pc-tab",onClick:()=>x(i.key),onKeyDown:h=>N(h,b),children:i.label},i.key))}):null,S?jsxs("fieldset",{role:d.length>1?"tabpanel":void 0,id:`${p}-panel-${S.key}`,"aria-labelledby":d.length>1?`${p}-tab-${S.key}`:void 0,className:"pc-fields",disabled:s,children:[e.presets&&v===S.key?jsxs("div",{className:"pc-field",children:[jsx("label",{className:"pc-label",htmlFor:`${p}-preset`,children:e.presets.label}),jsxs("select",{id:`${p}-preset`,className:"pc-control",value:t.preset?.code??"",onChange:i=>g(i.target.value),children:[e.presets.required?null:jsx("option",{value:"",children:c.presetNone}),t.presets.map(i=>jsx("option",{value:i.code,children:i.label},i.code))]})]}):null,t.parameters.filter(i=>ye(i)&&i.tab===S.key).map(i=>Ce(i)?jsx(ze,{id:`${p}-${i.key}`,parameter:i,labels:c,money:M,onChange:b=>a(i.key,b)},i.key):jsx(Fe,{parameter:i,labels:c,money:M},i.key))]}):null,jsx(Ue,{quote:o,labels:c,money:M})]})}function ze(n){let{id:e,parameter:t,labels:o,money:r,onChange:l}=n;if(t.kind==="number"){let s={min:t.min??0,max:t.max??0,step:t.step??1},u=t.value,c=t.unit==="count"?o.unitCount:o.unitMm,p=f=>{Number.isFinite(f)&&l(he(f,s));};return jsxs("div",{className:"pc-field",children:[jsxs("label",{className:"pc-label",htmlFor:`${e}-range`,children:[t.label,jsxs("small",{children:[u," ",c]})]}),jsxs("div",{className:"pc-number",children:[jsx("input",{id:`${e}-range`,className:"pc-control",type:"range",min:s.min,max:s.max,step:s.step,value:u,disabled:t.fixed,onChange:f=>p(f.target.valueAsNumber)}),jsxs("span",{children:[jsx("label",{className:"pc-hidden",htmlFor:`${e}-number`,children:`${t.label} (${c})`}),jsx("input",{id:`${e}-number`,className:"pc-control",type:"number",inputMode:"numeric",min:s.min,max:s.max,step:s.step,defaultValue:u,readOnly:t.fixed,onBlur:f=>p(f.target.valueAsNumber),onKeyDown:f=>{f.key==="Enter"&&p(f.currentTarget.valueAsNumber);}},u)]})]})]})}if(t.kind==="toggle")return jsx("div",{className:"pc-field",children:jsxs("label",{className:"pc-switch",htmlFor:e,children:[jsx("input",{id:e,type:"checkbox",checked:t.value===true,onChange:s=>l(s.target.checked)}),jsx("span",{className:"pc-label",children:t.label})]})});let m=t.options??[];if(t.kind==="material"){let s=m.find(u=>u.code===t.value);return jsxs("fieldset",{className:"pc-field",children:[jsxs("legend",{className:"pc-label",children:[t.label,s?jsx("small",{children:s.label}):null]}),jsx("div",{className:"pc-swatches",children:m.map(u=>jsxs("label",{className:"pc-choice",title:u.label,children:[jsx("input",{type:"radio",name:e,value:u.code,checked:u.code===t.value,onChange:()=>l(u.code)}),jsx("span",{className:"pc-swatch",style:{backgroundColor:u.material?.color,backgroundImage:u.material?.texture?`url("${u.material.texture}")`:void 0},children:jsx("span",{className:"pc-hidden",children:u.label})})]},u.code))})]})}return jsxs("fieldset",{className:"pc-field",children:[jsx("legend",{className:"pc-label",children:t.label}),jsx("div",{className:"pc-choices",children:m.map(s=>jsxs("label",{className:"pc-choice",children:[jsx("input",{type:"radio",name:e,value:s.code,checked:s.code===t.value,onChange:()=>l(s.code)}),jsxs("span",{children:[s.label,jsx("small",{children:xe(s,o,r)})]})]},s.code))})]})}function Fe(n){let{parameter:e,labels:t,money:o}=n,r=e.options?.[0];return r?jsx("div",{className:"pc-field","data-pinned":e.key,children:jsxs("span",{className:"pc-label",children:[e.label,jsxs("small",{children:[r.label," \xB7 ",xe(r,t,o)]})]})}):null}function xe(n,e,t){return n.priceCents===null?e.optionOnRequest:n.priceCents>0?`${e.surchargePrefix} ${t(n.priceCents)}`:""}function Ue(n){let{quote:e,labels:t,money:o}=n,r,l=null;return e?e.state==="open"||e.totalCents===null?r=t.priceOnRequest:e.state==="partial"?(r=`${t.priceFrom} ${o(e.totalCents)}`,l=`${t.priceInPartOnRequest}, ${t.priceIncludingTax}`):(r=o(e.totalCents),l=t.priceIncludingTax):r=t.priceUnavailable,jsxs("div",{className:"pc-price","aria-live":"polite","data-quote-state":e?.state??"none",children:[jsx("span",{className:"pc-price-heading",children:t.priceHeading}),jsx("span",{className:"pc-price-total",children:r}),l?jsx("span",{className:"pc-price-note",children:l}):null]})}function Ce(n){return n.visible&&!n.settled}function ye(n){if(Ce(n))return true;let e=n.options??[],t=e.length===1?e[0]:void 0;return n.visible&&t!==void 0&&(t.priceCents===null||t.priceCents>0)}function ke(n){let{geometry:e,slots:t={},labels:o=G,className:r}=n,l=qe(e),m=Math.max(l.width,l.height)/42,s=[...e.parts].sort((c,p)=>c.at[2]+c.size[2]-(p.at[2]+p.size[2])),u=c=>l.top-c;return jsxs("div",{className:["pc-sketch","pc-scope",r].filter(Boolean).join(" "),children:[jsx(U,{}),jsxs("svg",{role:"img","aria-label":o.sketchTitle,viewBox:`${l.left} 0 ${l.width} ${l.height}`,preserveAspectRatio:"xMidYMid meet",children:[jsx("title",{children:o.sketchTitle}),s.map(c=>jsx(Be,{part:c,slot:t[c.slot],y:u},c.key)),e.dimensions.map(c=>jsx(Ve,{dimension:c,unit:o.unitMm,fontSize:m,y:u},c.id))]})]})}function Be(n$1){let{part:e,slot:t,y:o}=n$1,[r,l]=e.size,m=e.at[0],s=o(e.at[1]+l),u=t?n(t):null,c={className:"pc-sketch-part",fill:t?.color??X,fillOpacity:u?.transparent?.35:1,"data-part":e.key};if(e.type==="niche_panel"){let f=b$1(e),v=o(e.at[1]+f.y+f.height),d=`M${m} ${s}h${r}v${l}h${-r}Z`,y=f.width>0&&f.height>0?`M${m+f.x} ${v}h${f.width}v${f.height}h${-f.width}Z`:"";return jsx("path",{...c,d:d+y,fillRule:"evenodd"})}let p=e.type==="stadium_prism"?Math.min(r,l)/2:0;return jsx("rect",{...c,x:m,y:s,width:r,height:l,rx:p,ry:p})}function Ve(n){let{dimension:e,unit:t,fontSize:o,y:r}=n,l=o*.5,m=`${e.label?`${e.label} `:""}${Qe(e.length)} ${t}`,s=Math.min(e.from,e.to),u=Math.max(e.from,e.to);if(e.axis==="x"){let f=r(e.at);return jsxs("g",{"data-dimension":e.id,children:[jsx("path",{className:"pc-sketch-line",d:`M${s} ${f}H${u}M${s} ${f-l}v${l*2}M${u} ${f-l}v${l*2}`}),jsx("text",{className:"pc-sketch-text",x:(s+u)/2,y:f-l*1.4,fontSize:o,children:m})]})}let c=e.at,p=r((s+u)/2);return jsxs("g",{"data-dimension":e.id,children:[jsx("path",{className:"pc-sketch-line",d:`M${c} ${r(s)}V${r(u)}M${c-l} ${r(s)}h${l*2}M${c-l} ${r(u)}h${l*2}`}),jsx("text",{className:"pc-sketch-text",x:c-l*1.4,y:p,fontSize:o,transform:`rotate(-90 ${c-l*1.4} ${p})`,children:m})]})}function Qe(n){return String(Math.round(n*10)/10)}function qe(n){let e=1/0,t=-1/0,o=1/0,r=-1/0,l=(s,u,c,p)=>{e=Math.min(e,s),t=Math.max(t,u),o=Math.min(o,c),r=Math.max(r,p);};for(let s of n.parts)l(s.at[0],s.at[0]+s.size[0],s.at[1],s.at[1]+s.size[1]);for(let s of n.dimensions){let u=Math.min(s.from,s.to),c=Math.max(s.from,s.to);s.axis==="x"?l(u,c,s.at,s.at):l(s.at,s.at,u,c);}if(!Number.isFinite(e))return {left:0,top:1e3,width:1e3,height:1e3};let m=Math.max(t-e,r-o)*.08;return {left:e-m,top:r+m,width:t-e+m*2,height:r-o+m*2}}var Q;function Se(){if(Q!==void 0)return Q;try{let n=document.createElement("canvas");Q=!!(n.getContext("webgl2")??n.getContext("webgl"));}catch{Q=false;}return Q}function Re(n){let{children:e,placeholder:t=null,minHeight:o=280,rootMargin:r="200px",className:l}=n,m=useRef(null),[s,u]=useState(false);return useEffect(()=>{let c=m.current;if(s||!c)return;if(typeof IntersectionObserver>"u"){u(true);return}let p=new IntersectionObserver(f=>{f.some(v=>v.isIntersecting)&&(u(true),p.disconnect());},{rootMargin:r});return p.observe(c),()=>p.disconnect()},[s,r]),jsx("div",{ref:m,className:l,style:s?void 0:{minHeight:o},children:s?e:t})}var et=lazy(()=>import('./configurator-scene-3ABIR55G.js').then(n=>({default:n.ConfiguratorScene}))),tt=()=>()=>{},nt={values:{}};function te(n){let{structure:e,value:t,tax:o$1,initialSelection:r,onChange:l,locale:m,currency:s,interactive:u=true,className:c}=n,p=useMemo(()=>({...G,...n.labels}),[n.labels]),f=i=>W({structure:e,value:t,selection:i}).configuration.selection,[v,d]=useState(()=>f(r??nt)),y=useSyncExternalStore(tt,Se,()=>null),x=useMemo(()=>V({structure:e,value:t,selection:v,tax:o$1}),[e,t,v,o$1]),{configuration:S}=x,M=x.ok?x.quote:null,a=useMemo(()=>ge(e.geometry,S.inputs,me(S)),[e.geometry,S]),g=i=>{let b=f(i),h=V({structure:e,value:t,selection:b,tax:o$1});d(b),l?.(b,h.ok?h.quote:null);},N=a.ok?jsx(ke,{geometry:a.geometry,slots:S.slots,labels:p}):jsx("p",{className:"pc-scene-note",children:p.sketchUnavailable});return jsxs("div",{className:["pc-root","pc-scope",c].filter(Boolean).join(" "),children:[jsx(U,{}),jsxs("div",{className:"pc-visual",children:[y&&a.ok?jsx(Re,{className:"pc-scene",placeholder:jsx("p",{className:"pc-scene-note",children:p.sceneLoading}),children:jsx(o,{fallback:null,children:jsx(Suspense,{fallback:jsx("p",{className:"pc-scene-note",children:p.sceneLoading}),children:jsx("div",{role:"region","aria-label":p.sceneLabel,style:{position:"absolute",inset:0},children:jsx(et,{geometry:a.geometry,slots:S.slots,camera:e.geometry.camera,lighting:e.scene?.lighting,edges:e.scene?.edges,cameraLabels:p,interactive:u})})})})}):null,N]}),jsx(ve,{structure:e,configuration:S,quote:M,onSelectionChange:g,labels:p,locale:m,currency:s,disabled:!u})]})}var rt=e.number().int().min(0).max(1e8),Y=rt.nullable(),Ne=e.strictObject({basePriceCents:Y,numbers:e.record(f,e.strictObject({min:e.number().finite(),max:e.number().finite(),default:e.number().finite()})).default({}),choices:e.record(f,e.strictObject({options:e.record(g,e.strictObject({priceCents:Y})),default:g.optional()})).default({}),materials:e.record(f,e.strictObject({offered:e.array(g).max(b.materials),default:g.optional()})).default({}),toggles:e.record(f,e.strictObject({offered:e.boolean(),default:e.boolean()})).default({}),priceGroups:e.record(g,Y).default({}),amounts:e.record(f,Y).default({}),presets:e.array(e.strictObject({code:g,label:e.string().trim().min(1).max(80),productId:e.string().uuid().nullable(),values:e.record(f,e.number().finite())})).max(b.presets).default([])});var q=class extends Error{constructor(t,o){super(o);this.reason=t;this.name="ConfiguratorFieldError";}};function it(n,e){let t=n.fields[e];if(t==null)throw new q("missing",`The product has no public configurator under "${e}". Make the field public in the object builder.`);if(typeof t=="object"&&"configurator"in t&&!("structure"in t))throw new q("listing",`"${e}" is the listing's flag. Fetch the product itself (getProduct) to draw its configurator.`);let o=t,r=k.safeParse(o.structure),l=Ne.safeParse(o.value),m=o.tax;if(!r.success||!l.success||typeof o.structureHash!="string"||typeof o.valueHash!="string"||typeof m?.taxPercentage!="number"||typeof m.pricesIncludeTax!="boolean")throw new q("invalid",`"${e}" does not read as a configurator. Update @solumflow-app/product-configurator.`);return {structure:r.data,value:l.data,tax:{taxPercentage:m.taxPercentage,pricesIncludeTax:m.pricesIncludeTax},structureHash:o.structureHash,valueHash:o.valueHash}}function Pe(n,e,t,o){return {attribute:n,selection:t,structureHash:e,expected:{state:o.state,totalCents:o.totalCents}}}var st="Aanvragen";function bn(n){let{product:e,attribute:t,onChange:o,onSubmit:r}=n,l=useMemo(()=>it(e,t),[e,t]),[m,s]=useState(()=>{let c=n.initialSelection??{values:{}},p=V({structure:l.structure,value:l.value,selection:c,tax:l.tax});return {selection:p.configuration.selection,quote:p.ok?p.quote:null}}),u=m.quote?Pe(t,l.structureHash,m.selection,m.quote):null;return jsxs("div",{className:n.className,children:[jsx(te,{structure:l.structure,value:l.value,tax:l.tax,initialSelection:n.initialSelection,labels:n.labels,locale:n.locale,currency:n.currency,onChange:(c,p)=>{s({selection:c,quote:p}),o?.({selection:c,quote:p,payload:p?Pe(t,l.structureHash,c,p):null});}}),r?jsx("button",{type:"button",className:"pc-submit",disabled:u===null,onClick:()=>{u&&r(u);},children:n.submitLabel??st}):null]})}export{q as ConfiguratorFieldError,G as DEFAULT_CONFIGURATOR_LABELS,bn as ProductConfigurator,it as readConfigurator,Pe as toConfigurationPayload};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@solumflow-app/product-configurator",
3
- "version": "0.3.0",
3
+ "version": "0.3.1",
4
4
  "description": "Show a product's 3D configurator on your own website and send what a visitor put together back as a request or an order.",
5
5
  "license": "MIT",
6
6
  "files": [