mirror of
https://github.com/Matysh/houseplan-card
synced 2026-09-29 03:09:36 +00:00
43 lines
42 KiB
JavaScript
43 lines
42 KiB
JavaScript
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="8f3777a9cb13e5ce966a6d4abe6321583191da25876aadb60cccf8ed094c1c49";import{dF as e,dG as t,b5 as n,dH as o,dI as i,dJ as a,k as r,dK as s,dL as l,dM as c,dN as d,a4 as u,dO as f,aj as h,bY as p,bX as m,dP as g,ak as w,P as y,dQ as M,cV as b,dR as x,A as v,w as S,dS as $,dT as k,dU as z,dV as P,dW as C}from"./houseplan-card-BwLd7B5O.js";const I=e=>`${Number(e[0].toFixed(4))} ${Number(e[1].toFixed(4))}`;function T(e){let t=0;for(let n=0;n<e.length;n++){const o=e[n],i=e[(n+1)%e.length];t+=o[0]*i[1]-i[0]*o[1]}return t/2}function j(e,t){const n=function(e){const t=(Array.isArray(e)?e:[]).filter(e=>Array.isArray(e)&&Number.isFinite(e[0])&&Number.isFinite(e[1])).map(e=>[Number(e[0]),Number(e[1])]),n=t[t.length-1];return t.length>1&&t[0][0]===n[0]&&t[0][1]===n[1]&&t.pop(),t}(e);if(n.length<3)return[];const o=!t;return T(n)>0===o?n:[...n].reverse()}function O(e,t,o){return e.length?`M ${e.map(e=>I(n(e,o,t))).join(" L ")} Z`:""}function N(e,t,n){const o=t[1]-e[1],i=-(t[0]-e[0]),a=n.rotDeg*Math.PI/180;return o*Math.sin(a)+i*Math.cos(a)}function B(t,o,i=e){if(!Number.isFinite(o)||o<0)throw new Error("invalid floor edge height");const a=(t||[]).map(e=>(e||[]).map((e,t)=>function(e,t){const n=j(e,t);if(!n.length)return n;let o=0;for(let e=1;e<n.length;e++)(n[e][0]<n[o][0]||n[e][0]===n[o][0]&&n[e][1]<n[o][1])&&(o=e);return[...n.slice(o),...n.slice(0,o)]}(e,t>0)).filter(e=>e.length>=3&&Math.abs(T(e))>=1e-9)).filter(e=>e.length&&T(e[0])>0);a.sort((e,t)=>{const n=e[0][0],o=t[0][0];return n[0]-o[0]||n[1]-o[1]||Math.abs(T(t[0]))-Math.abs(T(e[0]))});const r=[],s=[];let l=0;for(let e=0;e<a.length;e++){const t=a[e];for(const e of t)r.push(O(e,i,0));const c=t[0];l+=c.length;for(let t=0;t<c.length;t++){const a=c[t],r=c[(t+1)%c.length];if(N(a,r,i)<=1e-9)continue;const l=n(a,0,i),d=n(r,0,i),u=n(r,-o,i),f=n(a,-o,i);s.push({d:`M ${I(l)} L ${I(d)} L ${I(u)} L ${I(f)} Z`,depth:Math.max(f[1],u[1]),component:e,edge:t,planEdge:[a,r]})}}return s.sort((e,t)=>e.depth-t.depth||e.component-t.component||e.edge-t.edge),{footprintPath:r.join(" "),sides:s,componentCount:a.length,edgeCount:l}}function H(e,t){return e^=Math.round(64*(Number.isFinite(t)?t:0)),Math.imul(e,16777619)>>>0}const R=Object.freeze({revision:3,leafThicknessRatio:.04,frameThicknessRatio:.05,doorTurnDeg:50,windowTurnDeg:65,gateTurnDeg:10,gateTopRatio:.88,windowFrameBottomRatio:.38,windowFrameTopRatio:1,windowSashBottomRatio:.4,windowSashTopRatio:.98,windowGlassBottomRatio:.45,windowGlassTopRatio:.93,doorTopRatio:.92});R.leafThicknessRatio,R.frameThicknessRatio;const F=e=>e.every(Number.isFinite);function A(e,t){return Object.freeze([Object.is(e,-0)?0:e,Object.is(t,-0)?0:t])}function V(e,t){return[e[0]+t[0],e[1]+t[1]]}function L(e,t){return[e[0]-t[0],e[1]-t[1]]}function G(e,t){return[e[0]*t,e[1]*t]}function D(e,t,n,o){const i=e[0]*n,a=e[1]*o,r=t*Math.PI/180;return[i*Math.cos(r)-a*Math.sin(r),i*Math.sin(r)+a*Math.cos(r)]}function W(e,t,n,i,a,r,s){const l=e.flipH?-1:1,c="gate"===e.type?1:e.flipV?-1:1,d="door"===e.type||"gate"===e.type?e.face:o(e.type,e.flipV,e.angle,e.face);return{leaf:t,hinge:V([e.x+d.ox,e.y+d.oy],D(n,e.angle,l,c)),closedVector:D(i,e.angle,l,c),quarterVector:D([-i[1],i[0]],e.angle,l,c),turnDeg:a,bottom:r,top:s}}const E=e=>`${Number(e[0].toFixed(4))} ${Number(e[1].toFixed(4))}`;function q(e,t,o,i,a={}){const r=o.map(e=>n(e.point,e.z,i)),s=i.rotDeg*Math.PI/180,l=i.tiltDeg*Math.PI/180,c=o.reduce((e,t)=>e+(t.point[0]*Math.sin(s)+t.point[1]*Math.cos(s))*Math.sin(l)+t.z*Math.cos(l),0)/o.length;return Object.freeze({kind:e,material:t,d:`M ${r.map(E).join(" L ")} Z`,cameraDepth:c,depth:Math.max(...r.map(e=>e[1])),...a})}function _(e,t,n,o,i,a,r,s={}){return q(e,t,[{point:n,z:i},{point:o,z:i},{point:o,z:a},{point:n,z:a}],r,s)}function U(t,o,i=e){const a=Math.max(0,Math.min(1,Number.isFinite(o)?o:0));return t.leaves.map(e=>{const o=function(e,t){const n=e.turnDeg*t*Math.PI/180;return[e.hinge[0]+e.closedVector[0]*Math.cos(n)+e.quarterVector[0]*Math.sin(n),e.hinge[1]+e.closedVector[1]*Math.cos(n)+e.quarterVector[1]*Math.sin(n)]}(e,a),r=n(e.hinge,e.bottom,i),s=n(o,e.bottom,i),l=n(o,e.top,i),c=n(e.hinge,e.top,i),d="window"===t.type?"light-window":"matte-leaf",u="window"===t.type?function(e,t,n,o){const i=e.windowProfile;if(!i)throw new Error("missing isometric window profile");const a=L(n,t.hinge),r=Math.hypot(a[0],a[1]);if(!(r>1e-9))return Object.freeze([]);const s=A(a[0]/r,a[1]/r),l=Math.min(i.member,r/4,(i.sashTop-i.sashBottom)/4),c=V(t.hinge,G(s,l)),d=L(n,G(s,l)),u=Math.min(.35*e.frameThickness,.02*r),f=A(-s[1]*u/2,s[0]*u/2),h=V(c,f),p=V(d,f),m=L(c,f),g=L(d,f),w=[_("window-sash-side","light-frame",t.hinge,c,i.sashBottom,i.sashTop,o,{edge:"hinge"}),_("window-sash-side","light-frame",d,n,i.sashBottom,i.sashTop,o,{edge:"tip"}),_("window-sash-bottom","light-frame",t.hinge,n,i.sashBottom,i.sashBottom+l,o),_("window-sash-top","light-frame",t.hinge,n,i.sashTop-l,i.sashTop,o),_("window-glass","glass-side",h,p,i.glassBottom,i.glassTop,o),_("window-glass","glass-side",g,m,i.glassBottom,i.glassTop,o),q("window-glass-top","glass-top",[{point:h,z:i.glassTop},{point:p,z:i.glassTop},{point:g,z:i.glassTop},{point:m,z:i.glassTop}],o)];return Object.freeze(w.sort((e,t)=>e.depth-t.depth||e.kind.localeCompare(t.kind)||String(e.edge||"").localeCompare(String(t.edge||""))))}(t,e,o,i):function(e,t,n,o){const i=L(t,e.hinge),a=Math.hypot(i[0],i[1]);if(!(a>1e-9&&n>0))return Object.freeze([]);const r=A(-i[1]*n/(2*a),i[0]*n/(2*a)),s=V(e.hinge,r),l=V(t,r),c=L(e.hinge,r),d=L(t,r),u=[_("leaf-back","matte-leaf",d,c,e.bottom,e.top,o),_("leaf-front","matte-leaf",s,l,e.bottom,e.top,o),_("leaf-edge","matte-leaf",c,s,e.bottom,e.top,o,{edge:"hinge"}),_("leaf-edge","matte-leaf",l,d,e.bottom,e.top,o,{edge:"tip"}),q("leaf-top","matte-leaf",[{point:s,z:e.top},{point:c,z:e.top},{point:d,z:e.top},{point:l,z:e.top}],o)];return Object.freeze(u.sort((e,t)=>e.depth-t.depth||e.kind.localeCompare(t.kind)||String(e.edge||"").localeCompare(String(t.edge||""))))}(e,o,t.leafThickness,i);return Object.freeze({id:t.id,sourceIndex:t.sourceIndex,type:t.type,leaf:e.leaf,d:`M ${E(r)} L ${E(s)} L ${E(l)} L ${E(c)} Z`,shadowD:`M ${E(n(e.hinge,0,i))} L ${E(n(o,0,i))}`,depth:Math.max(r[1],s[1]),material:d,thickness:"window"===t.type?0:t.leafThickness,surfaces:u})})}const K=1e-9,Z=(e,t)=>`${e}\0${t}`,J=e=>e.length>=2&&Number.isFinite(e[0])&&Number.isFinite(e[1]);function Q(e){let t=0;for(let n=0;n<e.length;n++){const o=e[n],i=e[(n+1)%e.length];t+=o[0]*i[1]-i[0]*o[1]}return t/2}function X(e){return e.length>=3&&e.every(J)&&Math.abs(Q(e))>K}function Y(e,t,n){const o=n[0]-t[0],i=n[1]-t[1],a=o*o+i*i,r=a?Math.max(0,Math.min(1,((e[0]-t[0])*o+(e[1]-t[1])*i)/a)):0;return Math.hypot(e[0]-t[0]-r*o,e[1]-t[1]-r*i)}function ee(e,t,n=1e-7){for(let o=0;o<t.length;o++)if(Y(e,t[o],t[(o+1)%t.length])<=n)return!0;return!1}function te(e,t){let n=!1;for(let o=0,i=t.length-1;o<t.length;i=o++){const a=t[o],r=t[i];a[1]>e[1]!=r[1]>e[1]&&e[0]<(r[0]-a[0])*(e[1]-a[1])/(r[1]-a[1])+a[0]&&(n=!n)}return n}function ne(e){return Math.max(0,Math.abs(Q(e.outer))-(e.holes||[]).reduce((e,t)=>e+Math.abs(Q(t)),0))}function oe(e){return!!e.id&&X(e.outer)&&(e.holes||[]).every(X)&&ne(e)>K}function ie(e,t){if(!oe(t)||ee(e,t.outer)||!te(e,t.outer))return!1;for(const n of t.holes||[])if(ee(e,n)||te(e,n))return!1;return!0}function ae(e){if(!oe(e))return null;if(e.safePoint&&ie(e.safePoint,e))return[e.safePoint[0],e.safePoint[1]];const t=e.outer.map(e=>e[0]),n=e.outer.map(e=>e[1]),o=Math.min(...t),i=Math.max(...t),a=Math.min(...n),r=Math.max(...n),s=[[(o+i)/2,(a+r)/2],[t.reduce((e,t)=>e+t,0)/t.length,n.reduce((e,t)=>e+t,0)/n.length]];for(let t=0;t<e.outer.length;t++){const n=e.outer[(t+e.outer.length-1)%e.outer.length],o=e.outer[t],i=e.outer[(t+1)%e.outer.length];s.push([(n[0]+o[0]+i[0])/3,(n[1]+o[1]+i[1])/3])}let l=null,c=-1/0;const d=t=>{if(!ie(t,e))return;const n=function(e,t){let n=1/0;for(const o of[t.outer,...t.holes||[]])for(let t=0;t<o.length;t++)n=Math.min(n,Y(e,o[t],o[(t+1)%o.length]));return n}(t,e);n>c+K&&(l=t,c=n)};s.forEach(d);for(let e=1;e<16;e++)for(let t=1;t<16;t++)d([o+(i-o)*e/16,a+(r-a)*t/16]);return l}function re(e){if(!J(e.floorAnchor))return null;const t=e.roomsValidated?e.rooms:e.rooms.filter(oe),n=e.preferredRoomId&&t.find(t=>t.id===e.preferredRoomId)||null;let o=null;return"device"===e.kind?(n&&ie(e.floorAnchor,n)&&(o=n),o||(o=t.filter(t=>ie(e.floorAnchor,t)).sort((e,t)=>ne(e)-ne(t)||((e,t)=>e<t?-1:e>t?1:0)(e.id,t.id))[0]||null)):o=n,o?{id:o.id,area:ne(o),safePoint:e.roomsValidated&&o.safePoint?[o.safePoint[0],o.safePoint[1]]:ae(o)}:null}function se(t,o,i,a=e,r=[0,0]){if(!J(t)||!J(o)||o[0]<0||o[1]<0||!Number.isFinite(i)||!J(r))throw new Error("invalid isometric overlay footprint");return[[t[0]-o[0],t[1]-o[1]],[t[0]+o[0],t[1]-o[1]],[t[0]+o[0],t[1]+o[1]],[t[0]-o[0],t[1]+o[1]]].map(e=>{const t=n(e,i,a);return[t[0]+r[0],t[1]+r[1]]})}function le(e,t,n){return(t[0]-e[0])*(n[1]-e[1])-(t[1]-e[1])*(n[0]-e[0])}function ce(e,t,n,o){const i=le(e,t,n),a=le(e,t,o),r=le(n,o,e),s=le(n,o,t);return(i>K&&a<-K||i<-K&&a>K)&&(r>K&&s<-K||r<-K&&s>K)||(Math.abs(i)<=K&&Y(n,e,t)<=K||Math.abs(a)<=K&&Y(o,e,t)<=K||Math.abs(r)<=K&&Y(e,n,o)<=K||Math.abs(s)<=K&&Y(t,n,o)<=K)}function de(e,t,n,o){return ce(e,t,n,o)?0:Math.min(Y(e,n,o),Y(t,n,o),Y(n,e,t),Y(o,e,t))}const ue=new WeakMap;function fe(e){if(!e.length)return null;let t=1/0,n=1/0,o=-1/0,i=-1/0;for(const a of e){if(!J(a))return null;t=Math.min(t,a[0]),n=Math.min(n,a[1]),o=Math.max(o,a[0]),i=Math.max(i,a[1])}return[t,n,o,i]}function he(e,t){if(!t)return fe(e.outer);if(ue.has(e))return ue.get(e)??null;const n=fe(e.outer);return ue.set(e,n),n}function pe(e,t,n){return e[0]<=t[2]+n&&e[2]>=t[0]-n&&e[1]<=t[3]+n&&e[3]>=t[1]-n}function me(e,t,n,o){return Math.min(t[0],n[0])<=e[2]+o&&Math.max(t[0],n[0])>=e[0]-o&&Math.min(t[1],n[1])<=e[3]+o&&Math.max(t[1],n[1])>=e[1]-o}function ge(e,t,n,o,i){const a=he(n,i);if(!a||!pe(t,a,o))return!1;if(e.some(e=>function(e,t){return!!te(e,t.outer)&&!(t.holes||[]).some(t=>te(e,t))}(e,n)))return!0;if(n.outer.some(n=>n[0]>=t[0]&&n[0]<=t[2]&&n[1]>=t[1]&&n[1]<=t[3]&&te(n,e)))return!0;for(const i of[n.outer,...n.holes||[]])for(let n=0;n<e.length;n++){const a=(n+1)%e.length;for(let r=0;r<i.length;r++){const s=(r+1)%i.length;if(me(t,i[r],i[s],o)&&de(e[n],e[a],i[r],i[s])<=o+K)return!0}}return!1}function we(e){return X(e.outer)&&(e.holes||[]).every(X)}function ye(e,t,n){if(!ie(e,n)||!ie(t,n))return!1;for(const o of[n.outer,...n.holes||[]])for(let n=0;n<o.length;n++)if(ce(e,t,o[n],o[(n+1)%o.length]))return!1;return!0}function Me(e,t,n){const o=t[0]-e[0],i=t[1]-e[1];return{from:e,to:t,visible:n,length:Math.hypot(o,i),angleDeg:180*Math.atan2(i,o)/Math.PI}}const be=Object.freeze((()=>{const e=[],t=Math.floor(48);for(let n=-t;n<=t;n++)for(let o=-t;o<=t;o++)o*o+n*n>t*t||e.push(Object.freeze([1*o,1*n]));return e.sort((e,t)=>e[0]*e[0]+e[1]*e[1]-(t[0]*t[0]+t[1]*t[1])||e[1]-t[1]||e[0]-t[0]),e})());function xe(e,t){return[t[0]-e.screenHalfSize[0],t[1]-e.screenHalfSize[1],t[0]+e.screenHalfSize[0],t[1]+e.screenHalfSize[1]]}function ve(e,t){return[e[0]-t,e[1]-t,e[2]+t,e[3]+t]}function Se(e,t,n){const o=Math.min(e[2],t[2])-Math.max(e[0],t[0])+n,i=Math.min(e[3],t[3])-Math.max(e[1],t[1])+n;return o>K&&i>K?o*i:0}function $e(e,t,n){const o=n.tiltDeg*Math.PI/180;return a([e[0],e[1]+t*n.zScale*Math.sin(o)],n)}function ke(e,t,n,o){const i=[t[0]*n,t[1]*n];if(!o&&Math.abs(i[0]-e.nudgeScene[0])<=K&&Math.abs(i[1]-e.nudgeScene[1])<=K)return e;const a=[i[0]-e.nudgeScene[0],i[1]-e.nudgeScene[1]],r=[e.raisedScene[0]+i[0],e.raisedScene[1]+i[1]],s=Math.hypot(t[0],t[1]);return{...e,visualScene:r,footprint:e.footprint.map(e=>[e[0]+a[0],e[1]+a[1]]),nudgeScene:i,nudgeCss:t,nudgeDistanceCss:s,nudged:s>K,capped:e.capped||o,status:o?"degraded":e.status,reason:o?"overlay-collision":e.reason,tether:Me(e.floorScene,r,!1)}}const ze="8f3777a9cb13e5ce966a6d4abe6321583191da25876aadb60cccf8ed094c1c49",Pe=e=>"wall-side"===e.layer?0:"wall-top"===e.layer?1:2,Ce=e=>{if("wall-side"===e.layer)return`${e.face.polygon}:${e.face.ring}:${e.face.edge}`;if("wall-top"===e.layer)return String(e.face.component);const t=e.surface;return`${t.sourceIndex}:${t.leaf??-1}:${t.kind}:${t.jamb??-1}:${t.edge??""}:${t.id}:${t.material}`};function Ie(e,t){const n=[...e.sides.map(e=>({layer:"wall-side",depth:e.depth,face:e})),...e.topFaces.map(e=>({layer:"wall-top",depth:e.depth,face:e})),...t.map(e=>({layer:"opening",depth:e.depth,surface:e}))];n.sort((e,t)=>e.depth-t.depth||Pe(e)-Pe(t)||Ce(e).localeCompare(Ce(t)));const o=new Map;for(const e of n){if("opening"!==e.layer)continue;const t=`${e.surface.type}\0${e.surface.id}`,n=o.get(t)||[];n.push(e),o.set(t,n)}for(const e of o.values())e.sort((e,t)=>{const n="opening"===e.layer?e.surface:null,o="opening"===t.layer?t.surface:null;return(n?.cameraDepth??n?.depth??0)-(o?.cameraDepth??o?.depth??0)||Ce(e).localeCompare(Ce(t))});const i=new Map;return Object.freeze(n.map(e=>{if("opening"!==e.layer)return e;const t=`${e.surface.type}\0${e.surface.id}`,n=i.get(t)||0;return i.set(t,n+1),o.get(t)?.[n]||e}))}const Te=Object.freeze({textLatinAdvance:.72,textWideAsciiAdvance:1,textWideAdvance:1.1,textSpaceAdvance:.4,textWidthSafety:1.08,deviceShellInset:.134375,deviceShellGap:.1,deviceSectionGap:.08,deviceBadgeMinWidth:.7875,deviceBadgeHeight:.7875,deviceBadgeInlinePadding:.28,deviceValueInlinePadding:.32,deviceAuxiliaryExtent:.7,deviceLqiFontSize:.38,deviceLqiTop:.734375,deviceLqiBelowBottomBadgeTop:1.571875,devicePadding:.08,roomNameLineHeight:1.25,roomAreaLinkWidth:1.1,roomMetricsTopGap:.15,roomMetricFontSize:.75,roomMetricLineHeight:1.25,roomMetricIconWidth:1.05,roomMetricInnerGap:.12,roomMetricRowGap:.55,roomMetricMinWidth:11,roomPadding:.4,openingLockHalfSize:.62,roomMetricTextCharacters:Object.freeze({temperature:10,humidity:8,lqi:6,light:24})});function je(e){return[...String(e)].reduce((e,t)=>/\s/.test(t)?e+Te.textSpaceAdvance:/[MW@#%&]/.test(t)?e+Te.textWideAsciiAdvance:e+(t.codePointAt(0)>255?Te.textWideAdvance:Te.textLatinAdvance),0)*Te.textWidthSafety}function Oe(e,t){return je(e)*P(t||e)}function Ne(e,t){return[Math.max(Math.abs(e.left),Math.abs(e.right))+t,Math.max(Math.abs(e.top),Math.abs(e.bottom))+t]}function Be(e){if("opening-lock"===e.kind){const t=(Number.isFinite(e.size)&&e.size>0?e.size:0)*Te.openingLockHalfSize;return[t,t]}if("room-label"===e.kind){const t=Number.isFinite(e.font)&&e.font>0?e.font:0,n=b(e.room.settings?.name_scale),o=b(e.room.settings?.label_scale),i=(je(e.room.name||"")+(e.room.area?Te.roomAreaLinkWidth:0))*n,a=Te.roomNameLineHeight*n,r=[e.display.labelTemp?Te.roomMetricTextCharacters.temperature:0,e.display.labelHum?Te.roomMetricTextCharacters.humidity:0,e.display.labelLqi&&e.room.area?Te.roomMetricTextCharacters.lqi:0,e.display.labelLight?Te.roomMetricTextCharacters.light:0].filter(e=>e>0),s=Te.roomMetricFontSize*o,l=r.length?Math.max(Te.roomMetricMinWidth,r.reduce((e,t)=>e+Te.roomMetricIconWidth+Te.roomMetricInnerGap+t*Te.textLatinAdvance*Te.textWidthSafety,0)+(r.length-1)*Te.roomMetricRowGap)*s:0,c=r.length?s*Te.roomMetricLineHeight:0,d=Ne({left:-Math.max(i,l)/2,right:Math.max(i,l)/2,top:-a/2,bottom:r.length?a/2+Te.roomMetricsTopGap+c:a/2},Te.roomPadding);return[d[0]*t,d[1]*t]}const t=Number.isFinite(e.core)&&e.core>0?e.core:0,n=e.presentation,o=null==n.valueText?1:Math.max(1,Oe(n.valueText,n.valueFullText||n.valueText)+Te.deviceValueInlinePadding),i=[];n.valueBadge&&i.push(Math.max(Te.deviceBadgeMinWidth,Oe(n.valueBadge.text,n.valueBadge.fullText||n.valueBadge.text)+Te.deviceBadgeInlinePadding));for(const e of x(n)){const t=e.text+e.suffix;i.push(Math.max(Te.deviceBadgeMinWidth,Oe(t,t)+Te.deviceBadgeInlinePadding))}const a=n.valueBadge?.position||"right";let r;if(!i.length||"left"!==a&&"right"!==a)if(i.length){const e=i.reduce((e,t)=>e+t,0)+(i.length-1)*Te.deviceSectionGap,t=Math.max(o,e),n=1+Te.deviceShellGap+Te.deviceBadgeHeight;r="bottom"===a?{left:-t/2-Te.deviceShellInset,right:t/2+Te.deviceShellInset,top:-.5-Te.deviceShellInset,bottom:-.5+n+Te.deviceShellInset}:{left:-t/2-Te.deviceShellInset,right:t/2+Te.deviceShellInset,top:.5-n-Te.deviceShellInset,bottom:.5+Te.deviceShellInset}}else r={left:-.5-Te.deviceShellInset,right:-.5+o+Te.deviceShellInset,top:-.5-Te.deviceShellInset,bottom:.5+Te.deviceShellInset};else{const e=Math.max(...i),t=i.length*Te.deviceBadgeHeight+(i.length-1)*Te.deviceSectionGap,n=o+Te.deviceShellGap+e,s=Math.max(1,t);r="right"===a?{left:-.5-Te.deviceShellInset,right:-.5+n+Te.deviceShellInset,top:-s/2-Te.deviceShellInset,bottom:s/2+Te.deviceShellInset}:{left:.5-n-Te.deviceShellInset,right:.5+Te.deviceShellInset,top:-s/2-Te.deviceShellInset,bottom:s/2+Te.deviceShellInset}}const s=Te.deviceAuxiliaryExtent;if(r.left=Math.min(r.left,-s),r.right=Math.max(r.right,s),r.top=Math.min(r.top,-s),r.bottom=Math.max(r.bottom,s),n.pulse.animated){const e=Math.max(1,n.pulse.diameterScale)/2;r.left=Math.min(r.left,-e),r.right=Math.max(r.right,e),r.top=Math.min(r.top,-e),r.bottom=Math.max(r.bottom,e)}if(null!=n.lqiText){const e="bottom"===n.valueBadge?.position?Te.deviceLqiBelowBottomBadgeTop:Te.deviceLqiTop,t=je(n.lqiText)*Te.deviceLqiFontSize/2;r.left=Math.min(r.left,-t),r.right=Math.max(r.right,t),r.bottom=Math.max(r.bottom,e+Te.deviceLqiFontSize)}const l=Ne(r,Te.devicePadding);return[l[0]*t,l[1]*t]}function He(e,t){return e.flatMap((e,n)=>e.orphanReason?[]:[{id:String(e.id||n),sourceIndex:n,type:e.type,x:e.rx,y:e.ry,angle:Number(e.angle)||0,length:e.rlen>0?e.rlen:.9*t,flipH:!!e.flip_h,flipV:!!e.flip_v}])}function Re(e){return{id:e.id,x:e.x,y:e.y,w:e.w,h:e.h,poly:e.poly,wall_ids:e.wall_ids}}function Fe(e,t){const n=e?.partitionHost;if(!n)return null;const o="gate"===t.type?!t.flipV:t.flipV;return{sourceIndex:t.sourceIndex,hostId:n.host.id,t:n.t,depth:n.depth,face:m(n,o)}}function Ae(n,o=R){const i=He(n.openings,n.coordinateScale),a=i.map(e=>Fe(n.openings[e.sourceIndex],e)),s=r(t,n.cellCm),m=r(l,n.cellCm),g=r(c,n.cellCm);return{key:`${n.space.id}|${function(e){let t=2166136261;const n=e=>{if("number"!=typeof e)if("string"!=typeof e)if("boolean"!=typeof e)if(Array.isArray(e)){t=H(t,e.length);for(const t of e)n(t)}else{if(e&&"object"==typeof e){const t=e;for(const e of Object.keys(t).sort())n(e),n(t[e]);return}t=H(t,-1)}else t=H(t,e?1:0);else for(const n of e)t=H(t,n.codePointAt(0)||0);else t=H(t,e)};return n(e),t.toString(36)}({rooms:n.space.rooms.map(Re),walls:n.walls,openCuts:n.openCuts,openings:i,openingHosts:a,openingGeometryPolicy:o,partitions:n.space.partitions,columns:n.space.wall_columns,cellCm:n.cellCm,gridPitch:n.gridPitch,wallKeyPitch:n.wallKeyPitch,camera:e,wallHeight:s,raisedHeight:g,floorEdgeHeight:m,algorithm:5})}`,build:()=>{n.onBuild();const r=d(n.space,n.cellCm,n.gridPitch,2e-4*n.gridPitch,n.partitionCuts()).all,l=n.roomOpenings(),c=n.walls.length||r.length?u(n.space.rooms,n.walls,n.openCuts,l,n.wallKeyPitch,n.cellCm,n.gridPitch,n.coordinateScale,r):null;if(c&&("failed-core"===c.status||"not-applicable"===c.status))throw new Error("wall boolean geometry failed");const m=c?.paperGeom??f(n.space.rooms,n.walls,n.openCuts,n.wallKeyPitch,n.cellCm,n.gridPitch,n.coordinateScale);if(!m)throw new Error("floor boolean geometry failed");const g=c?.openingIndex||h(n.space.rooms,n.walls,n.openCuts,n.wallKeyPitch,n.cellCm,n.gridPitch,n.coordinateScale),w=i.map((e,i)=>{const r=a[i],l="gate"===e.type?!e.flipV:e.flipV,c=r?r.face:n.walls.length||"gate"===e.type?p(g,{x:e.x,y:e.y,angle:e.angle,length:e.length,flip_v:l}):{ox:0,oy:0,cm:0,side:-1};return function(e,n=t,o=R){const i=e.face.cm??0;if(!F([e.x,e.y,e.angle,e.length,e.face.ox,e.face.oy,i,n])||!(e.length>0)||!(n>0)||-1!==e.face.side&&1!==e.face.side||i<0)throw new Error("invalid isometric opening input");const a=e.length/2,r=e.angle*Math.PI/180,s=A(Math.cos(r),Math.sin(r)),l=A(-Math.sin(r),Math.cos(r)),c=A(e.x,e.y),d=A(e.x-s[0]*a,e.y-s[1]*a),u=A(e.x+s[0]*a,e.y+s[1]*a),f=A(e.face.ox,e.face.oy),h=A(d[0]+f[0],d[1]+f[1]),p=A(u[0]+f[0],u[1]+f[1]),m=A(d[0]-f[0],d[1]-f[1]),g=A(u[0]-f[0],u[1]-f[1]),w=Object.freeze({center:c,tangent:s,normal:l,start:d,end:u}),y=Object.freeze({side:e.face.side,cm:i,depth:2*Math.hypot(e.face.ox,e.face.oy),offset:f,selectedStart:h,selectedEnd:p,oppositeStart:m,oppositeEnd:g}),M="passage"===e.type?[]:[Object.freeze({jamb:0,center:d,selected:h,opposite:m}),Object.freeze({jamb:1,center:u,selected:p,opposite:g})];let b;if("passage"===e.type)b=[];else if("gate"===e.type){const t=e.face.side*o.gateTurnDeg;b=[W(e,0,[-a,0],[a,0],t,0,n*o.gateTopRatio),W(e,1,[a,0],[-a,0],-t,0,n*o.gateTopRatio)]}else b="window"===e.type?[W(e,0,[-a,0],[a,0],-o.windowTurnDeg,n*o.windowSashBottomRatio,n*o.windowSashTopRatio),W(e,1,[a,0],[-a,0],o.windowTurnDeg,n*o.windowSashBottomRatio,n*o.windowSashTopRatio)]:[W(e,0,[-a,0],[e.length,0],-o.doorTurnDeg,0,n*o.doorTopRatio)];const x="window"===e.type?Object.freeze({frameBottom:n*o.windowFrameBottomRatio,frameTop:n*o.windowFrameTopRatio,sashBottom:n*o.windowSashBottomRatio,sashTop:n*o.windowSashTopRatio,glassBottom:n*o.windowGlassBottomRatio,glassTop:n*o.windowGlassTopRatio,member:n*o.frameThicknessRatio}):null;return Object.freeze({id:e.id,sourceIndex:e.sourceIndex,type:e.type,wallHeight:n,leafThickness:n*o.leafThicknessRatio,frameThickness:n*o.frameThicknessRatio,windowProfile:x,axis:w,face:y,reveals:Object.freeze(M),leaves:Object.freeze(b.map(e=>Object.freeze({...e,hinge:A(e.hinge[0],e.hinge[1]),closedVector:A(e.closedVector[0],e.closedVector[1]),quarterVector:A(e.quarterVector[0],e.quarterVector[1])})))})}({...e,face:c},s,o)}),y=Object.freeze(w);return{walls:c?.components.flatMap(e=>e.geom)||[],floor:m,openings:y,openingSurfaces:Object.freeze(y.flatMap(t=>function(t,n=e){if("passage"===t.type)return Object.freeze([]);const o=[];if(t.face.depth>1e-9)for(const e of t.reveals)o.push(_("jamb-reveal","reveal",e.selected,e.opposite,0,t.wallHeight,n,{jamb:e.jamb}));if("window"!==t.type||!t.leaves.length)return Object.freeze(o.sort((e,t)=>e.depth-t.depth||e.kind.localeCompare(t.kind)||(e.jamb??0)-(t.jamb??0)));const i=t.windowProfile;if(!i)throw new Error("missing isometric window profile");const a=i.frameBottom,r=i.frameTop,s=Math.min(t.frameThickness,Math.hypot(t.axis.end[0]-t.axis.start[0],t.axis.end[1]-t.axis.start[1])/4,(r-a)/4),l=V(t.axis.start,G(t.axis.tangent,s)),c=L(t.axis.end,G(t.axis.tangent,s)),d=t.face.depth>1e-9?[t.face.offset,A(-t.face.offset[0],-t.face.offset[1])]:[t.face.offset];for(const e of d){const i=V(t.axis.start,e),d=V(t.axis.end,e),u=V(l,e),f=V(c,e);o.push(_("window-frame-side","light-frame",i,u,a,r,n,{jamb:0}),_("window-frame-side","light-frame",f,d,a,r,n,{jamb:1}),_("window-frame-top","light-frame",u,f,Math.max(a,r-s),r,n))}return t.face.depth>1e-9&&o.push(q("window-sill","light-sill",[{point:t.face.selectedStart,z:a},{point:t.face.selectedEnd,z:a},{point:t.face.oppositeEnd,z:a},{point:t.face.oppositeStart,z:a}],n)),Object.freeze(o.sort((e,t)=>e.depth-t.depth||e.kind.localeCompare(t.kind)||(e.jamb??0)-(t.jamb??0)))}(t).map(e=>Object.freeze({...e,id:t.id,sourceIndex:t.sourceIndex,type:t.type}))))}}}}const Ve=e=>Array.isArray(e)?e:[];function Le(e,t){const o=e=>Ve(e).flatMap(e=>Array.isArray(e)&&Number.isFinite(e[0])&&Number.isFinite(e[1])?[n([Number(e[0]),Number(e[1])],t)]:[]);return Ve(e).flatMap(e=>{const t=Ve(e);if(!t.length)return[];const n=o(t[0]);if(n.length<3)return[];return[{outer:n,holes:t.slice(1).map(o).filter(e=>e.length>=3)}]})}function Ge(o){const i=r(t,o.cellCm),a=r(l,o.cellCm),s=r(c,o.cellCm),d=$(o.cache,o.source.key);let u=d.hit?d.value:void 0;if(!u){const r=o.source.build(),s=function(o,i=e,a=t){if(!Number.isFinite(a)||a<0)throw new Error("invalid wall height");const r=[],s=[],l=[],c=[];let d=0;for(let e=0;e<(o||[]).length;e++){const t=o[e],u=[];let f=-1/0;for(let o=0;o<(t||[]).length;o++){const s=j(t[o],o>0);if(s.length<3||Math.abs(T(s))<1e-9)continue;const h=O(s,i,a);r.push(h),u.push(h),f=Math.max(f,...s.map(e=>n(e,a,i)[1])),d+=s.length;for(let t=0;t<s.length;t++){const r=s[t],d=s[(t+1)%s.length],u=n(r,0,i),f=n(d,0,i);if(c.push(`M ${I(u)} L ${I(f)}`),N(r,d,i)<=1e-9)continue;const h=n(d,a,i),p=n(r,a,i),m=Object.freeze([u,f,h,p]);l.push({d:`M ${m.map(I).join(" L ")} Z`,points:m,depth:Math.max(u[1],f[1]),polygon:e,ring:o,edge:t})}}u.length&&s.push({d:u.join(" "),depth:f,component:e})}return l.sort((e,t)=>e.depth-t.depth||e.polygon-t.polygon||e.ring-t.ring||e.edge-t.edge),s.sort((e,t)=>e.depth-t.depth||e.component-t.component),{topPath:r.join(" "),topFaces:s,sides:l,contactPath:c.join(" "),edgeCount:d}}(r.walls,e,i),l=Le(r.walls,i);u={geometry:s,floor:B(r.floor,a),wallSilhouettes:Object.freeze([...l,...s.sides.map(e=>({outer:e.points}))]),openings:r.openings,openingSurfaces:r.openingSurfaces},k(o.cache,o.source.key,u,8)}const f=function(e){let t=1/0,n=1/0,o=-1/0,i=-1/0;const a=(e,a=0)=>{t=Math.min(t,e[0]-a),n=Math.min(n,e[1]-a),o=Math.max(o,e[0]+a),i=Math.max(i,e[1]+a)};for(const t of e)if("passage"!==t.type){a(t.axis.start),a(t.axis.end),a(t.face.selectedStart),a(t.face.selectedEnd),a(t.face.oppositeStart),a(t.face.oppositeEnd);for(const e of t.leaves){const n=Math.hypot(e.closedVector[0],e.closedVector[1])+t.leafThickness/2;a(e.hinge,n)}}return F([t,n,o,i])?{x:t,y:n,w:o-t,h:i-n}:null}(u.openings),h=f?De(o.liveFrame,f):o.liveFrame,p=z({rect:h,wallHeight:i,openingHeight:i,floorDepth:a,raisedHeight:s});return{key:o.source.key,...u,frame:p}}const De=(e,t)=>{const n=Math.min(e.x,t.x),o=Math.min(e.y,t.y);return{x:n,y:o,w:Math.max(e.x+e.w,t.x+t.w)-n,h:Math.max(e.y+e.h,t.y+t.h)-o}},We=e=>{if(!e.length||!e.every(e=>Number.isFinite(e[0])&&Number.isFinite(e[1])))return null;const t=e.map(e=>e[0]),n=e.map(e=>e[1]),o=Math.min(...t),i=Math.min(...n);return{x:o,y:i,w:Math.max(...t)-o,h:Math.max(...n)-i}},Ee=(e,t)=>{const n=e.placement,o=t?n.visualScene:n.raisedScene,[i,a]=e.screenHalfSize,r=t?n.footprint:n.footprint.map(e=>[e[0]-n.nudgeScene[0],e[1]-n.nudgeScene[1]]);return[n.floorScene,...r,[o[0]-i,o[1]-a],[o[0]+i,o[1]-a],[o[0]+i,o[1]+a],[o[0]-i,o[1]+a]]},qe=(e,t)=>void 0===t?e:e.filter(e=>e.placement.owner?.id===t);function _e(e,t){return e?We(qe(e.entries,t).flatMap(e=>Ee(e,!0))):null}function Ue(e){const t=qe(e.entries,e.ownerId),n=We(t.flatMap(e=>Ee(e,!1))),o=n?De(e.baseBounds,n):e.baseBounds,i=e.targetView(o);if(!(i&&i.w>0&&i.h>0&&[i.x,i.y,i.w,i.h].every(Number.isFinite)))return null;const a=e.stageSize;if(!(n&&a&&a.width>0&&a.height>0))return{bounds:o,view:i};const r=e=>Math.max(e.w/a.width,e.h/a.height),s=t=>{const o=48*t,i={x:n.x-o,y:n.y-o,w:n.w+2*o,h:n.h+2*o},a=De(e.baseBounds,i),r=e.targetView(a);return r&&[r.x,r.y,r.w,r.h].every(Number.isFinite)&&r.w>0&&r.h>0?{bounds:a,view:r}:null};let l=0,c=Math.max(r(i),Number.EPSILON),d=s(c);for(let e=0;d&&r(d.view)>c*(1+1e-10)&&e<24;e++)l=c,c*=2,d=s(c);if(!d)return null;for(let e=0;e<40;e++){const e=(l+c)/2,t=s(e);if(!t)return null;r(t.view)<=e?(c=e,d=t):l=e}return d}const Ke=new WeakMap,Ze=2048,Je=new WeakMap,Qe=new WeakMap,Xe=new WeakMap;function Ye(e,t){if(e.size!==t.size)return!1;for(const[n,o]of t)if(e.get(n)!==o)return!1;return!0}function et(e){const t=Ke.get(e.rooms);if(t)return t;const n=e.rooms.flatMap((e,t)=>{const n=y(e);return n&&n.length>=3?[{room:e,index:t,poly:n}]:[]}),o=Object.freeze(n.map(({room:e,index:t,poly:o})=>{const i=M(o,n.filter(e=>e.index!==t).map(e=>e.poly)),a={id:e.id||`room-index-${t}`,outer:o.map(e=>[e[0],e[1]]),holes:i.map(e=>e.map(e=>[e[0],e[1]]))};return{room:e,overlayRoom:{...a,safePoint:ae(a)||void 0}}}));return Ke.set(e.rooms,o),o}function tt(o){const a=o.stageSize&&o.stageSize.width>0&&o.stageSize.height>0?Math.max(o.view.w/o.stageSize.width,o.view.h/o.stageSize.height):Math.max(o.view.w,o.view.h)/1e3,l=et(o.space),c=l.map(e=>e.overlayRoom),d=r(t,o.cellCm),u=r(i,o.cellCm),f=new Map,h=new Map,p=new Map,m=[];let g=Je.get(o.wallSilhouettes);g||(g=new Map,Je.set(o.wallSilhouettes,g));let w=Qe.get(l);w||(w=new Map,Qe.set(l,w));const y=o.iconPct*s(o.space)*o.kioskIconScale/100,M=o.deviceBasePct*s(o.space)*o.kioskIconScale/100,b=(r,s,l,f,h)=>{const p=`${!1===o.resolveCollisions?"fit":"live"}\0${r}\0${s}`,m=[l[0],l[1],f[0],f[1],h||"",d,u].join("|"),y=`${m}|${a}`,M=$(g,p);if(M.hit&&M.value.signature===y)return M.value.placement;if(M.hit&&M.value.shapeSignature===m&&a<=M.value.unitsPerPixel){const e=M.value.placement,t=e.nudgeDistanceCss*M.value.unitsPerPixel/a;if(!e.nearWallBefore||e.cleared&&t<=48)return e}const b=`${r}\0${s}`,x=[l[0],l[1],h||""].join("|"),v=$(w,b),S=v.hit&&v.value.signature===x?v.value.owner:re({kind:r,floorAnchor:l,rooms:c,roomsValidated:!0,preferredRoomId:h});v.hit&&v.value.signature===x||k(w,b,{signature:x,owner:S},Ze);const z=function(o){const a=o.camera||e,r=o.wallHeight??t,s=o.visualOffset??i,l=o.sceneUnitsPerCssPixel??1,c=o.safetyGapCssPx??4,d=o.maxNudgeCssPx??48;if(!J(o.floorAnchor)||!J(o.footprintHalfSize)||o.footprintHalfSize[0]<0||o.footprintHalfSize[1]<0||!Number.isFinite(r)||r<0||!Number.isFinite(s)||s<0||!Number.isFinite(l)||l<=0||!Number.isFinite(c)||c<0||!Number.isFinite(d)||d<0)throw new Error("invalid isometric overlay input");const u=[o.floorAnchor[0],o.floorAnchor[1]],f=n(u,0,a),h=(p=o.kind,!o.showBorders||"device"!==p&&"room-label"!==p&&"opening-lock"!==p?"floor":"raised");var p;if("floor"===h)return{plane:h,owner:null,floorAnchor:u,floorScene:f,raisedScene:f,visualScene:f,footprint:[],nudgeScene:[0,0],nudgeCss:[0,0],nudgeDistanceCss:0,nudged:!1,nearWallBefore:!1,nearWallAfter:!1,cleared:!0,capped:!1,grounding:{center:f,visible:!1},tether:Me(f,f,!1),status:"ok",reason:null};const m=s,g=n(u,m,a),w=o.ownerAlreadyResolved?o.resolvedOwner??null:re(o),y=o.wallGeometryValidated??o.wallSilhouettes.every(we),M=c*l,b=se(u,o.footprintHalfSize,m,a),x=e=>{const t=fe(e);return!!t&&o.wallSilhouettes.some(n=>ge(e,t,n,M,!0===o.wallGeometryValidated))},v=!y||x(b);let S=0,$=[0,0],k=null,z=!1,P=y?"ok":"degraded",C=y?null:"invalid-wall-geometry";if(y&&v)if(w)if(w.safePoint){const e=o.rooms.find(e=>e.id===w.id)||null,t=n(w.safePoint,m,a),i=t[0]-g[0],r=t[1]-g[1],s=Math.hypot(i,r);if(s<=K)P="degraded",C="invalid-safe-point";else{const t=i/s,n=r/s,a=Math.min(d,s/l),c=a*l/s,f=[u[0]+(w.safePoint[0]-u[0])*c,u[1]+(w.safePoint[1]-u[1])*c],h=[t*a*l,n*a*l],p=fe([...b,...b.map(e=>[e[0]+h[0],e[1]+h[1]])]),m=p?o.wallSilhouettes.filter(e=>{const t=he(e,!0===o.wallGeometryValidated);return!!t&&pe(p,t,M)}):o.wallSilhouettes,g=!!e&&ye(u,f,e),y=e=>{const i=[t*e*l,n*e*l],a=b.map(e=>[e[0]+i[0],e[1]+i[1]]),r=fe(a);return!!r&&m.some(e=>ge(a,r,e,M,!0===o.wallGeometryValidated))},x=o.nudgeHintCss;if(Number.isFinite(x)&&x>=0&&x<=a){const t=x*l/s,n=[u[0]+(w.safePoint[0]-u[0])*t,u[1]+(w.safePoint[1]-u[1])*t];(g||e&&ye(u,n,e))&&!y(x)&&(S=x,k=!1)}if(null===k){let t=null,n=0,o=!1;const i=Math.ceil(a);for(let r=1;r<=i;r++){const i=Math.min(a,r),c=i*l/s,d=[u[0]+(w.safePoint[0]-u[0])*c,u[1]+(w.safePoint[1]-u[1])*c];if(!(g||e&&ye(u,d,e))){o=!0;break}if(!y(i)){t=i;break}n=i}if(null!==t){let e=n,o=t;for(let t=0;t<14;t++){const t=(e+o)/2;y(t)?e=t:o=t}S=o}else S=n,z=!0,P="degraded",C=o?"owner-boundary":"nudge-cap"}$=[t*S*l,n*S*l]}}else P="degraded",C="invalid-safe-point";else P="degraded",C="missing-owner";const I=[g[0]+$[0],g[1]+$[1]],T=se(u,o.footprintHalfSize,m,a,$),j=!y||(k??x(T)),O=S>K;return{plane:h,owner:w,floorAnchor:u,floorScene:f,raisedScene:g,visualScene:I,footprint:T,nudgeScene:$,nudgeCss:[$[0]/l,$[1]/l],nudgeDistanceCss:S,nudged:O,nearWallBefore:v,nearWallAfter:j,cleared:!j,capped:z,grounding:{center:f,visible:!1},tether:Me(f,I,!1),status:P,reason:C}}({kind:r,floorAnchor:l,rooms:c,roomsValidated:!0,preferredRoomId:h,ownerAlreadyResolved:!0,resolvedOwner:S,nudgeHintCss:M.hit&&M.value.shapeSignature===m?M.value.placement.nudgeDistanceCss*M.value.unitsPerPixel/a:void 0,showBorders:!0,wallSilhouettes:!1===o.resolveCollisions?[]:o.wallSilhouettes,wallGeometryValidated:!0,footprintHalfSize:f,wallHeight:d,visualOffset:u,sceneUnitsPerCssPixel:a});return k(g,p,{signature:y,shapeSignature:m,unitsPerPixel:a,placement:z},Ze),z};for(const e of o.devices){const t=o.positionOf(e),n=o.presentationOf(e,o.showLqi),i=M*n.scale,a=Be({kind:"device",core:i,presentation:n}),r=e.marker?.room_id||l.find(t=>!!e.area&&t.room.area===e.area)?.overlayRoom.id||null,s=b("device",e.id,[t.x,t.y],a,r);f.set(e.id,s),m.push({id:e.id,kind:"device",placement:s,groundRadius:Math.max(.32*i,2),screenHalfSize:a})}for(const{room:e,overlayRoom:t}of l){if(!o.display.showNames||!e.name)continue;const n=o.labelPositionOf(e,o.space.id),i=.5*y*(o.labelScaleOf(e)*o.kioskFontScale*o.display.cardFontScale),a=Be({kind:"room-label",font:i,room:e,display:o.display}),r=b("room-label",t.id,[n.x,n.y],a,t.id);h.set(e,r),m.push({id:t.id,kind:"room-label",placement:r,groundRadius:Math.max(.75*i,2),screenHalfSize:a})}const x=o.openings.filter(e=>!e.orphanReason&&("door"===e.type||"gate"===e.type)&&"string"==typeof e.lock&&!!e.lock&&o.openingEntityAvailable(e.lock));if(x.length){const e=o.openingWallIndex();for(const t of x){const n=ot(t,e,o.cellCm),i=n.floorAnchor,a=.62*y,r=Be({kind:"opening-lock",size:a}),s=b("opening-lock",String(t.id),i,r,n.preferredRoomId);p.set(String(t.id),s),m.push({id:String(t.id),kind:"opening-lock",placement:s,groundRadius:Math.max(.28*a,2),screenHalfSize:r})}}const v=!1===o.resolveCollisions?"fit":"live";let S=Xe.get(o.wallSilhouettes);S||(S=new Map,Xe.set(o.wallSilhouettes,S));const z=S.get(v),P=m.map(e=>{const t=e.placement;return[e.kind,e.id,t.floorAnchor[0],t.floorAnchor[1],t.raisedScene[0],t.raisedScene[1],t.nudgeScene[0],t.nudgeScene[1],t.owner?.id||"",t.status,t.reason||"",e.screenHalfSize[0],e.screenHalfSize[1],a].join("|")}).sort().join("");if(z?.collisionSignature===P&&Ye(z.rooms,h))return z;const C="live"===v?function(t){const n=t.sceneUnitsPerCssPixel,o=t.maxNudgeCssPx??48,a=t.safetyGapCssPx??4,r=t.visualOffset??i,s=t.camera||e;if(!(n>0&&Number.isFinite(n)&&o>=0&&Number.isFinite(o)&&a>=0&&Number.isFinite(a)))throw new Error("invalid isometric overlay collision input");const l=a*n,c=64*n,d=new Map(t.rooms.filter(oe).map(e=>[e.id,e])),u=t.wallSilhouettes.every(we),f=[],h=new Map,p=new Map,m=[],g=[...t.items].sort((e,t)=>e.placement.nudgeDistanceCss-t.placement.nudgeDistanceCss||Z(e.kind,e.id).localeCompare(Z(t.kind,t.id))),w=e=>[Math.floor(e[0]/c),Math.floor(e[1]/c),Math.floor(e[2]/c),Math.floor(e[3]/c)],y=e=>{const[t,n,o,i]=w(ve(e,l)),a=new Set;for(let e=n;e<=i;e++)for(let n=t;n<=o;n++)for(const t of h.get(`${n}:${e}`)||[])a.add(t);return[...a].sort((e,t)=>e-t)},M=e=>{const t=f.push(e)-1,[n,o,i,a]=w(e.bounds);for(let e=o;e<=a;e++)for(let o=n;o<=i;o++){const n=`${o}:${e}`,i=h.get(n)||[];i.push(t),h.set(n,i)}};for(const e of g){const i=Z(e.kind,e.id),a=e.placement,c=[a.nudgeScene[0]/n,a.nudgeScene[1]/n],h=a.footprint.map(e=>[e[0]-a.nudgeScene[0],e[1]-a.nudgeScene[1]]),g=a.owner&&d.get(a.owner.id)||null,w=$e(a.visualScene,r,s),b=u&&h.length?t.wallSilhouettes.filter(e=>{const t=he(e,!0);if(!t)return!1;const i=o*n,a=fe(h);return!!a&&pe(ve(a,i),t,l)}):t.wallSilhouettes,x=t=>{if(Math.hypot(t[0],t[1])>o+K)return null;const i=[t[0]*n,t[1]*n],c=Math.abs(i[0]-a.nudgeScene[0])<=K&&Math.abs(i[1]-a.nudgeScene[1])<=K,d=[a.raisedScene[0]+i[0],a.raisedScene[1]+i[1]];if(!c){if(!u||!g)return null;const e=$e(d,r,s);if(!ie(e,g))return null;if(ie(w,g)&&!ye(w,e,g))return null;const t=h.map(e=>[e[0]+i[0],e[1]+i[1]]),n=fe(t);if(!n||b.some(e=>ge(t,n,e,l,!0)))return null}const p=xe(e,d),m=y(p).filter(e=>Se(p,f[e].bounds,l)>K),M=m.reduce((e,t)=>e+Se(p,f[t].bounds,l),0);return{placement:ke(a,t,n,!1),bounds:p,conflicts:m,penalty:M}};let v=x(c);if(!v||v.conflicts.length)for(const e of be){if(Math.hypot(e[0],e[1])>o+K)break;if(Math.abs(e[0]-c[0])<=K&&Math.abs(e[1]-c[1])<=K)continue;const t=x(e);if(t){if(!t.conflicts.length){v=t;break}(!v||t.penalty<v.penalty-K||Math.abs(t.penalty-v.penalty)<=K&&t.placement.nudgeDistanceCss<v.placement.nudgeDistanceCss-K)&&(v=t)}}if(v)v.conflicts.length&&(v={...v,placement:ke(a,v.placement.nudgeCss,n,!0)});else{const t=ke(a,c,n,!0),o=xe(e,t.visualScene);v={placement:t,bounds:o,conflicts:y(o),penalty:1/0}}for(const e of v.conflicts)Se(v.bounds,f[e].bounds,l)>K&&m.push(Object.freeze([f[e].key,i]));p.set(i,v.placement),M({key:i,bounds:v.bounds})}return{placements:p,residualPairs:Object.freeze(m)}}({items:m.flatMap(e=>"room-label"===e.kind?[]:[{id:e.id,kind:e.kind,placement:e.placement,screenHalfSize:e.screenHalfSize}]),rooms:c,wallSilhouettes:o.wallSilhouettes,sceneUnitsPerCssPixel:a,visualOffset:u}):{placements:new Map,residualPairs:[]},I=Object.freeze(m.map(e=>{if("room-label"===e.kind)return e;const t=C.placements.get(Z(e.kind,e.id))||e.placement;return t===e.placement?e:{...e,placement:t}})),T=new Map,j=new Map;for(const e of I)"device"===e.kind?T.set(e.id,e.placement):"opening-lock"===e.kind&&j.set(e.id,e.placement);const O={devices:T,rooms:h,locks:j,entries:I,collisionSignature:P,residualPairs:Object.freeze([...C.residualPairs])};return z&&function(e,t){return e.length===t.length&&t.every((t,n)=>{const o=e[n];return o.id===t.id&&o.kind===t.kind&&o.placement===t.placement&&o.groundRadius===t.groundRadius&&o.screenHalfSize[0]===t.screenHalfSize[0]&&o.screenHalfSize[1]===t.screenHalfSize[1]})}(z.entries,O.entries)&&Ye(z.devices,O.devices)&&Ye(z.rooms,O.rooms)&&Ye(z.locks,O.locks)?z:(S.set(v,O),O)}function nt(e,t,n){return ot(e,t,n).floorAnchor}function ot(e,t,n){const o=!e.flip_v,i="gate"===e.type?e.partitionHost?m(e.partitionHost,o):p(t,{x:e.rx,y:e.ry,angle:e.angle,length:e.rlen,flip_v:o}):null,[a,r]=g({x:e.rx,y:e.ry,angle:e.angle,flipV:!!e.flip_v,gateFace:i},n);if(e.partitionHost)return{floorAnchor:a,preferredRoomId:null};const s=w(t,{x:e.rx,y:e.ry,angle:e.angle,length:e.rlen},!0),l=r?"negative":"positive";return{floorAnchor:a,preferredRoomId:s[l]?.roomId||null}}function it(e){let t=!1;try{t="undefined"!=typeof CSS&&"function"==typeof CSS.supports&&CSS.supports("filter","blur(1px)")}catch{t=!1}let n=!1;try{n="function"==typeof matchMedia&&matchMedia("(forced-colors: active)").matches}catch{n=!0}return function(e){const t=!!e.showBorders;return{structural:t,panels:t&&!e.hideOpenings,shadows:t&&e.filtersSupported&&!e.forcedColors,materialNuance:t&&e.filtersSupported&&!e.forcedColors,floorSymbols:!e.hideOpenings&&!t}}({showBorders:e.showBorders,hideOpenings:e.hideOpenings,filtersSupported:t,forcedColors:n})}function at(e,t,n,o){if(!e.panels||!t)return[];return t.openings.flatMap(e=>{const t=n[e.sourceIndex];return t?U(e,o(t)):[]}).sort((e,t)=>e.depth-t.depth||e.sourceIndex-t.sourceIndex||e.leaf-t.leaf)}function rt(e){const t=it(e.display),n=t.panels?at(t,e.scene,e.openings,e.amountOf):[],o=e.overlays(t),i=t=>({layers:t,panels:n,overlays:o,underlay:ft(t,e.scene?.floor,e.cellCm),shadows:ht(t,n,e.scene?.geometry,e.cellCm),walls:pt(e.projection,t,e.scene,n,e.cellCm),grounds:dt(o,t,e.cellCm),raised:ut()});try{return i(t)}catch(e){if(!t.shadows&&!t.materialNuance)throw e;return i({...t,shadows:!1,materialNuance:!1})}}const st=()=>S``;function lt(e){return`translate(${r(4,e)} ${r(8,e)})`}function ct(e,t,n){const o=C(n);return S`<defs>
|
|
${"walls"===t&&e.materialNuance?S`
|
|
<linearGradient id="hp-iso-wall-side" data-hp-iso-material-def x1="0" y1="0" x2="0" y2="1">
|
|
<stop offset="0" class="iso-side-hi"></stop><stop offset="1" class="iso-side-lo"></stop>
|
|
</linearGradient>
|
|
<linearGradient id="hp-iso-wall-top" data-hp-iso-material-def x1="0" y1="0" x2="1" y2="1">
|
|
<stop offset="0" class="iso-top-hi"></stop><stop offset="1" class="iso-top-lo"></stop>
|
|
</linearGradient>
|
|
<pattern id="hp-iso-wall-texture" data-hp-iso-material-def patternUnits="userSpaceOnUse"
|
|
width="${12*o}" height="${12*o}">
|
|
<circle class="iso-texture-mark" cx="${2*o}" cy="${2*o}"
|
|
r="${.55*o}"></circle>
|
|
<path class="iso-texture-line" d="M ${5*o} ${10*o}
|
|
l ${5*o} ${-5*o}"></path>
|
|
</pattern>`:v}
|
|
${"underlay"===t&&e.materialNuance?S`
|
|
<pattern id="hp-iso-floor-texture" data-hp-iso-material-def patternUnits="userSpaceOnUse"
|
|
width="${14*o}" height="${14*o}">
|
|
<circle class="iso-texture-mark" cx="${3*o}" cy="${3*o}"
|
|
r="${.5*o}"></circle>
|
|
</pattern>`:v}
|
|
${"underlay"===t&&e.shadows?S`
|
|
<filter id="hp-iso-ambient-shadow" data-hp-iso-material-def x="-12%" y="-12%" width="124%" height="130%">
|
|
<feGaussianBlur stdDeviation="${7*o}"></feGaussianBlur>
|
|
</filter>`:v}
|
|
</defs>`}function dt(e,t,n){return st()}function ut(e){return st()}function ft(e,t,n){return e.structural&&t?S`<g class="iso-underlay" data-hp="iso-underlay" aria-hidden="true" pointer-events="none">
|
|
${ct(e,"underlay",n)}
|
|
${e.shadows&&t.footprintPath?S`<path class="iso-ambient-shadow" d=${t.footprintPath}
|
|
transform=${lt(n)}></path>`:v}
|
|
<g class="iso-floor-edge">${t.sides.map(t=>S`<path class="iso-floor-side" d=${t.d} data-component=${t.component}
|
|
data-edge=${t.edge}></path>${e.materialNuance?S`<path class="iso-material-texture iso-floor-texture" d=${t.d}></path>`:v}`)}</g>
|
|
</g>`:st()}function ht(e,t,n,o){return st()}function pt(e,t,n,o,i){if("iso"!==e||!t.structural||!n)return st();const a=t.panels?[...n.openingSurfaces,...o.flatMap(e=>e.surfaces.map(t=>({...t,id:e.id,sourceIndex:e.sourceIndex,type:e.type,leaf:e.leaf})))]:[],r=Ie(n.geometry,a);return S`<g class="iso-walls" data-hp="iso-walls" data-fingerprint=${n.key}>
|
|
${ct(t,"walls",i)}
|
|
<g class=${t.panels?"iso-wall-depth-queue iso-openings":"iso-wall-depth-queue"}
|
|
data-hp=${t.panels?"iso-openings":v}
|
|
aria-hidden="true" pointer-events="none">${r.map(e=>{if("wall-side"===e.layer){const n=e.face;return S`<path class="iso-wall-side" d=${n.d} data-edge=${n.edge}></path>${t.materialNuance?S`<path class="iso-material-texture iso-wall-texture" d=${n.d}></path>`:v}`}if("wall-top"===e.layer){const n=e.face;return S`<path class="iso-wall-top" d=${n.d} data-component=${n.component}
|
|
fill-rule="evenodd"></path>${t.materialNuance?S`<path class="iso-material-texture iso-wall-texture" d=${n.d}
|
|
fill-rule="evenodd"></path>`:v}`}const n=e.surface;return S`<path class="iso-opening-panel iso-${n.type} iso-opening-${n.kind} iso-material-${n.material}"
|
|
d=${n.d} data-id=${n.id} data-kind=${n.type}
|
|
data-surface=${n.kind} data-leaf=${n.leaf??v}></path>${t.materialNuance?S`<path class="iso-material-texture iso-wall-texture iso-opening-texture"
|
|
d=${n.d}></path>`:v}`})}</g>
|
|
</g>`}export{Ze as ISO_OVERLAY_PLACEMENT_CACHE_LIMIT,Te as ISO_RAISED_FOOTPRINT,ze as ISO_SCENE_RUNTIME_FINGERPRINT,tt as buildIsoOverlayRenderScene,Ie as buildIsoWallDepthQueue,Ae as createIsoStructuralSource,lt as isoFixedLightTransform,nt as isoOpeningLockAnchor,ot as isoOpeningLockPlacement,et as isoOverlayRooms,_e as isoOverlaySceneBounds,Be as isoRaisedOverlayHalfSize,He as isoSourceOpenings,Fe as isoStructuralOpeningHost,Re as isoStructuralRoomGeometry,Le as isoWallSilhouettesOf,dt as renderIsoOverlayGrounds,ut as renderIsoRaisedOverlays,ht as renderIsoShadows,ft as renderIsoUnderlay,pt as renderIsoWalls,it as resolveIsoDecorationLayers,rt as resolveIsoFramePresentation,at as resolveIsoOpeningPanels,Ue as resolveIsoOverlayFitEnvelope,Ge as resolveIsoScene};
|