From 1290927f104825cf5716a97bcd7b42e1d85c03f5 Mon Sep 17 00:00:00 2001 From: Sergey Matyunin Date: Wed, 19 Aug 2026 18:47:33 +0300 Subject: [PATCH] fix: hide disabled room names Issue: #203 User-Visible: yes --- .../houseplan/frontend/houseplan-card.js | 64 +++----- demo/smoke_hide_room_names.mjs | 152 ++++++++++++++++++ demo/smoke_styling_hooks.mjs | 13 +- demo/srv/assets/houseplan-card.js | 64 +++----- dist/houseplan-card.js | 64 +++----- docs/CHANGELOG.md | 7 + docs/CHANGELOG.ru.md | 8 + docs/STYLING-HOOKS.md | 8 +- docs/TESTING.md | 18 ++- docs/USER-GUIDE.ru.md | 6 +- docs/UX-MODES.md | 13 +- docs/images/screenshots.json | 22 +-- scripts/mutation-gate.mjs | 50 ++++++ src/houseplan-card.ts | 14 +- src/space-render.ts | 12 +- src/styles.ts | 8 - 16 files changed, 348 insertions(+), 175 deletions(-) create mode 100644 demo/smoke_hide_room_names.mjs diff --git a/custom_components/houseplan/frontend/houseplan-card.js b/custom_components/houseplan/frontend/houseplan-card.js index f9ecb54e..aefea4d6 100755 --- a/custom_components/houseplan/frontend/houseplan-card.js +++ b/custom_components/houseplan/frontend/houseplan-card.js @@ -1,4 +1,4 @@ -globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="51c4bdb005b2539779085578bcce5ee1b4b3e3137542ef1aeb440232344c3105";const t=globalThis,e=t.ShadowRoot&&(void 0===t.ShadyCSS||t.ShadyCSS.nativeShadow)&&"adoptedStyleSheets"in Document.prototype&&"replace"in CSSStyleSheet.prototype,i=Symbol(),s=new WeakMap;let n=class{constructor(t,e,s){if(this._$cssResult$=!0,s!==i)throw Error("CSSResult is not constructable. Use `unsafeCSS` or `css` instead.");this.cssText=t,this.t=e}get styleSheet(){let t=this.o;const i=this.t;if(e&&void 0===t){const e=void 0!==i&&1===i.length;e&&(t=s.get(i)),void 0===t&&((this.o=t=new CSSStyleSheet).replaceSync(this.cssText),e&&s.set(i,t))}return t}toString(){return this.cssText}};const o=(t,...e)=>{const s=1===t.length?t[0]:e.reduce((e,i,s)=>e+(t=>{if(!0===t._$cssResult$)return t.cssText;if("number"==typeof t)return t;throw Error("Value passed to 'css' function must be a 'css' function result: "+t+". Use 'unsafeCSS' to pass non-literal values, but take care to ensure page security.")})(i)+t[s+1],t[0]);return new n(s,t,i)},a=e?t=>t:t=>t instanceof CSSStyleSheet?(t=>{let e="";for(const i of t.cssRules)e+=i.cssText;return(t=>new n("string"==typeof t?t:t+"",void 0,i))(e)})(t):t,{is:r,defineProperty:l,getOwnPropertyDescriptor:c,getOwnPropertyNames:h,getOwnPropertySymbols:d,getPrototypeOf:u}=Object,p=globalThis,_=p.trustedTypes,g=_?_.emptyScript:"",m=p.reactiveElementPolyfillSupport,f=(t,e)=>t,v={toAttribute(t,e){switch(e){case Boolean:t=t?g:null;break;case Object:case Array:t=null==t?t:JSON.stringify(t)}return t},fromAttribute(t,e){let i=t;switch(e){case Boolean:i=null!==t;break;case Number:i=null===t?null:Number(t);break;case Object:case Array:try{i=JSON.parse(t)}catch(t){i=null}}return i}},y=(t,e)=>!r(t,e),b={attribute:!0,type:String,converter:v,reflect:!1,useDefault:!1,hasChanged:y};Symbol.metadata??=Symbol("metadata"),p.litPropertyMetadata??=new WeakMap;let w=class extends HTMLElement{static addInitializer(t){this._$Ei(),(this.l??=[]).push(t)}static get observedAttributes(){return this.finalize(),this._$Eh&&[...this._$Eh.keys()]}static createProperty(t,e=b){if(e.state&&(e.attribute=!1),this._$Ei(),this.prototype.hasOwnProperty(t)&&((e=Object.create(e)).wrapped=!0),this.elementProperties.set(t,e),!e.noAccessor){const i=Symbol(),s=this.getPropertyDescriptor(t,i,e);void 0!==s&&l(this.prototype,t,s)}}static getPropertyDescriptor(t,e,i){const{get:s,set:n}=c(this.prototype,t)??{get(){return this[e]},set(t){this[e]=t}};return{get:s,set(e){const o=s?.call(this);n?.call(this,e),this.requestUpdate(t,o,i)},configurable:!0,enumerable:!0}}static getPropertyOptions(t){return this.elementProperties.get(t)??b}static _$Ei(){if(this.hasOwnProperty(f("elementProperties")))return;const t=u(this);t.finalize(),void 0!==t.l&&(this.l=[...t.l]),this.elementProperties=new Map(t.elementProperties)}static finalize(){if(this.hasOwnProperty(f("finalized")))return;if(this.finalized=!0,this._$Ei(),this.hasOwnProperty(f("properties"))){const t=this.properties,e=[...h(t),...d(t)];for(const i of e)this.createProperty(i,t[i])}const t=this[Symbol.metadata];if(null!==t){const e=litPropertyMetadata.get(t);if(void 0!==e)for(const[t,i]of e)this.elementProperties.set(t,i)}this._$Eh=new Map;for(const[t,e]of this.elementProperties){const i=this._$Eu(t,e);void 0!==i&&this._$Eh.set(i,t)}this.elementStyles=this.finalizeStyles(this.styles)}static finalizeStyles(t){const e=[];if(Array.isArray(t)){const i=new Set(t.flat(1/0).reverse());for(const t of i)e.unshift(a(t))}else void 0!==t&&e.push(a(t));return e}static _$Eu(t,e){const i=e.attribute;return!1===i?void 0:"string"==typeof i?i:"string"==typeof t?t.toLowerCase():void 0}constructor(){super(),this._$Ep=void 0,this.isUpdatePending=!1,this.hasUpdated=!1,this._$Em=null,this._$Ev()}_$Ev(){this._$ES=new Promise(t=>this.enableUpdating=t),this._$AL=new Map,this._$E_(),this.requestUpdate(),this.constructor.l?.forEach(t=>t(this))}addController(t){(this._$EO??=new Set).add(t),void 0!==this.renderRoot&&this.isConnected&&t.hostConnected?.()}removeController(t){this._$EO?.delete(t)}_$E_(){const t=new Map,e=this.constructor.elementProperties;for(const i of e.keys())this.hasOwnProperty(i)&&(t.set(i,this[i]),delete this[i]);t.size>0&&(this._$Ep=t)}createRenderRoot(){const i=this.shadowRoot??this.attachShadow(this.constructor.shadowRootOptions);return((i,s)=>{if(e)i.adoptedStyleSheets=s.map(t=>t instanceof CSSStyleSheet?t:t.styleSheet);else for(const e of s){const s=document.createElement("style"),n=t.litNonce;void 0!==n&&s.setAttribute("nonce",n),s.textContent=e.cssText,i.appendChild(s)}})(i,this.constructor.elementStyles),i}connectedCallback(){this.renderRoot??=this.createRenderRoot(),this.enableUpdating(!0),this._$EO?.forEach(t=>t.hostConnected?.())}enableUpdating(t){}disconnectedCallback(){this._$EO?.forEach(t=>t.hostDisconnected?.())}attributeChangedCallback(t,e,i){this._$AK(t,i)}_$ET(t,e){const i=this.constructor.elementProperties.get(t),s=this.constructor._$Eu(t,i);if(void 0!==s&&!0===i.reflect){const n=(void 0!==i.converter?.toAttribute?i.converter:v).toAttribute(e,i.type);this._$Em=t,null==n?this.removeAttribute(s):this.setAttribute(s,n),this._$Em=null}}_$AK(t,e){const i=this.constructor,s=i._$Eh.get(t);if(void 0!==s&&this._$Em!==s){const t=i.getPropertyOptions(s),n="function"==typeof t.converter?{fromAttribute:t.converter}:void 0!==t.converter?.fromAttribute?t.converter:v;this._$Em=s;const o=n.fromAttribute(e,t.type);this[s]=o??this._$Ej?.get(s)??o,this._$Em=null}}requestUpdate(t,e,i,s=!1,n){if(void 0!==t){const o=this.constructor;if(!1===s&&(n=this[t]),i??=o.getPropertyOptions(t),!((i.hasChanged??y)(n,e)||i.useDefault&&i.reflect&&n===this._$Ej?.get(t)&&!this.hasAttribute(o._$Eu(t,i))))return;this.C(t,e,i)}!1===this.isUpdatePending&&(this._$ES=this._$EP())}C(t,e,{useDefault:i,reflect:s,wrapped:n},o){i&&!(this._$Ej??=new Map).has(t)&&(this._$Ej.set(t,o??e??this[t]),!0!==n||void 0!==o)||(this._$AL.has(t)||(this.hasUpdated||i||(e=void 0),this._$AL.set(t,e)),!0===s&&this._$Em!==t&&(this._$Eq??=new Set).add(t))}async _$EP(){this.isUpdatePending=!0;try{await this._$ES}catch(t){Promise.reject(t)}const t=this.scheduleUpdate();return null!=t&&await t,!this.isUpdatePending}scheduleUpdate(){return this.performUpdate()}performUpdate(){if(!this.isUpdatePending)return;if(!this.hasUpdated){if(this.renderRoot??=this.createRenderRoot(),this._$Ep){for(const[t,e]of this._$Ep)this[t]=e;this._$Ep=void 0}const t=this.constructor.elementProperties;if(t.size>0)for(const[e,i]of t){const{wrapped:t}=i,s=this[e];!0!==t||this._$AL.has(e)||void 0===s||this.C(e,void 0,i,s)}}let t=!1;const e=this._$AL;try{t=this.shouldUpdate(e),t?(this.willUpdate(e),this._$EO?.forEach(t=>t.hostUpdate?.()),this.update(e)):this._$EM()}catch(e){throw t=!1,this._$EM(),e}t&&this._$AE(e)}willUpdate(t){}_$AE(t){this._$EO?.forEach(t=>t.hostUpdated?.()),this.hasUpdated||(this.hasUpdated=!0,this.firstUpdated(t)),this.updated(t)}_$EM(){this._$AL=new Map,this.isUpdatePending=!1}get updateComplete(){return this.getUpdateComplete()}getUpdateComplete(){return this._$ES}shouldUpdate(t){return!0}update(t){this._$Eq&&=this._$Eq.forEach(t=>this._$ET(t,this[t])),this._$EM()}updated(t){}firstUpdated(t){}};w.elementStyles=[],w.shadowRootOptions={mode:"open"},w[f("elementProperties")]=new Map,w[f("finalized")]=new Map,m?.({ReactiveElement:w}),(p.reactiveElementVersions??=[]).push("2.1.2");const k=globalThis,x=t=>t,$=k.trustedTypes,S=$?$.createPolicy("lit-html",{createHTML:t=>t}):void 0,M="$lit$",C=`lit$${Math.random().toFixed(9).slice(2)}$`,D="?"+C,T=`<${D}>`,P=document,R=()=>P.createComment(""),A=t=>null===t||"object"!=typeof t&&"function"!=typeof t,I=Array.isArray,E="[ \t\n\f\r]",F=/<(?:(!--|\/[^a-zA-Z])|(\/?[a-zA-Z][^>\s]*)|(\/?$))/g,z=/-->/g,O=/>/g,H=RegExp(`>|${E}(?:([^\\s"'>=/]+)(${E}*=${E}*(?:[^ \t\n\f\r"'\`<>=]|("|')|))|$)`,"g"),N=/'/g,L=/"/g,B=/^(?:script|style|textarea|title)$/i,q=t=>(e,...i)=>({_$litType$:t,strings:e,values:i}),j=q(1),W=q(2),U=Symbol.for("lit-noChange"),G=Symbol.for("lit-nothing"),V=new WeakMap,K=P.createTreeWalker(P,129);function Y(t,e){if(!I(t)||!t.hasOwnProperty("raw"))throw Error("invalid template strings array");return void 0!==S?S.createHTML(e):e}const X=(t,e)=>{const i=t.length-1,s=[];let n,o=2===e?"":3===e?"":"",a=F;for(let e=0;e"===l[0]?(a=n??F,c=-1):void 0===l[1]?c=-2:(c=a.lastIndex-l[2].length,r=l[1],a=void 0===l[3]?H:'"'===l[3]?L:N):a===L||a===N?a=H:a===z||a===O?a=F:(a=H,n=void 0);const d=a===H&&t[e+1].startsWith("/>")?" ":"";o+=a===F?i+T:c>=0?(s.push(r),i.slice(0,c)+M+i.slice(c)+C+d):i+C+(-2===c?e:d)}return[Y(t,o+(t[i]||"")+(2===e?"":3===e?"":"")),s]};class J{constructor({strings:t,_$litType$:e},i){let s;this.parts=[];let n=0,o=0;const a=t.length-1,r=this.parts,[l,c]=X(t,e);if(this.el=J.createElement(l,i),K.currentNode=this.el.content,2===e||3===e){const t=this.el.content.firstChild;t.replaceWith(...t.childNodes)}for(;null!==(s=K.nextNode())&&r.length0){s.textContent=$?$.emptyScript:"";for(let i=0;iI(t)||"function"==typeof t?.[Symbol.iterator])(t)?this.k(t):this._(t)}O(t){return this._$AA.parentNode.insertBefore(t,this._$AB)}T(t){this._$AH!==t&&(this._$AR(),this._$AH=this.O(t))}_(t){this._$AH!==G&&A(this._$AH)?this._$AA.nextSibling.data=t:this.T(P.createTextNode(t)),this._$AH=t}$(t){const{values:e,_$litType$:i}=t,s="number"==typeof i?this._$AC(t):(void 0===i.el&&(i.el=J.createElement(Y(i.h,i.h[0]),this.options)),i);if(this._$AH?._$AD===s)this._$AH.p(e);else{const t=new Q(s,this),i=t.u(this.options);t.p(e),this.T(i),this._$AH=t}}_$AC(t){let e=V.get(t.strings);return void 0===e&&V.set(t.strings,e=new J(t)),e}k(t){I(this._$AH)||(this._$AH=[],this._$AR());const e=this._$AH;let i,s=0;for(const n of t)s===e.length?e.push(i=new tt(this.O(R()),this.O(R()),this,this.options)):i=e[s],i._$AI(n),s++;s2||""!==i[0]||""!==i[1]?(this._$AH=Array(i.length-1).fill(new String),this.strings=i):this._$AH=G}_$AI(t,e=this,i,s){const n=this.strings;let o=!1;if(void 0===n)t=Z(this,t,e,0),o=!A(t)||t!==this._$AH&&t!==U,o&&(this._$AH=t);else{const s=t;let a,r;for(t=n[0],a=0;a{const s=i?.renderBefore??e;let n=s._$litPart$;if(void 0===n){const t=i?.renderBefore??null;s._$litPart$=n=new tt(e.insertBefore(R(),t),t,void 0,i??{})}return n._$AI(t),n},ct=globalThis;let ht=class extends w{constructor(){super(...arguments),this.renderOptions={host:this},this._$Do=void 0}createRenderRoot(){const t=super.createRenderRoot();return this.renderOptions.renderBefore??=t.firstChild,t}update(t){const e=this.render();this.hasUpdated||(this.renderOptions.isConnected=this.isConnected),super.update(t),this._$Do=lt(e,this.renderRoot,this.renderOptions)}connectedCallback(){super.connectedCallback(),this._$Do?.setConnected(!0)}disconnectedCallback(){super.disconnectedCallback(),this._$Do?.setConnected(!1)}render(){return U}};ht._$litElement$=!0,ht.finalized=!0,ct.litElementHydrateSupport?.({LitElement:ht});const dt=ct.litElementPolyfillSupport;dt?.({LitElement:ht}),(ct.litElementVersions??=[]).push("4.2.2");const ut=2,pt=t=>(...e)=>({_$litDirective$:t,values:e});let _t=class{constructor(t){}get _$AU(){return this._$AM._$AU}_$AT(t,e,i){this._$Ct=t,this._$AM=e,this._$Ci=i}_$AS(t,e){return this.update(t,e)}update(t,e){return this.render(...e)}};const gt={},mt=pt(class extends _t{constructor(){super(...arguments),this.ot=gt}render(t,e){return e()}update(t,[e,i]){if(Array.isArray(e)){if(Array.isArray(this.ot)&&this.ot.length===e.length&&e.every((t,e)=>t===this.ot[e]))return U}else if(this.ot===e)return U;return this.ot=Array.isArray(e)?Array.from(e):e,this.render(e,i)}}),{I:ft}=at,vt=t=>t,yt=()=>document.createComment(""),bt=(t,e,i)=>{const s=t._$AA.parentNode,n=void 0===e?t._$AB:e._$AA;if(void 0===i){const e=s.insertBefore(yt(),n),o=s.insertBefore(yt(),n);i=new ft(e,o,t,t.options)}else{const e=i._$AB.nextSibling,o=i._$AM,a=o!==t;if(a){let e;i._$AQ?.(t),i._$AM=t,void 0!==i._$AP&&(e=t._$AU)!==o._$AU&&i._$AP(e)}if(e!==n||a){let t=i._$AA;for(;t!==e;){const e=vt(t).nextSibling;vt(s).insertBefore(t,n),t=e}}}return i},wt=(t,e,i=t)=>(t._$AI(e,i),t),kt={},xt=(t,e=kt)=>t._$AH=e,$t=t=>{t._$AR(),t._$AA.remove()},St=(t,e,i)=>{const s=new Map;for(let n=e;n<=i;n++)s.set(t[n],n);return s},Mt=pt(class extends _t{constructor(t){if(super(t),t.type!==ut)throw Error("repeat() can only be used in text expressions")}dt(t,e,i){let s;void 0===i?i=e:void 0!==e&&(s=e);const n=[],o=[];let a=0;for(const e of t)n[a]=s?s(e,a):a,o[a]=i(e,a),a++;return{values:o,keys:n}}render(t,e,i){return this.dt(t,e,i).values}update(t,[e,i,s]){const n=(t=>t._$AH)(t),{values:o,keys:a}=this.dt(e,i,s);if(!Array.isArray(n))return this.ut=a,o;const r=this.ut??=[],l=[];let c,h,d=0,u=n.length-1,p=0,_=o.length-1;for(;d<=u&&p<=_;)if(null===n[d])d++;else if(null===n[u])u--;else if(r[d]===a[p])l[p]=wt(n[d],o[p]),d++,p++;else if(r[u]===a[_])l[_]=wt(n[u],o[_]),u--,_--;else if(r[d]===a[_])l[_]=wt(n[d],o[_]),bt(t,l[_+1],n[d]),d++,_--;else if(r[u]===a[p])l[p]=wt(n[u],o[p]),bt(t,n[d],n[u]),u--,p++;else if(void 0===c&&(c=St(a,p,_),h=St(r,d,u)),c.has(r[d]))if(c.has(r[u])){const e=h.get(a[p]),i=void 0!==e?n[e]:null;if(null===i){const e=bt(t,n[d]);wt(e,o[p]),l[p]=e}else l[p]=wt(i,o[p]),bt(t,n[d],i),n[e]=null;p++}else $t(n[u]),u--;else $t(n[d]),d++;for(;p<=_;){const e=bt(t,l[_+1]);wt(e,o[p]),l[p++]=e}for(;d<=u;){const t=n[d++];null!==t&&$t(t)}return this.ut=a,xt(t,l),U}}),Ct=new WeakMap;let Dt=0;class Tt extends ht{constructor(){super(...arguments),this.title="",this.icon="",this.wide=!1,this.dismissOnScrim=!1,this.hass=null,this._opener=null,this._focusRoot=null,this._useHaDialog=!1,this._closing=!1,this._overlays=[],this._titleId="hp-dialog-title-"+ ++Dt,this._focusInitial=()=>{const t=this._focusableElements(),e=t.find(t=>t.hasAttribute("autofocus"))||t[0]||(this._useHaDialog?null:this.renderRoot.querySelector(".close"))||this.renderRoot.querySelector(".surface")||this.renderRoot.querySelector("ha-dialog");e?.focus({preventScroll:!0})},this._requestClose=()=>{this._closing||(this._closing=!0,this.dispatchEvent(new CustomEvent("hp-close",{bubbles:!0,composed:!0})))},this._onKeyDown=t=>{if("Escape"===t.key){t.preventDefault(),t.stopImmediatePropagation(),this._pruneOverlays();const e=this._overlays[this._overlays.length-1];return e?void this._closeOverlay(e,"escape"):void this._requestClose()}if("Tab"!==t.key||this._useHaDialog)return;const e=this.renderRoot.querySelector(".close"),i=e?[e,...this._focusableElements()]:this._focusableElements();if(!i.length)return t.preventDefault(),void this.renderRoot.querySelector(".surface")?.focus({preventScroll:!0});const s=this._deepActiveElement(),n=i[0],o=i[i.length-1];!t.shiftKey||s!==n&&i.includes(s)?t.shiftKey||s!==o||(t.preventDefault(),n.focus()):(t.preventDefault(),o.focus())},this._onFallbackCancel=t=>{t.preventDefault(),this._requestClose()},this._onFallbackClick=t=>{this.dismissOnScrim&&t.target===t.currentTarget&&this._requestClose()}}connectedCallback(){super.connectedCallback(),this._opener=this._deepActiveElement();const t=this.getRootNode();this._focusRoot=t;const e=Ct.get(t)||{dialogs:new Set,opener:this._opener};e.dialogs.add(this),Ct.set(t,e),this._useHaDialog=!!customElements.get("ha-dialog"),this.addEventListener("keydown",this._onKeyDown,!0)}disconnectedCallback(){this.removeEventListener("keydown",this._onKeyDown,!0);const t=[...this._overlays];this._overlays=[];for(const e of t.reverse())e.close("disconnect");const e=this._focusRoot,i=this._opener;this._opener=null,this._focusRoot=null;const s=e?Ct.get(e):void 0;s?.dialogs.delete(this),super.disconnectedCallback(),e&&s&&requestAnimationFrame(()=>{const t=Ct.get(e);if(!t)return;if(!t.dialogs.size)return t.opener?.isConnected&&t.opener.focus({preventScroll:!0}),void Ct.delete(e);const s=i?.closest("hp-dialog");i?.isConnected&&s&&t.dialogs.has(s)&&i.focus({preventScroll:!0})})}firstUpdated(t){if(super.firstUpdated(t),!this._useHaDialog){const t=this.renderRoot.querySelector("dialog");t&&!t.open&&t.showModal()}queueMicrotask(()=>this._focusInitial())}_deepActiveElement(){let t=document.activeElement;for(;t?.shadowRoot?.activeElement;)t=t.shadowRoot.activeElement;return t&&t!==document.body?t:null}_focusableElements(){const t=["[autofocus]","a[href]","button:not([disabled])",'input:not([disabled]):not([type="hidden"])',"select:not([disabled])","textarea:not([disabled])",'[contenteditable="true"]','[tabindex]:not([tabindex="-1"])'].join(","),e=[],i=new Set,s=n=>{if(!i.has(n)){if(i.add(n),n instanceof HTMLElement){if(n.matches(t)&&e.push(n),n instanceof HTMLSlotElement){for(const t of n.assignedNodes({flatten:!0}))s(t);return}if(n.shadowRoot){for(const t of n.shadowRoot.childNodes)s(t);return}}for(const t of n.childNodes)s(t)}};for(const t of this.childNodes)s(t);const n=this.overlayPortal();return n&&s(n),e.filter(t=>{let e=t;for(;e;){const t=getComputedStyle(e);if(e.hidden||e.inert||"true"===e.getAttribute("aria-hidden")||"none"===t.display||"hidden"===t.visibility)return!1;if(e=e.assignedSlot||e.parentElement||(e.getRootNode()instanceof ShadowRoot?e.getRootNode().host:null),e===this)break}return!0})}_pruneOverlays(){this._overlays=this._overlays.filter(t=>t.owner.isConnected)}_closeOverlay(t,e){const i=this._overlays.findIndex(e=>e.token===t.token);i>=0&&this._overlays.splice(i,1),t.close(e)}registerOverlay(t){this._pruneOverlays();const e=this._overlays.find(e=>e.owner===t.owner);e&&this._overlays.splice(this._overlays.indexOf(e),1);const i=t.group||"transient";for(const t of[...this._overlays].reverse())t.group===i&&this._closeOverlay(t,"exclusive");const s={...t,group:i,token:Symbol("hp-overlay")};this._overlays.push(s);let n=!1;return()=>{if(n)return;n=!0;const t=this._overlays.findIndex(t=>t.token===s.token);t>=0&&this._overlays.splice(t,1)}}closeTransientOverlays(t="outside"){this._pruneOverlays();const e=[...this._overlays].filter(t=>"transient"===(t.group||"transient"));for(const i of e.reverse())this._closeOverlay(i,t);return e.length>0}overlayPortal(){return this.renderRoot.querySelector(".overlay-portal")}render(){const t=j` +globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="49963a7758df03d7aaaa3af3b9f198d629f4ca44af5c8ef9834c7afce5fda8ba";const t=globalThis,e=t.ShadowRoot&&(void 0===t.ShadyCSS||t.ShadyCSS.nativeShadow)&&"adoptedStyleSheets"in Document.prototype&&"replace"in CSSStyleSheet.prototype,i=Symbol(),s=new WeakMap;let n=class{constructor(t,e,s){if(this._$cssResult$=!0,s!==i)throw Error("CSSResult is not constructable. Use `unsafeCSS` or `css` instead.");this.cssText=t,this.t=e}get styleSheet(){let t=this.o;const i=this.t;if(e&&void 0===t){const e=void 0!==i&&1===i.length;e&&(t=s.get(i)),void 0===t&&((this.o=t=new CSSStyleSheet).replaceSync(this.cssText),e&&s.set(i,t))}return t}toString(){return this.cssText}};const o=(t,...e)=>{const s=1===t.length?t[0]:e.reduce((e,i,s)=>e+(t=>{if(!0===t._$cssResult$)return t.cssText;if("number"==typeof t)return t;throw Error("Value passed to 'css' function must be a 'css' function result: "+t+". Use 'unsafeCSS' to pass non-literal values, but take care to ensure page security.")})(i)+t[s+1],t[0]);return new n(s,t,i)},a=e?t=>t:t=>t instanceof CSSStyleSheet?(t=>{let e="";for(const i of t.cssRules)e+=i.cssText;return(t=>new n("string"==typeof t?t:t+"",void 0,i))(e)})(t):t,{is:r,defineProperty:l,getOwnPropertyDescriptor:c,getOwnPropertyNames:h,getOwnPropertySymbols:d,getPrototypeOf:u}=Object,p=globalThis,_=p.trustedTypes,g=_?_.emptyScript:"",m=p.reactiveElementPolyfillSupport,f=(t,e)=>t,v={toAttribute(t,e){switch(e){case Boolean:t=t?g:null;break;case Object:case Array:t=null==t?t:JSON.stringify(t)}return t},fromAttribute(t,e){let i=t;switch(e){case Boolean:i=null!==t;break;case Number:i=null===t?null:Number(t);break;case Object:case Array:try{i=JSON.parse(t)}catch(t){i=null}}return i}},y=(t,e)=>!r(t,e),b={attribute:!0,type:String,converter:v,reflect:!1,useDefault:!1,hasChanged:y};Symbol.metadata??=Symbol("metadata"),p.litPropertyMetadata??=new WeakMap;let w=class extends HTMLElement{static addInitializer(t){this._$Ei(),(this.l??=[]).push(t)}static get observedAttributes(){return this.finalize(),this._$Eh&&[...this._$Eh.keys()]}static createProperty(t,e=b){if(e.state&&(e.attribute=!1),this._$Ei(),this.prototype.hasOwnProperty(t)&&((e=Object.create(e)).wrapped=!0),this.elementProperties.set(t,e),!e.noAccessor){const i=Symbol(),s=this.getPropertyDescriptor(t,i,e);void 0!==s&&l(this.prototype,t,s)}}static getPropertyDescriptor(t,e,i){const{get:s,set:n}=c(this.prototype,t)??{get(){return this[e]},set(t){this[e]=t}};return{get:s,set(e){const o=s?.call(this);n?.call(this,e),this.requestUpdate(t,o,i)},configurable:!0,enumerable:!0}}static getPropertyOptions(t){return this.elementProperties.get(t)??b}static _$Ei(){if(this.hasOwnProperty(f("elementProperties")))return;const t=u(this);t.finalize(),void 0!==t.l&&(this.l=[...t.l]),this.elementProperties=new Map(t.elementProperties)}static finalize(){if(this.hasOwnProperty(f("finalized")))return;if(this.finalized=!0,this._$Ei(),this.hasOwnProperty(f("properties"))){const t=this.properties,e=[...h(t),...d(t)];for(const i of e)this.createProperty(i,t[i])}const t=this[Symbol.metadata];if(null!==t){const e=litPropertyMetadata.get(t);if(void 0!==e)for(const[t,i]of e)this.elementProperties.set(t,i)}this._$Eh=new Map;for(const[t,e]of this.elementProperties){const i=this._$Eu(t,e);void 0!==i&&this._$Eh.set(i,t)}this.elementStyles=this.finalizeStyles(this.styles)}static finalizeStyles(t){const e=[];if(Array.isArray(t)){const i=new Set(t.flat(1/0).reverse());for(const t of i)e.unshift(a(t))}else void 0!==t&&e.push(a(t));return e}static _$Eu(t,e){const i=e.attribute;return!1===i?void 0:"string"==typeof i?i:"string"==typeof t?t.toLowerCase():void 0}constructor(){super(),this._$Ep=void 0,this.isUpdatePending=!1,this.hasUpdated=!1,this._$Em=null,this._$Ev()}_$Ev(){this._$ES=new Promise(t=>this.enableUpdating=t),this._$AL=new Map,this._$E_(),this.requestUpdate(),this.constructor.l?.forEach(t=>t(this))}addController(t){(this._$EO??=new Set).add(t),void 0!==this.renderRoot&&this.isConnected&&t.hostConnected?.()}removeController(t){this._$EO?.delete(t)}_$E_(){const t=new Map,e=this.constructor.elementProperties;for(const i of e.keys())this.hasOwnProperty(i)&&(t.set(i,this[i]),delete this[i]);t.size>0&&(this._$Ep=t)}createRenderRoot(){const i=this.shadowRoot??this.attachShadow(this.constructor.shadowRootOptions);return((i,s)=>{if(e)i.adoptedStyleSheets=s.map(t=>t instanceof CSSStyleSheet?t:t.styleSheet);else for(const e of s){const s=document.createElement("style"),n=t.litNonce;void 0!==n&&s.setAttribute("nonce",n),s.textContent=e.cssText,i.appendChild(s)}})(i,this.constructor.elementStyles),i}connectedCallback(){this.renderRoot??=this.createRenderRoot(),this.enableUpdating(!0),this._$EO?.forEach(t=>t.hostConnected?.())}enableUpdating(t){}disconnectedCallback(){this._$EO?.forEach(t=>t.hostDisconnected?.())}attributeChangedCallback(t,e,i){this._$AK(t,i)}_$ET(t,e){const i=this.constructor.elementProperties.get(t),s=this.constructor._$Eu(t,i);if(void 0!==s&&!0===i.reflect){const n=(void 0!==i.converter?.toAttribute?i.converter:v).toAttribute(e,i.type);this._$Em=t,null==n?this.removeAttribute(s):this.setAttribute(s,n),this._$Em=null}}_$AK(t,e){const i=this.constructor,s=i._$Eh.get(t);if(void 0!==s&&this._$Em!==s){const t=i.getPropertyOptions(s),n="function"==typeof t.converter?{fromAttribute:t.converter}:void 0!==t.converter?.fromAttribute?t.converter:v;this._$Em=s;const o=n.fromAttribute(e,t.type);this[s]=o??this._$Ej?.get(s)??o,this._$Em=null}}requestUpdate(t,e,i,s=!1,n){if(void 0!==t){const o=this.constructor;if(!1===s&&(n=this[t]),i??=o.getPropertyOptions(t),!((i.hasChanged??y)(n,e)||i.useDefault&&i.reflect&&n===this._$Ej?.get(t)&&!this.hasAttribute(o._$Eu(t,i))))return;this.C(t,e,i)}!1===this.isUpdatePending&&(this._$ES=this._$EP())}C(t,e,{useDefault:i,reflect:s,wrapped:n},o){i&&!(this._$Ej??=new Map).has(t)&&(this._$Ej.set(t,o??e??this[t]),!0!==n||void 0!==o)||(this._$AL.has(t)||(this.hasUpdated||i||(e=void 0),this._$AL.set(t,e)),!0===s&&this._$Em!==t&&(this._$Eq??=new Set).add(t))}async _$EP(){this.isUpdatePending=!0;try{await this._$ES}catch(t){Promise.reject(t)}const t=this.scheduleUpdate();return null!=t&&await t,!this.isUpdatePending}scheduleUpdate(){return this.performUpdate()}performUpdate(){if(!this.isUpdatePending)return;if(!this.hasUpdated){if(this.renderRoot??=this.createRenderRoot(),this._$Ep){for(const[t,e]of this._$Ep)this[t]=e;this._$Ep=void 0}const t=this.constructor.elementProperties;if(t.size>0)for(const[e,i]of t){const{wrapped:t}=i,s=this[e];!0!==t||this._$AL.has(e)||void 0===s||this.C(e,void 0,i,s)}}let t=!1;const e=this._$AL;try{t=this.shouldUpdate(e),t?(this.willUpdate(e),this._$EO?.forEach(t=>t.hostUpdate?.()),this.update(e)):this._$EM()}catch(e){throw t=!1,this._$EM(),e}t&&this._$AE(e)}willUpdate(t){}_$AE(t){this._$EO?.forEach(t=>t.hostUpdated?.()),this.hasUpdated||(this.hasUpdated=!0,this.firstUpdated(t)),this.updated(t)}_$EM(){this._$AL=new Map,this.isUpdatePending=!1}get updateComplete(){return this.getUpdateComplete()}getUpdateComplete(){return this._$ES}shouldUpdate(t){return!0}update(t){this._$Eq&&=this._$Eq.forEach(t=>this._$ET(t,this[t])),this._$EM()}updated(t){}firstUpdated(t){}};w.elementStyles=[],w.shadowRootOptions={mode:"open"},w[f("elementProperties")]=new Map,w[f("finalized")]=new Map,m?.({ReactiveElement:w}),(p.reactiveElementVersions??=[]).push("2.1.2");const k=globalThis,x=t=>t,$=k.trustedTypes,S=$?$.createPolicy("lit-html",{createHTML:t=>t}):void 0,M="$lit$",C=`lit$${Math.random().toFixed(9).slice(2)}$`,D="?"+C,T=`<${D}>`,P=document,R=()=>P.createComment(""),A=t=>null===t||"object"!=typeof t&&"function"!=typeof t,I=Array.isArray,E="[ \t\n\f\r]",F=/<(?:(!--|\/[^a-zA-Z])|(\/?[a-zA-Z][^>\s]*)|(\/?$))/g,z=/-->/g,O=/>/g,H=RegExp(`>|${E}(?:([^\\s"'>=/]+)(${E}*=${E}*(?:[^ \t\n\f\r"'\`<>=]|("|')|))|$)`,"g"),N=/'/g,L=/"/g,B=/^(?:script|style|textarea|title)$/i,q=t=>(e,...i)=>({_$litType$:t,strings:e,values:i}),j=q(1),W=q(2),U=Symbol.for("lit-noChange"),G=Symbol.for("lit-nothing"),V=new WeakMap,K=P.createTreeWalker(P,129);function Y(t,e){if(!I(t)||!t.hasOwnProperty("raw"))throw Error("invalid template strings array");return void 0!==S?S.createHTML(e):e}const X=(t,e)=>{const i=t.length-1,s=[];let n,o=2===e?"":3===e?"":"",a=F;for(let e=0;e"===l[0]?(a=n??F,c=-1):void 0===l[1]?c=-2:(c=a.lastIndex-l[2].length,r=l[1],a=void 0===l[3]?H:'"'===l[3]?L:N):a===L||a===N?a=H:a===z||a===O?a=F:(a=H,n=void 0);const d=a===H&&t[e+1].startsWith("/>")?" ":"";o+=a===F?i+T:c>=0?(s.push(r),i.slice(0,c)+M+i.slice(c)+C+d):i+C+(-2===c?e:d)}return[Y(t,o+(t[i]||"")+(2===e?"":3===e?"":"")),s]};class J{constructor({strings:t,_$litType$:e},i){let s;this.parts=[];let n=0,o=0;const a=t.length-1,r=this.parts,[l,c]=X(t,e);if(this.el=J.createElement(l,i),K.currentNode=this.el.content,2===e||3===e){const t=this.el.content.firstChild;t.replaceWith(...t.childNodes)}for(;null!==(s=K.nextNode())&&r.length0){s.textContent=$?$.emptyScript:"";for(let i=0;iI(t)||"function"==typeof t?.[Symbol.iterator])(t)?this.k(t):this._(t)}O(t){return this._$AA.parentNode.insertBefore(t,this._$AB)}T(t){this._$AH!==t&&(this._$AR(),this._$AH=this.O(t))}_(t){this._$AH!==G&&A(this._$AH)?this._$AA.nextSibling.data=t:this.T(P.createTextNode(t)),this._$AH=t}$(t){const{values:e,_$litType$:i}=t,s="number"==typeof i?this._$AC(t):(void 0===i.el&&(i.el=J.createElement(Y(i.h,i.h[0]),this.options)),i);if(this._$AH?._$AD===s)this._$AH.p(e);else{const t=new Q(s,this),i=t.u(this.options);t.p(e),this.T(i),this._$AH=t}}_$AC(t){let e=V.get(t.strings);return void 0===e&&V.set(t.strings,e=new J(t)),e}k(t){I(this._$AH)||(this._$AH=[],this._$AR());const e=this._$AH;let i,s=0;for(const n of t)s===e.length?e.push(i=new tt(this.O(R()),this.O(R()),this,this.options)):i=e[s],i._$AI(n),s++;s2||""!==i[0]||""!==i[1]?(this._$AH=Array(i.length-1).fill(new String),this.strings=i):this._$AH=G}_$AI(t,e=this,i,s){const n=this.strings;let o=!1;if(void 0===n)t=Z(this,t,e,0),o=!A(t)||t!==this._$AH&&t!==U,o&&(this._$AH=t);else{const s=t;let a,r;for(t=n[0],a=0;a{const s=i?.renderBefore??e;let n=s._$litPart$;if(void 0===n){const t=i?.renderBefore??null;s._$litPart$=n=new tt(e.insertBefore(R(),t),t,void 0,i??{})}return n._$AI(t),n},ct=globalThis;let ht=class extends w{constructor(){super(...arguments),this.renderOptions={host:this},this._$Do=void 0}createRenderRoot(){const t=super.createRenderRoot();return this.renderOptions.renderBefore??=t.firstChild,t}update(t){const e=this.render();this.hasUpdated||(this.renderOptions.isConnected=this.isConnected),super.update(t),this._$Do=lt(e,this.renderRoot,this.renderOptions)}connectedCallback(){super.connectedCallback(),this._$Do?.setConnected(!0)}disconnectedCallback(){super.disconnectedCallback(),this._$Do?.setConnected(!1)}render(){return U}};ht._$litElement$=!0,ht.finalized=!0,ct.litElementHydrateSupport?.({LitElement:ht});const dt=ct.litElementPolyfillSupport;dt?.({LitElement:ht}),(ct.litElementVersions??=[]).push("4.2.2");const ut=2,pt=t=>(...e)=>({_$litDirective$:t,values:e});let _t=class{constructor(t){}get _$AU(){return this._$AM._$AU}_$AT(t,e,i){this._$Ct=t,this._$AM=e,this._$Ci=i}_$AS(t,e){return this.update(t,e)}update(t,e){return this.render(...e)}};const gt={},mt=pt(class extends _t{constructor(){super(...arguments),this.ot=gt}render(t,e){return e()}update(t,[e,i]){if(Array.isArray(e)){if(Array.isArray(this.ot)&&this.ot.length===e.length&&e.every((t,e)=>t===this.ot[e]))return U}else if(this.ot===e)return U;return this.ot=Array.isArray(e)?Array.from(e):e,this.render(e,i)}}),{I:ft}=at,vt=t=>t,yt=()=>document.createComment(""),bt=(t,e,i)=>{const s=t._$AA.parentNode,n=void 0===e?t._$AB:e._$AA;if(void 0===i){const e=s.insertBefore(yt(),n),o=s.insertBefore(yt(),n);i=new ft(e,o,t,t.options)}else{const e=i._$AB.nextSibling,o=i._$AM,a=o!==t;if(a){let e;i._$AQ?.(t),i._$AM=t,void 0!==i._$AP&&(e=t._$AU)!==o._$AU&&i._$AP(e)}if(e!==n||a){let t=i._$AA;for(;t!==e;){const e=vt(t).nextSibling;vt(s).insertBefore(t,n),t=e}}}return i},wt=(t,e,i=t)=>(t._$AI(e,i),t),kt={},xt=(t,e=kt)=>t._$AH=e,$t=t=>{t._$AR(),t._$AA.remove()},St=(t,e,i)=>{const s=new Map;for(let n=e;n<=i;n++)s.set(t[n],n);return s},Mt=pt(class extends _t{constructor(t){if(super(t),t.type!==ut)throw Error("repeat() can only be used in text expressions")}dt(t,e,i){let s;void 0===i?i=e:void 0!==e&&(s=e);const n=[],o=[];let a=0;for(const e of t)n[a]=s?s(e,a):a,o[a]=i(e,a),a++;return{values:o,keys:n}}render(t,e,i){return this.dt(t,e,i).values}update(t,[e,i,s]){const n=(t=>t._$AH)(t),{values:o,keys:a}=this.dt(e,i,s);if(!Array.isArray(n))return this.ut=a,o;const r=this.ut??=[],l=[];let c,h,d=0,u=n.length-1,p=0,_=o.length-1;for(;d<=u&&p<=_;)if(null===n[d])d++;else if(null===n[u])u--;else if(r[d]===a[p])l[p]=wt(n[d],o[p]),d++,p++;else if(r[u]===a[_])l[_]=wt(n[u],o[_]),u--,_--;else if(r[d]===a[_])l[_]=wt(n[d],o[_]),bt(t,l[_+1],n[d]),d++,_--;else if(r[u]===a[p])l[p]=wt(n[u],o[p]),bt(t,n[d],n[u]),u--,p++;else if(void 0===c&&(c=St(a,p,_),h=St(r,d,u)),c.has(r[d]))if(c.has(r[u])){const e=h.get(a[p]),i=void 0!==e?n[e]:null;if(null===i){const e=bt(t,n[d]);wt(e,o[p]),l[p]=e}else l[p]=wt(i,o[p]),bt(t,n[d],i),n[e]=null;p++}else $t(n[u]),u--;else $t(n[d]),d++;for(;p<=_;){const e=bt(t,l[_+1]);wt(e,o[p]),l[p++]=e}for(;d<=u;){const t=n[d++];null!==t&&$t(t)}return this.ut=a,xt(t,l),U}}),Ct=new WeakMap;let Dt=0;class Tt extends ht{constructor(){super(...arguments),this.title="",this.icon="",this.wide=!1,this.dismissOnScrim=!1,this.hass=null,this._opener=null,this._focusRoot=null,this._useHaDialog=!1,this._closing=!1,this._overlays=[],this._titleId="hp-dialog-title-"+ ++Dt,this._focusInitial=()=>{const t=this._focusableElements(),e=t.find(t=>t.hasAttribute("autofocus"))||t[0]||(this._useHaDialog?null:this.renderRoot.querySelector(".close"))||this.renderRoot.querySelector(".surface")||this.renderRoot.querySelector("ha-dialog");e?.focus({preventScroll:!0})},this._requestClose=()=>{this._closing||(this._closing=!0,this.dispatchEvent(new CustomEvent("hp-close",{bubbles:!0,composed:!0})))},this._onKeyDown=t=>{if("Escape"===t.key){t.preventDefault(),t.stopImmediatePropagation(),this._pruneOverlays();const e=this._overlays[this._overlays.length-1];return e?void this._closeOverlay(e,"escape"):void this._requestClose()}if("Tab"!==t.key||this._useHaDialog)return;const e=this.renderRoot.querySelector(".close"),i=e?[e,...this._focusableElements()]:this._focusableElements();if(!i.length)return t.preventDefault(),void this.renderRoot.querySelector(".surface")?.focus({preventScroll:!0});const s=this._deepActiveElement(),n=i[0],o=i[i.length-1];!t.shiftKey||s!==n&&i.includes(s)?t.shiftKey||s!==o||(t.preventDefault(),n.focus()):(t.preventDefault(),o.focus())},this._onFallbackCancel=t=>{t.preventDefault(),this._requestClose()},this._onFallbackClick=t=>{this.dismissOnScrim&&t.target===t.currentTarget&&this._requestClose()}}connectedCallback(){super.connectedCallback(),this._opener=this._deepActiveElement();const t=this.getRootNode();this._focusRoot=t;const e=Ct.get(t)||{dialogs:new Set,opener:this._opener};e.dialogs.add(this),Ct.set(t,e),this._useHaDialog=!!customElements.get("ha-dialog"),this.addEventListener("keydown",this._onKeyDown,!0)}disconnectedCallback(){this.removeEventListener("keydown",this._onKeyDown,!0);const t=[...this._overlays];this._overlays=[];for(const e of t.reverse())e.close("disconnect");const e=this._focusRoot,i=this._opener;this._opener=null,this._focusRoot=null;const s=e?Ct.get(e):void 0;s?.dialogs.delete(this),super.disconnectedCallback(),e&&s&&requestAnimationFrame(()=>{const t=Ct.get(e);if(!t)return;if(!t.dialogs.size)return t.opener?.isConnected&&t.opener.focus({preventScroll:!0}),void Ct.delete(e);const s=i?.closest("hp-dialog");i?.isConnected&&s&&t.dialogs.has(s)&&i.focus({preventScroll:!0})})}firstUpdated(t){if(super.firstUpdated(t),!this._useHaDialog){const t=this.renderRoot.querySelector("dialog");t&&!t.open&&t.showModal()}queueMicrotask(()=>this._focusInitial())}_deepActiveElement(){let t=document.activeElement;for(;t?.shadowRoot?.activeElement;)t=t.shadowRoot.activeElement;return t&&t!==document.body?t:null}_focusableElements(){const t=["[autofocus]","a[href]","button:not([disabled])",'input:not([disabled]):not([type="hidden"])',"select:not([disabled])","textarea:not([disabled])",'[contenteditable="true"]','[tabindex]:not([tabindex="-1"])'].join(","),e=[],i=new Set,s=n=>{if(!i.has(n)){if(i.add(n),n instanceof HTMLElement){if(n.matches(t)&&e.push(n),n instanceof HTMLSlotElement){for(const t of n.assignedNodes({flatten:!0}))s(t);return}if(n.shadowRoot){for(const t of n.shadowRoot.childNodes)s(t);return}}for(const t of n.childNodes)s(t)}};for(const t of this.childNodes)s(t);const n=this.overlayPortal();return n&&s(n),e.filter(t=>{let e=t;for(;e;){const t=getComputedStyle(e);if(e.hidden||e.inert||"true"===e.getAttribute("aria-hidden")||"none"===t.display||"hidden"===t.visibility)return!1;if(e=e.assignedSlot||e.parentElement||(e.getRootNode()instanceof ShadowRoot?e.getRootNode().host:null),e===this)break}return!0})}_pruneOverlays(){this._overlays=this._overlays.filter(t=>t.owner.isConnected)}_closeOverlay(t,e){const i=this._overlays.findIndex(e=>e.token===t.token);i>=0&&this._overlays.splice(i,1),t.close(e)}registerOverlay(t){this._pruneOverlays();const e=this._overlays.find(e=>e.owner===t.owner);e&&this._overlays.splice(this._overlays.indexOf(e),1);const i=t.group||"transient";for(const t of[...this._overlays].reverse())t.group===i&&this._closeOverlay(t,"exclusive");const s={...t,group:i,token:Symbol("hp-overlay")};this._overlays.push(s);let n=!1;return()=>{if(n)return;n=!0;const t=this._overlays.findIndex(t=>t.token===s.token);t>=0&&this._overlays.splice(t,1)}}closeTransientOverlays(t="outside"){this._pruneOverlays();const e=[...this._overlays].filter(t=>"transient"===(t.group||"transient"));for(const i of e.reverse())this._closeOverlay(i,t);return e.length>0}overlayPortal(){return this.renderRoot.querySelector(".overlay-portal")}render(){const t=j` ${this.icon?j``:G} ${this.title} `;return this._useHaDialog?j` `})} - `}const er={color:"#607d8b",opacity:1,widthCm:3.6,fill:!1,fillColor:"#607d8b",fillOpacity:.25},ir=(t,e=1)=>{const i=Number(t);return Number.isFinite(i)?Math.min(1,Math.max(0,i)):e},sr=t=>{let e=Number(t);return Number.isFinite(e)?(e=(e%360+360)%360,e>180?e-360:e):0};function nr(t,e,i){return sr(e)?[t.x,t.y]:i([t.x,t.y])}const or=(t,e,i)=>{const s=Number(t),n=Number.isFinite(e)&&e>0?e:5;return Number.isFinite(s)&&s>0?s/n*i:0},ar=(t,e,i)=>{const s=Number(t),n=Number.isFinite(e)&&e>0?e:5;return Number.isFinite(s)&&i>0?s/i*n:0},rr=(t,e,i,s=er.widthCm)=>{const n=Number(t?.width_cm);if(Number.isFinite(n)&&n>0)return n;const o=Number(t?.width);return Number.isFinite(o)&&o>0?ar(o,e,i):s};function lr(t,e){return{color:t.color,opacity:ir(t.opacity),width_cm:Math.max(.1,Math.min(100,Number(t.widthCm)||.1)),...e?{fill:t.fill,fill_color:t.fillColor,fill_opacity:ir(t.fillOpacity,.25)}:{}}}function cr(t){const e=t.x+t.w/2,i=t.y+t.h/2,s=sr(t.angle)*Math.PI/180,n=Math.cos(s),o=Math.sin(s),a=(t,s)=>{const a=t-e,r=s-i;return[e+a*n-r*o,i+a*o+r*n]};return[a(t.x,t.y),a(t.x+t.w,t.y),a(t.x+t.w,t.y+t.h),a(t.x,t.y+t.h)]}function hr(t){const e=cr(t),i=(t,e)=>[(t[0]+e[0])/2,(t[1]+e[1])/2],s=[(e[0][0]+e[2][0])/2,(e[0][1]+e[2][1])/2];return{points:[...e,i(e[0],e[1]),i(e[1],e[2]),i(e[2],e[3]),i(e[3],e[0]),s],segments:e.map((t,i)=>({a:t,b:e[(i+1)%4]}))}}function dr(t,e,i,s,n,o,a,r){const l=sr(t.angle)*Math.PI/180,c=Math.cos(l),h=Math.sin(l),d=-Math.sin(l),u=Math.cos(l),p=t.x+t.w/2,_=t.y+t.h/2,g=e>0?-t.w/2:t.w/2,m=i>0?-t.h/2:t.h/2,f=p+g*c+m*d,v=_+g*h+m*u,y=s-f,b=n-v;let w=(y*c+b*h)*(e>0?1:-1),k=(y*d+b*u)*(i>0?1:-1),x=null;if(o){const e=w/Math.max(t.w,r),i=k/Math.max(t.h,r);x=Math.max(r/Math.max(t.w,r),r/Math.max(t.h,r),e,i),w=t.w*x,k=t.h*x}if(a>0)if(o){const e=Math.max(1,Math.round(t.w/a)),i=Math.max(1,Math.round(t.h/a));if(Math.abs(t.w-e*a)<1e-6&&Math.abs(t.h-i*a)<1e-6){const s=(t,e)=>{let i=Math.abs(t),s=Math.abs(e);for(;s;)[i,s]=[s,i%s];return Math.max(1,i)},n=1/s(e,i),o=Math.max(r/t.w,r/t.h),a=Math.max(o,Math.round((x??1)/n)*n);w=t.w*a,k=t.h*a}else{t.w>=t.h?(w=Math.round(w/a)*a,k=w*(t.h/Math.max(t.w,r))):(k=Math.round(k/a)*a,w=k*(t.w/Math.max(t.h,r)))}}else w=Math.round(w/a)*a,k=Math.round(k/a)*a;w=Math.max(r,w),k=Math.max(r,k);return{x:f+(e>0?w/2:-w/2)*c+(i>0?k/2:-k/2)*d-w/2,y:v+(e>0?w/2:-w/2)*h+(i>0?k/2:-k/2)*u-k/2,w:w,h:k,angle:sr(t.angle)||void 0}}const ur=(t,e,i)=>{const s=i[0]-e[0],n=i[1]-e[1],o=s*s+n*n;if(o<1e-12)return[...e];const a=Math.max(0,Math.min(1,((t[0]-e[0])*s+(t[1]-e[1])*n)/o));return[e[0]+s*a,e[1]+n*a]};const pr=15;function _r(t,e){return Number.isFinite(t)&&t>0&&Number.isFinite(e)&&e>0&&t*e<3}function gr(t){return Number.isFinite(t)?Math.max(1,Math.min(100,t)):1}function mr(t,e){return!Number.isFinite(t)||t<=0?"":String(e?Math.round(t/2.54*100)/100:Math.round(100*t)/100)}function fr(t,e,i){const s=Number(e)>0?Number(e):5;return gr(t)/s*i}function vr(t,e){return e>0&&Number.isFinite(t)?Math.round(t/e)*e:t}function yr(t,e){let i=e[0]-t[0],s=e[1]-t[1];const n=Math.hypot(i,s);return n<1e-12?[1,0]:(i/=n,s/=n,(i<-1e-12||Math.abs(i)<=1e-12&&s<0)&&(i=-i,s=-s),[i,s])}function br(t,e,i){const s=vr((t[0]+e[0])/2,i),n=vr((t[1]+e[1])/2,i),[o,a]=yr(t,e);let r=Math.atan2(a,o);r<0&&(r+=Math.PI);const l=Math.round(1800*r)/1800,c=i>0&&i<.01?6:i<1?4:2;return`${s.toFixed(c)},${n.toFixed(c)}@${l.toFixed(4)}`}function wr(t,e,i,s){return 1===s?br(t,e,i):br([t[0]/s,t[1]/s],[e[0]/s,e[1]/s],i)}function kr(t,e){if(!Array.isArray(t.a)||!Array.isArray(t.b)||t.a.length<2||t.b.length<2)return null;const i=[Number(t.a[0]),Number(t.a[1]),Number(t.b[0]),Number(t.b[1])];if(!i.every(Number.isFinite))return null;const s=e>0?e:1;return[[i[0]*s,i[1]*s],[i[2]*s,i[3]*s]]}function xr(t,e,i,s,n){const o=n>0?n:1;return{key:wr(t,e,s,o),cm:gr(i),a:[t[0]/o,t[1]/o],b:[e[0]/o,e[1]/o]}}function $r(t,e){const i=e>0?e:1,s=[];for(const e of t){const t=e.key.lastIndexOf("@");if(t<0)continue;const[n,o]=e.key.slice(0,t).split(",").map(Number),a=Number(e.key.slice(t+1));[n,o,a].every(Number.isFinite)&&s.push({w:e,x:n*i,y:o*i,ang:a})}return s}function Sr(t,e){const[i,s]=yr(t,e);let n=Math.atan2(s,i);return n<0&&(n+=Math.PI),n}function Mr(t,e){let i=Math.abs(t-e);return i>Math.PI/2&&(i=Math.PI-i),i<.02}function Cr(t,e,i,s,n=1){if(!t?.length)return null;const o=wr(e,i,s,n),a=t.find(t=>t.key===o);if(a)return a;const r=n>0?n:1,l=(e[0]+i[0])/2,c=(e[1]+i[1])/2,h=Sr(e,i),d=Math.max(.5*s,1e-9)*r;for(const e of $r(t,r))if(Mr(e.ang,h)&&Math.hypot(e.x-l,e.y-c)<=d)return e.w;return null}function Dr(t,e,i,s,n=1){const o=Cr(t,e,i,s,n);if(o&&o.cm>0)return gr(o.cm);const a=function(t,e,i,s,n){if(!t?.length)return null;const o=n>0?n:1,a=Math.hypot(i[0]-e[0],i[1]-e[1]);if(a<1e-12)return null;const r=Sr(e,i),l=Math.max(.5*s,1e-9)*o;let c=null;for(const s of t){if(!(s.cm>0))continue;const t=kr(s,o);if(!t)continue;const n=Math.hypot(t[1][0]-t[0][0],t[1][1]-t[0][1]);if(n<1e-12||!Mr(Sr(t[0],t[1]),r))continue;if(sl(e[0],e[1],t[0][0],t[0][1],t[1][0],t[1][1])>l||sl(i[0],i[1],t[0][0],t[0][1],t[1][0],t[1][1])>l)continue;if(n+l(o.has(t.key)||(t=>{const e=kr(t,s);if(!e)return!1;const[i,o]=e,r=o[0]-i[0],c=o[1]-i[1],h=Math.hypot(r,c);if(h<=l)return!1;if(!a.some(t=>{const e=[t[0],t[1]],s=[t[2],t[3]];return Mr(Sr(i,o),Sr(e,s))&&sl(i[0],i[1],e[0],e[1],s[0],s[1])<=l&&sl(o[0],o[1],e[0],e[1],s[0],s[1])<=l}))return!1;const d=(n||[]).some(t=>{const e=[t[0],t[1]],s=[t[2],t[3]];if(!Mr(Sr(i,o),Sr(e,s)))return!1;const n=t=>Math.abs((t[0]-i[0])*c-(t[1]-i[1])*r)/h;if(n(e)>l||n(s)>l)return!1;const a=h*h,d=((e[0]-i[0])*r+(e[1]-i[1])*c)/a,u=((s[0]-i[0])*r+(s[1]-i[1])*c)/a;return Math.min(1,Math.max(d,u))-Math.max(0,Math.min(d,u))>l/h});return!d})(t))&&t.cm>=1&&t.cm<=100)}function Pr(t,e,i,s=8){const[n,o]=yr(t,e);let a=Math.atan2(o,n);a<0&&(a+=Math.PI);let r=i*Math.PI/180%Math.PI;r<0&&(r+=Math.PI);let l=Math.abs(a-r);return l>Math.PI/2&&(l=Math.PI-l),l<=s*Math.PI/180}function Rr(t,e,i,s,n=1){if(!t?.length)return[];if(e.length!==i.length)return t.slice();const o=new Map;for(let t=0;t0?n:1,r=Math.max(.5*s,1e-9)*a,l=new Set,c=[];for(const n of t){let t="",h=null;const d=kr(n,a);if(d)for(let n=0;nr||sl(d[1][0],d[1][1],o[0],o[1],l[0],l[1])>r)continue;const p=l[0]-o[0],_=l[1]-o[1],g=p*p+_*_;if(g<1e-18)continue;const m=t=>{const e=Math.max(0,Math.min(1,((t[0]-o[0])*p+(t[1]-o[1])*_)/g));return[c[0]+(u[0]-c[0])*e,c[1]+(u[1]-c[1])*e]};h=[m(d[0]),m(d[1])],t=wr(h[0],h[1],s,a);break}if(d||(t=o.get(n.key)||""),!t){const o=$r([n],a)[0];if(o)for(let n=0;n1.000001)continue;if(sl(o.x,o.y,l[0],l[1],c[0],c[1])>r)continue;const m=h[0]+(d[0]-h[0])*Math.max(0,Math.min(1,g)),f=h[1]+(d[1]-h[1])*Math.max(0,Math.min(1,g)),[v,y]=yr(h,d),b=Math.max(s*a,1e-6);t=wr([m-v*b,f-y*b],[m+v*b,f+y*b],s,a);break}}t||(t=n.key),l.has(t)||(l.add(t),c.push(h?xr(h[0],h[1],n.cm,s,a):{...n,key:t,cm:gr(n.cm)}))}return c}function Ar(t,e,i,s,n,o=1){const a=wr(e,i,n,o),r=(t||[]).filter(t=>t.key!==a);return null==s||s<1?r:[...r,xr(e,i,s,n,o)]}function Ir(t,e,i,s,n,o=[],a=1){let r=t?t.slice():[];for(const t of function(t,e,i,s,n=1,o=[]){const a=Xr(t,e,i,s,n,o);if(!a)return[];const r=[];for(let t=0;t0||(c=Ar(c,e,i,s,n,a)))}return c}function Fr(t){const{a:e,b:i,halfDepth:s}=t;if(!Array.isArray(e)||!Array.isArray(i)||e.length<2||i.length<2||![e[0],e[1],i[0],i[1]].every(Number.isFinite))return null;const n=i[0]-e[0],o=i[1]-e[1],a=Math.hypot(n,o);if(!(a>1e-9&&s>0&&Number.isFinite(s)))return null;const r=-o/a*s,l=n/a*s;return[[e[0]+r,e[1]+l],[i[0]+r,i[1]+l],[i[0]-r,i[1]-l],[e[0]-r,e[1]-l]]}function zr(t,e,i){return Math.hypot(t[0]-e[0],t[1]-e[1])<=i}function Or(t,e,i){const s=e.b[0]-e.a[0],n=e.b[1]-e.a[1],o=s*s+n*n;if(!(o>i*i))return!1;const a=((t[0]-e.a[0])*s+(t[1]-e.a[1])*n)/o;if(!(a>0&&a<1))return!1;const r=[e.a[0]+s*a,e.a[1]+n*a];return Math.hypot(t[0]-r[0],t[1]-r[1])<=i}function Hr(t,e,i,s){const n=Math.hypot(e,i);if(!(n>1e-9&&s>0))return;const o=[e/n,i/n],a=t.find(t=>Math.abs(t.u[0]*o[1]-t.u[1]*o[0])<1e-9&&t.u[0]*o[0]+t.u[1]*o[1]>1-1e-9);a?a.halfDepth=Math.max(a.halfDepth,s):t.push({u:o,halfDepth:s})}function Nr(t,e=1e-6){const i=(t||[]).filter(t=>t&&Array.isArray(t.a)&&Array.isArray(t.b)&&t.a.length>=2&&t.b.length>=2&&t.a.every(Number.isFinite)&&t.b.every(Number.isFinite)&&Number.isFinite(t.halfDepth)&&t.halfDepth>0&&Math.hypot(t.b[0]-t.a[0],t.b[1]-t.a[1])>1e-9);if(i.length<2)return[];const s=Math.max(Number.isFinite(e)?e:0,1e-9),n=i.flatMap(t=>[t.a,t.b]).map(t=>[t[0],t[1]]).sort((t,e)=>t[0]-e[0]||t[1]-e[1]),o=[];for(const t of n)o.some(e=>zr(e,t,s))||o.push(t);const a=[];for(const t of o){const e=[];for(const n of i)zr(t,n.a,s)?Hr(e,n.b[0]-n.a[0],n.b[1]-n.a[1],n.halfDepth):zr(t,n.b,s)?Hr(e,n.a[0]-n.b[0],n.a[1]-n.b[1],n.halfDepth):Or(t,n,s)&&(Hr(e,n.a[0]-t[0],n.a[1]-t[1],n.halfDepth),Hr(e,n.b[0]-t[0],n.b[1]-t[1],n.halfDepth));if(!(e.length<2)){e.sort((t,e)=>Math.atan2(t.u[1],t.u[0])-Math.atan2(e.u[1],e.u[0])||t.halfDepth-e.halfDepth);for(let i=0;is*s&&a.push(m)}}}return a}function Lr(t,e,i,s){if(!(e>0)||!t||t.length<2)return"";if(i&&t.length>=3){let i=t;const n=t[t.length-1];if(t.length>=4&&Math.hypot(t[0][0]-n[0],t[0][1]-n[1])<1e-9&&(i=t.slice(0,-1)),i.length>=3){const t=i.map((t,i)=>s?.[i]||e),n=_l(i,t),o=Vr(i,t);if(n&&o)return`${Kr(n)} ${Kr(Yr(o))}`}}const n=[];for(let i=0;i=1e-9&&r>0&&n.push({a:o,b:a,halfDepth:r})}const o=[...n.map(Fr).filter(t=>!!t),...Nr(n)],a=function(t){let e=null;try{for(const i of t){if(i.length<3)continue;const t=ol(i);e=e?si(e,t):[t]}return e}catch{return null}}(o);return a?hl(a):o.map(t=>Kr(t)).join(" ")}function Br(t,e,i,s,n=1){if(!i.length)return!1;const o=qr(s,n),a=(t[0]+e[0])/2,r=(t[1]+e[1])/2,[l,c]=yr(t,e);for(const t of i){const[e,i]=yr([t[0],t[1]],[t[2],t[3]]);if(!(Math.abs(l*i-c*e)>.05)&&sl(a,r,t[0],t[1],t[2],t[3])<=o)return!0}return!1}function qr(t,e){return Math.max(t*(e>0?e:1)*.04,1e-9)}function jr(t){let e=0;for(let i=0;it[1]!=l>t[1]&&t[0]<(r-o)*(t[1]-a)/(l-a+0)+o&&(i=!i)}return i}([c[0]+.001*r,c[1]+.001*l],t)||(r=-r,l=-l),[r,l]}function Ur(t,e){const i=t[0]*e[1]-t[1]*e[0],s=t[0]*e[0]+t[1]*e[1];return Math.abs(i)<1e-9&&s>0}function Gr(t,e,i,s){const n=e[0]*s[1]-e[1]*s[0];if(Math.abs(n)<1e-12)return null;const o=[i[0]-t[0],i[1]-t[1]],a=(o[0]*s[1]-o[1]*s[0])/n;return[t[0]+a*e[0],t[1]+a*e[1]]}function Vr(t,e){const i=t?.length||0;if(i<3||e.length!==i)return null;if(e.every(t=>!(t>0)))return t.map(t=>[t[0],t[1]]);const s=[];for(let n=0;n0||d>0)){s.push([t[n][0],t[n][1]]);continue}if(h>0!=d>0){const e=t[n],i=h>0?[e[0]+u*h,e[1]+p*h]:[e[0],e[1]],o=d>0?[e[0]+_*d,e[1]+g*d]:[e[0],e[1]];s.push(i),Math.hypot(o[0]-i[0],o[1]-i[1])>1e-9&&s.push(o);continue}if(Ur(b,w)){const e=t[n],i=[e[0]+u*h,e[1]+p*h],o=[e[0]+_*d,e[1]+g*d];s.push(i),Math.hypot(o[0]-i[0],o[1]-i[1])>1e-9&&s.push(o);continue}const $=Gr(k,b,x,w),S=Math.max(h,d,1e-9);if($){if(Math.hypot($[0]-t[n][0],$[1]-t[n][1])<=4*S){s.push($);continue}}h>0&&s.push([t[n][0]+u*h,t[n][1]+p*h]),d>0&&s.push([t[n][0]+_*d,t[n][1]+g*d]),h>0||d>0||s.push([t[n][0],t[n][1]])}return s.length>=3?s:null}function Kr(t,e=!0){if(!t.length)return"";let i=`M ${t[0][0]} ${t[0][1]}`;for(let e=1;et?.id===e),r=hi(a);if(!r||r.length<3)return null;const l=qr(s,n),c=[];for(const i of t||[]){if(!i||i.id===e)continue;const t=hi(i);if(t)for(const e of Cs(r,t,l))c.push([e[0],e[1]],[e[2],e[3]])}for(const t of i||[])c.push([t[0],t[1]],[t[2],t[3]]);for(const t of o||[]){const e=kr(t,n);e&&c.push(e[0],e[1])}const h=[],d=[];for(let t=0;tl)continue;const a=((t[0]-e[0])*(i[0]-e[0])+(t[1]-e[1])*(i[1]-e[1]))/(s*s);a<=n||a>=1-n||(o.some(t=>Math.abs(t-a)*s<=2*l)||o.push(a))}o.sort((t,e)=>t-e);for(const s of o)h.push([e[0]+(i[0]-e[0])*s,e[1]+(i[1]-e[1])*s]),d.push(t)}return{poly:h,parent:d,orig:r}}function Jr(t,e,i,s){const n=e.poly.length,o=new Array(n).fill(0);if(!t?.length)return o;const a=new Set,r=[];for(let l=0;l0?(o[l]=gr(c.cm),a.add(c.key)):r.push(l)}if(!r.length)return o;const l=s>0?s:1,c=Math.max(.5*i,1e-9)*l,h=$r(t,l).filter(t=>t.w.cm>0);for(let t=r.length-1;t>=0;t--){const i=r[t],s=e.poly[i],a=e.poly[(i+1)%n],d=Sr(s,a);let u=null;for(const t of h){const e=kr(t.w,l);if(!e||!Mr(Sr(e[0],e[1]),d))continue;if(sl(s[0],s[1],e[0][0],e[0][1],e[1][0],e[1][1])>c||sl(a[0],a[1],e[0][0],e[0][1],e[1][0],e[1][1])>c)continue;const i=Math.hypot(a[0]-s[0],a[1]-s[1]),n=Math.hypot(e[1][0]-e[0][0],e[1][1]-e[0][1]),o=Math.max(0,n-i);(!u||oc||sl(n[0],n[1],e[0][0],e[0][1],e[1][0],e[1][1])>c)continue;i=!0,o=Math.max(0,Math.hypot(e[1][0]-e[0][0],e[1][1]-e[0][1])-_)}else{if(sl(t.x,t.y,s[0],s[1],n[0],n[1])>c)continue;o=Math.hypot(t.x-d,t.y-u)}(!p||i&&!p.exact||i===p.exact&&ot?.id===e),n=hi(s);if(!n)return[];const o=[];for(const s of t||[]){if(!s||s.id===e)continue;const t=hi(s);if(t)for(const e of Cs(n,t,i))o.push(e)}return o}(t,e,qr(n,r)),h=function(t,e,i,s,n){const o=qr(s,n),a=[];for(let r=0;rsl(h,d,t[0],t[1],t[2],t[3])<=o);a.push(u?"shared":"outer")}return a}(l.poly,c,s,n,r),d=Jr(i,l,n,r),u=d.map((t,e)=>h[e]&&t>0?fr(t,o,a)/2:0);return{...l,kinds:h,cms:d,offsets:u}}function Qr(t,e,i,s,n,o,a=1){const r=[];for(const l of t||[]){if(!l?.id)continue;const c=Zr(t,l.id,e,i,s,n,o,a);if(c)for(let t=0;t0&&(r=Ar(r,t.a,t.b,t.cm,s,a));return r}function el(t,e,i,s,n,o,a=1){if(!e?.length)return[];const r=[],l=new Set;for(const c of Qr(t,e,i,s,n,o,a))!c.open&&c.cm>0&&!l.has(c.key)&&(l.add(c.key),r.push(c));const c=[];for(const r of t||[]){if(!r?.id)continue;const l=Zr(t,r.id,e,i,s,n,o,a);if(l)for(let t=0;t0)||null===l.kinds[i]){t++;continue}let o=t;for(;o+10&&c.push({a:[h[0],h[1]],b:[d[0],d[1]],key:wr(h,d,s,a),cm:n,len:u}),t=o+1}}}c.sort((t,e)=>e.len-t.len||t.key.localeCompare(e.key));const h=[],d=new Set,u=new Set,p=4*qr(s,a);for(const t of c){const e=r.filter(e=>!u.has(e.key)&&e.cm===t.cm&&Mr(Sr(e.a,e.b),Sr(t.a,t.b))&&sl(e.a[0],e.a[1],t.a[0],t.a[1],t.b[0],t.b[1])<=p&&sl(e.b[0],e.b[1],t.a[0],t.a[1],t.b[0],t.b[1])<=p);if(e.length){for(const t of e)u.add(t.key);d.has(t.key)||(d.add(t.key),h.push(xr(t.a,t.b,t.cm,s,a)))}}for(const t of r)u.has(t.key)||d.has(t.key)||(d.add(t.key),h.push(xr(t.a,t.b,t.cm,s,a)));return h}function il(t,e,i,s,n,o,a,r=1){const l=qr(n,r),c=(s[0]+s[2])/2,h=(s[1]+s[3])/2,d=Sr([s[0],s[1]],[s[2],s[3]]);let u=null;for(const s of Qr(t,e,i,n,o,a,r)){if(!Mr(Sr(s.a,s.b),d))continue;const t=sl(c,h,s.a[0],s.a[1],s.b[0],s.b[1]);t>4*l||(!u||tt?.id===e),c=hi(l);if(!c||c.length<3)return null;if(!i?.length)return c.map(t=>[t[0],t[1]]);const h=Zr(t,e,i,s,n,o,a,r);return h&&h.offsets.some(t=>t>0)&&Vr(h.poly,h.offsets)||c.map(t=>[t[0],t[1]])}function ol(t){const e=t.map(t=>[t[0],t[1]]);return e.push([t[0][0],t[0][1]]),[e]}function al(t,e=1){if(!Array.isArray(t)||t.length<3)return null;const i=Number.isFinite(e)&&e>0?e:1,s=1e-12*Math.max(1,i),n=[];for(const e of t){if(!Array.isArray(e)||e.length<2)return null;const t=Number(e[0]),i=Number(e[1]);if(!Number.isFinite(t)||!Number.isFinite(i))return null;const o=Math.round(t/s)*s,a=Math.round(i/s)*s;if(!Number.isFinite(o)||!Number.isFinite(a))return null;n.push([Object.is(o,-0)?0:o,Object.is(a,-0)?0:a])}return Math.abs(jr(n))>s*s?n:null}function rl(t,e,i,s){if(sl(t[0],t[1],e[0],e[1],i[0],i[1])>s)return!1;const n=i[0]-e[0],o=i[1]-e[1],a=(t[0]-e[0])*n+(t[1]-e[1])*o,r=n*n+o*o,l=s*Math.sqrt(r);return a>=-l&&a<=r+l}function ll(t,e,i){const s=[],n=[];for(let o=0;oi*i))continue;const d=i/Math.sqrt(h),u=[0,1];for(const t of e)for(const e of[t.a,t.b]){if(!rl(e,a,r,i))continue;const t=((e[0]-a[0])*l+(e[1]-a[1])*c)/h;t>d&&t<1-d&&u.push(t)}u.sort((t,e)=>t-e);const p=u.filter((t,e)=>0===e||Math.abs(t-u[e-1])>d);for(let t=0;t=3&&n.length===s.length?{poly:s,offsets:n}:null}function cl(t,e,i,s,n,o,a){const r=(t||[]).map(hi).filter(t=>!!t&&t.length>=3);if(!r.length)return null;let l=si(ol(r[0]));for(let t=1;t"outer"===t.kind&&t.half>0),h=4*qr(s,a);let d=null;for(const t of function(t){const e=[];for(const i of Array.isArray(t)?t:[])if(Array.isArray(i))for(const t of i){if(!Array.isArray(t)||t.length<4)continue;const i=t.slice(0,-1).map(t=>[t[0],t[1]]);i.length>=3&&e.push(i)}return e}(l)){const e=ll(t,c,h);if(!e||!e.offsets.some(t=>t>0))continue;const i=_l(e.poly,e.offsets),s=Vr(e.poly,e.offsets);if(!i||!s)continue;const n=oi(ol(i),ol(s));d=d?si(d,n):n}return{centre:l,shell:d||[]}}function hl(t){if(!t)return"";let e="";for(const i of t)if(Array.isArray(i))for(const t of i){if(!Array.isArray(t)||t.length<4)continue;const i=t.slice(0,t.length-1);i.length<3||(e+=(e?" ":"")+Kr(i.map(t=>[t[0],t[1]])))}return e}function dl(t,e,i,s=[],n,o,a,r=1,l=[]){if(!e?.length&&!l.length)return null;const c=[];let h=0;for(const s of t||[]){if(!s?.id)continue;const l=Zr(t,s.id,e,i,n,o,a,r);if(!l||l.poly.length<3||!l.offsets.some(t=>t>0))continue;for(const t of l.offsets)t>0&&(h=Math.max(h,2*t));const d=_l(l.poly,l.offsets),u=Vr(l.poly,l.offsets);d&&c.push({outset:d,inset:u})}for(const t of l){const e=t.map(t=>t[0]),i=t.map(t=>t[1]);if(e.length){const s=Math.min(Math.max(...e)-Math.min(...e),Math.max(...i)-Math.min(...i)),n=Math.min(...t.map((e,i)=>{const s=t[(i+1)%t.length];return Math.hypot(s[0]-e[0],s[1]-e[1])}));h=Math.max(h,t.length>16?s:n)}}const d=function(t,e,i,s,n,o,a){if(!e?.length||!i?.length)return[];const r=4*qr(s,a),l=new Map;for(const r of Qr(t,e,i,s,n,o,a))!r.open&&r.half>0&&!l.has(r.key)&&l.set(r.key,r);const c=[...l.values()];if(c.length<2)return[];const h=[];for(const t of i)for(const e of[[t[0],t[1]],[t[2],t[3]]])h.some(t=>Math.hypot(t[0]-e[0],t[1]-e[1])<=r)||h.push(e);const d=[],u=(t,e)=>{let i=0,s=0;if(Math.hypot(t.a[0]-e[0],t.a[1]-e[1])<=r)i=t.b[0]-t.a[0],s=t.b[1]-t.a[1];else{if(!(Math.hypot(t.b[0]-e[0],t.b[1]-e[1])<=r))return null;i=t.a[0]-t.b[0],s=t.a[1]-t.b[1]}const n=Math.hypot(i,s);return n>r?[i/n,s/n]:null};for(const t of h){const e=c.map(e=>({iv:e,u:u(e,t)})).filter(t=>!!t.u);for(let i=0;i4*_||d.push(a>0?[t.slice(),h,p,u]:[t.slice(),u,p,h])}}return d}(t,e,i,n,o,a,r),u=s.length?gl(t,e,i,n,o,a,r):null;try{const p=cl(t,e,i,n,o,a,r),_=p?p.shell?.length?si(p.centre,p.shell):p.centre:[],g=t=>{const e=ol(t.outset);return t.inset?oi(e,ol(t.inset)):e};let m=null;for(const t of c)try{const e=g(t);m=m?si(m,e):e}catch{}if(p)for(const s of pl(t,e,i,n,o,a,r))try{const t=ni(ol(s.quad),p.centre);m=m?si(m,t):t}catch{}m=function(t,e,i=1,s=si){let n=t;for(const t of e||[]){const e=al(t,i);if(e)try{const t=ol(e);n=n?s(n,t):t}catch{}}return n}(m,d,r),m&&p&&(m=ni(m,p.centre)),p?.shell?.length&&(m=m?si(m,p.shell):p.shell);for(const t of s){if(!(t.length>0))continue;const e=vl(u,t,!0);if(!e.negative&&!e.positive)continue;const i=t.angle*Math.PI/180,s=Math.cos(i),o=Math.sin(i),a=-o,l=s,c=t.length/2,d=1.25*Math.max(h,n*r),p=[[t.x-s*c-a*d,t.y-o*c-l*d],[t.x+s*c-a*d,t.y+o*c-l*d],[t.x+s*c+a*d,t.y+o*c+l*d],[t.x-s*c+a*d,t.y-o*c+l*d]];m&&(m=oi(m,ol(p)))}for(const t of l)t.length<3||(m=m?si(m,ol(t)):[ol(t)]);return{geom:m||[],paperGeom:_,depthUnits:h,openingIndex:u}}catch{return null}}function ul(t,e,i,s=[],n,o,a,r=1,l=[]){if(!e?.length&&!l.length)return null;const c=dl(t,e,i,s,n,o,a,r,l),h=c?hl(c.geom):"",d=c?hl(c.paperGeom):"";return c&&h?{d:h,paperD:d,depthUnits:c.depthUnits,fillRule:"evenodd"}:null}function pl(t,e,i,s,n,o,a=1){if(!e?.length)return[];const r=new Set,l=[];for(const c of t||[]){if(!c?.id)continue;const h=Zr(t,c.id,e,i,s,n,o,a);if(!h)continue;const d=h.poly;for(let t=0;t0))continue;const p=wr(e,i,s,a);if(r.has(p))continue;r.add(p);const _=fr(u,n,o),[g,m]=Wr(d,t),f=-g,v=-m,y=_/2,b=[[e[0]+f*y,e[1]+v*y],[i[0]+f*y,i[1]+v*y],[i[0]+g*y,i[1]+m*y],[e[0]+g*y,e[1]+m*y]];l.push({key:p,kind:c,cm:u,quad:b,a:[e[0],e[1]],b:[i[0],i[1]],depthUnits:_})}}return l}function _l(t,e){const i=t?.length||0;if(i<3||e.length!==i)return null;if(e.every(t=>!(t>0)))return t.map(t=>[t[0],t[1]]);Yr(t),e.slice().reverse();const s=[];for(let n=0;n0||r>0)){s.push([t[n][0],t[n][1]]);continue}if(a>0!=r>0){const e=t[n],i=a>0?[e[0]-l*a,e[1]-c*a]:[e[0],e[1]],o=r>0?[e[0]-h*r,e[1]-d*r]:[e[0],e[1]];s.push(i),Math.hypot(o[0]-i[0],o[1]-i[1])>1e-9&&s.push(o);continue}if(Ur(b,w)){const e=t[n],i=[e[0]-l*a,e[1]-c*a],o=[e[0]-h*r,e[1]-d*r];s.push(i),Math.hypot(o[0]-i[0],o[1]-i[1])>1e-9&&s.push(o);continue}const $=Gr(k,b,x,w),S=Math.max(a,r,1e-9);if($){if(Math.hypot($[0]-t[n][0],$[1]-t[n][1])<=4*S){s.push($);continue}}a>0&&s.push([t[n][0]-l*a,t[n][1]-c*a]),r>0&&s.push([t[n][0]-h*r,t[n][1]-d*r])}return s.length>=3?s:null}function gl(t,e,i,s,n,o,a=1){const r=[];for(const l of t||[]){if(!l?.id)continue;const c=Zr(t,l.id,e,i,s,n,o,a);if(!c)continue;const h=Math.abs(Pi(c.poly));for(let t=0;t[Math.max(e,t.x0),Math.min(i,t.x1)]).filter(t=>t[1]-t[0]>s).sort((t,e)=>t[0]-e[0]||t[1]-e[1]);if(!n.length)return{coverage:0,full:!1};let o=n[0][0],a=n[0][1],r=0,l=o<=e+s;for(let t=1;t=i-s,{coverage:r,full:l}}function fl(t,e){return Number(e.full)-Number(t.full)||t.faceDistance-e.faceDistance||t.area-e.area||t.roomId.localeCompare(e.roomId)}function vl(t,e,i=!1){const s=Number(e?.x),n=Number(e?.y),o=Number(e?.angle),a=Number(e?.length);if(!([s,n,o,a].every(Number.isFinite)&&a>0))return{negative:null,positive:null};const r=o*Math.PI/180,l=Math.cos(r),c=Math.sin(r),h=-c,d=l,u=a/2,p=Math.max(1e-9,t.adjacencyEps),_=new Map;let g=0;for(const e of t.edges){if(i&&!(e.half>0))continue;if(!Pr(e.a,e.b,o))continue;const[t,a]=yr(e.a,e.b);if(Math.abs((s-e.a[0])*a-(n-e.a[1])*t)>p)continue;const r=(e.a[0]-s)*l+(e.a[1]-n)*c,m=(e.b[0]-s)*l+(e.b[1]-n)*c,f=Math.max(-u,Math.min(r,m)),v=Math.min(u,Math.max(r,m));if(v-f<=p)continue;const y=e.inward[0]*h+e.inward[1]*d>=0?1:-1,b=((e.a[0]+e.b[0])/2-s)*h+((e.a[1]+e.b[1])/2-n)*d,w=Math.abs(b+y*e.half),k=`${y}|${e.roomId}`,x={x0:f,x1:v,half:e.half,cm:e.cm,key:e.key,axis:[t,a]},$=_.get(k);$?($.pieces.push(x),$.faceDistance=Math.min($.faceDistance,w)):_.set(k,{roomId:e.roomId,side:y,order:g++,pieces:[x],faceDistance:w,area:e.area,coverage:0,full:!1})}for(const t of _.values()){const e=ml(t.pieces,-u,u,p);t.coverage=e.coverage,t.full=e.full}const m=t=>{const e=[..._.values()].filter(e=>e.side===t&&e.coverage>p);return e.sort(fl),e[0]||null};return{negative:m(-1),positive:m(1)}}function yl(t,e){const i=vl(t,e),s=[i.negative,i.positive].filter(t=>!!t).sort((t,e)=>t.order-e.order);if(!s.length)return{ox:0,oy:0,cm:0,side:-1};const n=s[0],o=e.flip_v?-n.side:n.side,a=(-1===o?i.negative:i.positive)||n,r=[...a.pieces].sort((t,e)=>(t.x0<=0&&t.x1>=0?0:Math.min(Math.abs(t.x0),Math.abs(t.x1)))-(e.x0<=0&&e.x1>=0?0:Math.min(Math.abs(e.x0),Math.abs(e.x1)))||e.x1-e.x0-(t.x1-t.x0)||t.key.localeCompare(e.key))[0];if(!(r.half>0&&r.cm>0))return{ox:0,oy:0,cm:0,side:o};const l=e.angle*Math.PI/180,c=-Math.sin(l),h=Math.cos(l);return{ox:c*o*r.half,oy:h*o*r.half,cm:r.cm,side:o}}function bl(t,e){const i=1e-9,s=e.filter(t=>Number.isFinite(t.x0)&&Number.isFinite(t.x1)&&Number.isFinite(t.half)&&t.x1>t.x0&&t.half>0);if(!s.length)return"";const n=s.flatMap(t=>[t.x0,t.x1]).sort((t,e)=>t-e),o=[];for(const t of n){const e=o[o.length-1];(void 0===e||t>e+i)&&o.push(t)}const a=[];for(let t=0;t+1e+i))continue;const r=(e+n)/2,l=s.reduce((t,e)=>r>=e.x0-i&&r<=e.x1+i?Math.max(t,e.half):t,0);if(!(l>0))continue;const c=a[a.length-1];c&&e<=c.x1+i&&Math.abs(l-c.half)<=i?c.x1=n:a.push({x0:e,x1:n,half:l})}const r=[];for(const t of a){const e=r[r.length-1],s=e?.[e.length-1];s&&t.x0<=s.x1+i?(t.x0=s.x1,e.push(t)):r.push([t])}return r.map(e=>{const i=e[0],s=e[e.length-1],n=Math.min(.25*Math.min(...e.map(t=>t.half)),.75),o=-t*n,a=[];if(1===t){a.push(`M ${i.x0} ${o} L ${s.x1} ${o}`);for(let t=e.length-1;t>=0;t--){const i=e[t];a.push(`L ${i.x1} ${i.half} L ${i.x0} ${i.half}`)}}else{a.push(`M ${s.x1} ${o} L ${i.x0} ${o}`);for(const t of e)a.push(`L ${t.x0} ${-t.half} L ${t.x1} ${-t.half}`)}return a.push("Z"),a.join(" ")}).join(" ")}function wl(t,e,i,s){if(!s)return i;const n=t.angle*Math.PI/180,o=Math.cos(n),a=Math.sin(n),r=[],l=1e-9;for(const n of i){const[i,c]=n.axis,h=o*i+a*c;if(Math.abs(h)<=l)continue;const d=t.x*i+t.y*c,u=d+h*n.x0,p=d+h*n.x1,_=Math.min(u,p),g=Math.max(u,p),m=`${n.key}|${e}`,f=s.get(m)||[];let v=[[_,g]];for(const[t,e]of f){const i=[];for(const[s,n]of v)e<=s+l||t>=n-l?i.push([s,n]):(t>s+l&&i.push([s,Math.min(n,t)]),et[0]-e[0]||t[1]-e[1]),b=[];for(const t of y){const e=b[b.length-1];e&&t[0]<=e[1]+l?e[1]=Math.max(e[1],t[1]):b.push([t[0],t[1]])}s.set(m,b)}return r}function kl(t,e){const i=new Map;return e.map(e=>function(t,e,i){const s=vl(t,e,!0),n=s.negative,o=s.positive;if(!n&&!o)return null;let a;if(n&&o)a=[{candidate:n,side:-1},{candidate:o,side:1}];else{const t=n||o;a=[{candidate:t,side:-1},{candidate:t,side:1}]}const r=a.map(({candidate:t,side:s})=>({candidate:t,side:s,pieces:wl(e,s,t.pieces,i)})),l=r.map(({candidate:t,side:e,pieces:i})=>({side:e,roomId:t.roomId,d:bl(e,i)})),c=r.flatMap(({pieces:t})=>t);if(!c.length)return null;const h=Math.max(...c.map(t=>t.half));return{faces:l,minY:-h,maxY:h,wallKey:[...new Set(c.map(t=>t.key))].sort().join("|")}}(t,e,i))}const xl=150;function $l(t){return Number.isFinite(t)?Math.max(1,Math.min(xl,t)):1}function Sl(t){return((Number.isFinite(Number(t))?Number(t):0)%90+90)%90}const Ml=t=>{const e=t.map(t=>[t[0],t[1]]);return!e.length||e[0][0]===e[e.length-1][0]&&e[0][1]===e[e.length-1][1]||e.push([...e[0]]),[e]};function Cl(t){const e=[];for(const i of t||[])for(const t of i||[]){const i=(t||[]).filter(t=>Array.isArray(t)&&t.length>=2);i.length<4||e.push(`M ${i.slice(0,-1).map(t=>`${t[0]} ${t[1]}`).join(" L ")} Z`)}return e.join(" ")}function Dl(t,e,i,s,n){return Fr({a:t,b:e,halfDepth:fr(i,s,n)/2})}function Tl(t,e,i){const s=Number(e)>0?Number(e):5,n=$l(t.cm)/s*i,o=t.center[0],a=t.center[1];if("circle"===t.shape){const t=n/2;return Array.from({length:96},(e,i)=>{const s=i/96*Math.PI*2;return[o+Math.cos(s)*t,a+Math.sin(s)*t]})}const r=n/2,l=Sl(t.angle)*Math.PI/180,c=Math.cos(l),h=Math.sin(l);return[[-r,-r],[r,-r],[r,r],[-r,r]].map(([t,e])=>[o+t*c-e*h,a+t*h+e*c])}function Pl(t,e,i=1e-9){if(!e.length)return[t];let s=[Ml(t)];try{for(const t of e){const e=t.b[0]-t.a[0],n=t.b[1]-t.a[1],o=Math.hypot(e,n);if(!(o>i))continue;const a=e/o,r=n/o,l=-r,c=a,h=1.25*Math.max(Number(t.depth)||0,4*i),d=Math.max(2*i,1e-9*o),u=[[t.a[0]-a*d-l*h,t.a[1]-r*d-c*h],[t.b[0]+a*d-l*h,t.b[1]+r*d-c*h],[t.b[0]+a*d+l*h,t.b[1]+r*d+c*h],[t.a[0]-a*d+l*h,t.a[1]-r*d+c*h]];s=oi(s,Ml(u))}return Ol(s)}catch{return[t]}}function Rl(t,e,i,s=Math.max(2e-4*i,1e-9),n=[]){const o=[],a=[],r=new Map;for(const t of n){const e=r.get(t.hostId)||[];e.push(t),r.set(t.hostId,e)}const l=[],c=[],h=[];for(const s of t.room_drafts||[])for(let t=0;t+1Tl(t,e,i)),u=Nr([...o,...a],s).flatMap(t=>Pl(t,n,s));return{drafts:l,partitions:c,columns:d,patches:u,all:[...l,...h,...u,...d]}}function Al(t){try{const e=t.filter(t=>t.length>=3).map(t=>Ml(t));return e.length?si(e[0],...e.slice(1)):null}catch{return null}}const Il=t=>`M ${t.map(t=>`${t[0]} ${t[1]}`).join(" L ")} Z`;function El(t,e){const i=Al(t.filter(t=>t.length>=3)),s=Al(e.filter(t=>t.length>=3));if(!i)return[];if(!s)return[];try{return function(t){const e=[];for(const i of t||[]){if(zl([i])<=1e-6)continue;const t=[];for(const e of i||[]){const i=(e||[]).filter(t=>Array.isArray(t)&&t.length>=2);i.length<4||t.push(Il(i.slice(0,-1)))}t.length&&e.push(t.join(" "))}return e}(ni(i,s))}catch{return[]}}function Fl(t,e){if(!e.length)return[Ml(t)];try{const i=Al(e);if(i)return oi(Ml(t),i)}catch{}let i=[Ml(t)];for(const t of e)if(!(t.length<3))try{i=oi(i,Ml(t))}catch{}return i}function zl(t){let e=0;for(const i of t||[])if(i?.length){e+=Pi(i[0]||[]);for(let t=1;t=4&&e.push(t.slice(0,-1).map(t=>[t[0],t[1]]))}return e}function Hl(t,e){let i=!1;for(let s=0,n=e.length-1;st[1]!=l>t[1]&&t[0]<(r-o)*(t[1]-a)/(l-a||1e-12)+o&&(i=!i)}return i}function Nl(t,e,i){return function(t,e){for(const i of e||[]){const e=i?.[0];if(!e?.length||!Hl(t,e))continue;let s=!1;for(let e=1;eHl(t,e))}function Ll(t,e,i){if(Math.hypot(t.center[0]-e.center[0],t.center[1]-e.center[1])>i)return!1;if(Math.abs($l(t.cm)-$l(e.cm))>1e-6)return!1;if(t.shape!==e.shape)return!0;if("circle"===t.shape||"circle"===e.shape)return!0;const s=Math.abs(Sl(t.angle)-Sl(e.angle));return Math.min(s,90-s)<=1e-6}const Bl=1e3;function ql(t,e){const i=Number(t),s=Number.isFinite(i)&&i>0?i:1,n=s>=1?e:e*s,o=s>=1?e/s:e;return{x:(e-n)/2,y:(e-o)/2,w:n,h:o}}const jl=.01,Wl=100;function Ul(t,e=1e3){const i=ql(t?.plan_aspect,e),s=Number(t?.plan_scale),n=Number.isFinite(s)&&s>0?Math.min(Wl,Math.max(jl,s)):1,o=Number(t?.plan_scale_x),a=Number(t?.plan_scale_y),r=Number.isFinite(o)&&o>0?Math.min(Wl,Math.max(jl,o)):n,l=Number.isFinite(a)&&a>0?Math.min(Wl,Math.max(jl,a)):n,c=Number(t?.plan_x),h=Number(t?.plan_y),d=sr(t?.plan_angle);return{x:i.x+(Number.isFinite(c)?ic(c):0)*e,y:i.y+(Number.isFinite(h)?ic(h):0)*e,w:i.w*r,h:i.h*l,...d?{angle:d}:{}}}function Gl(t){if(null==t.x||null==t.y)return{x:t.x,y:t.y,w:t.w,h:t.h};const e=Number(t.w)||0,i=Number(t.h)||0;return{x:e<0?t.x+e:t.x,y:i<0?t.y+i:t.y,w:Math.abs(e),h:Math.abs(i)}}function Vl(t){return t&&Array.isArray(t.spaces)?t.spaces.map(t=>{const e=Bl,i=function(t){return Array.isArray(t)&&4===t.length&&t.every(t=>Number.isFinite(t))&&t[2]>1e-6&&t[3]>1e-6?t:[0,0,1,1]}(t.view_box);return{id:t.id,title:t.title,vb:[i[0]*Bl,i[1]*e,i[2]*Bl,i[3]*e],bg:t.plan_url?{href:Is(t.plan_url),...Ul(t,Bl)}:null,rooms:(t.rooms||[]).map(t=>{const i={...t,...Gl(t)};return{id:i.id,name:i.name,area:i.area??null,open_to:i.open_to||void 0,settings:i.settings||void 0,x:null!=i.x?i.x*Bl:void 0,y:null!=i.y?i.y*e:void 0,w:null!=i.w?i.w*Bl:void 0,h:null!=i.h?i.h*e:void 0,poly:i.poly?i.poly.map(t=>[t[0]*Bl,t[1]*e]):void 0}}),room_drafts:(t.room_drafts||[]).map(t=>({id:t.id,points:(t.points||[]).map(t=>[t[0]*Bl,t[1]*e]),segments:(t.segments||[]).map(t=>({cm:Number(t.cm)}))})),partitions:(t.partitions||[]).map(t=>({id:t.id,a:[t.a[0]*Bl,t.a[1]*e],b:[t.b[0]*Bl,t.b[1]*e],cm:Number(t.cm)})),wall_columns:(t.wall_columns||[]).map(t=>({id:t.id,shape:"circle"===t.shape?"circle":"square",center:[t.center[0]*Bl,t.center[1]*e],cm:Number(t.cm),..."circle"===t.shape?{}:{angle:Sl(t.angle)}}))}}):[]}const Kl=5e3,Yl=Kl*Bl,Xl=240,Jl=Bl/Xl,Zl=1/Xl;function Ql(t){if(!Number.isFinite(t))return t;const e=Math.round(t*Xl/Bl)*Bl/Xl;return Math.abs(e-t)<=1e-9*Jl?t:e}function tc(t){return{x:Ql(t.x),y:Ql(t.y)}}function ec(t){return Number.isFinite(t)?Math.min(Yl,Math.max(-Yl,t)):0}function ic(t){return Number.isFinite(t)?Math.min(Kl,Math.max(-Kl,t)):0}const sc=1/3,nc=200;function oc(t){let e=1/0,i=1/0,s=-1/0,n=-1/0;for(const o of t){const t=Number(o[0]),a=Number(o[1]);Number.isFinite(t)&&Number.isFinite(a)&&(ts&&(s=t),a>n&&(n=a))}return e>s?null:{minX:e,minY:i,maxX:s,maxY:n}}function ac(t){return t.poly&&t.poly.length?oc(t.poly):null==t.x||null==t.y?null:oc([[t.x,t.y],[t.x+(t.w||0),t.y+(t.h||0)]])}function rc(t,e){const i=[];for(const e of t.rooms||[]){const t=ac(e);t&&i.push(t)}if(t.bg){const e=oc(cr(t.bg));e&&i.push(e)}for(const t of e||[])if(Array.isArray(t)){const e=oc([t]);e&&i.push(e)}else i.push(t);return i}const lc=t=>{if(!t.length)return 0;const e=[...t].sort((t,e)=>t-e),i=e.length>>1;return e.length%2?e[i]:(e[i-1]+e[i])/2},cc=t=>{let e=1/0,i=1/0,s=-1/0,n=-1/0;for(const o of t)o.minXs&&(s=o.maxX),o.maxY>n&&(n=o.maxY);return e>s||i>n?null:{x:e,y:i,w:s-e,h:n-i}};function hc(t,e){let{x:i,y:s,w:n,h:o}=t;n<30&&(i=i+n/2-100,n=nc),o<30&&(s=s+o/2-100,o=nc);const a=Math.max(n,o)*e;return{x:i-a,y:s-a,w:n+2*a,h:o+2*a}}function dc(t,e={}){const i=e.pad??.05,s=e.k??10,n=e.minSpread??50,o=t.filter(t=>Number.isFinite(t.minX)&&Number.isFinite(t.minY)&&Number.isFinite(t.maxX)&&Number.isFinite(t.maxY)&&Math.abs(t.minX)<=Yl&&Math.abs(t.maxX)<=Yl&&Math.abs(t.minY)<=Yl&&Math.abs(t.maxY)<=Yl);if(!o.length)return{core:null,all:null,outliers:0};const a=cc(o);if(o.length<4){const t=hc(a,i);return{core:t,all:t,outliers:0}}const r=o.map(t=>(t.minX+t.maxX)/2),l=o.map(t=>(t.minY+t.maxY)/2),c=lc(r),h=lc(l),d=o.map((t,e)=>Math.max(Math.abs(r[e]-c),Math.abs(l[e]-h))),u=Math.max(((t,e)=>t.length?t[Math.min(t.length-1,Math.max(0,Math.round(e*(t.length-1))))]:0)([...d].sort((t,e)=>t-e),.75),n),p=d.map(t=>t>s*u),_=p.filter(Boolean).length,g=_&&_<=o.length*sc?o.filter((t,e)=>!p[e]):o;return{core:hc(cc(g)||a,i),all:hc(a,i),outliers:g===o?0:_}}function uc(t,e,i=.05){const s=dc(rc(t,e),{pad:i});if(s.core)return s.core;const n=t.vb&&4===t.vb.length&&t.vb[2]>0&&t.vb[3]>0?t.vb:[0,0,Bl,Bl];return{x:n[0],y:n[1],w:n[2],h:n[3]}}function pc(t){const e=uc(t);return{x:e.x+e.w/2,y:e.y+e.h/2}}function _c(t){const e=[];for(const i of t.rooms||[]){const t=ac(i);t&&e.push(t)}const i=dc(e,{pad:0}).core;return i?Math.max(Bl,Math.min(Yl,Math.max(i.w,i.h))):Bl}function gc(t,e,i,s=1){const n=Number(i),o=Number.isFinite(s)&&s>0?s:1;return!Number.isFinite(n)||n<=0?t*o:t*_c(e)*o/n}const mc=[1,2,5,10,20,50,100,200,500,1e3];function fc(t){if(t.poly&&t.poly.length){const e=t.poly.map(t=>t[0]),i=t.poly.map(t=>t[1]),s=Math.min(...e),n=Math.min(...i);return{x:s,y:n,w:Math.max(...e)-s,h:Math.max(...i)-n}}return{x:t.x??0,y:t.y??0,w:t.w??0,h:t.h??0}}function vc(t){if(t.poly){const e=t.poly.length;return[t.poly.reduce((t,e)=>t+e[0],0)/e,t.poly.reduce((t,e)=>t+e[1],0)/e]}return[t.x+t.w/2,t.y+.1*Math.min(t.w,t.h)]}const yc=["furniture","appliance","sanitary","other"],bc=[{id:"sofa",group:"furniture",w:220,h:90,g:[["r",0,0,1,1],["l",.09,.26,.91,.26],["l",.09,.26,.09,1],["l",.91,.26,.91,1],["l",.5,.26,.5,1]]},{id:"armchair",group:"furniture",w:90,h:85,g:[["r",0,0,1,1],["l",.14,.28,.86,.28],["l",.14,.28,.14,1],["l",.86,.28,.86,1]]},{id:"coffee_table",group:"furniture",w:110,h:60,g:[["r",0,0,1,1],["r",.08,.14,.84,.72]]},{id:"table_dining",group:"furniture",w:140,h:80,g:[["r",0,0,1,1],["r",.06,.11,.88,.78]]},{id:"table_round",group:"furniture",w:120,h:120,g:[["e",.5,.5,.5,.5],["e",.5,.5,.41,.41]]},{id:"chair",group:"furniture",w:45,h:45,g:[["r",0,0,1,.18],["r",.06,.18,.88,.8]]},{id:"desk",group:"furniture",w:120,h:60,g:[["r",0,0,1,1],["r",.63,.07,.31,.86],["l",.63,.5,.94,.5]]},{id:"bed_double",group:"furniture",w:160,h:200,g:[["r",0,0,1,1],["r",0,0,1,.07],["r",.06,.1,.4,.15],["r",.54,.1,.4,.15],["l",0,.33,1,.33]]},{id:"bed_single",group:"furniture",w:90,h:200,g:[["r",0,0,1,1],["r",0,0,1,.07],["r",.15,.1,.7,.15],["l",0,.33,1,.33]]},{id:"nightstand",group:"furniture",w:45,h:40,g:[["r",0,0,1,1],["r",.12,.14,.76,.33],["r",.12,.53,.76,.33]]},{id:"wardrobe",group:"furniture",w:100,h:60,g:[["r",0,0,1,1],["l",0,.72,1,.72],["l",.5,.72,.5,1]]},{id:"bookshelf",group:"furniture",w:80,h:30,g:[["r",0,0,1,1],["l",.34,0,.34,1],["l",.67,0,.67,1]]},{id:"fridge",group:"appliance",w:60,h:65,g:[["r",0,0,1,1],["l",0,.36,1,.36],["l",.83,.44,.83,.64]]},{id:"stove",group:"appliance",w:60,h:60,g:[["r",0,0,1,1],["e",.29,.31,.15,.15],["e",.71,.31,.15,.15],["e",.29,.71,.15,.15],["e",.71,.71,.15,.15]]},{id:"dishwasher",group:"appliance",w:60,h:60,g:[["r",0,0,1,1],["r",.1,.12,.8,.76],["e",.5,.5,.27,.27],["e",.5,.5,.13,.13]]},{id:"washer",group:"appliance",w:60,h:60,g:[["r",0,0,1,1],["l",.08,.17,.92,.17],["e",.5,.57,.3,.3],["e",.5,.57,.14,.14]]},{id:"dryer",group:"appliance",w:60,h:60,g:[["r",0,0,1,1],["l",.08,.17,.92,.17],["e",.5,.57,.3,.3],["p",.36,.5,.5,.64,.64,.5]]},{id:"tv",group:"appliance",w:120,h:30,g:[["r",0,0,1,.42],["l",.5,.42,.5,.72],["l",.3,.72,.7,.72]]},{id:"ac",group:"appliance",w:90,h:25,g:[["r",0,0,1,1],["l",.05,.55,.95,.55],["l",.05,.79,.95,.79]]},{id:"water_heater",group:"appliance",w:45,h:45,g:[["e",.5,.5,.5,.5],["e",.5,.5,.31,.31]]},{id:"toilet",group:"sanitary",w:40,h:70,g:[["r",.06,0,.88,.2],["e",.5,.58,.37,.35],["e",.5,.58,.22,.2]]},{id:"bathtub",group:"sanitary",w:170,h:75,g:[["r",0,0,1,1],["r",.05,.11,.77,.78],["e",.89,.5,.045,.1]]},{id:"shower",group:"sanitary",w:90,h:90,g:[["r",0,0,1,1],["l",0,0,1,1],["l",1,0,0,1],["e",.5,.5,.08,.08]]},{id:"sink",group:"sanitary",w:60,h:45,g:[["r",0,0,1,1],["e",.5,.6,.34,.3],["e",.5,.15,.07,.07]]},{id:"kitchen_sink",group:"sanitary",w:80,h:60,g:[["r",0,0,1,1],["r",.06,.24,.44,.64],["r",.54,.24,.4,.64],["e",.5,.12,.06,.06]]},{id:"bidet",group:"sanitary",w:40,h:55,g:[["e",.5,.5,.44,.5],["e",.5,.5,.26,.3]]},{id:"stairs",group:"other",w:100,h:280,g:[["r",0,0,1,1],["l",0,.111,1,.111],["l",0,.222,1,.222],["l",0,.333,1,.333],["l",0,.444,1,.444],["l",0,.556,1,.556],["l",0,.667,1,.667],["l",0,.778,1,.778],["l",0,.889,1,.889],["l",.5,.93,.5,.06],["p",.38,.16,.5,.06,.62,.16]]},{id:"fireplace",group:"other",w:120,h:40,g:[["r",0,0,1,1],["p",.22,1,.22,.42,.78,.42,.78,1]]},{id:"plant",group:"other",w:40,h:40,g:[["e",.5,.5,.22,.22],["l",.5,.28,.5,.02],["l",.5,.72,.5,.98],["l",.28,.5,.02,.5],["l",.72,.5,.98,.5],["l",.34,.34,.13,.13],["l",.66,.66,.87,.87],["l",.66,.34,.87,.13],["l",.34,.66,.13,.87]]},{id:"rug",group:"other",w:200,h:140,g:[["r",0,0,1,1],["r",.06,.09,.88,.82]]}],wc=new Map(bc.map(t=>[t.id,t]));function kc(t){return t&&wc.get(t)||null}function xc(t){return bc.filter(e=>e.group===t)}function $c(t,e,i=Jl,s=1e3){const n=Number(e)>0?Number(e):5;return(Number(t)||0)/n*i/s}const Sc=5e-4,Mc=Kl;function Cc(t){return Number.isFinite(t)?Math.max(Sc,Math.min(Mc,t)):Sc}const Dc=t=>{const e=Math.round(1e3*t)/1e3;return Object.is(e,-0)?"0":String(e)};function Tc(t,e,i){const s=kc(t);if(!(s&&e>0&&i>0))return"";const n=t=>Dc(t*e),o=t=>Dc(t*i),a=[];for(const t of s.g)if("r"===t[0]){const[,e,i,s,r]=t;a.push(`M${n(e)} ${o(i)}H${n(e+s)}V${o(i+r)}H${n(e)}Z`)}else if("l"===t[0]){const[,e,i,s,r]=t;a.push(`M${n(e)} ${o(i)}L${n(s)} ${o(r)}`)}else if("e"===t[0]){const[,s,r,l,c]=t;a.push(`M${n(s-l)} ${o(r)}A${Dc(l*e)} ${Dc(c*i)} 0 0 1 ${n(s+l)} ${o(r)}A${Dc(l*e)} ${Dc(c*i)} 0 0 1 ${n(s-l)} ${o(r)}Z`)}else{const e=t.slice(1);if(e.length<4)continue;let i=`M${n(e[0])} ${o(e[1])}`;for(let t=2;t+1{let e=(t%360+360)%360;return e>180&&(e-=360),e};function Rc(t,e,i,s,n,o=0){let a=null,r=n;for(const n of s){const[s,l,c,h]=n,d=c-s,u=h-l,p=d*d+u*u;if(!p)continue;const _=Math.sqrt(p);let g=((t-s)*d+(e-l)*u)/p;g=Math.max(0,Math.min(1,g));let m=s+g*d,f=l+g*u;const v=Math.hypot(t-m,e-f);if(!(v0){const t=Math.round(g*_/o)*o;m=s+t/_*d,f=l+t/_*u}a={cx:m+y*(i/2),cy:f+b*(i/2),angle:Pc(180*Math.atan2(-y,b)/Math.PI),dist:v}}return a}function Ac(t,e,i){const s=i;return{a:[t[0]/s,t[1]/s],b:[e[0]/s,e[1]/s]}}function Ic(t,e){const i=e;return[t.a[0]*i,t.a[1]*i,t.b[0]*i,t.b[1]*i]}function Ec(t){return Array.isArray(t)&&t.length>=2&&Number.isFinite(Number(t[0]))&&Number.isFinite(Number(t[1]))}function Fc(t){if(!Array.isArray(t))return[];const e=[];for(const i of t){if(!i||"object"!=typeof i)continue;const t=i;if(!Ec(t.a)||!Ec(t.b))continue;const s=[Number(t.a[0]),Number(t.a[1])],n=[Number(t.b[0]),Number(t.b[1])];Math.hypot(n[0]-s[0],n[1]-s[1])<.001||e.push({a:s,b:n})}return e}function zc(t,e){const i=e[0],s=e[1],n=e[2]-i,o=e[3]-s,a=n*n+o*o;if(a<1e-18){return{q:[i,s],t:0,d:Math.hypot(t[0]-i,t[1]-s)}}let r=((t[0]-i)*n+(t[1]-s)*o)/a;r=Math.max(0,Math.min(1,r));const l=[i+r*n,s+r*o];return{q:l,t:r,d:Math.hypot(t[0]-l[0],t[1]-l[1])}}function Oc(t,e){return zc(t,e).q}function Hc(t,e,i,s,n){const o=zc(t,e).q;let a=o,r=1/0;for(const t of i){const e=Math.hypot(o[0]-t[0],o[1]-t[1]);e<=n&&e0?s:1,g=Math.round(p/_)*_,m=Math.max(0,Math.min(u,g))/u;return[l+h*m,c+d*m]}function Nc(t,e){const i=[],s=(t||[]).filter(t=>t?.id);for(let t=0;tt?.id),a=Fc(e);if(a.length)return Kc(a,t,i,s).map(t=>Ic(t,i));if(!n)return[];const r=[],l=(t,e)=>(t.open_to||[]).includes(e.id)||(e.open_to||[]).includes(t.id);for(let t=0;tAc([t[0],t[1]],[t[2],t[3]],e))}function qc(t,e,i,s){for(const e of t||[])e.open_to&&delete e.open_to;if(!i.length)return;const n=(e||[]).filter(t=>t?.id);new Map(n.map(t=>[t.id,t]));const o=new Map((t||[]).filter(t=>t?.id).map(t=>[t.id,t])),a=(t,e)=>{const i=o.get(t),s=o.get(e);i&&s&&((i.open_to||[]).includes(e)||(i.open_to=[...i.open_to||[],e]),(s.open_to||[]).includes(t)||(s.open_to=[...s.open_to||[],t]))};for(let t=0;tNs(i,t)<4*s)){a(n[t].id,n[e].id);break}}}for(const e of t||[])e.open_to&&!e.open_to.length&&delete e.open_to}function jc(t,e,i,s=0){const n=e[2]-e[0],o=e[3]-e[1],a=Math.hypot(n,o);if(!(a>1e-9))return null;const r=n/a,l=o/a,c=(t[0]-e[0])*r+(t[1]-e[1])*l;if(c<-s||c>a+s)return null;return Math.abs((t[0]-e[0])*l-(t[1]-e[1])*r)>i?null:Ns(t,e)}function Wc(t,e,i){const s=t[2]-t[0],n=t[3]-t[1],o=e[2]-e[0],a=e[3]-e[1],r=Math.hypot(s,n),l=Math.hypot(o,a);return r>1e-9&&l>1e-9&&(!(Math.abs(s/r*(a/l)-n/r*(o/l))>1e-6)&&(Ns([e[0],e[1]],t)<=4*i||Ns([t[0],t[1]],e)<=4*i))}function Uc(t,e,i){if(!t.length)return null;t.sort((t,e)=>t.distance-e.distance);const s=t[0];for(let n=1;ne)break;if(o.semantic!==s.semantic||!Wc(s.seg,o.seg,i))return"ambiguous"}return s}function Gc(t,e,i,s,n=1,o=15){const a=function(t,e,i,s,n=1,o=15){const[a,r]=yr([e[0],e[1]],[e[2],e[3]]);let l=0,c=1/0;const h=[(e[0]+e[2])/2,(e[1]+e[3])/2];for(const e of i){const[i,o]=yr([e[0],e[1]],[e[2],e[3]]);if(Math.abs(a*o-r*i)>.05)continue;const d=Dr(t,[e[0],e[1]],[e[2],e[3]],s,n);if(!(d>0))continue;const u=[(e[0]+e[2])/2,(e[1]+e[3])/2],p=Math.hypot(u[0]-h[0],u[1]-h[1]);p0?l:o}(t,e,i,s,n,o);return Ar(t,[e[0],e[1]],[e[2],e[3]],a,s,n)}function Vc(t,e,i){const s=[[t[0],t[1]],[t[2],t[3]]],n=[(t[0]+t[2])/2,(t[1]+t[3])/2];for(const o of e)if(!(Ns(n,o)>Math.hypot(t[2]-t[0],t[3]-t[1])&&Ns([o[0],o[1]],t)>i))for(const e of[[o[0],o[1]],[o[2],o[3]]])Ns(e,t)<=2*i&&s.push(e);return s}function Kc(t,e,i,s){const n=Fc(t);if(!n.length)return[];const o=Nc(e,s);if(!o.length)return[];const a=[],r=Math.max(4*s,1e-6);for(const t of n){const e=Ic(t,i),n=e[0],l=e[1],c=e[2]-n,h=e[3]-l,d=Math.hypot(c,h);if(d4*s||o>4*s)continue;const a=(t[0]-n)*u+(t[1]-l)*p,c=(t[2]-n)*u+(t[3]-l)*p,h=Math.max(0,Math.min(a,c)),g=Math.min(d,Math.max(a,c));if(g-ht.lo-e.lo||t.hi-e.hi);const i=[];for(const t of e){const e=i[i.length-1];e&&t.lo<=e.hi+r?e.hi=Math.max(e.hi,t.hi):i.push({...t})}for(const e of i){const i=[n+u*e.lo,l+p*e.lo],s=[n+u*e.hi,l+p*e.hi];Math.hypot(s[0]-i[0],s[1]-i[1])i.pair===t&&Math.abs(i.ux*a-i.uy*o)<=1e-6&&Math.abs((e[0]-i.origin[0])*i.uy-(e[1]-i.origin[1])*i.ux)<=c&&Math.abs((e[2]-i.origin[0])*i.uy-(e[3]-i.origin[1])*i.ux)<=c);h||(h={pair:t,origin:[e[0],e[1]],ux:o,uy:a,ranges:[]},l.push(h));const d=(e[0]-h.origin[0])*h.ux+(e[1]-h.origin[1])*h.uy,u=(e[2]-h.origin[0])*h.ux+(e[3]-h.origin[1])*h.uy;h.ranges.push({lo:Math.min(d,u),hi:Math.max(d,u)})}const h=[];for(const t of l){t.ranges.sort((t,e)=>t.lo-e.lo||t.hi-e.hi);const e=[];for(const i of t.ranges){const t=e[e.length-1];t&&i.lo<=t.hi+r?t.hi=Math.max(t.hi,i.hi):e.push({...i})}for(const s of e){const e=[t.origin[0]+t.ux*s.lo,t.origin[1]+t.uy*s.lo],n=[t.origin[0]+t.ux*s.hi,t.origin[1]+t.uy*s.hi];Math.hypot(n[0]-e[0],n[1]-e[1])>=r&&h.push(Ac(e,n,i))}}return h}function Yc(t,e,i,s){const n=Fc(t);if(!n.length)return[];if(e.length!==i.length)return n;const o=[];for(const t of n){const n=Ic(t,s),a=[n[0],n[1]],r=[n[2],n[3]];let l=a,c=r;for(let t=0;t{const e=zc(t,[s[0],s[1],n[0],n[1]]);if(e.d>.001)return t;const i=h[0]-o[0],a=h[1]-o[1];return[o[0]+i*e.t,o[1]+a*e.t]};if(zc([(a[0]+r[0])/2,(a[1]+r[1])/2],[s[0],s[1],n[0],n[1]]).d<.01){l=d(a),c=d(r);break}}o.push(Ac(l,c,s))}return o}const Xc=15e3,Jc=2e3,Zc=new WeakMap;function Qc(t,e){let i=Zc.get(t);if(!i){const e=new Set;i={hiddenAt:"hidden"===t.visibilityState?Date.now():0,token:0,subscribers:e,onVisibility:()=>{const e=Zc.get(t);if(!e)return;const i=Date.now();if("hidden"===t.visibilityState){e.hiddenAt||(e.hiddenAt=i);const t={kind:"hidden",token:e.token,at:i,hiddenFor:0,long:!1};for(const i of[...e.subscribers])i(t);return}const s=e.hiddenAt?Math.max(0,i-e.hiddenAt):0;e.hiddenAt=0,e.token++;const n={kind:"visible",token:e.token,at:i,hiddenFor:s,long:s>=Xc};for(const t of[...e.subscribers])t(n)},onPageShow:e=>{const i=Zc.get(t);if(!i)return;const s=Date.now();i.token++;const n={kind:"pageshow",token:i.token,at:s,hiddenFor:0,long:!!e.persisted,persisted:!!e.persisted};for(const t of[...i.subscribers])t(n)}},Zc.set(t,i),t.addEventListener("visibilitychange",i.onVisibility),t.defaultView?.addEventListener("pageshow",i.onPageShow)}return i.subscribers.add(e),()=>{const i=Zc.get(t);i&&(i.subscribers.delete(e),i.subscribers.size||(t.removeEventListener("visibilitychange",i.onVisibility),t.defaultView?.removeEventListener("pageshow",i.onPageShow),Zc.delete(t)))}}const th={now:()=>Date.now(),setTimeout:(t,e)=>window.setTimeout(t,e),clearTimeout:t=>window.clearTimeout(t),requestAnimationFrame:t=>window.requestAnimationFrame(t),cancelAnimationFrame:t=>window.cancelAnimationFrame(t)};class eh{constructor(t,e=th){this.onChange=t,this.clock=e,this._state="steady",this._token=0,this._frameFingerprint="",this._hasCompleteFrame=!1,this._overlayPhase="none",this._recoveryReason=null,this._overlayTimer=0,this._overlayRaf=0,this._overlayOpaqueAt=0,this._barrierRafs=new Set,this._trace=[],this._disposed=!1}get state(){return this._state}get token(){return this._token}get frameFingerprint(){return this._frameFingerprint}get hasCompleteFrame(){return this._hasCompleteFrame}get overlayPhase(){return this._overlayPhase}get overlayVisible(){return"none"!==this._overlayPhase}get overlayBlocksInteraction(){return this.overlayVisible}get recoveryReason(){return this._recoveryReason}get trace(){return this._trace.map(t=>({...t,...t.stage?{stage:[...t.stage]}:{}}))}note(t,e={}){this.record(t,void 0,e)}record(t,e,i={}){this._trace.push({at:this.clock.now(),token:this._token,event:t,state:this._state,...e?{reason:e}:{},...i}),this._trace.length>80&&this._trace.splice(0,this._trace.length-80)}changed(){this._disposed||this.onChange()}adoptCompleteFrame(t){t&&(this._hasCompleteFrame=!0,this._frameFingerprint=t,this._state="steady",this._recoveryReason=null,this.clearOverlay(),this.record("frame-adopted"),this.changed())}markCompleteFrame(t){t&&(this._hasCompleteFrame=!0,this._frameFingerprint=t,this._state="steady",this._recoveryReason=null,this.clearOverlay(),this.record("frame-complete"),this.changed())}refreshCompleteFrame(t){!this._disposed&&this._hasCompleteFrame&&"steady"===this._state&&t&&t!==this._frameFingerprint&&(this._frameFingerprint=t,this.record("frame-refreshed"))}visibility(t){return"hidden"===t.kind?(this.record("visibility-hidden"),this._token):t.long||"visible"!==t.kind&&"pageshow"!==t.kind?this.beginCandidate("pageshow"===t.kind?"pageshow":"long-resume"):(this.record("pageshow"===t.kind?"pageshow-noop":"visibility-visible-quick"),this._token)}beginCandidate(t,e="plan"){return this._token++,this._recoveryReason=e,this._hasCompleteFrame?(this._state="connection"===e?"offline-stale":"holding",this.clearOverlay()):this.overlayVisible?this._state="overlay-visible":(this._state="overlay-pending",this.scheduleOverlay(e)),this.record("candidate-start",t),this.changed(),this._token}connectionLost(){return this.beginCandidate("connection-lost","connection")}candidateReady(t){return!this._disposed&&t===this._token&&(this._state="candidate-ready",this.record("candidate-ready"),this.changed(),!0)}async commitAfterPaint(t,e){if(this._disposed||t!==this._token)return!1;let i=!0;const s=(async()=>{for(await e.updateComplete();i&&!this._disposed&&t===this._token;)if(e.stageValid()&&e.assetsReady()){if(await this.nextFrame(),t!==this._token||!e.stageValid()||!e.assetsReady())continue;if(await this.nextFrame(),t===this._token&&e.stageValid()&&e.assetsReady())return!0}else await this.nextFrame();return!1})();let n=0;const o=new Promise(t=>{n=this.clock.setTimeout(()=>t({ready:!1,timedOut:!0}),Jc)}),a=await Promise.race([s.then(t=>({ready:t,timedOut:!1})),o]);return i=!1,this.clock.clearTimeout(n),!this._disposed&&t===this._token&&(!(!a.ready&&!a.timedOut)&&(a.ready?(this._hasCompleteFrame=!0,this._frameFingerprint=e.frameFingerprint(),this.record("paint-barrier"),this.finishOverlayAfterCommit(),!0):(this.record("paint-barrier-timeout"),this._hasCompleteFrame?(this._state="connection"===this._recoveryReason?"offline-stale":"steady",this.clearOverlay()):(this._state="recovery-error","opaque"!==this._overlayPhase&&this.showOverlayNow()),this.changed(),!1)))}retry(t=this._recoveryReason||"plan"){return this.beginCandidate("retry",t)}nextFrame(){return new Promise(t=>{const e=this.clock.requestAnimationFrame(()=>{this._barrierRafs.delete(e),t()});this._barrierRafs.add(e)})}scheduleOverlay(t){this.clearOverlayTimer(),this._recoveryReason=t,this._overlayTimer=this.clock.setTimeout(()=>{this._overlayTimer=0,this._hasCompleteFrame||"overlay-pending"!==this._state&&"candidate-ready"!==this._state||(this._state="overlay-visible",this._overlayPhase="entering",this.record("overlay-enter"),this.changed(),this._overlayRaf=this.clock.requestAnimationFrame(()=>{this._overlayRaf=0,"entering"===this._overlayPhase&&(this._overlayPhase="fading-in",this.changed(),this._overlayTimer=this.clock.setTimeout(()=>{this._overlayTimer=0,"fading-in"===this._overlayPhase&&(this._overlayPhase="opaque",this._overlayOpaqueAt=this.clock.now(),this.record("overlay-opaque"),this.changed())},150))}))},150)}showOverlayNow(){this.clearOverlayTimer(),this._overlayPhase="opaque",this._overlayOpaqueAt=this.clock.now(),this.record("overlay-error")}finishOverlayAfterCommit(){if(this.clearOverlayTimer(),"none"===this._overlayPhase||"entering"===this._overlayPhase||"fading-in"===this._overlayPhase)return this.clearOverlay(),this._state="steady",this._recoveryReason=null,this.record("candidate-committed"),void this.changed();const t=Math.max(0,this._overlayOpaqueAt+250-this.clock.now());this._overlayTimer=this.clock.setTimeout(()=>{this._overlayTimer=0,this._overlayPhase="leaving",this.record("overlay-leave"),this.changed(),this._overlayTimer=this.clock.setTimeout(()=>{this._overlayTimer=0,this._overlayPhase="none",this._state="steady",this._recoveryReason=null,this.record("candidate-committed"),this.changed()},180)},t)}clearOverlayTimer(){this._overlayTimer&&this.clock.clearTimeout(this._overlayTimer),this._overlayTimer=0}clearOverlay(){this.clearOverlayTimer(),this._overlayRaf&&this.clock.cancelAnimationFrame(this._overlayRaf),this._overlayRaf=0,this._overlayPhase="none",this._overlayOpaqueAt=0}dispose(){this._disposed=!0,this._token++,this.clearOverlay();for(const t of this._barrierRafs)this.clock.cancelAnimationFrame(t);this._barrierRafs.clear()}}function ih(t){let e=2166136261,i=2654435769;const s=new WeakSet,n=t=>{for(let s=0;s>>0)+(i>>>2)}},o=t=>{if(null===t)return void n("n");const e=typeof t;if("string"===e)return void n(`s${t.length}:${t}`);if("number"===e)return void n(`d${Number.isNaN(t)?"NaN":String(t)}`);if("boolean"===e)return void n(t?"t":"f");if("undefined"===e)return void n("u");if("object"!==e)return void n(`${e}:${String(t)}`);const i=t;if(s.has(i))n("[cycle]");else{if(s.add(i),Array.isArray(t)){n("[");for(const e of t)o(e);return n("]"),void s.delete(i)}n("{");for(const e of Object.keys(t).sort())n(e),o(t[e]);n("}"),s.delete(i)}};return o(t),`${(e>>>0).toString(16).padStart(8,"0")}${(i>>>0).toString(16).padStart(8,"0")}`}function sh(t){return ih(t)}const nh=new WeakMap;class oh{constructor(t,e=()=>Date.now()){this.onUpdate=t,this.now=e,this.fallbackAuthority={},this.referenceOwner={},this.referenced=new Set,this.queued=new Set,this.disposed=!1,this.sharedUpdate=()=>{this.disposed||this.onUpdate()}}bind(t){const e=((t,e)=>{const i=t?.connection||t?.callWS||e;return!i||"object"!=typeof i&&"function"!=typeof i?e:i})(t,this.fallbackAuthority);return this.shared&&this.authority===e||(this.shared&&(this.shared.listeners.delete(this.sharedUpdate),this.shared.references.delete(this.referenceOwner)),this.authority=e,this.shared=(t=>{let e=nh.get(t);return e||(e={signed:{},queued:new Set,inFlight:new Map,retry:new Map,listeners:new Set,settlers:new Set,references:new Map},nh.set(t,e)),e})(e),this.disposed||(this.shared.listeners.add(this.sharedUpdate),this.shared.references.set(this.referenceOwner,new Set(this.referenced)))),this.shared}start(t,e){this.disposed=!1,this.referenced=new Set(e());const i=this.bind(t());i.listeners.add(this.sharedUpdate),i.references.set(this.referenceOwner,new Set(this.referenced)),this.stopTimer(),this.resignTimer=setInterval(()=>this.resign(t(),e()),288e5)}dispose(){if(this.disposed=!0,this.stopTimer(),clearTimeout(this.batchTimer),this.shared){this.shared.listeners.delete(this.sharedUpdate),this.shared.references.delete(this.referenceOwner);for(const t of this.queued)this.shared.queued.delete(t)}this.queued.clear()}invalidate(t){const e=this.bind(t);clearTimeout(this.batchTimer),this.queued.clear(),e.queued.clear(),e.inFlight.clear(),e.retry.clear(),e.signed={}}stopTimer(){void 0!==this.resignTimer&&clearInterval(this.resignTimer),this.resignTimer=void 0}display(t,e){const i=Is(e);if(!i.startsWith("/api/houseplan/content/"))return i;const s=this.bind(t);this.referenced.add(i),s.references.set(this.referenceOwner,new Set(this.referenced));const n=s.signed[i],o=n?this.now()-n.at:1/0;return o{const e=[...this.queued];this.queued.clear();for(const t of e)i.queued.delete(t);this.sign(t,e)},30))}sign(t,e){if(!e.length||!t?.callWS)return;const i=this.bind(t);for(const s of function(t,e){const i=Math.max(1,Math.floor(e)),s=[];for(let e=0;e{const s=i.inFlight.get(t);return!(void 0!==s&&e-s<15e3)&&(i.inFlight.set(t,e),!0)});n.length&&t.callWS({type:"houseplan/content/sign",paths:n}).then(t=>{const e=this.now();let s=0,o=!1;for(const a of n){const n=t?.urls?.[a];if("string"==typeof n&&n){const t=i.signed[a];t?.loaded&&t.url!==n?(t.pending={url:n,at:e},this.preloadReplacement(i,a,n,e)):(i.signed[a]={url:n,at:e,loaded:t?.url===n&&!!t.loaded},o=!0),i.retry.delete(a),s++}else this.backOff(i,a)}if(s&&(this.trimShared(i),o))for(const t of[...i.listeners])t()}).catch(()=>{for(const t of n)this.backOff(i,t)}).finally(()=>{for(const t of n)i.inFlight.get(t)===e&&i.inFlight.delete(t);for(const t of[...i.settlers])t()})}}preloadReplacement(t,e,i,s){const n=()=>{const n=t.signed[e];if(n?.pending?.url===i){t.signed[e]={url:i,at:s,loaded:!0},t.retry.delete(e),this.trimShared(t);for(const e of[...t.listeners])e()}},o=()=>{const s=t.signed[e];s?.pending?.url===i&&(delete s.pending,this.backOff(t,e))};if("undefined"==typeof Image)return void n();const a=new Image;a.onload=()=>{("function"==typeof a.decode?a.decode():Promise.resolve()).then(n).catch(o)},a.onerror=o,a.src=i}preloadCurrentImage(t,e,i){if(i.loaded)return Promise.resolve(!0);if(i.preload)return i.preload;if("undefined"==typeof Image)return i.loaded=!0,Promise.resolve(!0);const s=i.url;return i.preload=new Promise(n=>{const o=new Image;let a=!1;const r=o=>{if(a)return;a=!0,clearTimeout(l);const r=t.signed[e];if(r===i&&delete r.preload,o&&r===i&&r.url===s){r.loaded=!0;for(const e of[...t.listeners])e();n(!0)}else o||r!==i||this.backOff(t,e),n(!1)};o.onload=()=>{("function"==typeof o.decode?o.decode():Promise.resolve()).then(()=>r(!0)).catch(()=>r(!1))},o.onerror=()=>r(!1);const l=setTimeout(()=>r(!1),Jc);o.src=s}),i.preload}prepareImage(t,e){const i=Is(e);if(!i.startsWith("/api/houseplan/content/"))return Promise.resolve(!0);const s=this.bind(t),n=()=>{const e=s.signed[i];if(e&&this.now()-e.atthis.now()&&!s.inFlight.has(i)&&!s.queued.has(i)?Promise.resolve(!1):null},o=n();return o?(a=o,new Promise(t=>{let e=!1;const i=i=>{e||(e=!0,clearTimeout(s),t(i))},s=setTimeout(()=>i(!1),Jc);a.then(i).catch(()=>i(!1))})):new Promise(t=>{let e=!1,i=null;const o=i=>{e||(e=!0,clearTimeout(r),s.settlers.delete(a),t(i))},a=()=>{e||i||(i=n(),i&&i.then(o).catch(()=>o(!1)))},r=setTimeout(()=>o(!1),Jc);s.settlers.add(a),a()});var a}backOff(t,e){const i=t.retry.get(e)?.delay||0,s=Math.min(6e4,i?2*i:2e3);t.retry.set(e,{notBefore:this.now()+s,delay:s})}trimShared(t){const e=Object.entries(t.signed);if(e.length<=512)return;const i=new Set(t.inFlight.keys());for(const e of t.references.values())for(const t of e)i.add(t);for(const[t,s]of e)(s.pending||s.preload)&&i.add(t);e.sort((t,e)=>e[1].at-t[1].at);const s=e.filter(([t])=>i.has(t));for(const t of e){if(s.length>=512)break;i.has(t[0])||s.push(t)}t.signed=Object.fromEntries(s)}resign(t,e){const i=this.bind(t);this.referenced=new Set(e),i.references.set(this.referenceOwner,new Set(this.referenced));const s=this.now(),n=new Set;for(const t of i.references.values())for(const e of t)n.add(e);const o={};for(const[t,e]of Object.entries(i.signed))n.has(t)&&s-e.at!!o[t]&&!o[t].pending))}markLoaded(t,e,i){const s=Is(e);if(!s.startsWith("/api/houseplan/content/"))return;const n=this.bind(t).signed[s];if(n&&(!i||n.url===i)&&!n.loaded){n.loaded=!0;for(const e of[...this.bind(t).listeners])e()}}isReady(t,e){const i=Is(e);if(!i.startsWith("/api/houseplan/content/"))return!0;const s=this.bind(t).signed[i];return!!s&&this.now()-s.at{if(null==t||""===t)return null;const e=Number(t);return Number.isFinite(e)?e:null},ch=t=>{const e=t,i=lh(Array.isArray(e)?e[0]:e?.x),s=lh(Array.isArray(e)?e[1]:e?.y);return null==i||null==s?null:[i,s]};function hh(t){if(!Array.isArray(t))return null;const e=[];for(const i of t){const t=ch(i);if(!t)return null;e.push(t)}if(e.length>1){const t=e[0],i=e[e.length-1];t[0]===i[0]&&t[1]===i[1]&&e.pop()}if(e.length<3)return null;let i=0,s=0,n=0;for(let t=0;tt+e[0],0)/e.length,e.reduce((t,e)=>t+e[1],0)/e.length]:[s/(3*i),n/(3*i)]}function dh(t){if(!Array.isArray(t))return null;const e=[];for(const i of t){const t=ch(i);if(!t)return null;e.push(t)}if(e.length>1){const t=e[0],i=e[e.length-1];t[0]===i[0]&&t[1]===i[1]&&e.pop()}const i=hh(e);if(!i)return null;const s=e.map(t=>t[0]),n=e.map(t=>t[1]);return{centroid:i,bbox:[Math.min(...s),Math.min(...n),Math.max(...s),Math.max(...n)]}}function uh(t){let e=t;if(e&&"object"==typeof e&&!Array.isArray(e)){const t=e;e=t.path??t.points??e}if(!Array.isArray(e)||!e.length)return[];let i=(e.some(t=>(t=>Array.isArray(t)?t.length>=2&&!Array.isArray(t[0])&&("object"!=typeof t[0]||null==t[0]):!!t&&"object"==typeof t&&("x"in t||"y"in t))(t))?[e]:e.filter(Array.isArray)).map(t=>t.map(ch).filter(t=>null!=t)).filter(t=>t.length>=2);i.length>64&&(i=i.slice(-64));if(i.reduce((t,e)=>t+e.length,0)<=4e3)return i.map(t=>t.slice());const s=4e3-2*i.length,n=i.map(t=>t.length-2),o=n.reduce((t,e)=>t+e,0),a=n.map(t=>s*t/o),r=a.map(Math.floor);let l=s-r.reduce((t,e)=>t+e,0);const c=a.map((t,e)=>({index:e,fraction:t-Math.floor(t)})).sort((t,e)=>e.fraction-t.fraction||t.index-e.index);for(let t=0;tfunction(t,e){if(e>=t.length)return t.slice();if(e<=2)return[t[0],t[t.length-1]];const i=[];for(let s=0;st.slice()),i=e[e.length-1];return i?(i.length>2?i.pop():e.pop(),e):[]}function gh(t){if(!t)return null;const e=t.vacuum_position||t.robot_position||null,i=e&&null!=lh(e.x)&&null!=lh(e.y)?{x:lh(e.x),y:lh(e.y),a:lh(e.a??e.angle??e.theta)}:null,s=uh(t.path?.path??t.path?.points??t.path),n=[],o=t.rooms,a=Array.isArray(o)?o.map((t,e)=>[String(t?.id??e),t]):o&&"object"==typeof o?Object.entries(o):[];for(const[t,e]of a){if(!e||"object"!=typeof e)continue;const i=String(e.name??e.label??"").trim(),s=[[lh(e.cx),lh(e.cy)],[lh(e.center?.x),lh(e.center?.y)],[lh(e.x),lh(e.y)]].find(([t,e])=>null!=t&&null!=e);let o=s?.[0]??null,a=s?.[1]??null;const r=dh(e.outline),l=lh(e.x0),c=lh(e.y0),h=lh(e.x1),d=lh(e.y1),u=(null!=l&&null!=c&&null!=h&&null!=d?[Math.min(l,h),Math.min(c,d),Math.max(l,h),Math.max(c,d)]:null)||r?.bbox||null;if(null!=o&&null!=a||!r||([o,a]=r.centroid),null!=o&&null!=a||!u||(o=(u[0]+u[2])/2,a=(u[1]+u[3])/2),i&&null!=o&&null!=a){const e={id:t,name:i,cx:o,cy:a};u&&([e.x0,e.y0,e.x1,e.y1]=u),n.push(e)}}const r=function(t){return String(t.map_name??t.current_map??t.map_index??t.selected_map??"default")}(t);return i||n.length||s.length?{pos:i,path:s,rooms:n,mapId:r}:null}function mh(t,e,i){if(!t||!e)return null;const s=e.attributes||{},n=t.split(".")[0]||"",o=null!=i?.platform?String(i.platform):null,a=!!ch(s.vacuum_position??s.robot_position),r=!(!s.rooms||"object"!=typeof s.rooms),l=uh(s.path?.path??s.path?.points??s.path).length>0,c=[s.map_name,s.current_map,s.map_index,s.selected_map].some(t=>null!=t),h="xiaomi_cloud_map_extractor"===o,d=r||l||c;let u=null;if(a?u="compatible":h?u="known_xcme_incomplete":d?u="partial":"camera"===n&&(u="camera"),!u)return null;const p=a?"camera"===n?300:200:h?100:d?50:0;return{entityId:t,name:String(s.friendly_name||t),platform:o,category:u,hasPosition:a,hasRooms:r,hasPath:l,hasMapId:c,score:p}}const fh=t=>t.toLowerCase().replace(/[\s_\-.,]+/g,"");function vh(t,e){const i=new Map(e.map(t=>[fh(t.name),t])),s=[],n=[];for(const e of t){const t=i.get(fh(e.name));t&&(s.push([[e.cx,e.cy],[t.cx,t.cy]]),n.push(e.name))}if(s.length<3)return null;const o=function(t){if(t.length<3)return null;let e=0,i=0,s=0,n=0,o=0,a=0,r=0,l=0,c=0,h=0,d=0,u=0;for(const[[p,_],[g,m]]of t){if(![p,_,g,m].every(Number.isFinite))return null;e+=p*p,i+=p*_,s+=p,n+=_*_,o+=_,a+=1,r+=p*g,l+=_*g,c+=g,h+=p*m,d+=_*m,u+=m}const p=[e,i,s,i,n,o,s,o,a],_=t=>{const[e,i,s,n,o,a,r,l,c]=p,h=e*(o*c-a*l)-i*(n*c-a*r)+s*(n*l-o*r);if(!Number.isFinite(h)||Math.abs(h)<1e-9)return null;const d=[(o*c-a*l)/h,(s*l-i*c)/h,(i*a-s*o)/h,(a*r-n*c)/h,(e*c-s*r)/h,(s*n-e*a)/h,(n*l-o*r)/h,(i*r-e*l)/h,(e*o-i*n)/h];return[d[0]*t[0]+d[1]*t[1]+d[2]*t[2],d[3]*t[0]+d[4]*t[1]+d[5]*t[2],d[6]*t[0]+d[7]*t[1]+d[8]*t[2]]},g=_([r,l,c]),m=_([h,d,u]);if(!g||!m)return null;const f=[g[0],g[1],g[2],m[0],m[1],m[2]];return f.every(Number.isFinite)?f:null}(s);return o?{matrix:o,matched:n,residual:rh(o,s)}:null}function yh(t,e,i){const s=t[t.length-1];if(s&&s[0]===e[0]&&s[1]===e[1])return t;if(t.push(e),t.length<=600)return t;let n=function(t,e){if(t.length<3)return t.slice();const i=new Uint8Array(t.length);i[0]=i[t.length-1]=1;const s=[[0,t.length-1]];for(;s.length;){const[n,o]=s.pop(),[a,r]=t[n],[l,c]=t[o],h=l-a,d=c-r,u=Math.hypot(h,d)||1e-9;let p=0,_=-1;for(let e=n+1;ep&&(p=i,_=e)}_>0&&p>e&&(i[_]=1,s.push([n,_],[_,o]))}const n=[];for(let e=0;e600&&(n=n.filter((t,e)=>e%2==0||e===n.length-1)),n}function bh(t){return"cleaning"===t||"returning"===t||"on"===t}const wh={0:[1,0],90:[0,1],180:[-1,0],270:[0,-1]};function kh(t){const[e,i]=wh[t.rot]||[1,0],s=t.mir?-1:1;return[t.s*e*s,-t.s*i,t.ox,t.s*i*s,t.s*e,t.oy]}function xh(t){const e=t[0]*t[4]-t[1]*t[3];if(!Number.isFinite(e)||Math.abs(e)<1e-12)return null;const i=e<0,s=Math.sqrt(Math.abs(e));let n=180*Math.atan2(-t[1],t[4])/Math.PI;return n=(90*Math.round(n/90)%360+360)%360,{ox:t[2],oy:t[5],s:s,rot:n,mir:i}}function $h(t,e,i,s){const[n,o]=ah(kh(e),i,s),a=kh({...t,ox:0,oy:0}),[r,l]=ah(a,i,s);return{...t,ox:n-r,oy:o-l}}function Sh(t){const e=t?.trail_mode;return"never"===e||"cleaning"===e||"always"===e?e:!1===t?.trail?"never":"cleaning"}const Mh={offStates:["off"],unknownUsesToggle:!0},Ch={light:Mh,switch:Mh,fan:Mh,humidifier:Mh,input_boolean:Mh,automation:Mh,remote:Mh,group:Mh,climate:{...Mh,featureMasks:{turn_on:256,turn_off:128,toggle:384}},media_player:{...Mh,featureMasks:{turn_on:128,turn_off:256,toggle:384}},siren:{...Mh,featureMasks:{turn_on:1,turn_off:2,toggle:3}},vacuum:{...Mh,featureMasks:{turn_on:1,turn_off:2,toggle:3}},water_heater:{...Mh,featureMasks:{turn_on:8,turn_off:8,toggle:8}},camera:{...Mh,featureMasks:{turn_on:1,turn_off:1,toggle:1}}};function Dh(t){return t.slice(0,t.indexOf("."))}function Th(t,e,i){if(!t?.services||"object"!=typeof t.services)return!1;const s=t.services?.[e];return!!s&&Object.prototype.hasOwnProperty.call(s,i)}function Ph(t,e,i){return Th(t,e,i)?{domain:e,service:i}:Th(t,"homeassistant",i)?{domain:"homeassistant",service:i}:null}function Rh(t,e){return t?.entities?.[e]||null}function Ah(t,e,i){const s=t?.states?.[i],n=Rh(e,i);return s?.attributes?.friendly_name||n?.name||n?.original_name||i}function Ih(t,e){const i=Rh(t,e);if(null!=i?.disabled_by)return!0;const s=i?.device_id?t?.devices?.[i.device_id]:null;return null!=s?.disabled_by}function Eh(t,e){const i=t?.attributes?.supported_features;if(null==i||""===i)return!1;const s=Number(i);return Number.isFinite(s)&&(s&e)===e}function Fh(t,e,i){const s=Dh(i);if("lock"===s||"alarm_control_panel"===s)return!0;if("cover"!==s)return!1;const n=t?.states?.[i],o=Rh(e,i),a=String(n?.attributes?.device_class||o?.device_class||o?.original_device_class||"");return Ui.has(a)}function zh(t,e,i,s,n){return{ref:i,entityId:s,name:s?Ah(t,e,s):null,reason:n}}function Oh(t,e,i,s,n,o=null){return{target:null,skipped:zh(t,e,i,s,n),semantics:o,nextEffect:null,command:null}}function Hh(t,e,i,s,n=i){const o=Dh(i);if("cover"!==o&&"valve"!==o)return function(t,e,i,s,n=i){const o=Dh(i),a=t?.states?.[i];if(Ih(e,i))return Oh(t,e,n,i,"ha-disabled","power");if(Fh(t,e,i))return Oh(t,e,n,i,"secure");if(!a)return Oh(t,e,n,i,"missing","power");if("unavailable"===a.state)return Oh(t,e,n,i,"unavailable","power");const r=Ch[o];if(!r)return Oh(t,e,n,i,"unsupported");let l,c;if("unknown"===a.state||""===a.state){if(!r.unknownUsesToggle)return Oh(t,e,n,i,"unsupported","power");l="toggle",c="toggle"}else r.offStates.includes(String(a.state))?(l="turn-on",c="turn_on"):(l="turn-off",c="turn_off");const h=r.featureMasks?.[c];if(h&&!Eh(a,h))return Oh(t,e,n,i,"unsupported","power");const d=Ph(t,o,c);return d?{target:{entityId:i,name:Ah(t,e,i),state:String(a.state||""),via:s},skipped:null,semantics:"power",nextEffect:l,command:{...d,data:{entity_id:i}}}:Oh(t,e,n,i,"unsupported","power")}(t,e,i,s,n);if(Ih(e,i))return Oh(t,e,n,i,"ha-disabled",o);if(Fh(t,e,i))return Oh(t,e,n,i,"secure",o);const a=t?.states?.[i];if(!a)return Oh(t,e,n,i,"missing",o);if("unavailable"===a.state)return Oh(t,e,n,i,"unavailable",o);const r=function(t,e,i){const s=String(i?.state||""),n="closed"===s?{service:`open_${e}`,effect:"open",feature:1}:"open"===s?{service:`close_${e}`,effect:"close",feature:2}:"opening"===s||"closing"===s?{service:`stop_${e}`,effect:"stop",feature:8}:null;return n&&Eh(i,n.feature)&&Th(t,e,n.service)?n:Eh(i,3)&&Th(t,e,"toggle")?{service:"toggle",effect:"toggle"}:null}(t,o,a);if(!r)return Oh(t,e,n,i,"unsupported",o);return{target:{entityId:i,name:Ah(t,e,i),state:String(a.state||""),via:s},skipped:null,semantics:o,nextEffect:r.effect,command:{domain:o,service:r.service,data:{entity_id:i}}}}function Nh(t){return"entity"===t.bindingKind?t.bindingRef&&Ms(t.bindingRef)?[t.bindingRef]:[]:"virtual"===t.bindingKind?[]:Zn(t)}function Lh(t){const e=t.marker?.toggle_entity;return e&&Nh(t).includes(e)?e:null}function Bh(t,e,i){const s=function(t,e){if("entity"===t.bindingKind&&t.bindingRef){const e=t.marker?.light_entity?Qn(t):null;return[...new Set([e,t.bindingRef].filter(t=>!!t))]}const i=t.entities.length?t.entities:t.allEntities||[],s=t.marker?.light_entity||t.primary&&Ms(t.primary)?Qn(t):null;return[...new Set([s,...Vn(e,i)].filter(t=>!!t))]}(i,e);if(!s.length)return null;const n="entity"===i.bindingKind?"binding":"device-role";if("binding"===n)return Hh(t,e,s[0],n);let o=null,a=null;for(const i of s){const s=Hh(t,e,i,n);if(s.command)return s;const r=s.skipped?.reason;if("missing"===r||"unavailable"===r||"secure"===r)return s;"ha-disabled"!==r?o||=s:a||=s}return o||a}function qh(t){const e=t.skipped?.reason;return"missing"===e?"unavailable":e||"unsupported"}function jh(t,e){return{origin:t,kind:"none",semantics:null,targets:[],skippedTargets:[],noneReason:e,nextEffect:null,command:null}}function Wh(t,e){return"cover"===t||"toggle"===t?"toggle":"more-info"===t||"run"===t||"info"===t?t:(null==t||""===t)&&"light"===e?"toggle":"info"}function Uh(t,e){return{origin:t,kind:"single",semantics:e.semantics,targets:e.target?[e.target]:[],skippedTargets:e.skipped?[e.skipped]:[],noneReason:e.command?null:qh(e),nextEffect:e.nextEffect,command:e.command}}function Gh(t,e,i,s=[]){const n=new Map,o=[],a=new Set,r=t=>{const e=`${t.ref}\n${t.entityId||""}\n${t.reason}`;a.has(e)||(a.add(e),o.push(t))};for(const t of s)r(t);for(const s of i){const i=Hh(t,e,s.entityId,s.via,s.ref);i.target?n.set(s.entityId,n.get(s.entityId)||i.target):i.skipped&&r(i.skipped)}const l=[...n.values()];if(!l.length)return{origin:"explicit-toggle",kind:"group",semantics:"group-power",targets:l,skippedTargets:o,noneReason:o.length&&o.every(t=>"secure"===t.reason)?"secure":"configured-targets-missing",nextEffect:null,command:null};const c=l.some(t=>"on"===t.state)?"turn_off":"turn_on",h=Ph(t,"homeassistant",c);return h?{origin:"explicit-toggle",kind:"group",semantics:"group-power",targets:l,skippedTargets:o,noneReason:null,nextEffect:"turn_on"===c?"turn-on":"turn-off",command:{...h,data:{entity_id:l.map(t=>t.entityId)}}}:{origin:"explicit-toggle",kind:"group",semantics:"group-power",targets:[],skippedTargets:[...o,...l.map(i=>zh(t,e,i.entityId,i.entityId,"unsupported"))],noneReason:"unsupported",nextEffect:null,command:null}}function Vh(t){return String(t.marker?.id||t.id||"")}function Kh(t){const{hass:e,device:i}=t,s=t.registryHass||e,n=function(t){return"toggle"===t.tapAction?"explicit-toggle":"cover"===t.tapAction?"legacy-cover":!t.tapAction&&t.primary?.startsWith("light.")?"default-light":null}(i);if(!n)return null;const o=i.marker;if("explicit-toggle"===n&&yn(o)){const e=String(o?.id||i.id||""),s=oo(t.devices).get(e);if(s)return function(t,e){const i=t.registryHass||t.hass;return Gh(t.hass,i,e.driverEids.map(t=>({entityId:t,via:"control-marker-driver",ref:`marker:${e.markerId}`})))}(t,s);const a=bn(o,t.virtualLights);return{origin:n,kind:"single",semantics:"power",targets:[{entityId:"",name:i.name,state:a?"on":"off",via:"virtual-light"}],skippedTargets:[],noneReason:null,nextEffect:a?"turn-off":"turn-on",command:null,operation:{kind:"virtual-light",markerId:o.id}}}if("explicit-toggle"===n){if(Xn(i.marker?.binding,i.marker?.controls??i.controls,i.entities).length)return function(t,e=null){const{hass:i,device:s,devices:n}=t,o=t.registryHass||i,a=Xn(s.marker?.binding,s.marker?.controls??s.controls,s.entities),r=t.lightSources||lo(i,n,null,t.virtualLights),l=new Map;for(const t of r){if(!t.key.startsWith("marker:"))continue;const e=l.get(t.key)||[];e.push(t),l.set(t.key,e)}const c=oo(n),h=new Map;for(const t of n){const e=String(t.marker?.id||t.id||"");e&&h.set(e,t)}const d=[],u=[];e&&d.push({entityId:e,via:"entity"===s.bindingKind?"binding":"device-role",ref:e});for(const t of a){if(!t.startsWith("marker:")){Ms(t)?d.push({entityId:t,via:"control-entity",ref:t}):u.push(zh(i,o,t,t.includes(".")?t:null,"unsupported"));continue}const e=l.get(t)||[];if(!e.length){const e=h.get(t.slice(7));if("ha_disabled"===e?.bindingStatus?.kind){const s=e.bindingStatus.allEntityIds[0]||null;u.push({ref:t,entityId:s,name:e.name||(s?Ah(i,o,s):null),reason:"ha-disabled"})}else u.push(zh(i,o,t,null,"missing"));continue}const n=[...new Set(e.flatMap(t=>t.serviceEids))];if(n.length){for(const e of n)d.push({entityId:e,via:"control-entity",ref:t});continue}const a=e.some(t=>t.passive),r=t.slice(7),p=Vh(s),_=c.get(r)?.controllers.find(t=>Vh(t.device)===p);if(a&&_?.driverEids.length)for(const e of _.driverEids)d.push({entityId:e,via:"control-marker-driver",ref:t});else u.push(zh(i,o,t,null,a?"missing":"unsupported"))}return Gh(i,o,d,u)}(t,Lh(i))}if("legacy-cover"===n){const t=i.entities.find(t=>t.startsWith("cover."))||i.allEntities?.find(t=>t.startsWith("cover."));return t?Uh(n,Hh(e,s,t,"device-role")):jh(n,"no-actionable-entity")}const a=Lh(i),r=a?Hh(e,s,a,"entity"===i.bindingKind?"binding":"device-role"):Bh(e,s,i);return r?Uh(n,r):jh(n,i.virtual||"virtual"===i.bindingKind?"no-actionable-entity":"no-binding")}function Yh(t){if(!t)return[];const e=Array.isArray(t.data.entity_id)?t.data.entity_id:[t.data.entity_id];return[...new Set(e)].sort()}function Xh(t){return t?t.operation?t.operation:t.command?{kind:"ha-service",command:t.command}:null:null}function Jh(t,e){const i=Xh(t),s=Xh(e);return!(!i||!s||i.kind!==s.kind)&&("virtual-light"===i.kind&&"virtual-light"===s.kind?i.markerId===s.markerId:"ha-service"===i.kind&&"ha-service"===s.kind&&function(t,e){const i=Yh(t),s=Yh(e);return i.length===s.length&&i.every((t,e)=>t===s[e])}(i.command,s.command))}const Zh=t=>!!t&&t.length>=2&&Number.isFinite(t[0])&&Number.isFinite(t[1]);function Qh(t,e=5,i=5){return fr(t.cm,e,i)/2}function td(t,e,i=1,s=5,n=5,o=0){const a=t.host;if(!a||"partition"!==a.kind||"string"!=typeof a.id||!a.id)return{resolved:null,reason:"invalid-host"};const r=e.find(t=>t.id===a.id);if(!r)return{resolved:null,reason:"missing-partition"};if(!Zh(r.a)||!Zh(r.b)||!Number.isFinite(a.t)||a.t<0||a.t>1)return{resolved:null,reason:"invalid-position"};const l=r.b[0]-r.a[0],c=r.b[1]-r.a[1],h=Math.hypot(l,c),d=Number(t.length)*i;if(!(h>1e-9&&d>0&&Number.isFinite(d)))return{resolved:null,reason:"invalid-length"};const u=a.t*h;if(u-d/2h-o+1e-9)return{resolved:null,reason:"does-not-fit"};const p=l/h,_=c/h;let g=180*Math.atan2(c,l)/Math.PI;return g>=90?g-=180:g<-90&&(g+=180),{reason:null,resolved:{opening:t,host:a,partition:r,center:[r.a[0]+l*a.t,r.a[1]+c*a.t],angle:g,length:d,depth:fr(r.cm,s,n),t:a.t,axis:{a:[r.a[0],r.a[1]],b:[r.b[0],r.b[1]],ux:p,uy:_,length:h}}}}function ed(t,e,i=1,s=5,n=5){return td(t,e,i,s,n,0)}function id(t,e,i=1,s=5,n=5){const o=t.host,a="partition"===o?.kind?e.find(t=>t.id===o.id):void 0;if(!a)return ed(t,e,i,s,n);const r=td(t,e,i,s,n,Qh(a,s,n));return"does-not-fit"===r.reason?{resolved:null,reason:"does-not-fit-jamb"}:r}function sd(t,e){return!t||(t.length!==e.length||t.host?.kind!==e.host?.kind||t.host?.id!==e.host?.id||t.host?.t!==e.host?.t)}function nd(t){const{center:e,length:i,axis:s,host:n}=t,o=i/2;return{hostId:n.id,a:[e[0]-s.ux*o,e[1]-s.uy*o],b:[e[0]+s.ux*o,e[1]+s.uy*o],depth:t.depth}}function od(t,e=!1){const i=e?1:-1,s=t.depth/2;return{ox:-t.axis.uy*i*s,oy:t.axis.ux*i*s,cm:t.partition.cm,side:i}}function ad(t,e,i){const{center:s,length:n,axis:o}=t,a=n/2,r=e.flatMap(t=>{if(!t.kind||t.open)return[];const e=t.b[0]-t.a[0],n=t.b[1]-t.a[1],r=Math.hypot(e,n);if(!(r>i))return[];const l=e/r,c=n/r;if(Math.abs(o.ux*c-o.uy*l)>1e-6)return[];if(Math.abs((s[0]-t.a[0])*c-(s[1]-t.a[1])*l)>i)return[];const h=t=>(t[0]-s[0])*o.ux+(t[1]-s[1])*o.uy,d=h(t.a),u=h(t.b),p=Math.max(-a,Math.min(d,u)),_=Math.min(a,Math.max(d,u));return _>=p-i?[[p,_]]:[]});if(!r.length)return!1;r.sort((t,e)=>t[0]-e[0]||t[1]-e[1]);let l=-a;for(const[t,e]of r){if(t>l+i)return!1;if(l=Math.max(l,e),l>=a-i)return!0}return!1}function rd(t,e,i){return{...t,x:e.center[0]/i,y:e.center[1]/i,angle:e.angle}}function ld(t){return!!t&&t.length>=2&&Number.isFinite(t[0])&&Number.isFinite(t[1])}function cd(t){return`${t[0].toFixed(6)},${t[1].toFixed(6)}`}function hd(t,e,i){return Math.abs(t[0]-e[0])_d(s,t,e)))continue;const t=cd(s);a.has(t)||a.set(t,{point:[s[0],s[1]],key:t})}}}return{segments:[...o.values()].sort((t,e)=>t.key.localeCompare(e.key)),endpoints:[...a.values()].sort((t,e)=>t.key.localeCompare(e.key))}}function md(t,e,i){return e.some(e=>ld(e)&&hd(t,e,i))}function fd(t,e,i){if(!i)return!0;const s=t-i.distance;return s<-1e-9||Math.abs(s)<=1e-9&&e.localeCompare(i.key)<0}function vd(t,e,i){const s=t.b[0]-t.a[0],n=t.b[1]-t.a[1],o=Math.hypot(s,n);if(!(o>0))return[...t.a];const a=s/o,r=n/o,l=Math.max(0,Math.min(o,(e[0]-t.a[0])*a+(e[1]-t.a[1])*r)),c=i>0?Math.max(0,Math.min(o,Math.round(l/i)*i)):l;return[t.a[0]+a*c,t.a[1]+r*c]}const yd=.001;function bd(t,e,i){const s=[];for(let n=0;n+1=0?e[n]:i;s.push({a:[o[0],o[1]],b:[a[0],a[1]],cm:r})}return s}function wd(t){return!!t&&t.length>=2&&Number.isFinite(t[0])&&Number.isFinite(t[1])}function kd(t,e,i,s){return t*s-e*i}function xd(t){let e=0;for(let i=0;it.localeCompare(e)),e[0]}function Dd(t,e,i){const s=[...t];for(let t=!0;t&&s.length>=3;){t=!1;for(let n=0;n=0){s.splice(n,1),t=!0;break}}}return s}function Td(t,e){const i=t.map(t=>Math.max(0,Math.min(1,t))).sort((t,e)=>t-e),s=[];for(const t of i)(!s.length||Math.abs(t-s[s.length-1])>e)&&s.push(t);return s}function Pd(t,e){return[t.a[0]+(t.b[0]-t.a[0])*e,t.a[1]+(t.b[1]-t.a[1])*e]}function Rd(t,e,i){const s=function(t,e){const i=e.b[0]-e.a[0],s=e.b[1]-e.a[1],n=i*i+s*s;return n>0?((t[0]-e.a[0])*i+(t[1]-e.a[1])*s)/n:0}(t,e);if(s<-i||s>1+i)return null;const n=Pd(e,s);return Math.hypot(n[0]-t[0],n[1]-t[1])<=i?Math.max(0,Math.min(1,s)):null}function Ad(t,e,i,s,n){const o=t.b[0]-t.a[0],a=t.b[1]-t.a[1],r=e.b[0]-e.a[0],l=e.b[1]-e.a[1],c=e.a[0]-t.a[0],h=e.a[1]-t.a[1],d=kd(o,a,r,l),u=Math.max(Math.hypot(o,a),Math.hypot(r,l),1);if(Math.abs(d)>n*u){const t=kd(c,h,r,l)/d,e=kd(c,h,o,a)/d;return void(t>=-n&&t<=1+n&&e>=-n&&e<=1+n&&(i.push(Math.max(0,Math.min(1,t))),s.push(Math.max(0,Math.min(1,e)))))}if(!(Math.abs(kd(c,h,o,a))>n*u)){for(const s of[e.a,e.b]){const e=Rd(s,t,n);null!=e&&i.push(e)}for(const i of[t.a,t.b]){const t=Rd(i,e,n);null!=t&&s.push(t)}}}function Id(t){let e=t+1|0;return e^=e<<13,e^=e>>>17,e^=e<<5,e>>>0}function Ed(t,e){return t.minY-e.minY||t.index-e.index}function Fd(t){return t.subtreeMaxY=Math.max(t.item.maxY,t.left?.subtreeMaxY??-1/0,t.right?.subtreeMaxY??-1/0),t}function zd(t){const e=t.right;return t.right=e.left,e.left=Fd(t),Fd(e)}function Od(t){const e=t.left;return t.left=e.right,e.right=Fd(t),Fd(e)}function Hd(t,e){return t?(Ed(e,t.item)<0?(t.left=Hd(t.left,e),t.left.priority0)t.right=Nd(t.right,e);else{if(!t.left)return t.right;if(!t.right)return t.left;t.left.priority=e&&Ld(t.left,e,i,s),t.item.minY<=i&&t.item.maxY>=e&&s.push(t.item),t.item.minY<=i&&Ld(t.right,e,i,s))}function Bd(t,e=.001){const i=Number.isFinite(e)&&e>0?e:yd,s=t.filter(t=>wd(t.a)&&wd(t.b)&&"string"==typeof t.key&&t.key.length>0&&Math.hypot(t.b[0]-t.a[0],t.b[1]-t.a[1])>i),n=s.map(()=>[0,1]);!function(t,e,i){const s=t.map((t,e)=>({index:e,minX:Math.min(t.a[0],t.b[0])-i,maxX:Math.max(t.a[0],t.b[0])+i,minY:Math.min(t.a[1],t.b[1])-i,maxY:Math.max(t.a[1],t.b[1])+i})),n=[...s].sort((t,e)=>t.minX-e.minX||t.minY-e.minY||t.index-e.index),o=[...s].sort((t,e)=>t.maxX-e.maxX||t.index-e.index),a=new Set;let r=null,l=0;for(const s of n){for(;lt.index-e.index);for(const o of n)Ad(t[o.index],t[s.index],e[o.index],e[s.index],i);a.add(s.index),r=Hd(r,s)}}(s,n,i);const o=new Map;for(let t=0;t({key:t,a:e.a,b:e.b,sourceKeys:[...e.sourceKeys].sort((t,e)=>t.localeCompare(e))})).sort((t,e)=>t.key.localeCompare(e.key))}const qd=1e-5;function jd(t){const e=t.map(()=>[]);for(let i=0;i=1-1e-9||u<=1e-9||u>=1-1e-9||(e[i].push(d),e[a].push(u))}}const i=[];for(let s=0;st-e),1];for(let t=1;t{const i=e[2]-e[0],s=e[3]-e[1],n=i*i+s*s;if(!(n>0))return Math.hypot(t[0]-e[0],t[1]-e[1]);const o=Math.max(0,Math.min(1,((t[0]-e[0])*i+(t[1]-e[1])*s)/n));return Math.hypot(t[0]-(e[0]+o*i),t[1]-(e[1]+o*s))},Gd=(t,e,i,s)=>{const n=s[2]-s[0],o=s[3]-s[1],a=e*o-i*n;if(Math.abs(a)<1e-12)return 1/0;const r=s[0]-t[0],l=s[1]-t[1],c=(r*o-l*n)/a;if(!(c>1e-9))return 1/0;const h=(r*i-l*e)/a;return h<-1e-9||h>1+1e-9?1/0:c};function Vd(t,e,i,s=96){if(!(e>0&&Number.isFinite(t[0])&&Number.isFinite(t[1])))return[];const n=[];for(const s of i){if(!s||s.length<4)continue;if(![s[0],s[1],s[2],s[3]].every(Number.isFinite))continue;const i=Ud(t,s);if(i<1e-7)return[];i>e||n.push(s)}const o=[],a=Math.max(12,Math.round(s));for(let t=0;tt-e);const l=[];let c=Number.NEGATIVE_INFINITY;for(const i of o){if(i-c<1e-9)continue;c=i;const s=Math.cos(i),o=Math.sin(i);let a=e;for(const e of n){const i=Gd(t,s,o,e);i=3?l:[]}class Kd extends ht{constructor(){super(...arguments),this._spaces=null,this._spacesLoading=!1}setConfig(t){this._config=t}async _loadSpaces(){if(!this._spaces&&!this._spacesLoading&&this.hass){this._spacesLoading=!0;try{const t=await this.hass.callWS({type:"houseplan/config/get"});this._spaces=(t?.config?.spaces||[]).map(t=>({value:t.id,label:t.title||t.id}))}catch{this._spaces=[]}finally{this._spacesLoading=!1}}}get _lang(){return sa(this.hass,this._config?.language)}get _schema(){const t=this._spaces||[],e=this._lang;return[{name:"title",selector:{text:{}}},t.length?{name:"default_floor",selector:{select:{mode:"dropdown",options:t}}}:{name:"default_floor",selector:{text:{}}},{name:"language",selector:{select:{mode:"dropdown",options:[{value:"",label:na(e,"editor.lang_auto")},{value:"en",label:na(e,"editor.lang_en")},{value:"ru",label:na(e,"editor.lang_ru")}]}}},{name:"icon_size",selector:{number:{min:1,max:6,step:.1,mode:"box"}}},{name:"show_temperature",selector:{boolean:{}}},{name:"live_states",selector:{boolean:{}}},{name:"show_signal",selector:{boolean:{}}},{name:"kiosk",selector:{boolean:{}}},{name:"cycle",selector:{number:{min:0,max:3600,step:5,mode:"box"}}}]}render(){if(!this.hass||!this._config)return G;this._loadSpaces();const t=this._lang,e={title:na(t,"editor.title"),default_floor:na(t,"editor.default_floor"),language:na(t,"editor.language"),icon_size:na(t,"editor.icon_size"),show_temperature:na(t,"editor.show_temperature"),live_states:na(t,"editor.live_states"),show_signal:na(t,"editor.show_signal"),kiosk:na(t,"editor.kiosk"),cycle:na(t,"editor.cycle")};return j``}const er={color:"#607d8b",opacity:1,widthCm:3.6,fill:!1,fillColor:"#607d8b",fillOpacity:.25},ir=(t,e=1)=>{const i=Number(t);return Number.isFinite(i)?Math.min(1,Math.max(0,i)):e},sr=t=>{let e=Number(t);return Number.isFinite(e)?(e=(e%360+360)%360,e>180?e-360:e):0};function nr(t,e,i){return sr(e)?[t.x,t.y]:i([t.x,t.y])}const or=(t,e,i)=>{const s=Number(t),n=Number.isFinite(e)&&e>0?e:5;return Number.isFinite(s)&&s>0?s/n*i:0},ar=(t,e,i)=>{const s=Number(t),n=Number.isFinite(e)&&e>0?e:5;return Number.isFinite(s)&&i>0?s/i*n:0},rr=(t,e,i,s=er.widthCm)=>{const n=Number(t?.width_cm);if(Number.isFinite(n)&&n>0)return n;const o=Number(t?.width);return Number.isFinite(o)&&o>0?ar(o,e,i):s};function lr(t,e){return{color:t.color,opacity:ir(t.opacity),width_cm:Math.max(.1,Math.min(100,Number(t.widthCm)||.1)),...e?{fill:t.fill,fill_color:t.fillColor,fill_opacity:ir(t.fillOpacity,.25)}:{}}}function cr(t){const e=t.x+t.w/2,i=t.y+t.h/2,s=sr(t.angle)*Math.PI/180,n=Math.cos(s),o=Math.sin(s),a=(t,s)=>{const a=t-e,r=s-i;return[e+a*n-r*o,i+a*o+r*n]};return[a(t.x,t.y),a(t.x+t.w,t.y),a(t.x+t.w,t.y+t.h),a(t.x,t.y+t.h)]}function hr(t){const e=cr(t),i=(t,e)=>[(t[0]+e[0])/2,(t[1]+e[1])/2],s=[(e[0][0]+e[2][0])/2,(e[0][1]+e[2][1])/2];return{points:[...e,i(e[0],e[1]),i(e[1],e[2]),i(e[2],e[3]),i(e[3],e[0]),s],segments:e.map((t,i)=>({a:t,b:e[(i+1)%4]}))}}function dr(t,e,i,s,n,o,a,r){const l=sr(t.angle)*Math.PI/180,c=Math.cos(l),h=Math.sin(l),d=-Math.sin(l),u=Math.cos(l),p=t.x+t.w/2,_=t.y+t.h/2,g=e>0?-t.w/2:t.w/2,m=i>0?-t.h/2:t.h/2,f=p+g*c+m*d,v=_+g*h+m*u,y=s-f,b=n-v;let w=(y*c+b*h)*(e>0?1:-1),k=(y*d+b*u)*(i>0?1:-1),x=null;if(o){const e=w/Math.max(t.w,r),i=k/Math.max(t.h,r);x=Math.max(r/Math.max(t.w,r),r/Math.max(t.h,r),e,i),w=t.w*x,k=t.h*x}if(a>0)if(o){const e=Math.max(1,Math.round(t.w/a)),i=Math.max(1,Math.round(t.h/a));if(Math.abs(t.w-e*a)<1e-6&&Math.abs(t.h-i*a)<1e-6){const s=(t,e)=>{let i=Math.abs(t),s=Math.abs(e);for(;s;)[i,s]=[s,i%s];return Math.max(1,i)},n=1/s(e,i),o=Math.max(r/t.w,r/t.h),a=Math.max(o,Math.round((x??1)/n)*n);w=t.w*a,k=t.h*a}else{t.w>=t.h?(w=Math.round(w/a)*a,k=w*(t.h/Math.max(t.w,r))):(k=Math.round(k/a)*a,w=k*(t.w/Math.max(t.h,r)))}}else w=Math.round(w/a)*a,k=Math.round(k/a)*a;w=Math.max(r,w),k=Math.max(r,k);return{x:f+(e>0?w/2:-w/2)*c+(i>0?k/2:-k/2)*d-w/2,y:v+(e>0?w/2:-w/2)*h+(i>0?k/2:-k/2)*u-k/2,w:w,h:k,angle:sr(t.angle)||void 0}}const ur=(t,e,i)=>{const s=i[0]-e[0],n=i[1]-e[1],o=s*s+n*n;if(o<1e-12)return[...e];const a=Math.max(0,Math.min(1,((t[0]-e[0])*s+(t[1]-e[1])*n)/o));return[e[0]+s*a,e[1]+n*a]};const pr=15;function _r(t,e){return Number.isFinite(t)&&t>0&&Number.isFinite(e)&&e>0&&t*e<3}function gr(t){return Number.isFinite(t)?Math.max(1,Math.min(100,t)):1}function mr(t,e){return!Number.isFinite(t)||t<=0?"":String(e?Math.round(t/2.54*100)/100:Math.round(100*t)/100)}function fr(t,e,i){const s=Number(e)>0?Number(e):5;return gr(t)/s*i}function vr(t,e){return e>0&&Number.isFinite(t)?Math.round(t/e)*e:t}function yr(t,e){let i=e[0]-t[0],s=e[1]-t[1];const n=Math.hypot(i,s);return n<1e-12?[1,0]:(i/=n,s/=n,(i<-1e-12||Math.abs(i)<=1e-12&&s<0)&&(i=-i,s=-s),[i,s])}function br(t,e,i){const s=vr((t[0]+e[0])/2,i),n=vr((t[1]+e[1])/2,i),[o,a]=yr(t,e);let r=Math.atan2(a,o);r<0&&(r+=Math.PI);const l=Math.round(1800*r)/1800,c=i>0&&i<.01?6:i<1?4:2;return`${s.toFixed(c)},${n.toFixed(c)}@${l.toFixed(4)}`}function wr(t,e,i,s){return 1===s?br(t,e,i):br([t[0]/s,t[1]/s],[e[0]/s,e[1]/s],i)}function kr(t,e){if(!Array.isArray(t.a)||!Array.isArray(t.b)||t.a.length<2||t.b.length<2)return null;const i=[Number(t.a[0]),Number(t.a[1]),Number(t.b[0]),Number(t.b[1])];if(!i.every(Number.isFinite))return null;const s=e>0?e:1;return[[i[0]*s,i[1]*s],[i[2]*s,i[3]*s]]}function xr(t,e,i,s,n){const o=n>0?n:1;return{key:wr(t,e,s,o),cm:gr(i),a:[t[0]/o,t[1]/o],b:[e[0]/o,e[1]/o]}}function $r(t,e){const i=e>0?e:1,s=[];for(const e of t){const t=e.key.lastIndexOf("@");if(t<0)continue;const[n,o]=e.key.slice(0,t).split(",").map(Number),a=Number(e.key.slice(t+1));[n,o,a].every(Number.isFinite)&&s.push({w:e,x:n*i,y:o*i,ang:a})}return s}function Sr(t,e){const[i,s]=yr(t,e);let n=Math.atan2(s,i);return n<0&&(n+=Math.PI),n}function Mr(t,e){let i=Math.abs(t-e);return i>Math.PI/2&&(i=Math.PI-i),i<.02}function Cr(t,e,i,s,n=1){if(!t?.length)return null;const o=wr(e,i,s,n),a=t.find(t=>t.key===o);if(a)return a;const r=n>0?n:1,l=(e[0]+i[0])/2,c=(e[1]+i[1])/2,h=Sr(e,i),d=Math.max(.5*s,1e-9)*r;for(const e of $r(t,r))if(Mr(e.ang,h)&&Math.hypot(e.x-l,e.y-c)<=d)return e.w;return null}function Dr(t,e,i,s,n=1){const o=Cr(t,e,i,s,n);if(o&&o.cm>0)return gr(o.cm);const a=function(t,e,i,s,n){if(!t?.length)return null;const o=n>0?n:1,a=Math.hypot(i[0]-e[0],i[1]-e[1]);if(a<1e-12)return null;const r=Sr(e,i),l=Math.max(.5*s,1e-9)*o;let c=null;for(const s of t){if(!(s.cm>0))continue;const t=kr(s,o);if(!t)continue;const n=Math.hypot(t[1][0]-t[0][0],t[1][1]-t[0][1]);if(n<1e-12||!Mr(Sr(t[0],t[1]),r))continue;if(sl(e[0],e[1],t[0][0],t[0][1],t[1][0],t[1][1])>l||sl(i[0],i[1],t[0][0],t[0][1],t[1][0],t[1][1])>l)continue;if(n+l(o.has(t.key)||(t=>{const e=kr(t,s);if(!e)return!1;const[i,o]=e,r=o[0]-i[0],c=o[1]-i[1],h=Math.hypot(r,c);if(h<=l)return!1;if(!a.some(t=>{const e=[t[0],t[1]],s=[t[2],t[3]];return Mr(Sr(i,o),Sr(e,s))&&sl(i[0],i[1],e[0],e[1],s[0],s[1])<=l&&sl(o[0],o[1],e[0],e[1],s[0],s[1])<=l}))return!1;const d=(n||[]).some(t=>{const e=[t[0],t[1]],s=[t[2],t[3]];if(!Mr(Sr(i,o),Sr(e,s)))return!1;const n=t=>Math.abs((t[0]-i[0])*c-(t[1]-i[1])*r)/h;if(n(e)>l||n(s)>l)return!1;const a=h*h,d=((e[0]-i[0])*r+(e[1]-i[1])*c)/a,u=((s[0]-i[0])*r+(s[1]-i[1])*c)/a;return Math.min(1,Math.max(d,u))-Math.max(0,Math.min(d,u))>l/h});return!d})(t))&&t.cm>=1&&t.cm<=100)}function Pr(t,e,i,s=8){const[n,o]=yr(t,e);let a=Math.atan2(o,n);a<0&&(a+=Math.PI);let r=i*Math.PI/180%Math.PI;r<0&&(r+=Math.PI);let l=Math.abs(a-r);return l>Math.PI/2&&(l=Math.PI-l),l<=s*Math.PI/180}function Rr(t,e,i,s,n=1){if(!t?.length)return[];if(e.length!==i.length)return t.slice();const o=new Map;for(let t=0;t0?n:1,r=Math.max(.5*s,1e-9)*a,l=new Set,c=[];for(const n of t){let t="",h=null;const d=kr(n,a);if(d)for(let n=0;nr||sl(d[1][0],d[1][1],o[0],o[1],l[0],l[1])>r)continue;const p=l[0]-o[0],_=l[1]-o[1],g=p*p+_*_;if(g<1e-18)continue;const m=t=>{const e=Math.max(0,Math.min(1,((t[0]-o[0])*p+(t[1]-o[1])*_)/g));return[c[0]+(u[0]-c[0])*e,c[1]+(u[1]-c[1])*e]};h=[m(d[0]),m(d[1])],t=wr(h[0],h[1],s,a);break}if(d||(t=o.get(n.key)||""),!t){const o=$r([n],a)[0];if(o)for(let n=0;n1.000001)continue;if(sl(o.x,o.y,l[0],l[1],c[0],c[1])>r)continue;const m=h[0]+(d[0]-h[0])*Math.max(0,Math.min(1,g)),f=h[1]+(d[1]-h[1])*Math.max(0,Math.min(1,g)),[v,y]=yr(h,d),b=Math.max(s*a,1e-6);t=wr([m-v*b,f-y*b],[m+v*b,f+y*b],s,a);break}}t||(t=n.key),l.has(t)||(l.add(t),c.push(h?xr(h[0],h[1],n.cm,s,a):{...n,key:t,cm:gr(n.cm)}))}return c}function Ar(t,e,i,s,n,o=1){const a=wr(e,i,n,o),r=(t||[]).filter(t=>t.key!==a);return null==s||s<1?r:[...r,xr(e,i,s,n,o)]}function Ir(t,e,i,s,n,o=[],a=1){let r=t?t.slice():[];for(const t of function(t,e,i,s,n=1,o=[]){const a=Xr(t,e,i,s,n,o);if(!a)return[];const r=[];for(let t=0;t0||(c=Ar(c,e,i,s,n,a)))}return c}function Fr(t){const{a:e,b:i,halfDepth:s}=t;if(!Array.isArray(e)||!Array.isArray(i)||e.length<2||i.length<2||![e[0],e[1],i[0],i[1]].every(Number.isFinite))return null;const n=i[0]-e[0],o=i[1]-e[1],a=Math.hypot(n,o);if(!(a>1e-9&&s>0&&Number.isFinite(s)))return null;const r=-o/a*s,l=n/a*s;return[[e[0]+r,e[1]+l],[i[0]+r,i[1]+l],[i[0]-r,i[1]-l],[e[0]-r,e[1]-l]]}function zr(t,e,i){return Math.hypot(t[0]-e[0],t[1]-e[1])<=i}function Or(t,e,i){const s=e.b[0]-e.a[0],n=e.b[1]-e.a[1],o=s*s+n*n;if(!(o>i*i))return!1;const a=((t[0]-e.a[0])*s+(t[1]-e.a[1])*n)/o;if(!(a>0&&a<1))return!1;const r=[e.a[0]+s*a,e.a[1]+n*a];return Math.hypot(t[0]-r[0],t[1]-r[1])<=i}function Hr(t,e,i,s){const n=Math.hypot(e,i);if(!(n>1e-9&&s>0))return;const o=[e/n,i/n],a=t.find(t=>Math.abs(t.u[0]*o[1]-t.u[1]*o[0])<1e-9&&t.u[0]*o[0]+t.u[1]*o[1]>1-1e-9);a?a.halfDepth=Math.max(a.halfDepth,s):t.push({u:o,halfDepth:s})}function Nr(t,e=1e-6){const i=(t||[]).filter(t=>t&&Array.isArray(t.a)&&Array.isArray(t.b)&&t.a.length>=2&&t.b.length>=2&&t.a.every(Number.isFinite)&&t.b.every(Number.isFinite)&&Number.isFinite(t.halfDepth)&&t.halfDepth>0&&Math.hypot(t.b[0]-t.a[0],t.b[1]-t.a[1])>1e-9);if(i.length<2)return[];const s=Math.max(Number.isFinite(e)?e:0,1e-9),n=i.flatMap(t=>[t.a,t.b]).map(t=>[t[0],t[1]]).sort((t,e)=>t[0]-e[0]||t[1]-e[1]),o=[];for(const t of n)o.some(e=>zr(e,t,s))||o.push(t);const a=[];for(const t of o){const e=[];for(const n of i)zr(t,n.a,s)?Hr(e,n.b[0]-n.a[0],n.b[1]-n.a[1],n.halfDepth):zr(t,n.b,s)?Hr(e,n.a[0]-n.b[0],n.a[1]-n.b[1],n.halfDepth):Or(t,n,s)&&(Hr(e,n.a[0]-t[0],n.a[1]-t[1],n.halfDepth),Hr(e,n.b[0]-t[0],n.b[1]-t[1],n.halfDepth));if(!(e.length<2)){e.sort((t,e)=>Math.atan2(t.u[1],t.u[0])-Math.atan2(e.u[1],e.u[0])||t.halfDepth-e.halfDepth);for(let i=0;is*s&&a.push(m)}}}return a}function Lr(t,e,i,s){if(!(e>0)||!t||t.length<2)return"";if(i&&t.length>=3){let i=t;const n=t[t.length-1];if(t.length>=4&&Math.hypot(t[0][0]-n[0],t[0][1]-n[1])<1e-9&&(i=t.slice(0,-1)),i.length>=3){const t=i.map((t,i)=>s?.[i]||e),n=_l(i,t),o=Vr(i,t);if(n&&o)return`${Kr(n)} ${Kr(Yr(o))}`}}const n=[];for(let i=0;i=1e-9&&r>0&&n.push({a:o,b:a,halfDepth:r})}const o=[...n.map(Fr).filter(t=>!!t),...Nr(n)],a=function(t){let e=null;try{for(const i of t){if(i.length<3)continue;const t=ol(i);e=e?si(e,t):[t]}return e}catch{return null}}(o);return a?hl(a):o.map(t=>Kr(t)).join(" ")}function Br(t,e,i,s,n=1){if(!i.length)return!1;const o=qr(s,n),a=(t[0]+e[0])/2,r=(t[1]+e[1])/2,[l,c]=yr(t,e);for(const t of i){const[e,i]=yr([t[0],t[1]],[t[2],t[3]]);if(!(Math.abs(l*i-c*e)>.05)&&sl(a,r,t[0],t[1],t[2],t[3])<=o)return!0}return!1}function qr(t,e){return Math.max(t*(e>0?e:1)*.04,1e-9)}function jr(t){let e=0;for(let i=0;it[1]!=l>t[1]&&t[0]<(r-o)*(t[1]-a)/(l-a+0)+o&&(i=!i)}return i}([c[0]+.001*r,c[1]+.001*l],t)||(r=-r,l=-l),[r,l]}function Ur(t,e){const i=t[0]*e[1]-t[1]*e[0],s=t[0]*e[0]+t[1]*e[1];return Math.abs(i)<1e-9&&s>0}function Gr(t,e,i,s){const n=e[0]*s[1]-e[1]*s[0];if(Math.abs(n)<1e-12)return null;const o=[i[0]-t[0],i[1]-t[1]],a=(o[0]*s[1]-o[1]*s[0])/n;return[t[0]+a*e[0],t[1]+a*e[1]]}function Vr(t,e){const i=t?.length||0;if(i<3||e.length!==i)return null;if(e.every(t=>!(t>0)))return t.map(t=>[t[0],t[1]]);const s=[];for(let n=0;n0||d>0)){s.push([t[n][0],t[n][1]]);continue}if(h>0!=d>0){const e=t[n],i=h>0?[e[0]+u*h,e[1]+p*h]:[e[0],e[1]],o=d>0?[e[0]+_*d,e[1]+g*d]:[e[0],e[1]];s.push(i),Math.hypot(o[0]-i[0],o[1]-i[1])>1e-9&&s.push(o);continue}if(Ur(b,w)){const e=t[n],i=[e[0]+u*h,e[1]+p*h],o=[e[0]+_*d,e[1]+g*d];s.push(i),Math.hypot(o[0]-i[0],o[1]-i[1])>1e-9&&s.push(o);continue}const $=Gr(k,b,x,w),S=Math.max(h,d,1e-9);if($){if(Math.hypot($[0]-t[n][0],$[1]-t[n][1])<=4*S){s.push($);continue}}h>0&&s.push([t[n][0]+u*h,t[n][1]+p*h]),d>0&&s.push([t[n][0]+_*d,t[n][1]+g*d]),h>0||d>0||s.push([t[n][0],t[n][1]])}return s.length>=3?s:null}function Kr(t,e=!0){if(!t.length)return"";let i=`M ${t[0][0]} ${t[0][1]}`;for(let e=1;et?.id===e),r=hi(a);if(!r||r.length<3)return null;const l=qr(s,n),c=[];for(const i of t||[]){if(!i||i.id===e)continue;const t=hi(i);if(t)for(const e of Cs(r,t,l))c.push([e[0],e[1]],[e[2],e[3]])}for(const t of i||[])c.push([t[0],t[1]],[t[2],t[3]]);for(const t of o||[]){const e=kr(t,n);e&&c.push(e[0],e[1])}const h=[],d=[];for(let t=0;tl)continue;const a=((t[0]-e[0])*(i[0]-e[0])+(t[1]-e[1])*(i[1]-e[1]))/(s*s);a<=n||a>=1-n||(o.some(t=>Math.abs(t-a)*s<=2*l)||o.push(a))}o.sort((t,e)=>t-e);for(const s of o)h.push([e[0]+(i[0]-e[0])*s,e[1]+(i[1]-e[1])*s]),d.push(t)}return{poly:h,parent:d,orig:r}}function Jr(t,e,i,s){const n=e.poly.length,o=new Array(n).fill(0);if(!t?.length)return o;const a=new Set,r=[];for(let l=0;l0?(o[l]=gr(c.cm),a.add(c.key)):r.push(l)}if(!r.length)return o;const l=s>0?s:1,c=Math.max(.5*i,1e-9)*l,h=$r(t,l).filter(t=>t.w.cm>0);for(let t=r.length-1;t>=0;t--){const i=r[t],s=e.poly[i],a=e.poly[(i+1)%n],d=Sr(s,a);let u=null;for(const t of h){const e=kr(t.w,l);if(!e||!Mr(Sr(e[0],e[1]),d))continue;if(sl(s[0],s[1],e[0][0],e[0][1],e[1][0],e[1][1])>c||sl(a[0],a[1],e[0][0],e[0][1],e[1][0],e[1][1])>c)continue;const i=Math.hypot(a[0]-s[0],a[1]-s[1]),n=Math.hypot(e[1][0]-e[0][0],e[1][1]-e[0][1]),o=Math.max(0,n-i);(!u||oc||sl(n[0],n[1],e[0][0],e[0][1],e[1][0],e[1][1])>c)continue;i=!0,o=Math.max(0,Math.hypot(e[1][0]-e[0][0],e[1][1]-e[0][1])-_)}else{if(sl(t.x,t.y,s[0],s[1],n[0],n[1])>c)continue;o=Math.hypot(t.x-d,t.y-u)}(!p||i&&!p.exact||i===p.exact&&ot?.id===e),n=hi(s);if(!n)return[];const o=[];for(const s of t||[]){if(!s||s.id===e)continue;const t=hi(s);if(t)for(const e of Cs(n,t,i))o.push(e)}return o}(t,e,qr(n,r)),h=function(t,e,i,s,n){const o=qr(s,n),a=[];for(let r=0;rsl(h,d,t[0],t[1],t[2],t[3])<=o);a.push(u?"shared":"outer")}return a}(l.poly,c,s,n,r),d=Jr(i,l,n,r),u=d.map((t,e)=>h[e]&&t>0?fr(t,o,a)/2:0);return{...l,kinds:h,cms:d,offsets:u}}function Qr(t,e,i,s,n,o,a=1){const r=[];for(const l of t||[]){if(!l?.id)continue;const c=Zr(t,l.id,e,i,s,n,o,a);if(c)for(let t=0;t0&&(r=Ar(r,t.a,t.b,t.cm,s,a));return r}function el(t,e,i,s,n,o,a=1){if(!e?.length)return[];const r=[],l=new Set;for(const c of Qr(t,e,i,s,n,o,a))!c.open&&c.cm>0&&!l.has(c.key)&&(l.add(c.key),r.push(c));const c=[];for(const r of t||[]){if(!r?.id)continue;const l=Zr(t,r.id,e,i,s,n,o,a);if(l)for(let t=0;t0)||null===l.kinds[i]){t++;continue}let o=t;for(;o+10&&c.push({a:[h[0],h[1]],b:[d[0],d[1]],key:wr(h,d,s,a),cm:n,len:u}),t=o+1}}}c.sort((t,e)=>e.len-t.len||t.key.localeCompare(e.key));const h=[],d=new Set,u=new Set,p=4*qr(s,a);for(const t of c){const e=r.filter(e=>!u.has(e.key)&&e.cm===t.cm&&Mr(Sr(e.a,e.b),Sr(t.a,t.b))&&sl(e.a[0],e.a[1],t.a[0],t.a[1],t.b[0],t.b[1])<=p&&sl(e.b[0],e.b[1],t.a[0],t.a[1],t.b[0],t.b[1])<=p);if(e.length){for(const t of e)u.add(t.key);d.has(t.key)||(d.add(t.key),h.push(xr(t.a,t.b,t.cm,s,a)))}}for(const t of r)u.has(t.key)||d.has(t.key)||(d.add(t.key),h.push(xr(t.a,t.b,t.cm,s,a)));return h}function il(t,e,i,s,n,o,a,r=1){const l=qr(n,r),c=(s[0]+s[2])/2,h=(s[1]+s[3])/2,d=Sr([s[0],s[1]],[s[2],s[3]]);let u=null;for(const s of Qr(t,e,i,n,o,a,r)){if(!Mr(Sr(s.a,s.b),d))continue;const t=sl(c,h,s.a[0],s.a[1],s.b[0],s.b[1]);t>4*l||(!u||tt?.id===e),c=hi(l);if(!c||c.length<3)return null;if(!i?.length)return c.map(t=>[t[0],t[1]]);const h=Zr(t,e,i,s,n,o,a,r);return h&&h.offsets.some(t=>t>0)&&Vr(h.poly,h.offsets)||c.map(t=>[t[0],t[1]])}function ol(t){const e=t.map(t=>[t[0],t[1]]);return e.push([t[0][0],t[0][1]]),[e]}function al(t,e=1){if(!Array.isArray(t)||t.length<3)return null;const i=Number.isFinite(e)&&e>0?e:1,s=1e-12*Math.max(1,i),n=[];for(const e of t){if(!Array.isArray(e)||e.length<2)return null;const t=Number(e[0]),i=Number(e[1]);if(!Number.isFinite(t)||!Number.isFinite(i))return null;const o=Math.round(t/s)*s,a=Math.round(i/s)*s;if(!Number.isFinite(o)||!Number.isFinite(a))return null;n.push([Object.is(o,-0)?0:o,Object.is(a,-0)?0:a])}return Math.abs(jr(n))>s*s?n:null}function rl(t,e,i,s){if(sl(t[0],t[1],e[0],e[1],i[0],i[1])>s)return!1;const n=i[0]-e[0],o=i[1]-e[1],a=(t[0]-e[0])*n+(t[1]-e[1])*o,r=n*n+o*o,l=s*Math.sqrt(r);return a>=-l&&a<=r+l}function ll(t,e,i){const s=[],n=[];for(let o=0;oi*i))continue;const d=i/Math.sqrt(h),u=[0,1];for(const t of e)for(const e of[t.a,t.b]){if(!rl(e,a,r,i))continue;const t=((e[0]-a[0])*l+(e[1]-a[1])*c)/h;t>d&&t<1-d&&u.push(t)}u.sort((t,e)=>t-e);const p=u.filter((t,e)=>0===e||Math.abs(t-u[e-1])>d);for(let t=0;t=3&&n.length===s.length?{poly:s,offsets:n}:null}function cl(t,e,i,s,n,o,a){const r=(t||[]).map(hi).filter(t=>!!t&&t.length>=3);if(!r.length)return null;let l=si(ol(r[0]));for(let t=1;t"outer"===t.kind&&t.half>0),h=4*qr(s,a);let d=null;for(const t of function(t){const e=[];for(const i of Array.isArray(t)?t:[])if(Array.isArray(i))for(const t of i){if(!Array.isArray(t)||t.length<4)continue;const i=t.slice(0,-1).map(t=>[t[0],t[1]]);i.length>=3&&e.push(i)}return e}(l)){const e=ll(t,c,h);if(!e||!e.offsets.some(t=>t>0))continue;const i=_l(e.poly,e.offsets),s=Vr(e.poly,e.offsets);if(!i||!s)continue;const n=oi(ol(i),ol(s));d=d?si(d,n):n}return{centre:l,shell:d||[]}}function hl(t){if(!t)return"";let e="";for(const i of t)if(Array.isArray(i))for(const t of i){if(!Array.isArray(t)||t.length<4)continue;const i=t.slice(0,t.length-1);i.length<3||(e+=(e?" ":"")+Kr(i.map(t=>[t[0],t[1]])))}return e}function dl(t,e,i,s=[],n,o,a,r=1,l=[]){if(!e?.length&&!l.length)return null;const c=[];let h=0;for(const s of t||[]){if(!s?.id)continue;const l=Zr(t,s.id,e,i,n,o,a,r);if(!l||l.poly.length<3||!l.offsets.some(t=>t>0))continue;for(const t of l.offsets)t>0&&(h=Math.max(h,2*t));const d=_l(l.poly,l.offsets),u=Vr(l.poly,l.offsets);d&&c.push({outset:d,inset:u})}for(const t of l){const e=t.map(t=>t[0]),i=t.map(t=>t[1]);if(e.length){const s=Math.min(Math.max(...e)-Math.min(...e),Math.max(...i)-Math.min(...i)),n=Math.min(...t.map((e,i)=>{const s=t[(i+1)%t.length];return Math.hypot(s[0]-e[0],s[1]-e[1])}));h=Math.max(h,t.length>16?s:n)}}const d=function(t,e,i,s,n,o,a){if(!e?.length||!i?.length)return[];const r=4*qr(s,a),l=new Map;for(const r of Qr(t,e,i,s,n,o,a))!r.open&&r.half>0&&!l.has(r.key)&&l.set(r.key,r);const c=[...l.values()];if(c.length<2)return[];const h=[];for(const t of i)for(const e of[[t[0],t[1]],[t[2],t[3]]])h.some(t=>Math.hypot(t[0]-e[0],t[1]-e[1])<=r)||h.push(e);const d=[],u=(t,e)=>{let i=0,s=0;if(Math.hypot(t.a[0]-e[0],t.a[1]-e[1])<=r)i=t.b[0]-t.a[0],s=t.b[1]-t.a[1];else{if(!(Math.hypot(t.b[0]-e[0],t.b[1]-e[1])<=r))return null;i=t.a[0]-t.b[0],s=t.a[1]-t.b[1]}const n=Math.hypot(i,s);return n>r?[i/n,s/n]:null};for(const t of h){const e=c.map(e=>({iv:e,u:u(e,t)})).filter(t=>!!t.u);for(let i=0;i4*_||d.push(a>0?[t.slice(),h,p,u]:[t.slice(),u,p,h])}}return d}(t,e,i,n,o,a,r),u=s.length?gl(t,e,i,n,o,a,r):null;try{const p=cl(t,e,i,n,o,a,r),_=p?p.shell?.length?si(p.centre,p.shell):p.centre:[],g=t=>{const e=ol(t.outset);return t.inset?oi(e,ol(t.inset)):e};let m=null;for(const t of c)try{const e=g(t);m=m?si(m,e):e}catch{}if(p)for(const s of pl(t,e,i,n,o,a,r))try{const t=ni(ol(s.quad),p.centre);m=m?si(m,t):t}catch{}m=function(t,e,i=1,s=si){let n=t;for(const t of e||[]){const e=al(t,i);if(e)try{const t=ol(e);n=n?s(n,t):t}catch{}}return n}(m,d,r),m&&p&&(m=ni(m,p.centre)),p?.shell?.length&&(m=m?si(m,p.shell):p.shell);for(const t of s){if(!(t.length>0))continue;const e=vl(u,t,!0);if(!e.negative&&!e.positive)continue;const i=t.angle*Math.PI/180,s=Math.cos(i),o=Math.sin(i),a=-o,l=s,c=t.length/2,d=1.25*Math.max(h,n*r),p=[[t.x-s*c-a*d,t.y-o*c-l*d],[t.x+s*c-a*d,t.y+o*c-l*d],[t.x+s*c+a*d,t.y+o*c+l*d],[t.x-s*c+a*d,t.y-o*c+l*d]];m&&(m=oi(m,ol(p)))}for(const t of l)t.length<3||(m=m?si(m,ol(t)):[ol(t)]);return{geom:m||[],paperGeom:_,depthUnits:h,openingIndex:u}}catch{return null}}function ul(t,e,i,s=[],n,o,a,r=1,l=[]){if(!e?.length&&!l.length)return null;const c=dl(t,e,i,s,n,o,a,r,l),h=c?hl(c.geom):"",d=c?hl(c.paperGeom):"";return c&&h?{d:h,paperD:d,depthUnits:c.depthUnits,fillRule:"evenodd"}:null}function pl(t,e,i,s,n,o,a=1){if(!e?.length)return[];const r=new Set,l=[];for(const c of t||[]){if(!c?.id)continue;const h=Zr(t,c.id,e,i,s,n,o,a);if(!h)continue;const d=h.poly;for(let t=0;t0))continue;const p=wr(e,i,s,a);if(r.has(p))continue;r.add(p);const _=fr(u,n,o),[g,m]=Wr(d,t),f=-g,v=-m,y=_/2,b=[[e[0]+f*y,e[1]+v*y],[i[0]+f*y,i[1]+v*y],[i[0]+g*y,i[1]+m*y],[e[0]+g*y,e[1]+m*y]];l.push({key:p,kind:c,cm:u,quad:b,a:[e[0],e[1]],b:[i[0],i[1]],depthUnits:_})}}return l}function _l(t,e){const i=t?.length||0;if(i<3||e.length!==i)return null;if(e.every(t=>!(t>0)))return t.map(t=>[t[0],t[1]]);Yr(t),e.slice().reverse();const s=[];for(let n=0;n0||r>0)){s.push([t[n][0],t[n][1]]);continue}if(a>0!=r>0){const e=t[n],i=a>0?[e[0]-l*a,e[1]-c*a]:[e[0],e[1]],o=r>0?[e[0]-h*r,e[1]-d*r]:[e[0],e[1]];s.push(i),Math.hypot(o[0]-i[0],o[1]-i[1])>1e-9&&s.push(o);continue}if(Ur(b,w)){const e=t[n],i=[e[0]-l*a,e[1]-c*a],o=[e[0]-h*r,e[1]-d*r];s.push(i),Math.hypot(o[0]-i[0],o[1]-i[1])>1e-9&&s.push(o);continue}const $=Gr(k,b,x,w),S=Math.max(a,r,1e-9);if($){if(Math.hypot($[0]-t[n][0],$[1]-t[n][1])<=4*S){s.push($);continue}}a>0&&s.push([t[n][0]-l*a,t[n][1]-c*a]),r>0&&s.push([t[n][0]-h*r,t[n][1]-d*r])}return s.length>=3?s:null}function gl(t,e,i,s,n,o,a=1){const r=[];for(const l of t||[]){if(!l?.id)continue;const c=Zr(t,l.id,e,i,s,n,o,a);if(!c)continue;const h=Math.abs(Pi(c.poly));for(let t=0;t[Math.max(e,t.x0),Math.min(i,t.x1)]).filter(t=>t[1]-t[0]>s).sort((t,e)=>t[0]-e[0]||t[1]-e[1]);if(!n.length)return{coverage:0,full:!1};let o=n[0][0],a=n[0][1],r=0,l=o<=e+s;for(let t=1;t=i-s,{coverage:r,full:l}}function fl(t,e){return Number(e.full)-Number(t.full)||t.faceDistance-e.faceDistance||t.area-e.area||t.roomId.localeCompare(e.roomId)}function vl(t,e,i=!1){const s=Number(e?.x),n=Number(e?.y),o=Number(e?.angle),a=Number(e?.length);if(!([s,n,o,a].every(Number.isFinite)&&a>0))return{negative:null,positive:null};const r=o*Math.PI/180,l=Math.cos(r),c=Math.sin(r),h=-c,d=l,u=a/2,p=Math.max(1e-9,t.adjacencyEps),_=new Map;let g=0;for(const e of t.edges){if(i&&!(e.half>0))continue;if(!Pr(e.a,e.b,o))continue;const[t,a]=yr(e.a,e.b);if(Math.abs((s-e.a[0])*a-(n-e.a[1])*t)>p)continue;const r=(e.a[0]-s)*l+(e.a[1]-n)*c,m=(e.b[0]-s)*l+(e.b[1]-n)*c,f=Math.max(-u,Math.min(r,m)),v=Math.min(u,Math.max(r,m));if(v-f<=p)continue;const y=e.inward[0]*h+e.inward[1]*d>=0?1:-1,b=((e.a[0]+e.b[0])/2-s)*h+((e.a[1]+e.b[1])/2-n)*d,w=Math.abs(b+y*e.half),k=`${y}|${e.roomId}`,x={x0:f,x1:v,half:e.half,cm:e.cm,key:e.key,axis:[t,a]},$=_.get(k);$?($.pieces.push(x),$.faceDistance=Math.min($.faceDistance,w)):_.set(k,{roomId:e.roomId,side:y,order:g++,pieces:[x],faceDistance:w,area:e.area,coverage:0,full:!1})}for(const t of _.values()){const e=ml(t.pieces,-u,u,p);t.coverage=e.coverage,t.full=e.full}const m=t=>{const e=[..._.values()].filter(e=>e.side===t&&e.coverage>p);return e.sort(fl),e[0]||null};return{negative:m(-1),positive:m(1)}}function yl(t,e){const i=vl(t,e),s=[i.negative,i.positive].filter(t=>!!t).sort((t,e)=>t.order-e.order);if(!s.length)return{ox:0,oy:0,cm:0,side:-1};const n=s[0],o=e.flip_v?-n.side:n.side,a=(-1===o?i.negative:i.positive)||n,r=[...a.pieces].sort((t,e)=>(t.x0<=0&&t.x1>=0?0:Math.min(Math.abs(t.x0),Math.abs(t.x1)))-(e.x0<=0&&e.x1>=0?0:Math.min(Math.abs(e.x0),Math.abs(e.x1)))||e.x1-e.x0-(t.x1-t.x0)||t.key.localeCompare(e.key))[0];if(!(r.half>0&&r.cm>0))return{ox:0,oy:0,cm:0,side:o};const l=e.angle*Math.PI/180,c=-Math.sin(l),h=Math.cos(l);return{ox:c*o*r.half,oy:h*o*r.half,cm:r.cm,side:o}}function bl(t,e){const i=1e-9,s=e.filter(t=>Number.isFinite(t.x0)&&Number.isFinite(t.x1)&&Number.isFinite(t.half)&&t.x1>t.x0&&t.half>0);if(!s.length)return"";const n=s.flatMap(t=>[t.x0,t.x1]).sort((t,e)=>t-e),o=[];for(const t of n){const e=o[o.length-1];(void 0===e||t>e+i)&&o.push(t)}const a=[];for(let t=0;t+1e+i))continue;const r=(e+n)/2,l=s.reduce((t,e)=>r>=e.x0-i&&r<=e.x1+i?Math.max(t,e.half):t,0);if(!(l>0))continue;const c=a[a.length-1];c&&e<=c.x1+i&&Math.abs(l-c.half)<=i?c.x1=n:a.push({x0:e,x1:n,half:l})}const r=[];for(const t of a){const e=r[r.length-1],s=e?.[e.length-1];s&&t.x0<=s.x1+i?(t.x0=s.x1,e.push(t)):r.push([t])}return r.map(e=>{const i=e[0],s=e[e.length-1],n=Math.min(.25*Math.min(...e.map(t=>t.half)),.75),o=-t*n,a=[];if(1===t){a.push(`M ${i.x0} ${o} L ${s.x1} ${o}`);for(let t=e.length-1;t>=0;t--){const i=e[t];a.push(`L ${i.x1} ${i.half} L ${i.x0} ${i.half}`)}}else{a.push(`M ${s.x1} ${o} L ${i.x0} ${o}`);for(const t of e)a.push(`L ${t.x0} ${-t.half} L ${t.x1} ${-t.half}`)}return a.push("Z"),a.join(" ")}).join(" ")}function wl(t,e,i,s){if(!s)return i;const n=t.angle*Math.PI/180,o=Math.cos(n),a=Math.sin(n),r=[],l=1e-9;for(const n of i){const[i,c]=n.axis,h=o*i+a*c;if(Math.abs(h)<=l)continue;const d=t.x*i+t.y*c,u=d+h*n.x0,p=d+h*n.x1,_=Math.min(u,p),g=Math.max(u,p),m=`${n.key}|${e}`,f=s.get(m)||[];let v=[[_,g]];for(const[t,e]of f){const i=[];for(const[s,n]of v)e<=s+l||t>=n-l?i.push([s,n]):(t>s+l&&i.push([s,Math.min(n,t)]),et[0]-e[0]||t[1]-e[1]),b=[];for(const t of y){const e=b[b.length-1];e&&t[0]<=e[1]+l?e[1]=Math.max(e[1],t[1]):b.push([t[0],t[1]])}s.set(m,b)}return r}function kl(t,e){const i=new Map;return e.map(e=>function(t,e,i){const s=vl(t,e,!0),n=s.negative,o=s.positive;if(!n&&!o)return null;let a;if(n&&o)a=[{candidate:n,side:-1},{candidate:o,side:1}];else{const t=n||o;a=[{candidate:t,side:-1},{candidate:t,side:1}]}const r=a.map(({candidate:t,side:s})=>({candidate:t,side:s,pieces:wl(e,s,t.pieces,i)})),l=r.map(({candidate:t,side:e,pieces:i})=>({side:e,roomId:t.roomId,d:bl(e,i)})),c=r.flatMap(({pieces:t})=>t);if(!c.length)return null;const h=Math.max(...c.map(t=>t.half));return{faces:l,minY:-h,maxY:h,wallKey:[...new Set(c.map(t=>t.key))].sort().join("|")}}(t,e,i))}const xl=150;function $l(t){return Number.isFinite(t)?Math.max(1,Math.min(xl,t)):1}function Sl(t){return((Number.isFinite(Number(t))?Number(t):0)%90+90)%90}const Ml=t=>{const e=t.map(t=>[t[0],t[1]]);return!e.length||e[0][0]===e[e.length-1][0]&&e[0][1]===e[e.length-1][1]||e.push([...e[0]]),[e]};function Cl(t){const e=[];for(const i of t||[])for(const t of i||[]){const i=(t||[]).filter(t=>Array.isArray(t)&&t.length>=2);i.length<4||e.push(`M ${i.slice(0,-1).map(t=>`${t[0]} ${t[1]}`).join(" L ")} Z`)}return e.join(" ")}function Dl(t,e,i,s,n){return Fr({a:t,b:e,halfDepth:fr(i,s,n)/2})}function Tl(t,e,i){const s=Number(e)>0?Number(e):5,n=$l(t.cm)/s*i,o=t.center[0],a=t.center[1];if("circle"===t.shape){const t=n/2;return Array.from({length:96},(e,i)=>{const s=i/96*Math.PI*2;return[o+Math.cos(s)*t,a+Math.sin(s)*t]})}const r=n/2,l=Sl(t.angle)*Math.PI/180,c=Math.cos(l),h=Math.sin(l);return[[-r,-r],[r,-r],[r,r],[-r,r]].map(([t,e])=>[o+t*c-e*h,a+t*h+e*c])}function Pl(t,e,i=1e-9){if(!e.length)return[t];let s=[Ml(t)];try{for(const t of e){const e=t.b[0]-t.a[0],n=t.b[1]-t.a[1],o=Math.hypot(e,n);if(!(o>i))continue;const a=e/o,r=n/o,l=-r,c=a,h=1.25*Math.max(Number(t.depth)||0,4*i),d=Math.max(2*i,1e-9*o),u=[[t.a[0]-a*d-l*h,t.a[1]-r*d-c*h],[t.b[0]+a*d-l*h,t.b[1]+r*d-c*h],[t.b[0]+a*d+l*h,t.b[1]+r*d+c*h],[t.a[0]-a*d+l*h,t.a[1]-r*d+c*h]];s=oi(s,Ml(u))}return Ol(s)}catch{return[t]}}function Rl(t,e,i,s=Math.max(2e-4*i,1e-9),n=[]){const o=[],a=[],r=new Map;for(const t of n){const e=r.get(t.hostId)||[];e.push(t),r.set(t.hostId,e)}const l=[],c=[],h=[];for(const s of t.room_drafts||[])for(let t=0;t+1Tl(t,e,i)),u=Nr([...o,...a],s).flatMap(t=>Pl(t,n,s));return{drafts:l,partitions:c,columns:d,patches:u,all:[...l,...h,...u,...d]}}function Al(t){try{const e=t.filter(t=>t.length>=3).map(t=>Ml(t));return e.length?si(e[0],...e.slice(1)):null}catch{return null}}const Il=t=>`M ${t.map(t=>`${t[0]} ${t[1]}`).join(" L ")} Z`;function El(t,e){const i=Al(t.filter(t=>t.length>=3)),s=Al(e.filter(t=>t.length>=3));if(!i)return[];if(!s)return[];try{return function(t){const e=[];for(const i of t||[]){if(zl([i])<=1e-6)continue;const t=[];for(const e of i||[]){const i=(e||[]).filter(t=>Array.isArray(t)&&t.length>=2);i.length<4||t.push(Il(i.slice(0,-1)))}t.length&&e.push(t.join(" "))}return e}(ni(i,s))}catch{return[]}}function Fl(t,e){if(!e.length)return[Ml(t)];try{const i=Al(e);if(i)return oi(Ml(t),i)}catch{}let i=[Ml(t)];for(const t of e)if(!(t.length<3))try{i=oi(i,Ml(t))}catch{}return i}function zl(t){let e=0;for(const i of t||[])if(i?.length){e+=Pi(i[0]||[]);for(let t=1;t=4&&e.push(t.slice(0,-1).map(t=>[t[0],t[1]]))}return e}function Hl(t,e){let i=!1;for(let s=0,n=e.length-1;st[1]!=l>t[1]&&t[0]<(r-o)*(t[1]-a)/(l-a||1e-12)+o&&(i=!i)}return i}function Nl(t,e,i){return function(t,e){for(const i of e||[]){const e=i?.[0];if(!e?.length||!Hl(t,e))continue;let s=!1;for(let e=1;eHl(t,e))}function Ll(t,e,i){if(Math.hypot(t.center[0]-e.center[0],t.center[1]-e.center[1])>i)return!1;if(Math.abs($l(t.cm)-$l(e.cm))>1e-6)return!1;if(t.shape!==e.shape)return!0;if("circle"===t.shape||"circle"===e.shape)return!0;const s=Math.abs(Sl(t.angle)-Sl(e.angle));return Math.min(s,90-s)<=1e-6}const Bl=1e3;function ql(t,e){const i=Number(t),s=Number.isFinite(i)&&i>0?i:1,n=s>=1?e:e*s,o=s>=1?e/s:e;return{x:(e-n)/2,y:(e-o)/2,w:n,h:o}}const jl=.01,Wl=100;function Ul(t,e=1e3){const i=ql(t?.plan_aspect,e),s=Number(t?.plan_scale),n=Number.isFinite(s)&&s>0?Math.min(Wl,Math.max(jl,s)):1,o=Number(t?.plan_scale_x),a=Number(t?.plan_scale_y),r=Number.isFinite(o)&&o>0?Math.min(Wl,Math.max(jl,o)):n,l=Number.isFinite(a)&&a>0?Math.min(Wl,Math.max(jl,a)):n,c=Number(t?.plan_x),h=Number(t?.plan_y),d=sr(t?.plan_angle);return{x:i.x+(Number.isFinite(c)?ic(c):0)*e,y:i.y+(Number.isFinite(h)?ic(h):0)*e,w:i.w*r,h:i.h*l,...d?{angle:d}:{}}}function Gl(t){if(null==t.x||null==t.y)return{x:t.x,y:t.y,w:t.w,h:t.h};const e=Number(t.w)||0,i=Number(t.h)||0;return{x:e<0?t.x+e:t.x,y:i<0?t.y+i:t.y,w:Math.abs(e),h:Math.abs(i)}}function Vl(t){return t&&Array.isArray(t.spaces)?t.spaces.map(t=>{const e=Bl,i=function(t){return Array.isArray(t)&&4===t.length&&t.every(t=>Number.isFinite(t))&&t[2]>1e-6&&t[3]>1e-6?t:[0,0,1,1]}(t.view_box);return{id:t.id,title:t.title,vb:[i[0]*Bl,i[1]*e,i[2]*Bl,i[3]*e],bg:t.plan_url?{href:Is(t.plan_url),...Ul(t,Bl)}:null,rooms:(t.rooms||[]).map(t=>{const i={...t,...Gl(t)};return{id:i.id,name:i.name,area:i.area??null,open_to:i.open_to||void 0,settings:i.settings||void 0,x:null!=i.x?i.x*Bl:void 0,y:null!=i.y?i.y*e:void 0,w:null!=i.w?i.w*Bl:void 0,h:null!=i.h?i.h*e:void 0,poly:i.poly?i.poly.map(t=>[t[0]*Bl,t[1]*e]):void 0}}),room_drafts:(t.room_drafts||[]).map(t=>({id:t.id,points:(t.points||[]).map(t=>[t[0]*Bl,t[1]*e]),segments:(t.segments||[]).map(t=>({cm:Number(t.cm)}))})),partitions:(t.partitions||[]).map(t=>({id:t.id,a:[t.a[0]*Bl,t.a[1]*e],b:[t.b[0]*Bl,t.b[1]*e],cm:Number(t.cm)})),wall_columns:(t.wall_columns||[]).map(t=>({id:t.id,shape:"circle"===t.shape?"circle":"square",center:[t.center[0]*Bl,t.center[1]*e],cm:Number(t.cm),..."circle"===t.shape?{}:{angle:Sl(t.angle)}}))}}):[]}const Kl=5e3,Yl=Kl*Bl,Xl=240,Jl=Bl/Xl,Zl=1/Xl;function Ql(t){if(!Number.isFinite(t))return t;const e=Math.round(t*Xl/Bl)*Bl/Xl;return Math.abs(e-t)<=1e-9*Jl?t:e}function tc(t){return{x:Ql(t.x),y:Ql(t.y)}}function ec(t){return Number.isFinite(t)?Math.min(Yl,Math.max(-Yl,t)):0}function ic(t){return Number.isFinite(t)?Math.min(Kl,Math.max(-Kl,t)):0}const sc=1/3,nc=200;function oc(t){let e=1/0,i=1/0,s=-1/0,n=-1/0;for(const o of t){const t=Number(o[0]),a=Number(o[1]);Number.isFinite(t)&&Number.isFinite(a)&&(ts&&(s=t),a>n&&(n=a))}return e>s?null:{minX:e,minY:i,maxX:s,maxY:n}}function ac(t){return t.poly&&t.poly.length?oc(t.poly):null==t.x||null==t.y?null:oc([[t.x,t.y],[t.x+(t.w||0),t.y+(t.h||0)]])}function rc(t,e){const i=[];for(const e of t.rooms||[]){const t=ac(e);t&&i.push(t)}if(t.bg){const e=oc(cr(t.bg));e&&i.push(e)}for(const t of e||[])if(Array.isArray(t)){const e=oc([t]);e&&i.push(e)}else i.push(t);return i}const lc=t=>{if(!t.length)return 0;const e=[...t].sort((t,e)=>t-e),i=e.length>>1;return e.length%2?e[i]:(e[i-1]+e[i])/2},cc=t=>{let e=1/0,i=1/0,s=-1/0,n=-1/0;for(const o of t)o.minXs&&(s=o.maxX),o.maxY>n&&(n=o.maxY);return e>s||i>n?null:{x:e,y:i,w:s-e,h:n-i}};function hc(t,e){let{x:i,y:s,w:n,h:o}=t;n<30&&(i=i+n/2-100,n=nc),o<30&&(s=s+o/2-100,o=nc);const a=Math.max(n,o)*e;return{x:i-a,y:s-a,w:n+2*a,h:o+2*a}}function dc(t,e={}){const i=e.pad??.05,s=e.k??10,n=e.minSpread??50,o=t.filter(t=>Number.isFinite(t.minX)&&Number.isFinite(t.minY)&&Number.isFinite(t.maxX)&&Number.isFinite(t.maxY)&&Math.abs(t.minX)<=Yl&&Math.abs(t.maxX)<=Yl&&Math.abs(t.minY)<=Yl&&Math.abs(t.maxY)<=Yl);if(!o.length)return{core:null,all:null,outliers:0};const a=cc(o);if(o.length<4){const t=hc(a,i);return{core:t,all:t,outliers:0}}const r=o.map(t=>(t.minX+t.maxX)/2),l=o.map(t=>(t.minY+t.maxY)/2),c=lc(r),h=lc(l),d=o.map((t,e)=>Math.max(Math.abs(r[e]-c),Math.abs(l[e]-h))),u=Math.max(((t,e)=>t.length?t[Math.min(t.length-1,Math.max(0,Math.round(e*(t.length-1))))]:0)([...d].sort((t,e)=>t-e),.75),n),p=d.map(t=>t>s*u),_=p.filter(Boolean).length,g=_&&_<=o.length*sc?o.filter((t,e)=>!p[e]):o;return{core:hc(cc(g)||a,i),all:hc(a,i),outliers:g===o?0:_}}function uc(t,e,i=.05){const s=dc(rc(t,e),{pad:i});if(s.core)return s.core;const n=t.vb&&4===t.vb.length&&t.vb[2]>0&&t.vb[3]>0?t.vb:[0,0,Bl,Bl];return{x:n[0],y:n[1],w:n[2],h:n[3]}}function pc(t){const e=uc(t);return{x:e.x+e.w/2,y:e.y+e.h/2}}function _c(t){const e=[];for(const i of t.rooms||[]){const t=ac(i);t&&e.push(t)}const i=dc(e,{pad:0}).core;return i?Math.max(Bl,Math.min(Yl,Math.max(i.w,i.h))):Bl}function gc(t,e,i,s=1){const n=Number(i),o=Number.isFinite(s)&&s>0?s:1;return!Number.isFinite(n)||n<=0?t*o:t*_c(e)*o/n}const mc=[1,2,5,10,20,50,100,200,500,1e3];function fc(t){if(t.poly&&t.poly.length){const e=t.poly.map(t=>t[0]),i=t.poly.map(t=>t[1]),s=Math.min(...e),n=Math.min(...i);return{x:s,y:n,w:Math.max(...e)-s,h:Math.max(...i)-n}}return{x:t.x??0,y:t.y??0,w:t.w??0,h:t.h??0}}function vc(t,e,i,s){const n=i["rl_"+(t.id||"")];if(n&&n.s===e)return{x:n.x*Bl,y:n.y*Bl};const o=function(t){if(t.poly){const e=t.poly.length;return[t.poly.reduce((t,e)=>t+e[0],0)/e,t.poly.reduce((t,e)=>t+e[1],0)/e]}return[t.x+t.w/2,t.y+.1*Math.min(t.w,t.h)]}(t);return tc({x:o[0],y:o[1]})}const yc=["furniture","appliance","sanitary","other"],bc=[{id:"sofa",group:"furniture",w:220,h:90,g:[["r",0,0,1,1],["l",.09,.26,.91,.26],["l",.09,.26,.09,1],["l",.91,.26,.91,1],["l",.5,.26,.5,1]]},{id:"armchair",group:"furniture",w:90,h:85,g:[["r",0,0,1,1],["l",.14,.28,.86,.28],["l",.14,.28,.14,1],["l",.86,.28,.86,1]]},{id:"coffee_table",group:"furniture",w:110,h:60,g:[["r",0,0,1,1],["r",.08,.14,.84,.72]]},{id:"table_dining",group:"furniture",w:140,h:80,g:[["r",0,0,1,1],["r",.06,.11,.88,.78]]},{id:"table_round",group:"furniture",w:120,h:120,g:[["e",.5,.5,.5,.5],["e",.5,.5,.41,.41]]},{id:"chair",group:"furniture",w:45,h:45,g:[["r",0,0,1,.18],["r",.06,.18,.88,.8]]},{id:"desk",group:"furniture",w:120,h:60,g:[["r",0,0,1,1],["r",.63,.07,.31,.86],["l",.63,.5,.94,.5]]},{id:"bed_double",group:"furniture",w:160,h:200,g:[["r",0,0,1,1],["r",0,0,1,.07],["r",.06,.1,.4,.15],["r",.54,.1,.4,.15],["l",0,.33,1,.33]]},{id:"bed_single",group:"furniture",w:90,h:200,g:[["r",0,0,1,1],["r",0,0,1,.07],["r",.15,.1,.7,.15],["l",0,.33,1,.33]]},{id:"nightstand",group:"furniture",w:45,h:40,g:[["r",0,0,1,1],["r",.12,.14,.76,.33],["r",.12,.53,.76,.33]]},{id:"wardrobe",group:"furniture",w:100,h:60,g:[["r",0,0,1,1],["l",0,.72,1,.72],["l",.5,.72,.5,1]]},{id:"bookshelf",group:"furniture",w:80,h:30,g:[["r",0,0,1,1],["l",.34,0,.34,1],["l",.67,0,.67,1]]},{id:"fridge",group:"appliance",w:60,h:65,g:[["r",0,0,1,1],["l",0,.36,1,.36],["l",.83,.44,.83,.64]]},{id:"stove",group:"appliance",w:60,h:60,g:[["r",0,0,1,1],["e",.29,.31,.15,.15],["e",.71,.31,.15,.15],["e",.29,.71,.15,.15],["e",.71,.71,.15,.15]]},{id:"dishwasher",group:"appliance",w:60,h:60,g:[["r",0,0,1,1],["r",.1,.12,.8,.76],["e",.5,.5,.27,.27],["e",.5,.5,.13,.13]]},{id:"washer",group:"appliance",w:60,h:60,g:[["r",0,0,1,1],["l",.08,.17,.92,.17],["e",.5,.57,.3,.3],["e",.5,.57,.14,.14]]},{id:"dryer",group:"appliance",w:60,h:60,g:[["r",0,0,1,1],["l",.08,.17,.92,.17],["e",.5,.57,.3,.3],["p",.36,.5,.5,.64,.64,.5]]},{id:"tv",group:"appliance",w:120,h:30,g:[["r",0,0,1,.42],["l",.5,.42,.5,.72],["l",.3,.72,.7,.72]]},{id:"ac",group:"appliance",w:90,h:25,g:[["r",0,0,1,1],["l",.05,.55,.95,.55],["l",.05,.79,.95,.79]]},{id:"water_heater",group:"appliance",w:45,h:45,g:[["e",.5,.5,.5,.5],["e",.5,.5,.31,.31]]},{id:"toilet",group:"sanitary",w:40,h:70,g:[["r",.06,0,.88,.2],["e",.5,.58,.37,.35],["e",.5,.58,.22,.2]]},{id:"bathtub",group:"sanitary",w:170,h:75,g:[["r",0,0,1,1],["r",.05,.11,.77,.78],["e",.89,.5,.045,.1]]},{id:"shower",group:"sanitary",w:90,h:90,g:[["r",0,0,1,1],["l",0,0,1,1],["l",1,0,0,1],["e",.5,.5,.08,.08]]},{id:"sink",group:"sanitary",w:60,h:45,g:[["r",0,0,1,1],["e",.5,.6,.34,.3],["e",.5,.15,.07,.07]]},{id:"kitchen_sink",group:"sanitary",w:80,h:60,g:[["r",0,0,1,1],["r",.06,.24,.44,.64],["r",.54,.24,.4,.64],["e",.5,.12,.06,.06]]},{id:"bidet",group:"sanitary",w:40,h:55,g:[["e",.5,.5,.44,.5],["e",.5,.5,.26,.3]]},{id:"stairs",group:"other",w:100,h:280,g:[["r",0,0,1,1],["l",0,.111,1,.111],["l",0,.222,1,.222],["l",0,.333,1,.333],["l",0,.444,1,.444],["l",0,.556,1,.556],["l",0,.667,1,.667],["l",0,.778,1,.778],["l",0,.889,1,.889],["l",.5,.93,.5,.06],["p",.38,.16,.5,.06,.62,.16]]},{id:"fireplace",group:"other",w:120,h:40,g:[["r",0,0,1,1],["p",.22,1,.22,.42,.78,.42,.78,1]]},{id:"plant",group:"other",w:40,h:40,g:[["e",.5,.5,.22,.22],["l",.5,.28,.5,.02],["l",.5,.72,.5,.98],["l",.28,.5,.02,.5],["l",.72,.5,.98,.5],["l",.34,.34,.13,.13],["l",.66,.66,.87,.87],["l",.66,.34,.87,.13],["l",.34,.66,.13,.87]]},{id:"rug",group:"other",w:200,h:140,g:[["r",0,0,1,1],["r",.06,.09,.88,.82]]}],wc=new Map(bc.map(t=>[t.id,t]));function kc(t){return t&&wc.get(t)||null}function xc(t){return bc.filter(e=>e.group===t)}function $c(t,e,i=Jl,s=1e3){const n=Number(e)>0?Number(e):5;return(Number(t)||0)/n*i/s}const Sc=5e-4,Mc=Kl;function Cc(t){return Number.isFinite(t)?Math.max(Sc,Math.min(Mc,t)):Sc}const Dc=t=>{const e=Math.round(1e3*t)/1e3;return Object.is(e,-0)?"0":String(e)};function Tc(t,e,i){const s=kc(t);if(!(s&&e>0&&i>0))return"";const n=t=>Dc(t*e),o=t=>Dc(t*i),a=[];for(const t of s.g)if("r"===t[0]){const[,e,i,s,r]=t;a.push(`M${n(e)} ${o(i)}H${n(e+s)}V${o(i+r)}H${n(e)}Z`)}else if("l"===t[0]){const[,e,i,s,r]=t;a.push(`M${n(e)} ${o(i)}L${n(s)} ${o(r)}`)}else if("e"===t[0]){const[,s,r,l,c]=t;a.push(`M${n(s-l)} ${o(r)}A${Dc(l*e)} ${Dc(c*i)} 0 0 1 ${n(s+l)} ${o(r)}A${Dc(l*e)} ${Dc(c*i)} 0 0 1 ${n(s-l)} ${o(r)}Z`)}else{const e=t.slice(1);if(e.length<4)continue;let i=`M${n(e[0])} ${o(e[1])}`;for(let t=2;t+1{let e=(t%360+360)%360;return e>180&&(e-=360),e};function Rc(t,e,i,s,n,o=0){let a=null,r=n;for(const n of s){const[s,l,c,h]=n,d=c-s,u=h-l,p=d*d+u*u;if(!p)continue;const _=Math.sqrt(p);let g=((t-s)*d+(e-l)*u)/p;g=Math.max(0,Math.min(1,g));let m=s+g*d,f=l+g*u;const v=Math.hypot(t-m,e-f);if(!(v0){const t=Math.round(g*_/o)*o;m=s+t/_*d,f=l+t/_*u}a={cx:m+y*(i/2),cy:f+b*(i/2),angle:Pc(180*Math.atan2(-y,b)/Math.PI),dist:v}}return a}function Ac(t,e,i){const s=i;return{a:[t[0]/s,t[1]/s],b:[e[0]/s,e[1]/s]}}function Ic(t,e){const i=e;return[t.a[0]*i,t.a[1]*i,t.b[0]*i,t.b[1]*i]}function Ec(t){return Array.isArray(t)&&t.length>=2&&Number.isFinite(Number(t[0]))&&Number.isFinite(Number(t[1]))}function Fc(t){if(!Array.isArray(t))return[];const e=[];for(const i of t){if(!i||"object"!=typeof i)continue;const t=i;if(!Ec(t.a)||!Ec(t.b))continue;const s=[Number(t.a[0]),Number(t.a[1])],n=[Number(t.b[0]),Number(t.b[1])];Math.hypot(n[0]-s[0],n[1]-s[1])<.001||e.push({a:s,b:n})}return e}function zc(t,e){const i=e[0],s=e[1],n=e[2]-i,o=e[3]-s,a=n*n+o*o;if(a<1e-18){return{q:[i,s],t:0,d:Math.hypot(t[0]-i,t[1]-s)}}let r=((t[0]-i)*n+(t[1]-s)*o)/a;r=Math.max(0,Math.min(1,r));const l=[i+r*n,s+r*o];return{q:l,t:r,d:Math.hypot(t[0]-l[0],t[1]-l[1])}}function Oc(t,e){return zc(t,e).q}function Hc(t,e,i,s,n){const o=zc(t,e).q;let a=o,r=1/0;for(const t of i){const e=Math.hypot(o[0]-t[0],o[1]-t[1]);e<=n&&e0?s:1,g=Math.round(p/_)*_,m=Math.max(0,Math.min(u,g))/u;return[l+h*m,c+d*m]}function Nc(t,e){const i=[],s=(t||[]).filter(t=>t?.id);for(let t=0;tt?.id),a=Fc(e);if(a.length)return Kc(a,t,i,s).map(t=>Ic(t,i));if(!n)return[];const r=[],l=(t,e)=>(t.open_to||[]).includes(e.id)||(e.open_to||[]).includes(t.id);for(let t=0;tAc([t[0],t[1]],[t[2],t[3]],e))}function qc(t,e,i,s){for(const e of t||[])e.open_to&&delete e.open_to;if(!i.length)return;const n=(e||[]).filter(t=>t?.id);new Map(n.map(t=>[t.id,t]));const o=new Map((t||[]).filter(t=>t?.id).map(t=>[t.id,t])),a=(t,e)=>{const i=o.get(t),s=o.get(e);i&&s&&((i.open_to||[]).includes(e)||(i.open_to=[...i.open_to||[],e]),(s.open_to||[]).includes(t)||(s.open_to=[...s.open_to||[],t]))};for(let t=0;tNs(i,t)<4*s)){a(n[t].id,n[e].id);break}}}for(const e of t||[])e.open_to&&!e.open_to.length&&delete e.open_to}function jc(t,e,i,s=0){const n=e[2]-e[0],o=e[3]-e[1],a=Math.hypot(n,o);if(!(a>1e-9))return null;const r=n/a,l=o/a,c=(t[0]-e[0])*r+(t[1]-e[1])*l;if(c<-s||c>a+s)return null;return Math.abs((t[0]-e[0])*l-(t[1]-e[1])*r)>i?null:Ns(t,e)}function Wc(t,e,i){const s=t[2]-t[0],n=t[3]-t[1],o=e[2]-e[0],a=e[3]-e[1],r=Math.hypot(s,n),l=Math.hypot(o,a);return r>1e-9&&l>1e-9&&(!(Math.abs(s/r*(a/l)-n/r*(o/l))>1e-6)&&(Ns([e[0],e[1]],t)<=4*i||Ns([t[0],t[1]],e)<=4*i))}function Uc(t,e,i){if(!t.length)return null;t.sort((t,e)=>t.distance-e.distance);const s=t[0];for(let n=1;ne)break;if(o.semantic!==s.semantic||!Wc(s.seg,o.seg,i))return"ambiguous"}return s}function Gc(t,e,i,s,n=1,o=15){const a=function(t,e,i,s,n=1,o=15){const[a,r]=yr([e[0],e[1]],[e[2],e[3]]);let l=0,c=1/0;const h=[(e[0]+e[2])/2,(e[1]+e[3])/2];for(const e of i){const[i,o]=yr([e[0],e[1]],[e[2],e[3]]);if(Math.abs(a*o-r*i)>.05)continue;const d=Dr(t,[e[0],e[1]],[e[2],e[3]],s,n);if(!(d>0))continue;const u=[(e[0]+e[2])/2,(e[1]+e[3])/2],p=Math.hypot(u[0]-h[0],u[1]-h[1]);p0?l:o}(t,e,i,s,n,o);return Ar(t,[e[0],e[1]],[e[2],e[3]],a,s,n)}function Vc(t,e,i){const s=[[t[0],t[1]],[t[2],t[3]]],n=[(t[0]+t[2])/2,(t[1]+t[3])/2];for(const o of e)if(!(Ns(n,o)>Math.hypot(t[2]-t[0],t[3]-t[1])&&Ns([o[0],o[1]],t)>i))for(const e of[[o[0],o[1]],[o[2],o[3]]])Ns(e,t)<=2*i&&s.push(e);return s}function Kc(t,e,i,s){const n=Fc(t);if(!n.length)return[];const o=Nc(e,s);if(!o.length)return[];const a=[],r=Math.max(4*s,1e-6);for(const t of n){const e=Ic(t,i),n=e[0],l=e[1],c=e[2]-n,h=e[3]-l,d=Math.hypot(c,h);if(d4*s||o>4*s)continue;const a=(t[0]-n)*u+(t[1]-l)*p,c=(t[2]-n)*u+(t[3]-l)*p,h=Math.max(0,Math.min(a,c)),g=Math.min(d,Math.max(a,c));if(g-ht.lo-e.lo||t.hi-e.hi);const i=[];for(const t of e){const e=i[i.length-1];e&&t.lo<=e.hi+r?e.hi=Math.max(e.hi,t.hi):i.push({...t})}for(const e of i){const i=[n+u*e.lo,l+p*e.lo],s=[n+u*e.hi,l+p*e.hi];Math.hypot(s[0]-i[0],s[1]-i[1])i.pair===t&&Math.abs(i.ux*a-i.uy*o)<=1e-6&&Math.abs((e[0]-i.origin[0])*i.uy-(e[1]-i.origin[1])*i.ux)<=c&&Math.abs((e[2]-i.origin[0])*i.uy-(e[3]-i.origin[1])*i.ux)<=c);h||(h={pair:t,origin:[e[0],e[1]],ux:o,uy:a,ranges:[]},l.push(h));const d=(e[0]-h.origin[0])*h.ux+(e[1]-h.origin[1])*h.uy,u=(e[2]-h.origin[0])*h.ux+(e[3]-h.origin[1])*h.uy;h.ranges.push({lo:Math.min(d,u),hi:Math.max(d,u)})}const h=[];for(const t of l){t.ranges.sort((t,e)=>t.lo-e.lo||t.hi-e.hi);const e=[];for(const i of t.ranges){const t=e[e.length-1];t&&i.lo<=t.hi+r?t.hi=Math.max(t.hi,i.hi):e.push({...i})}for(const s of e){const e=[t.origin[0]+t.ux*s.lo,t.origin[1]+t.uy*s.lo],n=[t.origin[0]+t.ux*s.hi,t.origin[1]+t.uy*s.hi];Math.hypot(n[0]-e[0],n[1]-e[1])>=r&&h.push(Ac(e,n,i))}}return h}function Yc(t,e,i,s){const n=Fc(t);if(!n.length)return[];if(e.length!==i.length)return n;const o=[];for(const t of n){const n=Ic(t,s),a=[n[0],n[1]],r=[n[2],n[3]];let l=a,c=r;for(let t=0;t{const e=zc(t,[s[0],s[1],n[0],n[1]]);if(e.d>.001)return t;const i=h[0]-o[0],a=h[1]-o[1];return[o[0]+i*e.t,o[1]+a*e.t]};if(zc([(a[0]+r[0])/2,(a[1]+r[1])/2],[s[0],s[1],n[0],n[1]]).d<.01){l=d(a),c=d(r);break}}o.push(Ac(l,c,s))}return o}const Xc=15e3,Jc=2e3,Zc=new WeakMap;function Qc(t,e){let i=Zc.get(t);if(!i){const e=new Set;i={hiddenAt:"hidden"===t.visibilityState?Date.now():0,token:0,subscribers:e,onVisibility:()=>{const e=Zc.get(t);if(!e)return;const i=Date.now();if("hidden"===t.visibilityState){e.hiddenAt||(e.hiddenAt=i);const t={kind:"hidden",token:e.token,at:i,hiddenFor:0,long:!1};for(const i of[...e.subscribers])i(t);return}const s=e.hiddenAt?Math.max(0,i-e.hiddenAt):0;e.hiddenAt=0,e.token++;const n={kind:"visible",token:e.token,at:i,hiddenFor:s,long:s>=Xc};for(const t of[...e.subscribers])t(n)},onPageShow:e=>{const i=Zc.get(t);if(!i)return;const s=Date.now();i.token++;const n={kind:"pageshow",token:i.token,at:s,hiddenFor:0,long:!!e.persisted,persisted:!!e.persisted};for(const t of[...i.subscribers])t(n)}},Zc.set(t,i),t.addEventListener("visibilitychange",i.onVisibility),t.defaultView?.addEventListener("pageshow",i.onPageShow)}return i.subscribers.add(e),()=>{const i=Zc.get(t);i&&(i.subscribers.delete(e),i.subscribers.size||(t.removeEventListener("visibilitychange",i.onVisibility),t.defaultView?.removeEventListener("pageshow",i.onPageShow),Zc.delete(t)))}}const th={now:()=>Date.now(),setTimeout:(t,e)=>window.setTimeout(t,e),clearTimeout:t=>window.clearTimeout(t),requestAnimationFrame:t=>window.requestAnimationFrame(t),cancelAnimationFrame:t=>window.cancelAnimationFrame(t)};class eh{constructor(t,e=th){this.onChange=t,this.clock=e,this._state="steady",this._token=0,this._frameFingerprint="",this._hasCompleteFrame=!1,this._overlayPhase="none",this._recoveryReason=null,this._overlayTimer=0,this._overlayRaf=0,this._overlayOpaqueAt=0,this._barrierRafs=new Set,this._trace=[],this._disposed=!1}get state(){return this._state}get token(){return this._token}get frameFingerprint(){return this._frameFingerprint}get hasCompleteFrame(){return this._hasCompleteFrame}get overlayPhase(){return this._overlayPhase}get overlayVisible(){return"none"!==this._overlayPhase}get overlayBlocksInteraction(){return this.overlayVisible}get recoveryReason(){return this._recoveryReason}get trace(){return this._trace.map(t=>({...t,...t.stage?{stage:[...t.stage]}:{}}))}note(t,e={}){this.record(t,void 0,e)}record(t,e,i={}){this._trace.push({at:this.clock.now(),token:this._token,event:t,state:this._state,...e?{reason:e}:{},...i}),this._trace.length>80&&this._trace.splice(0,this._trace.length-80)}changed(){this._disposed||this.onChange()}adoptCompleteFrame(t){t&&(this._hasCompleteFrame=!0,this._frameFingerprint=t,this._state="steady",this._recoveryReason=null,this.clearOverlay(),this.record("frame-adopted"),this.changed())}markCompleteFrame(t){t&&(this._hasCompleteFrame=!0,this._frameFingerprint=t,this._state="steady",this._recoveryReason=null,this.clearOverlay(),this.record("frame-complete"),this.changed())}refreshCompleteFrame(t){!this._disposed&&this._hasCompleteFrame&&"steady"===this._state&&t&&t!==this._frameFingerprint&&(this._frameFingerprint=t,this.record("frame-refreshed"))}visibility(t){return"hidden"===t.kind?(this.record("visibility-hidden"),this._token):t.long||"visible"!==t.kind&&"pageshow"!==t.kind?this.beginCandidate("pageshow"===t.kind?"pageshow":"long-resume"):(this.record("pageshow"===t.kind?"pageshow-noop":"visibility-visible-quick"),this._token)}beginCandidate(t,e="plan"){return this._token++,this._recoveryReason=e,this._hasCompleteFrame?(this._state="connection"===e?"offline-stale":"holding",this.clearOverlay()):this.overlayVisible?this._state="overlay-visible":(this._state="overlay-pending",this.scheduleOverlay(e)),this.record("candidate-start",t),this.changed(),this._token}connectionLost(){return this.beginCandidate("connection-lost","connection")}candidateReady(t){return!this._disposed&&t===this._token&&(this._state="candidate-ready",this.record("candidate-ready"),this.changed(),!0)}async commitAfterPaint(t,e){if(this._disposed||t!==this._token)return!1;let i=!0;const s=(async()=>{for(await e.updateComplete();i&&!this._disposed&&t===this._token;)if(e.stageValid()&&e.assetsReady()){if(await this.nextFrame(),t!==this._token||!e.stageValid()||!e.assetsReady())continue;if(await this.nextFrame(),t===this._token&&e.stageValid()&&e.assetsReady())return!0}else await this.nextFrame();return!1})();let n=0;const o=new Promise(t=>{n=this.clock.setTimeout(()=>t({ready:!1,timedOut:!0}),Jc)}),a=await Promise.race([s.then(t=>({ready:t,timedOut:!1})),o]);return i=!1,this.clock.clearTimeout(n),!this._disposed&&t===this._token&&(!(!a.ready&&!a.timedOut)&&(a.ready?(this._hasCompleteFrame=!0,this._frameFingerprint=e.frameFingerprint(),this.record("paint-barrier"),this.finishOverlayAfterCommit(),!0):(this.record("paint-barrier-timeout"),this._hasCompleteFrame?(this._state="connection"===this._recoveryReason?"offline-stale":"steady",this.clearOverlay()):(this._state="recovery-error","opaque"!==this._overlayPhase&&this.showOverlayNow()),this.changed(),!1)))}retry(t=this._recoveryReason||"plan"){return this.beginCandidate("retry",t)}nextFrame(){return new Promise(t=>{const e=this.clock.requestAnimationFrame(()=>{this._barrierRafs.delete(e),t()});this._barrierRafs.add(e)})}scheduleOverlay(t){this.clearOverlayTimer(),this._recoveryReason=t,this._overlayTimer=this.clock.setTimeout(()=>{this._overlayTimer=0,this._hasCompleteFrame||"overlay-pending"!==this._state&&"candidate-ready"!==this._state||(this._state="overlay-visible",this._overlayPhase="entering",this.record("overlay-enter"),this.changed(),this._overlayRaf=this.clock.requestAnimationFrame(()=>{this._overlayRaf=0,"entering"===this._overlayPhase&&(this._overlayPhase="fading-in",this.changed(),this._overlayTimer=this.clock.setTimeout(()=>{this._overlayTimer=0,"fading-in"===this._overlayPhase&&(this._overlayPhase="opaque",this._overlayOpaqueAt=this.clock.now(),this.record("overlay-opaque"),this.changed())},150))}))},150)}showOverlayNow(){this.clearOverlayTimer(),this._overlayPhase="opaque",this._overlayOpaqueAt=this.clock.now(),this.record("overlay-error")}finishOverlayAfterCommit(){if(this.clearOverlayTimer(),"none"===this._overlayPhase||"entering"===this._overlayPhase||"fading-in"===this._overlayPhase)return this.clearOverlay(),this._state="steady",this._recoveryReason=null,this.record("candidate-committed"),void this.changed();const t=Math.max(0,this._overlayOpaqueAt+250-this.clock.now());this._overlayTimer=this.clock.setTimeout(()=>{this._overlayTimer=0,this._overlayPhase="leaving",this.record("overlay-leave"),this.changed(),this._overlayTimer=this.clock.setTimeout(()=>{this._overlayTimer=0,this._overlayPhase="none",this._state="steady",this._recoveryReason=null,this.record("candidate-committed"),this.changed()},180)},t)}clearOverlayTimer(){this._overlayTimer&&this.clock.clearTimeout(this._overlayTimer),this._overlayTimer=0}clearOverlay(){this.clearOverlayTimer(),this._overlayRaf&&this.clock.cancelAnimationFrame(this._overlayRaf),this._overlayRaf=0,this._overlayPhase="none",this._overlayOpaqueAt=0}dispose(){this._disposed=!0,this._token++,this.clearOverlay();for(const t of this._barrierRafs)this.clock.cancelAnimationFrame(t);this._barrierRafs.clear()}}function ih(t){let e=2166136261,i=2654435769;const s=new WeakSet,n=t=>{for(let s=0;s>>0)+(i>>>2)}},o=t=>{if(null===t)return void n("n");const e=typeof t;if("string"===e)return void n(`s${t.length}:${t}`);if("number"===e)return void n(`d${Number.isNaN(t)?"NaN":String(t)}`);if("boolean"===e)return void n(t?"t":"f");if("undefined"===e)return void n("u");if("object"!==e)return void n(`${e}:${String(t)}`);const i=t;if(s.has(i))n("[cycle]");else{if(s.add(i),Array.isArray(t)){n("[");for(const e of t)o(e);return n("]"),void s.delete(i)}n("{");for(const e of Object.keys(t).sort())n(e),o(t[e]);n("}"),s.delete(i)}};return o(t),`${(e>>>0).toString(16).padStart(8,"0")}${(i>>>0).toString(16).padStart(8,"0")}`}function sh(t){return ih(t)}const nh=new WeakMap;class oh{constructor(t,e=()=>Date.now()){this.onUpdate=t,this.now=e,this.fallbackAuthority={},this.referenceOwner={},this.referenced=new Set,this.queued=new Set,this.disposed=!1,this.sharedUpdate=()=>{this.disposed||this.onUpdate()}}bind(t){const e=((t,e)=>{const i=t?.connection||t?.callWS||e;return!i||"object"!=typeof i&&"function"!=typeof i?e:i})(t,this.fallbackAuthority);return this.shared&&this.authority===e||(this.shared&&(this.shared.listeners.delete(this.sharedUpdate),this.shared.references.delete(this.referenceOwner)),this.authority=e,this.shared=(t=>{let e=nh.get(t);return e||(e={signed:{},queued:new Set,inFlight:new Map,retry:new Map,listeners:new Set,settlers:new Set,references:new Map},nh.set(t,e)),e})(e),this.disposed||(this.shared.listeners.add(this.sharedUpdate),this.shared.references.set(this.referenceOwner,new Set(this.referenced)))),this.shared}start(t,e){this.disposed=!1,this.referenced=new Set(e());const i=this.bind(t());i.listeners.add(this.sharedUpdate),i.references.set(this.referenceOwner,new Set(this.referenced)),this.stopTimer(),this.resignTimer=setInterval(()=>this.resign(t(),e()),288e5)}dispose(){if(this.disposed=!0,this.stopTimer(),clearTimeout(this.batchTimer),this.shared){this.shared.listeners.delete(this.sharedUpdate),this.shared.references.delete(this.referenceOwner);for(const t of this.queued)this.shared.queued.delete(t)}this.queued.clear()}invalidate(t){const e=this.bind(t);clearTimeout(this.batchTimer),this.queued.clear(),e.queued.clear(),e.inFlight.clear(),e.retry.clear(),e.signed={}}stopTimer(){void 0!==this.resignTimer&&clearInterval(this.resignTimer),this.resignTimer=void 0}display(t,e){const i=Is(e);if(!i.startsWith("/api/houseplan/content/"))return i;const s=this.bind(t);this.referenced.add(i),s.references.set(this.referenceOwner,new Set(this.referenced));const n=s.signed[i],o=n?this.now()-n.at:1/0;return o{const e=[...this.queued];this.queued.clear();for(const t of e)i.queued.delete(t);this.sign(t,e)},30))}sign(t,e){if(!e.length||!t?.callWS)return;const i=this.bind(t);for(const s of function(t,e){const i=Math.max(1,Math.floor(e)),s=[];for(let e=0;e{const s=i.inFlight.get(t);return!(void 0!==s&&e-s<15e3)&&(i.inFlight.set(t,e),!0)});n.length&&t.callWS({type:"houseplan/content/sign",paths:n}).then(t=>{const e=this.now();let s=0,o=!1;for(const a of n){const n=t?.urls?.[a];if("string"==typeof n&&n){const t=i.signed[a];t?.loaded&&t.url!==n?(t.pending={url:n,at:e},this.preloadReplacement(i,a,n,e)):(i.signed[a]={url:n,at:e,loaded:t?.url===n&&!!t.loaded},o=!0),i.retry.delete(a),s++}else this.backOff(i,a)}if(s&&(this.trimShared(i),o))for(const t of[...i.listeners])t()}).catch(()=>{for(const t of n)this.backOff(i,t)}).finally(()=>{for(const t of n)i.inFlight.get(t)===e&&i.inFlight.delete(t);for(const t of[...i.settlers])t()})}}preloadReplacement(t,e,i,s){const n=()=>{const n=t.signed[e];if(n?.pending?.url===i){t.signed[e]={url:i,at:s,loaded:!0},t.retry.delete(e),this.trimShared(t);for(const e of[...t.listeners])e()}},o=()=>{const s=t.signed[e];s?.pending?.url===i&&(delete s.pending,this.backOff(t,e))};if("undefined"==typeof Image)return void n();const a=new Image;a.onload=()=>{("function"==typeof a.decode?a.decode():Promise.resolve()).then(n).catch(o)},a.onerror=o,a.src=i}preloadCurrentImage(t,e,i){if(i.loaded)return Promise.resolve(!0);if(i.preload)return i.preload;if("undefined"==typeof Image)return i.loaded=!0,Promise.resolve(!0);const s=i.url;return i.preload=new Promise(n=>{const o=new Image;let a=!1;const r=o=>{if(a)return;a=!0,clearTimeout(l);const r=t.signed[e];if(r===i&&delete r.preload,o&&r===i&&r.url===s){r.loaded=!0;for(const e of[...t.listeners])e();n(!0)}else o||r!==i||this.backOff(t,e),n(!1)};o.onload=()=>{("function"==typeof o.decode?o.decode():Promise.resolve()).then(()=>r(!0)).catch(()=>r(!1))},o.onerror=()=>r(!1);const l=setTimeout(()=>r(!1),Jc);o.src=s}),i.preload}prepareImage(t,e){const i=Is(e);if(!i.startsWith("/api/houseplan/content/"))return Promise.resolve(!0);const s=this.bind(t),n=()=>{const e=s.signed[i];if(e&&this.now()-e.atthis.now()&&!s.inFlight.has(i)&&!s.queued.has(i)?Promise.resolve(!1):null},o=n();return o?(a=o,new Promise(t=>{let e=!1;const i=i=>{e||(e=!0,clearTimeout(s),t(i))},s=setTimeout(()=>i(!1),Jc);a.then(i).catch(()=>i(!1))})):new Promise(t=>{let e=!1,i=null;const o=i=>{e||(e=!0,clearTimeout(r),s.settlers.delete(a),t(i))},a=()=>{e||i||(i=n(),i&&i.then(o).catch(()=>o(!1)))},r=setTimeout(()=>o(!1),Jc);s.settlers.add(a),a()});var a}backOff(t,e){const i=t.retry.get(e)?.delay||0,s=Math.min(6e4,i?2*i:2e3);t.retry.set(e,{notBefore:this.now()+s,delay:s})}trimShared(t){const e=Object.entries(t.signed);if(e.length<=512)return;const i=new Set(t.inFlight.keys());for(const e of t.references.values())for(const t of e)i.add(t);for(const[t,s]of e)(s.pending||s.preload)&&i.add(t);e.sort((t,e)=>e[1].at-t[1].at);const s=e.filter(([t])=>i.has(t));for(const t of e){if(s.length>=512)break;i.has(t[0])||s.push(t)}t.signed=Object.fromEntries(s)}resign(t,e){const i=this.bind(t);this.referenced=new Set(e),i.references.set(this.referenceOwner,new Set(this.referenced));const s=this.now(),n=new Set;for(const t of i.references.values())for(const e of t)n.add(e);const o={};for(const[t,e]of Object.entries(i.signed))n.has(t)&&s-e.at!!o[t]&&!o[t].pending))}markLoaded(t,e,i){const s=Is(e);if(!s.startsWith("/api/houseplan/content/"))return;const n=this.bind(t).signed[s];if(n&&(!i||n.url===i)&&!n.loaded){n.loaded=!0;for(const e of[...this.bind(t).listeners])e()}}isReady(t,e){const i=Is(e);if(!i.startsWith("/api/houseplan/content/"))return!0;const s=this.bind(t).signed[i];return!!s&&this.now()-s.at{if(null==t||""===t)return null;const e=Number(t);return Number.isFinite(e)?e:null},ch=t=>{const e=t,i=lh(Array.isArray(e)?e[0]:e?.x),s=lh(Array.isArray(e)?e[1]:e?.y);return null==i||null==s?null:[i,s]};function hh(t){if(!Array.isArray(t))return null;const e=[];for(const i of t){const t=ch(i);if(!t)return null;e.push(t)}if(e.length>1){const t=e[0],i=e[e.length-1];t[0]===i[0]&&t[1]===i[1]&&e.pop()}if(e.length<3)return null;let i=0,s=0,n=0;for(let t=0;tt+e[0],0)/e.length,e.reduce((t,e)=>t+e[1],0)/e.length]:[s/(3*i),n/(3*i)]}function dh(t){if(!Array.isArray(t))return null;const e=[];for(const i of t){const t=ch(i);if(!t)return null;e.push(t)}if(e.length>1){const t=e[0],i=e[e.length-1];t[0]===i[0]&&t[1]===i[1]&&e.pop()}const i=hh(e);if(!i)return null;const s=e.map(t=>t[0]),n=e.map(t=>t[1]);return{centroid:i,bbox:[Math.min(...s),Math.min(...n),Math.max(...s),Math.max(...n)]}}function uh(t){let e=t;if(e&&"object"==typeof e&&!Array.isArray(e)){const t=e;e=t.path??t.points??e}if(!Array.isArray(e)||!e.length)return[];let i=(e.some(t=>(t=>Array.isArray(t)?t.length>=2&&!Array.isArray(t[0])&&("object"!=typeof t[0]||null==t[0]):!!t&&"object"==typeof t&&("x"in t||"y"in t))(t))?[e]:e.filter(Array.isArray)).map(t=>t.map(ch).filter(t=>null!=t)).filter(t=>t.length>=2);i.length>64&&(i=i.slice(-64));if(i.reduce((t,e)=>t+e.length,0)<=4e3)return i.map(t=>t.slice());const s=4e3-2*i.length,n=i.map(t=>t.length-2),o=n.reduce((t,e)=>t+e,0),a=n.map(t=>s*t/o),r=a.map(Math.floor);let l=s-r.reduce((t,e)=>t+e,0);const c=a.map((t,e)=>({index:e,fraction:t-Math.floor(t)})).sort((t,e)=>e.fraction-t.fraction||t.index-e.index);for(let t=0;tfunction(t,e){if(e>=t.length)return t.slice();if(e<=2)return[t[0],t[t.length-1]];const i=[];for(let s=0;st.slice()),i=e[e.length-1];return i?(i.length>2?i.pop():e.pop(),e):[]}function gh(t){if(!t)return null;const e=t.vacuum_position||t.robot_position||null,i=e&&null!=lh(e.x)&&null!=lh(e.y)?{x:lh(e.x),y:lh(e.y),a:lh(e.a??e.angle??e.theta)}:null,s=uh(t.path?.path??t.path?.points??t.path),n=[],o=t.rooms,a=Array.isArray(o)?o.map((t,e)=>[String(t?.id??e),t]):o&&"object"==typeof o?Object.entries(o):[];for(const[t,e]of a){if(!e||"object"!=typeof e)continue;const i=String(e.name??e.label??"").trim(),s=[[lh(e.cx),lh(e.cy)],[lh(e.center?.x),lh(e.center?.y)],[lh(e.x),lh(e.y)]].find(([t,e])=>null!=t&&null!=e);let o=s?.[0]??null,a=s?.[1]??null;const r=dh(e.outline),l=lh(e.x0),c=lh(e.y0),h=lh(e.x1),d=lh(e.y1),u=(null!=l&&null!=c&&null!=h&&null!=d?[Math.min(l,h),Math.min(c,d),Math.max(l,h),Math.max(c,d)]:null)||r?.bbox||null;if(null!=o&&null!=a||!r||([o,a]=r.centroid),null!=o&&null!=a||!u||(o=(u[0]+u[2])/2,a=(u[1]+u[3])/2),i&&null!=o&&null!=a){const e={id:t,name:i,cx:o,cy:a};u&&([e.x0,e.y0,e.x1,e.y1]=u),n.push(e)}}const r=function(t){return String(t.map_name??t.current_map??t.map_index??t.selected_map??"default")}(t);return i||n.length||s.length?{pos:i,path:s,rooms:n,mapId:r}:null}function mh(t,e,i){if(!t||!e)return null;const s=e.attributes||{},n=t.split(".")[0]||"",o=null!=i?.platform?String(i.platform):null,a=!!ch(s.vacuum_position??s.robot_position),r=!(!s.rooms||"object"!=typeof s.rooms),l=uh(s.path?.path??s.path?.points??s.path).length>0,c=[s.map_name,s.current_map,s.map_index,s.selected_map].some(t=>null!=t),h="xiaomi_cloud_map_extractor"===o,d=r||l||c;let u=null;if(a?u="compatible":h?u="known_xcme_incomplete":d?u="partial":"camera"===n&&(u="camera"),!u)return null;const p=a?"camera"===n?300:200:h?100:d?50:0;return{entityId:t,name:String(s.friendly_name||t),platform:o,category:u,hasPosition:a,hasRooms:r,hasPath:l,hasMapId:c,score:p}}const fh=t=>t.toLowerCase().replace(/[\s_\-.,]+/g,"");function vh(t,e){const i=new Map(e.map(t=>[fh(t.name),t])),s=[],n=[];for(const e of t){const t=i.get(fh(e.name));t&&(s.push([[e.cx,e.cy],[t.cx,t.cy]]),n.push(e.name))}if(s.length<3)return null;const o=function(t){if(t.length<3)return null;let e=0,i=0,s=0,n=0,o=0,a=0,r=0,l=0,c=0,h=0,d=0,u=0;for(const[[p,_],[g,m]]of t){if(![p,_,g,m].every(Number.isFinite))return null;e+=p*p,i+=p*_,s+=p,n+=_*_,o+=_,a+=1,r+=p*g,l+=_*g,c+=g,h+=p*m,d+=_*m,u+=m}const p=[e,i,s,i,n,o,s,o,a],_=t=>{const[e,i,s,n,o,a,r,l,c]=p,h=e*(o*c-a*l)-i*(n*c-a*r)+s*(n*l-o*r);if(!Number.isFinite(h)||Math.abs(h)<1e-9)return null;const d=[(o*c-a*l)/h,(s*l-i*c)/h,(i*a-s*o)/h,(a*r-n*c)/h,(e*c-s*r)/h,(s*n-e*a)/h,(n*l-o*r)/h,(i*r-e*l)/h,(e*o-i*n)/h];return[d[0]*t[0]+d[1]*t[1]+d[2]*t[2],d[3]*t[0]+d[4]*t[1]+d[5]*t[2],d[6]*t[0]+d[7]*t[1]+d[8]*t[2]]},g=_([r,l,c]),m=_([h,d,u]);if(!g||!m)return null;const f=[g[0],g[1],g[2],m[0],m[1],m[2]];return f.every(Number.isFinite)?f:null}(s);return o?{matrix:o,matched:n,residual:rh(o,s)}:null}function yh(t,e,i){const s=t[t.length-1];if(s&&s[0]===e[0]&&s[1]===e[1])return t;if(t.push(e),t.length<=600)return t;let n=function(t,e){if(t.length<3)return t.slice();const i=new Uint8Array(t.length);i[0]=i[t.length-1]=1;const s=[[0,t.length-1]];for(;s.length;){const[n,o]=s.pop(),[a,r]=t[n],[l,c]=t[o],h=l-a,d=c-r,u=Math.hypot(h,d)||1e-9;let p=0,_=-1;for(let e=n+1;ep&&(p=i,_=e)}_>0&&p>e&&(i[_]=1,s.push([n,_],[_,o]))}const n=[];for(let e=0;e600&&(n=n.filter((t,e)=>e%2==0||e===n.length-1)),n}function bh(t){return"cleaning"===t||"returning"===t||"on"===t}const wh={0:[1,0],90:[0,1],180:[-1,0],270:[0,-1]};function kh(t){const[e,i]=wh[t.rot]||[1,0],s=t.mir?-1:1;return[t.s*e*s,-t.s*i,t.ox,t.s*i*s,t.s*e,t.oy]}function xh(t){const e=t[0]*t[4]-t[1]*t[3];if(!Number.isFinite(e)||Math.abs(e)<1e-12)return null;const i=e<0,s=Math.sqrt(Math.abs(e));let n=180*Math.atan2(-t[1],t[4])/Math.PI;return n=(90*Math.round(n/90)%360+360)%360,{ox:t[2],oy:t[5],s:s,rot:n,mir:i}}function $h(t,e,i,s){const[n,o]=ah(kh(e),i,s),a=kh({...t,ox:0,oy:0}),[r,l]=ah(a,i,s);return{...t,ox:n-r,oy:o-l}}function Sh(t){const e=t?.trail_mode;return"never"===e||"cleaning"===e||"always"===e?e:!1===t?.trail?"never":"cleaning"}const Mh={offStates:["off"],unknownUsesToggle:!0},Ch={light:Mh,switch:Mh,fan:Mh,humidifier:Mh,input_boolean:Mh,automation:Mh,remote:Mh,group:Mh,climate:{...Mh,featureMasks:{turn_on:256,turn_off:128,toggle:384}},media_player:{...Mh,featureMasks:{turn_on:128,turn_off:256,toggle:384}},siren:{...Mh,featureMasks:{turn_on:1,turn_off:2,toggle:3}},vacuum:{...Mh,featureMasks:{turn_on:1,turn_off:2,toggle:3}},water_heater:{...Mh,featureMasks:{turn_on:8,turn_off:8,toggle:8}},camera:{...Mh,featureMasks:{turn_on:1,turn_off:1,toggle:1}}};function Dh(t){return t.slice(0,t.indexOf("."))}function Th(t,e,i){if(!t?.services||"object"!=typeof t.services)return!1;const s=t.services?.[e];return!!s&&Object.prototype.hasOwnProperty.call(s,i)}function Ph(t,e,i){return Th(t,e,i)?{domain:e,service:i}:Th(t,"homeassistant",i)?{domain:"homeassistant",service:i}:null}function Rh(t,e){return t?.entities?.[e]||null}function Ah(t,e,i){const s=t?.states?.[i],n=Rh(e,i);return s?.attributes?.friendly_name||n?.name||n?.original_name||i}function Ih(t,e){const i=Rh(t,e);if(null!=i?.disabled_by)return!0;const s=i?.device_id?t?.devices?.[i.device_id]:null;return null!=s?.disabled_by}function Eh(t,e){const i=t?.attributes?.supported_features;if(null==i||""===i)return!1;const s=Number(i);return Number.isFinite(s)&&(s&e)===e}function Fh(t,e,i){const s=Dh(i);if("lock"===s||"alarm_control_panel"===s)return!0;if("cover"!==s)return!1;const n=t?.states?.[i],o=Rh(e,i),a=String(n?.attributes?.device_class||o?.device_class||o?.original_device_class||"");return Ui.has(a)}function zh(t,e,i,s,n){return{ref:i,entityId:s,name:s?Ah(t,e,s):null,reason:n}}function Oh(t,e,i,s,n,o=null){return{target:null,skipped:zh(t,e,i,s,n),semantics:o,nextEffect:null,command:null}}function Hh(t,e,i,s,n=i){const o=Dh(i);if("cover"!==o&&"valve"!==o)return function(t,e,i,s,n=i){const o=Dh(i),a=t?.states?.[i];if(Ih(e,i))return Oh(t,e,n,i,"ha-disabled","power");if(Fh(t,e,i))return Oh(t,e,n,i,"secure");if(!a)return Oh(t,e,n,i,"missing","power");if("unavailable"===a.state)return Oh(t,e,n,i,"unavailable","power");const r=Ch[o];if(!r)return Oh(t,e,n,i,"unsupported");let l,c;if("unknown"===a.state||""===a.state){if(!r.unknownUsesToggle)return Oh(t,e,n,i,"unsupported","power");l="toggle",c="toggle"}else r.offStates.includes(String(a.state))?(l="turn-on",c="turn_on"):(l="turn-off",c="turn_off");const h=r.featureMasks?.[c];if(h&&!Eh(a,h))return Oh(t,e,n,i,"unsupported","power");const d=Ph(t,o,c);return d?{target:{entityId:i,name:Ah(t,e,i),state:String(a.state||""),via:s},skipped:null,semantics:"power",nextEffect:l,command:{...d,data:{entity_id:i}}}:Oh(t,e,n,i,"unsupported","power")}(t,e,i,s,n);if(Ih(e,i))return Oh(t,e,n,i,"ha-disabled",o);if(Fh(t,e,i))return Oh(t,e,n,i,"secure",o);const a=t?.states?.[i];if(!a)return Oh(t,e,n,i,"missing",o);if("unavailable"===a.state)return Oh(t,e,n,i,"unavailable",o);const r=function(t,e,i){const s=String(i?.state||""),n="closed"===s?{service:`open_${e}`,effect:"open",feature:1}:"open"===s?{service:`close_${e}`,effect:"close",feature:2}:"opening"===s||"closing"===s?{service:`stop_${e}`,effect:"stop",feature:8}:null;return n&&Eh(i,n.feature)&&Th(t,e,n.service)?n:Eh(i,3)&&Th(t,e,"toggle")?{service:"toggle",effect:"toggle"}:null}(t,o,a);if(!r)return Oh(t,e,n,i,"unsupported",o);return{target:{entityId:i,name:Ah(t,e,i),state:String(a.state||""),via:s},skipped:null,semantics:o,nextEffect:r.effect,command:{domain:o,service:r.service,data:{entity_id:i}}}}function Nh(t){return"entity"===t.bindingKind?t.bindingRef&&Ms(t.bindingRef)?[t.bindingRef]:[]:"virtual"===t.bindingKind?[]:Zn(t)}function Lh(t){const e=t.marker?.toggle_entity;return e&&Nh(t).includes(e)?e:null}function Bh(t,e,i){const s=function(t,e){if("entity"===t.bindingKind&&t.bindingRef){const e=t.marker?.light_entity?Qn(t):null;return[...new Set([e,t.bindingRef].filter(t=>!!t))]}const i=t.entities.length?t.entities:t.allEntities||[],s=t.marker?.light_entity||t.primary&&Ms(t.primary)?Qn(t):null;return[...new Set([s,...Vn(e,i)].filter(t=>!!t))]}(i,e);if(!s.length)return null;const n="entity"===i.bindingKind?"binding":"device-role";if("binding"===n)return Hh(t,e,s[0],n);let o=null,a=null;for(const i of s){const s=Hh(t,e,i,n);if(s.command)return s;const r=s.skipped?.reason;if("missing"===r||"unavailable"===r||"secure"===r)return s;"ha-disabled"!==r?o||=s:a||=s}return o||a}function qh(t){const e=t.skipped?.reason;return"missing"===e?"unavailable":e||"unsupported"}function jh(t,e){return{origin:t,kind:"none",semantics:null,targets:[],skippedTargets:[],noneReason:e,nextEffect:null,command:null}}function Wh(t,e){return"cover"===t||"toggle"===t?"toggle":"more-info"===t||"run"===t||"info"===t?t:(null==t||""===t)&&"light"===e?"toggle":"info"}function Uh(t,e){return{origin:t,kind:"single",semantics:e.semantics,targets:e.target?[e.target]:[],skippedTargets:e.skipped?[e.skipped]:[],noneReason:e.command?null:qh(e),nextEffect:e.nextEffect,command:e.command}}function Gh(t,e,i,s=[]){const n=new Map,o=[],a=new Set,r=t=>{const e=`${t.ref}\n${t.entityId||""}\n${t.reason}`;a.has(e)||(a.add(e),o.push(t))};for(const t of s)r(t);for(const s of i){const i=Hh(t,e,s.entityId,s.via,s.ref);i.target?n.set(s.entityId,n.get(s.entityId)||i.target):i.skipped&&r(i.skipped)}const l=[...n.values()];if(!l.length)return{origin:"explicit-toggle",kind:"group",semantics:"group-power",targets:l,skippedTargets:o,noneReason:o.length&&o.every(t=>"secure"===t.reason)?"secure":"configured-targets-missing",nextEffect:null,command:null};const c=l.some(t=>"on"===t.state)?"turn_off":"turn_on",h=Ph(t,"homeassistant",c);return h?{origin:"explicit-toggle",kind:"group",semantics:"group-power",targets:l,skippedTargets:o,noneReason:null,nextEffect:"turn_on"===c?"turn-on":"turn-off",command:{...h,data:{entity_id:l.map(t=>t.entityId)}}}:{origin:"explicit-toggle",kind:"group",semantics:"group-power",targets:[],skippedTargets:[...o,...l.map(i=>zh(t,e,i.entityId,i.entityId,"unsupported"))],noneReason:"unsupported",nextEffect:null,command:null}}function Vh(t){return String(t.marker?.id||t.id||"")}function Kh(t){const{hass:e,device:i}=t,s=t.registryHass||e,n=function(t){return"toggle"===t.tapAction?"explicit-toggle":"cover"===t.tapAction?"legacy-cover":!t.tapAction&&t.primary?.startsWith("light.")?"default-light":null}(i);if(!n)return null;const o=i.marker;if("explicit-toggle"===n&&yn(o)){const e=String(o?.id||i.id||""),s=oo(t.devices).get(e);if(s)return function(t,e){const i=t.registryHass||t.hass;return Gh(t.hass,i,e.driverEids.map(t=>({entityId:t,via:"control-marker-driver",ref:`marker:${e.markerId}`})))}(t,s);const a=bn(o,t.virtualLights);return{origin:n,kind:"single",semantics:"power",targets:[{entityId:"",name:i.name,state:a?"on":"off",via:"virtual-light"}],skippedTargets:[],noneReason:null,nextEffect:a?"turn-off":"turn-on",command:null,operation:{kind:"virtual-light",markerId:o.id}}}if("explicit-toggle"===n){if(Xn(i.marker?.binding,i.marker?.controls??i.controls,i.entities).length)return function(t,e=null){const{hass:i,device:s,devices:n}=t,o=t.registryHass||i,a=Xn(s.marker?.binding,s.marker?.controls??s.controls,s.entities),r=t.lightSources||lo(i,n,null,t.virtualLights),l=new Map;for(const t of r){if(!t.key.startsWith("marker:"))continue;const e=l.get(t.key)||[];e.push(t),l.set(t.key,e)}const c=oo(n),h=new Map;for(const t of n){const e=String(t.marker?.id||t.id||"");e&&h.set(e,t)}const d=[],u=[];e&&d.push({entityId:e,via:"entity"===s.bindingKind?"binding":"device-role",ref:e});for(const t of a){if(!t.startsWith("marker:")){Ms(t)?d.push({entityId:t,via:"control-entity",ref:t}):u.push(zh(i,o,t,t.includes(".")?t:null,"unsupported"));continue}const e=l.get(t)||[];if(!e.length){const e=h.get(t.slice(7));if("ha_disabled"===e?.bindingStatus?.kind){const s=e.bindingStatus.allEntityIds[0]||null;u.push({ref:t,entityId:s,name:e.name||(s?Ah(i,o,s):null),reason:"ha-disabled"})}else u.push(zh(i,o,t,null,"missing"));continue}const n=[...new Set(e.flatMap(t=>t.serviceEids))];if(n.length){for(const e of n)d.push({entityId:e,via:"control-entity",ref:t});continue}const a=e.some(t=>t.passive),r=t.slice(7),p=Vh(s),_=c.get(r)?.controllers.find(t=>Vh(t.device)===p);if(a&&_?.driverEids.length)for(const e of _.driverEids)d.push({entityId:e,via:"control-marker-driver",ref:t});else u.push(zh(i,o,t,null,a?"missing":"unsupported"))}return Gh(i,o,d,u)}(t,Lh(i))}if("legacy-cover"===n){const t=i.entities.find(t=>t.startsWith("cover."))||i.allEntities?.find(t=>t.startsWith("cover."));return t?Uh(n,Hh(e,s,t,"device-role")):jh(n,"no-actionable-entity")}const a=Lh(i),r=a?Hh(e,s,a,"entity"===i.bindingKind?"binding":"device-role"):Bh(e,s,i);return r?Uh(n,r):jh(n,i.virtual||"virtual"===i.bindingKind?"no-actionable-entity":"no-binding")}function Yh(t){if(!t)return[];const e=Array.isArray(t.data.entity_id)?t.data.entity_id:[t.data.entity_id];return[...new Set(e)].sort()}function Xh(t){return t?t.operation?t.operation:t.command?{kind:"ha-service",command:t.command}:null:null}function Jh(t,e){const i=Xh(t),s=Xh(e);return!(!i||!s||i.kind!==s.kind)&&("virtual-light"===i.kind&&"virtual-light"===s.kind?i.markerId===s.markerId:"ha-service"===i.kind&&"ha-service"===s.kind&&function(t,e){const i=Yh(t),s=Yh(e);return i.length===s.length&&i.every((t,e)=>t===s[e])}(i.command,s.command))}const Zh=t=>!!t&&t.length>=2&&Number.isFinite(t[0])&&Number.isFinite(t[1]);function Qh(t,e=5,i=5){return fr(t.cm,e,i)/2}function td(t,e,i=1,s=5,n=5,o=0){const a=t.host;if(!a||"partition"!==a.kind||"string"!=typeof a.id||!a.id)return{resolved:null,reason:"invalid-host"};const r=e.find(t=>t.id===a.id);if(!r)return{resolved:null,reason:"missing-partition"};if(!Zh(r.a)||!Zh(r.b)||!Number.isFinite(a.t)||a.t<0||a.t>1)return{resolved:null,reason:"invalid-position"};const l=r.b[0]-r.a[0],c=r.b[1]-r.a[1],h=Math.hypot(l,c),d=Number(t.length)*i;if(!(h>1e-9&&d>0&&Number.isFinite(d)))return{resolved:null,reason:"invalid-length"};const u=a.t*h;if(u-d/2h-o+1e-9)return{resolved:null,reason:"does-not-fit"};const p=l/h,_=c/h;let g=180*Math.atan2(c,l)/Math.PI;return g>=90?g-=180:g<-90&&(g+=180),{reason:null,resolved:{opening:t,host:a,partition:r,center:[r.a[0]+l*a.t,r.a[1]+c*a.t],angle:g,length:d,depth:fr(r.cm,s,n),t:a.t,axis:{a:[r.a[0],r.a[1]],b:[r.b[0],r.b[1]],ux:p,uy:_,length:h}}}}function ed(t,e,i=1,s=5,n=5){return td(t,e,i,s,n,0)}function id(t,e,i=1,s=5,n=5){const o=t.host,a="partition"===o?.kind?e.find(t=>t.id===o.id):void 0;if(!a)return ed(t,e,i,s,n);const r=td(t,e,i,s,n,Qh(a,s,n));return"does-not-fit"===r.reason?{resolved:null,reason:"does-not-fit-jamb"}:r}function sd(t,e){return!t||(t.length!==e.length||t.host?.kind!==e.host?.kind||t.host?.id!==e.host?.id||t.host?.t!==e.host?.t)}function nd(t){const{center:e,length:i,axis:s,host:n}=t,o=i/2;return{hostId:n.id,a:[e[0]-s.ux*o,e[1]-s.uy*o],b:[e[0]+s.ux*o,e[1]+s.uy*o],depth:t.depth}}function od(t,e=!1){const i=e?1:-1,s=t.depth/2;return{ox:-t.axis.uy*i*s,oy:t.axis.ux*i*s,cm:t.partition.cm,side:i}}function ad(t,e,i){const{center:s,length:n,axis:o}=t,a=n/2,r=e.flatMap(t=>{if(!t.kind||t.open)return[];const e=t.b[0]-t.a[0],n=t.b[1]-t.a[1],r=Math.hypot(e,n);if(!(r>i))return[];const l=e/r,c=n/r;if(Math.abs(o.ux*c-o.uy*l)>1e-6)return[];if(Math.abs((s[0]-t.a[0])*c-(s[1]-t.a[1])*l)>i)return[];const h=t=>(t[0]-s[0])*o.ux+(t[1]-s[1])*o.uy,d=h(t.a),u=h(t.b),p=Math.max(-a,Math.min(d,u)),_=Math.min(a,Math.max(d,u));return _>=p-i?[[p,_]]:[]});if(!r.length)return!1;r.sort((t,e)=>t[0]-e[0]||t[1]-e[1]);let l=-a;for(const[t,e]of r){if(t>l+i)return!1;if(l=Math.max(l,e),l>=a-i)return!0}return!1}function rd(t,e,i){return{...t,x:e.center[0]/i,y:e.center[1]/i,angle:e.angle}}function ld(t){return!!t&&t.length>=2&&Number.isFinite(t[0])&&Number.isFinite(t[1])}function cd(t){return`${t[0].toFixed(6)},${t[1].toFixed(6)}`}function hd(t,e,i){return Math.abs(t[0]-e[0])_d(s,t,e)))continue;const t=cd(s);a.has(t)||a.set(t,{point:[s[0],s[1]],key:t})}}}return{segments:[...o.values()].sort((t,e)=>t.key.localeCompare(e.key)),endpoints:[...a.values()].sort((t,e)=>t.key.localeCompare(e.key))}}function md(t,e,i){return e.some(e=>ld(e)&&hd(t,e,i))}function fd(t,e,i){if(!i)return!0;const s=t-i.distance;return s<-1e-9||Math.abs(s)<=1e-9&&e.localeCompare(i.key)<0}function vd(t,e,i){const s=t.b[0]-t.a[0],n=t.b[1]-t.a[1],o=Math.hypot(s,n);if(!(o>0))return[...t.a];const a=s/o,r=n/o,l=Math.max(0,Math.min(o,(e[0]-t.a[0])*a+(e[1]-t.a[1])*r)),c=i>0?Math.max(0,Math.min(o,Math.round(l/i)*i)):l;return[t.a[0]+a*c,t.a[1]+r*c]}const yd=.001;function bd(t,e,i){const s=[];for(let n=0;n+1=0?e[n]:i;s.push({a:[o[0],o[1]],b:[a[0],a[1]],cm:r})}return s}function wd(t){return!!t&&t.length>=2&&Number.isFinite(t[0])&&Number.isFinite(t[1])}function kd(t,e,i,s){return t*s-e*i}function xd(t){let e=0;for(let i=0;it.localeCompare(e)),e[0]}function Dd(t,e,i){const s=[...t];for(let t=!0;t&&s.length>=3;){t=!1;for(let n=0;n=0){s.splice(n,1),t=!0;break}}}return s}function Td(t,e){const i=t.map(t=>Math.max(0,Math.min(1,t))).sort((t,e)=>t-e),s=[];for(const t of i)(!s.length||Math.abs(t-s[s.length-1])>e)&&s.push(t);return s}function Pd(t,e){return[t.a[0]+(t.b[0]-t.a[0])*e,t.a[1]+(t.b[1]-t.a[1])*e]}function Rd(t,e,i){const s=function(t,e){const i=e.b[0]-e.a[0],s=e.b[1]-e.a[1],n=i*i+s*s;return n>0?((t[0]-e.a[0])*i+(t[1]-e.a[1])*s)/n:0}(t,e);if(s<-i||s>1+i)return null;const n=Pd(e,s);return Math.hypot(n[0]-t[0],n[1]-t[1])<=i?Math.max(0,Math.min(1,s)):null}function Ad(t,e,i,s,n){const o=t.b[0]-t.a[0],a=t.b[1]-t.a[1],r=e.b[0]-e.a[0],l=e.b[1]-e.a[1],c=e.a[0]-t.a[0],h=e.a[1]-t.a[1],d=kd(o,a,r,l),u=Math.max(Math.hypot(o,a),Math.hypot(r,l),1);if(Math.abs(d)>n*u){const t=kd(c,h,r,l)/d,e=kd(c,h,o,a)/d;return void(t>=-n&&t<=1+n&&e>=-n&&e<=1+n&&(i.push(Math.max(0,Math.min(1,t))),s.push(Math.max(0,Math.min(1,e)))))}if(!(Math.abs(kd(c,h,o,a))>n*u)){for(const s of[e.a,e.b]){const e=Rd(s,t,n);null!=e&&i.push(e)}for(const i of[t.a,t.b]){const t=Rd(i,e,n);null!=t&&s.push(t)}}}function Id(t){let e=t+1|0;return e^=e<<13,e^=e>>>17,e^=e<<5,e>>>0}function Ed(t,e){return t.minY-e.minY||t.index-e.index}function Fd(t){return t.subtreeMaxY=Math.max(t.item.maxY,t.left?.subtreeMaxY??-1/0,t.right?.subtreeMaxY??-1/0),t}function zd(t){const e=t.right;return t.right=e.left,e.left=Fd(t),Fd(e)}function Od(t){const e=t.left;return t.left=e.right,e.right=Fd(t),Fd(e)}function Hd(t,e){return t?(Ed(e,t.item)<0?(t.left=Hd(t.left,e),t.left.priority0)t.right=Nd(t.right,e);else{if(!t.left)return t.right;if(!t.right)return t.left;t.left.priority=e&&Ld(t.left,e,i,s),t.item.minY<=i&&t.item.maxY>=e&&s.push(t.item),t.item.minY<=i&&Ld(t.right,e,i,s))}function Bd(t,e=.001){const i=Number.isFinite(e)&&e>0?e:yd,s=t.filter(t=>wd(t.a)&&wd(t.b)&&"string"==typeof t.key&&t.key.length>0&&Math.hypot(t.b[0]-t.a[0],t.b[1]-t.a[1])>i),n=s.map(()=>[0,1]);!function(t,e,i){const s=t.map((t,e)=>({index:e,minX:Math.min(t.a[0],t.b[0])-i,maxX:Math.max(t.a[0],t.b[0])+i,minY:Math.min(t.a[1],t.b[1])-i,maxY:Math.max(t.a[1],t.b[1])+i})),n=[...s].sort((t,e)=>t.minX-e.minX||t.minY-e.minY||t.index-e.index),o=[...s].sort((t,e)=>t.maxX-e.maxX||t.index-e.index),a=new Set;let r=null,l=0;for(const s of n){for(;lt.index-e.index);for(const o of n)Ad(t[o.index],t[s.index],e[o.index],e[s.index],i);a.add(s.index),r=Hd(r,s)}}(s,n,i);const o=new Map;for(let t=0;t({key:t,a:e.a,b:e.b,sourceKeys:[...e.sourceKeys].sort((t,e)=>t.localeCompare(e))})).sort((t,e)=>t.key.localeCompare(e.key))}const qd=1e-5;function jd(t){const e=t.map(()=>[]);for(let i=0;i=1-1e-9||u<=1e-9||u>=1-1e-9||(e[i].push(d),e[a].push(u))}}const i=[];for(let s=0;st-e),1];for(let t=1;t{const i=e[2]-e[0],s=e[3]-e[1],n=i*i+s*s;if(!(n>0))return Math.hypot(t[0]-e[0],t[1]-e[1]);const o=Math.max(0,Math.min(1,((t[0]-e[0])*i+(t[1]-e[1])*s)/n));return Math.hypot(t[0]-(e[0]+o*i),t[1]-(e[1]+o*s))},Gd=(t,e,i,s)=>{const n=s[2]-s[0],o=s[3]-s[1],a=e*o-i*n;if(Math.abs(a)<1e-12)return 1/0;const r=s[0]-t[0],l=s[1]-t[1],c=(r*o-l*n)/a;if(!(c>1e-9))return 1/0;const h=(r*i-l*e)/a;return h<-1e-9||h>1+1e-9?1/0:c};function Vd(t,e,i,s=96){if(!(e>0&&Number.isFinite(t[0])&&Number.isFinite(t[1])))return[];const n=[];for(const s of i){if(!s||s.length<4)continue;if(![s[0],s[1],s[2],s[3]].every(Number.isFinite))continue;const i=Ud(t,s);if(i<1e-7)return[];i>e||n.push(s)}const o=[],a=Math.max(12,Math.round(s));for(let t=0;tt-e);const l=[];let c=Number.NEGATIVE_INFINITY;for(const i of o){if(i-c<1e-9)continue;c=i;const s=Math.cos(i),o=Math.sin(i);let a=e;for(const e of n){const i=Gd(t,s,o,e);i=3?l:[]}class Kd extends ht{constructor(){super(...arguments),this._spaces=null,this._spacesLoading=!1}setConfig(t){this._config=t}async _loadSpaces(){if(!this._spaces&&!this._spacesLoading&&this.hass){this._spacesLoading=!0;try{const t=await this.hass.callWS({type:"houseplan/config/get"});this._spaces=(t?.config?.spaces||[]).map(t=>({value:t.id,label:t.title||t.id}))}catch{this._spaces=[]}finally{this._spacesLoading=!1}}}get _lang(){return sa(this.hass,this._config?.language)}get _schema(){const t=this._spaces||[],e=this._lang;return[{name:"title",selector:{text:{}}},t.length?{name:"default_floor",selector:{select:{mode:"dropdown",options:t}}}:{name:"default_floor",selector:{text:{}}},{name:"language",selector:{select:{mode:"dropdown",options:[{value:"",label:na(e,"editor.lang_auto")},{value:"en",label:na(e,"editor.lang_en")},{value:"ru",label:na(e,"editor.lang_ru")}]}}},{name:"icon_size",selector:{number:{min:1,max:6,step:.1,mode:"box"}}},{name:"show_temperature",selector:{boolean:{}}},{name:"live_states",selector:{boolean:{}}},{name:"show_signal",selector:{boolean:{}}},{name:"kiosk",selector:{boolean:{}}},{name:"cycle",selector:{number:{min:0,max:3600,step:5,mode:"box"}}}]}render(){if(!this.hass||!this._config)return G;this._loadSpaces();const t=this._lang,e={title:na(t,"editor.title"),default_floor:na(t,"editor.default_floor"),language:na(t,"editor.language"),icon_size:na(t,"editor.icon_size"),show_temperature:na(t,"editor.show_temperature"),live_states:na(t,"editor.live_states"),show_signal:na(t,"editor.show_signal"),kiosk:na(t,"editor.kiosk"),cycle:na(t,"editor.cycle")};return j`{const e=vc(t);return W`${t.name}`}),T=lo(a,c,null,t.virtualLights),P=c.map(s=>{const n=function(t,e,i,s,n){const o=e[t.id];return o&&o.s===t.space?{x:o.x*Bl,y:o.y*Bl}:s[t.id]?s[t.id]:tc(pc(n))}(s,t.layout,t.cfg,h,e),o=(n.x-y[0])/y[2]*100,l=(n.y-y[1])/y[3]*100,d=i.showLqi??!1!==t.showSignal,u=t.presentations?.get(hu(s.id,d))||au(a,s,{liveStates:!1!==t.liveStates,showTemperature:!1!==t.showTemperature,showSignal:d,activityRuntime:t.activityRuntime?.get(s.id),sourceDetails:!1,lightDevices:c,lightSources:T,registryHass:r,reducedMotion:t.reducedMotion}),p=[`left:${o}%`,`top:${l}%`,...jo(u)],_=[s.name,"none"!==u.pulse.kind?na(t.lang,`marker.pulse_a11y_${u.pulse.reason}`):"",To(u.valueBadge)].filter(Boolean).join(", ");return j`
`),C=new Map;for(const t of e.rooms)if(t.id){const e=b.get(t)||null;C.set(t.id,Fs(i.glow,t)&&(!e||e.opacity<=0)?{color:s.glow_base.c,opacity:s.glow_base.a,mode:"glow"}:null)}const D=lo(a,c,null,t.virtualLights),T=c.map(s=>{const n=function(t,e,i,s,n){const o=e[t.id];return o&&o.s===t.space?{x:o.x*Bl,y:o.y*Bl}:s[t.id]?s[t.id]:tc(pc(n))}(s,t.layout,t.cfg,h,e),o=(n.x-y[0])/y[2]*100,l=(n.y-y[1])/y[3]*100,d=i.showLqi??!1!==t.showSignal,u=t.presentations?.get(hu(s.id,d))||au(a,s,{liveStates:!1!==t.liveStates,showTemperature:!1!==t.showTemperature,showSignal:d,activityRuntime:t.activityRuntime?.get(s.id),sourceDetails:!1,lightDevices:c,lightSources:D,registryHass:r,reducedMotion:t.reducedMotion}),p=[`left:${o}%`,`top:${l}%`,...jo(u)],_=[s.name,"none"!==u.pulse.kind?na(t.lang,`marker.pulse_a11y_${u.pulse.reason}`):"",To(u.valueBadge)].filter(Boolean).join(", ");return j`
${Wo(u,{})} -
`}),R=i.showNames?e.rooms.filter(t=>t.name).map(s=>{const n=function(t,e,i){const s=i["rl_"+(t.id||"")];if(s&&s.s===e)return{x:s.x*Bl,y:s.y*Bl};const n=vc(t);return tc({x:n[0],y:n[1]})}(s,e.id,t.layout,t.cfg),o=(n.x-y[0])/y[2]*100,a=(n.y-y[1])/y[3]*100,r=Math.min(1,i.opacity+.25);return j`
`}),P=i.showNames?e.rooms.filter(t=>t.name).map(s=>{const n=vc(s,e.id,t.layout,t.cfg),o=(n.x-y[0])/y[2]*100,a=(n.y-y[1])/y[3]*100,r=Math.min(1,i.opacity+.25);return j`
${s.name}
`}):[],A=e.bg?t.displayUrl?t.displayUrl(e.bg.href):e.bg.href:"",I=t.cfg.spaces.find(e=>e.id===t.spaceId)?.settings||{},E="daynight"===Ya(t.cfg?.settings,I)?Ha(a,t.dayCycleNow??new Date):null,F=hs(t.cfg?.settings,i),z=!!(p.length||f.length&&i.showBorders),O=z?ih(k.length?{rooms:e.rooms,walls:p,extras:f,cellCm:_,passages:k.map(t=>({x:t.rx,y:t.ry,angle:t.angle,length:t.rlen})),hostedCompositeOpenings:$}:{rooms:e.rooms,walls:p,extras:f,cellCm:_}):"",H=z?function(t,e,i,s){let n=uu.get(t);n||(n=new Map,uu.set(t,n));const o=n.get(e);if(o?.fingerprint===i)return o.value;const a=s();return n.set(e,{fingerprint:i,value:a}),a}(t.cfg,e.id,O,()=>ul(e.rooms,p,[],[...k.filter(t=>!t.host).map(t=>({x:t.rx,y:t.ry,angle:t.angle,length:t.rlen})),...$],Zl,_,Jl,Bl,f)):null,N=k.length&&p.length?function(t,e,i,s,n,o,a,r=1){return[n,o,a,r].every(Number.isFinite)&&o>0&&r>0&&i?.length?kl(gl(t,i,s,n,o,a,r),e):e.map(()=>null)}(e.rooms,k.map(t=>({x:t.rx,y:t.ry,angle:t.angle,length:t.rlen})),p,[],Zl,_,Jl,Bl):k.map(()=>null),L=k.length?du({openings:k,geometries:N,fillsByRoomId:w,idPrefix:`${e.id}-static-data`,groupClass:"opening-tunnels static-opening-tunnels",dataLayer:"data"}):G,B=k.length?du({openings:k,geometries:N,fillsByRoomId:C,idPrefix:`${e.id}-static-glow`,groupClass:"opening-tunnels glow-base-tunnels static-opening-tunnels",dataLayer:"glow-base"}):G,q=p.length&&H?.paperD?[{path:H.paperD}]:di(e.rooms),U=i.showBorders?H:null,V=t.stageWidth&&y[2]?t.stageWidth/y[2]:1,K=!!U&&_r(U.depthUnits,V),Y=i.color||"#607d8b",X=i.hideOpenings?[]:g.map(t=>{const e=t.opening,i="passage"!==e.type&&e.contact?a.states?.[e.contact]?.state:null,s=gi(e.type,i,!!e.invert),n=s>0&&!!e.contact,o="gate"===e.type?!e.flip_v:!!e.flip_v,r={type:e.type,length:t.length,angle:t.angle,amount:s,flipH:!!e.flip_h,flipV:!!e.flip_v,base:Y,tone:n?"var(--hp-open)":Y,cellCm:_,gridPitch:Jl,face:od(t,o)};return W`${s.name}
`}):[],R=e.bg?t.displayUrl?t.displayUrl(e.bg.href):e.bg.href:"",A=t.cfg.spaces.find(e=>e.id===t.spaceId)?.settings||{},I="daynight"===Ya(t.cfg?.settings,A)?Ha(a,t.dayCycleNow??new Date):null,E=hs(t.cfg?.settings,i),F=!!(p.length||f.length&&i.showBorders),z=F?ih(k.length?{rooms:e.rooms,walls:p,extras:f,cellCm:_,passages:k.map(t=>({x:t.rx,y:t.ry,angle:t.angle,length:t.rlen})),hostedCompositeOpenings:$}:{rooms:e.rooms,walls:p,extras:f,cellCm:_}):"",O=F?function(t,e,i,s){let n=uu.get(t);n||(n=new Map,uu.set(t,n));const o=n.get(e);if(o?.fingerprint===i)return o.value;const a=s();return n.set(e,{fingerprint:i,value:a}),a}(t.cfg,e.id,z,()=>ul(e.rooms,p,[],[...k.filter(t=>!t.host).map(t=>({x:t.rx,y:t.ry,angle:t.angle,length:t.rlen})),...$],Zl,_,Jl,Bl,f)):null,H=k.length&&p.length?function(t,e,i,s,n,o,a,r=1){return[n,o,a,r].every(Number.isFinite)&&o>0&&r>0&&i?.length?kl(gl(t,i,s,n,o,a,r),e):e.map(()=>null)}(e.rooms,k.map(t=>({x:t.rx,y:t.ry,angle:t.angle,length:t.rlen})),p,[],Zl,_,Jl,Bl):k.map(()=>null),N=k.length?du({openings:k,geometries:H,fillsByRoomId:w,idPrefix:`${e.id}-static-data`,groupClass:"opening-tunnels static-opening-tunnels",dataLayer:"data"}):G,L=k.length?du({openings:k,geometries:H,fillsByRoomId:C,idPrefix:`${e.id}-static-glow`,groupClass:"opening-tunnels glow-base-tunnels static-opening-tunnels",dataLayer:"glow-base"}):G,B=p.length&&O?.paperD?[{path:O.paperD}]:di(e.rooms),q=i.showBorders?O:null,U=t.stageWidth&&y[2]?t.stageWidth/y[2]:1,V=!!q&&_r(q.depthUnits,U),K=i.color||"#607d8b",Y=i.hideOpenings?[]:g.map(t=>{const e=t.opening,i="passage"!==e.type&&e.contact?a.states?.[e.contact]?.state:null,s=gi(e.type,i,!!e.invert),n=s>0&&!!e.contact,o="gate"===e.type?!e.flip_v:!!e.flip_v,r={type:e.type,length:t.length,angle:t.angle,amount:s,flipH:!!e.flip_h,flipV:!!e.flip_v,base:K,tone:n?"var(--hp-open)":K,cellCm:_,gridPitch:Jl,face:od(t,o)};return W` ${Xd(r)} `});return j` -
- ${tr(E)} + style="aspect-ratio:${y[2]}/${y[3]}${E?";background:"+E:""};--wall-fill:${s.wall_fill.c};--wall-fill-op:${s.wall_fill.a}${I?`;${Qa(I)}`:""}"> + ${tr(I)} - ${U?W` + ${q?W` - + `:G} - ${q.map(t=>"path"in t?W``:"poly"in t?W``:W``)} - ${A?W`t.assetLoaded?.(e.bg.href,A)} + ${B.map(t=>"path"in t?W``:"poly"in t?W``:W``)} + ${R?W`t.assetLoaded?.(e.bg.href,R)} transform=${e.bg.angle?`rotate(${e.bg.angle} ${e.bg.x+e.bg.w/2} ${e.bg.y+e.bg.h/2})`:G} preserveAspectRatio="none" />`:G} ${S} - ${L} + ${N} ${M.length?W``:G} - ${B} - ${D} - ${U?W` - + - + `:G} - ${X} + ${Y} ${""} -
${P}${R}
+
${T}${P}
`}let mu=null,fu=null,vu=0,yu=-1,bu=null,wu=[];const ku=new Set,xu=(t,e)=>{"function"==typeof t&&e.push(t)};function $u(){if(mu)return mu;try{const t=JSON.parse(localStorage.getItem("houseplan_card_cfg_v1")||"null");if(t&&t.config&&Array.isArray(t.config.spaces)){const e=t.layout||{};return{config:t.config,rev:t.rev||0,configFingerprint:t.config_fingerprint||ih(t.config),layout:e,layoutRev:t.layout_rev||0,layoutFingerprint:t.layout_fingerprint||ih(e),virtualLights:gn(t.virtual_lights,t.rev||0)}}}catch{}return null}function Su(t,e=!1){if(e&&(mu=null,vu++,fu))return fu.catch(()=>null).then(()=>Su(t,!1));if(mu)return Promise.resolve(mu);if(fu)return yu!==vu?fu.catch(()=>null).then(()=>Su(t,!1)):fu;return yu=vu,fu=async function(t,e){const[i,s]=await Promise.all([t.callWS({type:"houseplan/config/get"}),t.callWS({type:"houseplan/layout/get"})]),n=i?.rev??0,o=mu?mn(mu.virtualLights,i?.virtual_lights,n,!!i&&"virtual_lights"in i):gn(i?.virtual_lights,n),a={config:i?.config??null,rev:n,configFingerprint:ih(i?.config??null),layout:s?.layout??{},layoutRev:s?.rev??0,layoutFingerprint:ih(s?.layout??{}),virtualLights:o};e===vu&&(mu=a);const r=t.connection;if(r?.subscribeEvents&&bu!==r){for(const t of wu)t();wu=[],bu=r;const t=()=>{mu=null,vu++,ku.forEach(t=>t())},e=[];try{if(xu(await r.subscribeEvents(t,"houseplan_config_updated"),e),xu(await r.subscribeEvents(t,"houseplan_layout_updated"),e),xu(await r.subscribeEvents(t=>{if(mu){const e=wn(mu.virtualLights,t?.data);if(e===mu.virtualLights)return;mu={...mu,virtualLights:e}}else vu++;ku.forEach(t=>t())},"houseplan_virtual_light_updated"),e),bu===r)wu=e;else for(const t of e)t()}catch{for(const t of e)t();bu===r&&(bu=null)}}return a}(t,vu).finally(()=>{fu=null,yu=-1}),fu}const Mu=3300;function Cu(t,e){return{sources:t,last:Object.fromEntries(e.map(t=>[t.eid,t.state])),flashTs:0,flashKind:null,timer:0,gen:0,expiresAt:0,alarmActive:"alarm"===dn(e).status}}function Du(t,e,i,s){s(t.timer);const n=Cu(e,i);Object.assign(t,n)}function Tu(t,e,i,s,n){t.flashTs&&i-t.flashTs"transition"===t.activity)&&(i(t.timer),t.flashTs=0,t.flashKind=null,t.expiresAt=0);if("alarm"===dn(e).status){t.alarmActive||(i(t.timer),t.flashTs=0,t.flashKind=null,t.expiresAt=0);for(const i of e)t.last[i.eid]=i.state;return t.alarmActive=!0,null}if(t.alarmActive){for(const i of e)t.last[i.eid]=i.state;return t.alarmActive=!1,null}let s=null;for(const i of e){const e=un(t.last[i.eid],i);("event"===e||!s&&e)&&(s=e),t.last[i.eid]=i.state}return s}class Ru extends ht{constructor(){super(...arguments),this._spaces=null,this._spacesLoading=!1}setConfig(t){this._config=t}async _loadSpaces(){if(!this._spaces&&!this._spacesLoading&&this.hass){this._spacesLoading=!0;try{const t=await this.hass.callWS({type:"houseplan/config/get"});this._spaces=(t?.config?.spaces||[]).map(t=>({value:t.id,label:t.title||t.id}))}catch{this._spaces=[]}finally{this._spacesLoading=!1}}}get _lang(){return sa(this.hass,this._config?.language)}get _schema(){const t=this._spaces||[];return[t.length?{name:"space",selector:{select:{mode:"dropdown",options:t}}}:{name:"space",selector:{text:{}}},{name:"title",selector:{text:{}}},{name:"show_button",selector:{boolean:{}}},{name:"button_label",selector:{text:{}}},{name:"button_target",selector:{text:{}}},{name:"icon_size",selector:{number:{min:1,max:6,step:.1,mode:"box"}}},{name:"show_temperature",selector:{boolean:{}}},{name:"live_states",selector:{boolean:{}}},{name:"show_signal",selector:{boolean:{}}}]}render(){if(!this.hass||!this._config)return G;this._loadSpaces();const t=this._lang,e={space:na(t,"editor.space"),title:na(t,"editor.title"),show_button:na(t,"editor.show_button"),button_label:na(t,"editor.button_label"),button_target:na(t,"editor.button_target"),icon_size:na(t,"editor.icon_size"),show_temperature:na(t,"editor.show_temperature"),live_states:na(t,"editor.live_states"),show_signal:na(t,"editor.show_signal")};return j``:W``});return W``}_renderSvgRoomLabels(t,e){return"iso"===this._renderProjection||t.bg||e.showNames||this._markup?W``:W`${t.rooms.map(t=>{const e=this._roomCenter(t);return W`${t.name}`})}`}_renderWallBodies(t){if("iso"===this._renderProjection)return W``;if(t&&!t.showBorders&&("view"===this._mode||"devices"===this._mode))return W``;const e=this._wallUnionGeometry();if(!e)return W``;const i=this._stageEl,s=this._viewOr(this._baseVb()),n=i&&i.clientWidth&&s.w?i.clientWidth/s.w:1,o=t?.color||"#607d8b",a=_r(e.depthUnits,n),r=this._fillColors.wall_fill;return W` + fill=${a.color} fill-opacity=${a.opacity} pointer-events="none">`});return W``}_renderWallBodies(t){if("iso"===this._renderProjection)return W``;if(t&&!t.showBorders&&("view"===this._mode||"devices"===this._mode))return W``;const e=this._wallUnionGeometry();if(!e)return W``;const i=this._stageEl,s=this._viewOr(this._baseVb()),n=i&&i.clientWidth&&s.w?i.clientWidth/s.w:1,o=t?.color||"#607d8b",a=_r(e.depthUnits,n),r=this._fillColors.wall_fill;return W` @@ -5560,7 +5547,6 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="51c4bdb005b2539779085578bcce5ee1b4b3 ${this._renderOpeningTunnelFills(i,u)} ${this._renderGlowBaseRooms(i,p)} ${this._renderOpeningTunnelFills(i,p,"glow-base")} - ${this._renderSvgRoomLabels(i,c)} ${A?this._renderGlowLayer(i,c):G} ${this._renderSunRays(i)} ${this._editing?W`${this._renderMeasureLabel(f)}
`:G} diff --git a/demo/smoke_hide_room_names.mjs b/demo/smoke_hide_room_names.mjs new file mode 100644 index 00000000..037903d5 --- /dev/null +++ b/demo/smoke_hide_room_names.mjs @@ -0,0 +1,152 @@ +// #203: `show_names:false` means no permanent room labels in every read-only +// renderer. Plan keeps its editor-only card and saving never discards layout. +import { launch, checkAll, finish } from './serve.mjs'; + +const { page, browser } = await launch({ width: 1000, height: 850 }); +const out = await page.evaluate(async () => { + const card = window.__card; + const root = (node = card) => node.renderRoot || node.shadowRoot; + const frame = () => new Promise((done) => requestAnimationFrame(() => requestAnimationFrame(done))); + const settle = async () => { await card.updateComplete; await frame(); }; + const waitMode = async () => { + await settle(); + while (card._modeTransitionBusy) await frame(); + }; + const labels = (node = card) => root(node).querySelectorAll('[data-hp="room-label"]'); + const htmlLabels = (node = card) => root(node).querySelectorAll('div.roomlabel[data-hp="room-label"]'); + const svgLabels = (node = card) => root(node).querySelectorAll('text.rlabel[data-hp="room-label"]'); + + card._setMode('view'); + await waitMode(); + const space = card._serverCfg.spaces.find((item) => item.id === card._space); + delete space.plan_url; + delete space.plan_aspect; + const room = space.rooms.find((item) => item.name && item.id && item.area) + || space.rooms.find((item) => item.name && item.id); + if (!room) throw new Error('fixture has no named room'); + space.settings = { + ...(space.settings || {}), show_borders: true, show_names: true, + label_temp: true, label_hum: true, label_lqi: true, label_light: true, + }; + const layoutKey = `rl_${room.id}`; + card._layout[layoutKey] = { s: space.id, x: 0.23, y: 0.31, k: 1.6 }; + card._cfgEpoch++; + card._regSignature = ''; + card.requestUpdate(); + await settle(); + + const first = root().querySelector(`[data-hp="room-label"][data-id="${room.id}"]`); + const savedLayout = JSON.stringify(card._layout[layoutKey]); + const trueState = { + oneHtmlPerNamedRoom: htmlLabels().length === space.rooms.filter((item) => item.name).length, + noLegacySvg: svgLabels().length === 0, + savedScaleApplied: first?.getAttribute('style')?.includes('--rl-scale:1.6') === true, + areaIconKept: !room.area || !!first?.querySelector('.rlgo'), + }; + + // Cancel: the live preview follows the pending false, but persisted config + // and the room-label layout return untouched when the dialog is dismissed. + card._openSpaceDialog('edit', space.id); + card._spaceDialog = { ...card._spaceDialog, showNames: false }; + card.requestUpdate(); + await settle(); + const livePreviewHidesAll = labels().length === 0; + card._spaceDialog = null; + card.requestUpdate(); + await settle(); + const cancelRestoresTrue = space.settings.show_names === true && htmlLabels().length > 0 + && JSON.stringify(card._layout[layoutKey]) === savedLayout; + + // Save + reopen: exercise the real existing-space persistence path. + card._openSpaceDialog('edit', space.id); + card._spaceDialog = { ...card._spaceDialog, showNames: false }; + await card._saveSpaceDialog(); + await settle(); + card._openSpaceDialog('edit', space.id); + const reopenReadsFalse = card._spaceDialog?.showNames === false + && space.settings.show_names === false; + card._spaceDialog = null; + card.requestUpdate(); + await settle(); + + const flatFalseHasNoLabels = labels().length === 0 + && htmlLabels().length === 0 && svgLabels().length === 0; + + card._setMode('plan'); + await waitMode(); + const planFalseKeepsEditorCard = htmlLabels().length > 0 + && svgLabels().length === 0 && !!root().querySelector('.rlgearbtn'); + card._setMode('view'); + await waitMode(); + const viewAfterPlanStillHidden = labels().length === 0; + + // The Labs registry flag is intentionally expired; use the same dormant + // renderer fixture hook as the canonical Stage 2 smokes. + const active = Object.freeze(['iso']); + card._onLabsSnapshot({ active, space: '' }); + window.__hpLabs = active; + await settle(); + card._setProjection('iso'); + await settle(); + const isoFalseHasNoLabels = !!root().querySelector('[data-hp="iso-walls"]') + && labels().length === 0; + card._setProjection('flat'); + await settle(); + + await customElements.whenDefined('houseplan-space-card'); + const cfgFalse = structuredClone(card._serverCfg); + const layout = structuredClone(card._layout); + const staticHass = { + ...card.hass, + callWS: async (message) => { + if (message.type === 'houseplan/config/get') return { config: cfgFalse, rev: 1 }; + if (message.type === 'houseplan/layout/get') return { layout, rev: 1 }; + return { ok: true }; + }, + }; + const host = document.createElement('div'); + document.body.appendChild(host); + const compact = document.createElement('houseplan-space-card'); + compact.setConfig({ type: 'custom:houseplan-space-card', space: space.id, show_button: false }); + compact.hass = staticHass; + host.appendChild(compact); + const deadline = Date.now() + 6000; + while (!root(compact)?.querySelector('.hp-static-stage') && Date.now() < deadline) { + await new Promise((done) => setTimeout(done, 60)); + } + await compact.updateComplete; + const compactFalseHasNoLabels = labels(compact).length === 0 + && htmlLabels(compact).length === 0 && svgLabels(compact).length === 0; + + // Turning names back on restores the existing HTML card and saved layout. + space.settings.show_names = true; + card._cfgEpoch++; + card.requestUpdate(); + await settle(); + const restored = root().querySelector(`[data-hp="room-label"][data-id="${room.id}"]`); + const trueRestoresExistingCard = !!restored + && restored.tagName.toLowerCase() === 'div' + && restored.getAttribute('style')?.includes('--rl-scale:1.6') === true + && JSON.stringify(card._layout[layoutKey]) === savedLayout; + + host.remove(); + card._onLabsSnapshot({ active: Object.freeze([]), space: '' }); + window.__hpLabs = Object.freeze([]); + await settle(); + + return { + ...trueState, + livePreviewHidesAll, + cancelRestoresTrue, + reopenReadsFalse, + flatFalseHasNoLabels, + planFalseKeepsEditorCard, + viewAfterPlanStillHidden, + isoFalseHasNoLabels, + compactFalseHasNoLabels, + trueRestoresExistingCard, + }; +}); + +checkAll(out); +await finish(browser, out); diff --git a/demo/smoke_styling_hooks.mjs b/demo/smoke_styling_hooks.mjs index 99e6287e..08c0b770 100644 --- a/demo/smoke_styling_hooks.mjs +++ b/demo/smoke_styling_hooks.mjs @@ -3,7 +3,7 @@ // НАХОДЯТСЯ через querySelector — ровно так, как их будет искать чужой CSS. // 1) устройство: data-hp="device" + data-id + data-entity + data-area; // 2) комната: data-hp="room" + data-id + data-area; -// 3) подпись комнаты: data-hp="room-label" + data-id (и в SVG, и в HTML-карточке); +// 3) видимая подпись комнаты: data-hp="room-label" + data-id на HTML-карточке; // 4) проём: data-hp="opening" + data-id + data-kind (door/window/gate); // 5) декор: data-hp="decor" + data-id + data-kind (line/rect/ellipse/text); // 6) вкладка пространства: data-hp="space-tab" + data-id; @@ -50,8 +50,8 @@ const res = await page.evaluate(async () => { out.roomIsAnSvgShape = !!kitchen && ['polygon', 'rect', 'path'].includes(kitchen.tagName.toLowerCase()); // ============ 3. подписи комнат ============ - // одно имя — две разные реализации: в SVG на плане без подложки и - // HTML-карточка, когда включены «имена на плане». Хук на обеих один и тот же. + // #203: false означает отсутствие подписи, а не вторую SVG-реализацию. + // При true единственный публичный hook живёт на HTML-карточке. const disp = c._curSpaceCfg.settings || (c._curSpaceCfg.settings = {}); const wasNames = disp.show_names; const planUrl = c._curSpaceCfg.plan_url; @@ -60,11 +60,8 @@ const res = await page.evaluate(async () => { await c.updateComplete; await sleep(60); await c.updateComplete; }; delete c._curSpaceCfg.plan_url; disp.show_names = false; await redraw(); - const svgLabels = qa('text.rlabel[data-hp="room-label"]'); - out.svgRoomLabelHooked = svgLabels.length > 0 - && svgLabels.every((e) => !!e.getAttribute('data-id')); - out.svgRoomLabelFoundById = !!q('text[data-hp="room-label"][data-id="r1"]'); - out.svgRoomLabelHasArea = q('text[data-hp="room-label"][data-id="r1"]')?.getAttribute('data-area') === 'living_room'; + out.hiddenRoomLabelsAreAbsent = qa('[data-hp="room-label"]').length === 0 + && qa('text.rlabel').length === 0; c._curSpaceCfg.plan_url = planUrl; disp.show_names = true; await redraw(); const htmlLabel = q('div.roomlabel[data-hp="room-label"][data-id="r2"]'); out.htmlRoomLabelHooked = !!htmlLabel; diff --git a/demo/srv/assets/houseplan-card.js b/demo/srv/assets/houseplan-card.js index f9ecb54e..aefea4d6 100755 --- a/demo/srv/assets/houseplan-card.js +++ b/demo/srv/assets/houseplan-card.js @@ -1,4 +1,4 @@ -globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="51c4bdb005b2539779085578bcce5ee1b4b3e3137542ef1aeb440232344c3105";const t=globalThis,e=t.ShadowRoot&&(void 0===t.ShadyCSS||t.ShadyCSS.nativeShadow)&&"adoptedStyleSheets"in Document.prototype&&"replace"in CSSStyleSheet.prototype,i=Symbol(),s=new WeakMap;let n=class{constructor(t,e,s){if(this._$cssResult$=!0,s!==i)throw Error("CSSResult is not constructable. Use `unsafeCSS` or `css` instead.");this.cssText=t,this.t=e}get styleSheet(){let t=this.o;const i=this.t;if(e&&void 0===t){const e=void 0!==i&&1===i.length;e&&(t=s.get(i)),void 0===t&&((this.o=t=new CSSStyleSheet).replaceSync(this.cssText),e&&s.set(i,t))}return t}toString(){return this.cssText}};const o=(t,...e)=>{const s=1===t.length?t[0]:e.reduce((e,i,s)=>e+(t=>{if(!0===t._$cssResult$)return t.cssText;if("number"==typeof t)return t;throw Error("Value passed to 'css' function must be a 'css' function result: "+t+". Use 'unsafeCSS' to pass non-literal values, but take care to ensure page security.")})(i)+t[s+1],t[0]);return new n(s,t,i)},a=e?t=>t:t=>t instanceof CSSStyleSheet?(t=>{let e="";for(const i of t.cssRules)e+=i.cssText;return(t=>new n("string"==typeof t?t:t+"",void 0,i))(e)})(t):t,{is:r,defineProperty:l,getOwnPropertyDescriptor:c,getOwnPropertyNames:h,getOwnPropertySymbols:d,getPrototypeOf:u}=Object,p=globalThis,_=p.trustedTypes,g=_?_.emptyScript:"",m=p.reactiveElementPolyfillSupport,f=(t,e)=>t,v={toAttribute(t,e){switch(e){case Boolean:t=t?g:null;break;case Object:case Array:t=null==t?t:JSON.stringify(t)}return t},fromAttribute(t,e){let i=t;switch(e){case Boolean:i=null!==t;break;case Number:i=null===t?null:Number(t);break;case Object:case Array:try{i=JSON.parse(t)}catch(t){i=null}}return i}},y=(t,e)=>!r(t,e),b={attribute:!0,type:String,converter:v,reflect:!1,useDefault:!1,hasChanged:y};Symbol.metadata??=Symbol("metadata"),p.litPropertyMetadata??=new WeakMap;let w=class extends HTMLElement{static addInitializer(t){this._$Ei(),(this.l??=[]).push(t)}static get observedAttributes(){return this.finalize(),this._$Eh&&[...this._$Eh.keys()]}static createProperty(t,e=b){if(e.state&&(e.attribute=!1),this._$Ei(),this.prototype.hasOwnProperty(t)&&((e=Object.create(e)).wrapped=!0),this.elementProperties.set(t,e),!e.noAccessor){const i=Symbol(),s=this.getPropertyDescriptor(t,i,e);void 0!==s&&l(this.prototype,t,s)}}static getPropertyDescriptor(t,e,i){const{get:s,set:n}=c(this.prototype,t)??{get(){return this[e]},set(t){this[e]=t}};return{get:s,set(e){const o=s?.call(this);n?.call(this,e),this.requestUpdate(t,o,i)},configurable:!0,enumerable:!0}}static getPropertyOptions(t){return this.elementProperties.get(t)??b}static _$Ei(){if(this.hasOwnProperty(f("elementProperties")))return;const t=u(this);t.finalize(),void 0!==t.l&&(this.l=[...t.l]),this.elementProperties=new Map(t.elementProperties)}static finalize(){if(this.hasOwnProperty(f("finalized")))return;if(this.finalized=!0,this._$Ei(),this.hasOwnProperty(f("properties"))){const t=this.properties,e=[...h(t),...d(t)];for(const i of e)this.createProperty(i,t[i])}const t=this[Symbol.metadata];if(null!==t){const e=litPropertyMetadata.get(t);if(void 0!==e)for(const[t,i]of e)this.elementProperties.set(t,i)}this._$Eh=new Map;for(const[t,e]of this.elementProperties){const i=this._$Eu(t,e);void 0!==i&&this._$Eh.set(i,t)}this.elementStyles=this.finalizeStyles(this.styles)}static finalizeStyles(t){const e=[];if(Array.isArray(t)){const i=new Set(t.flat(1/0).reverse());for(const t of i)e.unshift(a(t))}else void 0!==t&&e.push(a(t));return e}static _$Eu(t,e){const i=e.attribute;return!1===i?void 0:"string"==typeof i?i:"string"==typeof t?t.toLowerCase():void 0}constructor(){super(),this._$Ep=void 0,this.isUpdatePending=!1,this.hasUpdated=!1,this._$Em=null,this._$Ev()}_$Ev(){this._$ES=new Promise(t=>this.enableUpdating=t),this._$AL=new Map,this._$E_(),this.requestUpdate(),this.constructor.l?.forEach(t=>t(this))}addController(t){(this._$EO??=new Set).add(t),void 0!==this.renderRoot&&this.isConnected&&t.hostConnected?.()}removeController(t){this._$EO?.delete(t)}_$E_(){const t=new Map,e=this.constructor.elementProperties;for(const i of e.keys())this.hasOwnProperty(i)&&(t.set(i,this[i]),delete this[i]);t.size>0&&(this._$Ep=t)}createRenderRoot(){const i=this.shadowRoot??this.attachShadow(this.constructor.shadowRootOptions);return((i,s)=>{if(e)i.adoptedStyleSheets=s.map(t=>t instanceof CSSStyleSheet?t:t.styleSheet);else for(const e of s){const s=document.createElement("style"),n=t.litNonce;void 0!==n&&s.setAttribute("nonce",n),s.textContent=e.cssText,i.appendChild(s)}})(i,this.constructor.elementStyles),i}connectedCallback(){this.renderRoot??=this.createRenderRoot(),this.enableUpdating(!0),this._$EO?.forEach(t=>t.hostConnected?.())}enableUpdating(t){}disconnectedCallback(){this._$EO?.forEach(t=>t.hostDisconnected?.())}attributeChangedCallback(t,e,i){this._$AK(t,i)}_$ET(t,e){const i=this.constructor.elementProperties.get(t),s=this.constructor._$Eu(t,i);if(void 0!==s&&!0===i.reflect){const n=(void 0!==i.converter?.toAttribute?i.converter:v).toAttribute(e,i.type);this._$Em=t,null==n?this.removeAttribute(s):this.setAttribute(s,n),this._$Em=null}}_$AK(t,e){const i=this.constructor,s=i._$Eh.get(t);if(void 0!==s&&this._$Em!==s){const t=i.getPropertyOptions(s),n="function"==typeof t.converter?{fromAttribute:t.converter}:void 0!==t.converter?.fromAttribute?t.converter:v;this._$Em=s;const o=n.fromAttribute(e,t.type);this[s]=o??this._$Ej?.get(s)??o,this._$Em=null}}requestUpdate(t,e,i,s=!1,n){if(void 0!==t){const o=this.constructor;if(!1===s&&(n=this[t]),i??=o.getPropertyOptions(t),!((i.hasChanged??y)(n,e)||i.useDefault&&i.reflect&&n===this._$Ej?.get(t)&&!this.hasAttribute(o._$Eu(t,i))))return;this.C(t,e,i)}!1===this.isUpdatePending&&(this._$ES=this._$EP())}C(t,e,{useDefault:i,reflect:s,wrapped:n},o){i&&!(this._$Ej??=new Map).has(t)&&(this._$Ej.set(t,o??e??this[t]),!0!==n||void 0!==o)||(this._$AL.has(t)||(this.hasUpdated||i||(e=void 0),this._$AL.set(t,e)),!0===s&&this._$Em!==t&&(this._$Eq??=new Set).add(t))}async _$EP(){this.isUpdatePending=!0;try{await this._$ES}catch(t){Promise.reject(t)}const t=this.scheduleUpdate();return null!=t&&await t,!this.isUpdatePending}scheduleUpdate(){return this.performUpdate()}performUpdate(){if(!this.isUpdatePending)return;if(!this.hasUpdated){if(this.renderRoot??=this.createRenderRoot(),this._$Ep){for(const[t,e]of this._$Ep)this[t]=e;this._$Ep=void 0}const t=this.constructor.elementProperties;if(t.size>0)for(const[e,i]of t){const{wrapped:t}=i,s=this[e];!0!==t||this._$AL.has(e)||void 0===s||this.C(e,void 0,i,s)}}let t=!1;const e=this._$AL;try{t=this.shouldUpdate(e),t?(this.willUpdate(e),this._$EO?.forEach(t=>t.hostUpdate?.()),this.update(e)):this._$EM()}catch(e){throw t=!1,this._$EM(),e}t&&this._$AE(e)}willUpdate(t){}_$AE(t){this._$EO?.forEach(t=>t.hostUpdated?.()),this.hasUpdated||(this.hasUpdated=!0,this.firstUpdated(t)),this.updated(t)}_$EM(){this._$AL=new Map,this.isUpdatePending=!1}get updateComplete(){return this.getUpdateComplete()}getUpdateComplete(){return this._$ES}shouldUpdate(t){return!0}update(t){this._$Eq&&=this._$Eq.forEach(t=>this._$ET(t,this[t])),this._$EM()}updated(t){}firstUpdated(t){}};w.elementStyles=[],w.shadowRootOptions={mode:"open"},w[f("elementProperties")]=new Map,w[f("finalized")]=new Map,m?.({ReactiveElement:w}),(p.reactiveElementVersions??=[]).push("2.1.2");const k=globalThis,x=t=>t,$=k.trustedTypes,S=$?$.createPolicy("lit-html",{createHTML:t=>t}):void 0,M="$lit$",C=`lit$${Math.random().toFixed(9).slice(2)}$`,D="?"+C,T=`<${D}>`,P=document,R=()=>P.createComment(""),A=t=>null===t||"object"!=typeof t&&"function"!=typeof t,I=Array.isArray,E="[ \t\n\f\r]",F=/<(?:(!--|\/[^a-zA-Z])|(\/?[a-zA-Z][^>\s]*)|(\/?$))/g,z=/-->/g,O=/>/g,H=RegExp(`>|${E}(?:([^\\s"'>=/]+)(${E}*=${E}*(?:[^ \t\n\f\r"'\`<>=]|("|')|))|$)`,"g"),N=/'/g,L=/"/g,B=/^(?:script|style|textarea|title)$/i,q=t=>(e,...i)=>({_$litType$:t,strings:e,values:i}),j=q(1),W=q(2),U=Symbol.for("lit-noChange"),G=Symbol.for("lit-nothing"),V=new WeakMap,K=P.createTreeWalker(P,129);function Y(t,e){if(!I(t)||!t.hasOwnProperty("raw"))throw Error("invalid template strings array");return void 0!==S?S.createHTML(e):e}const X=(t,e)=>{const i=t.length-1,s=[];let n,o=2===e?"":3===e?"":"",a=F;for(let e=0;e"===l[0]?(a=n??F,c=-1):void 0===l[1]?c=-2:(c=a.lastIndex-l[2].length,r=l[1],a=void 0===l[3]?H:'"'===l[3]?L:N):a===L||a===N?a=H:a===z||a===O?a=F:(a=H,n=void 0);const d=a===H&&t[e+1].startsWith("/>")?" ":"";o+=a===F?i+T:c>=0?(s.push(r),i.slice(0,c)+M+i.slice(c)+C+d):i+C+(-2===c?e:d)}return[Y(t,o+(t[i]||"")+(2===e?"":3===e?"":"")),s]};class J{constructor({strings:t,_$litType$:e},i){let s;this.parts=[];let n=0,o=0;const a=t.length-1,r=this.parts,[l,c]=X(t,e);if(this.el=J.createElement(l,i),K.currentNode=this.el.content,2===e||3===e){const t=this.el.content.firstChild;t.replaceWith(...t.childNodes)}for(;null!==(s=K.nextNode())&&r.length0){s.textContent=$?$.emptyScript:"";for(let i=0;iI(t)||"function"==typeof t?.[Symbol.iterator])(t)?this.k(t):this._(t)}O(t){return this._$AA.parentNode.insertBefore(t,this._$AB)}T(t){this._$AH!==t&&(this._$AR(),this._$AH=this.O(t))}_(t){this._$AH!==G&&A(this._$AH)?this._$AA.nextSibling.data=t:this.T(P.createTextNode(t)),this._$AH=t}$(t){const{values:e,_$litType$:i}=t,s="number"==typeof i?this._$AC(t):(void 0===i.el&&(i.el=J.createElement(Y(i.h,i.h[0]),this.options)),i);if(this._$AH?._$AD===s)this._$AH.p(e);else{const t=new Q(s,this),i=t.u(this.options);t.p(e),this.T(i),this._$AH=t}}_$AC(t){let e=V.get(t.strings);return void 0===e&&V.set(t.strings,e=new J(t)),e}k(t){I(this._$AH)||(this._$AH=[],this._$AR());const e=this._$AH;let i,s=0;for(const n of t)s===e.length?e.push(i=new tt(this.O(R()),this.O(R()),this,this.options)):i=e[s],i._$AI(n),s++;s2||""!==i[0]||""!==i[1]?(this._$AH=Array(i.length-1).fill(new String),this.strings=i):this._$AH=G}_$AI(t,e=this,i,s){const n=this.strings;let o=!1;if(void 0===n)t=Z(this,t,e,0),o=!A(t)||t!==this._$AH&&t!==U,o&&(this._$AH=t);else{const s=t;let a,r;for(t=n[0],a=0;a{const s=i?.renderBefore??e;let n=s._$litPart$;if(void 0===n){const t=i?.renderBefore??null;s._$litPart$=n=new tt(e.insertBefore(R(),t),t,void 0,i??{})}return n._$AI(t),n},ct=globalThis;let ht=class extends w{constructor(){super(...arguments),this.renderOptions={host:this},this._$Do=void 0}createRenderRoot(){const t=super.createRenderRoot();return this.renderOptions.renderBefore??=t.firstChild,t}update(t){const e=this.render();this.hasUpdated||(this.renderOptions.isConnected=this.isConnected),super.update(t),this._$Do=lt(e,this.renderRoot,this.renderOptions)}connectedCallback(){super.connectedCallback(),this._$Do?.setConnected(!0)}disconnectedCallback(){super.disconnectedCallback(),this._$Do?.setConnected(!1)}render(){return U}};ht._$litElement$=!0,ht.finalized=!0,ct.litElementHydrateSupport?.({LitElement:ht});const dt=ct.litElementPolyfillSupport;dt?.({LitElement:ht}),(ct.litElementVersions??=[]).push("4.2.2");const ut=2,pt=t=>(...e)=>({_$litDirective$:t,values:e});let _t=class{constructor(t){}get _$AU(){return this._$AM._$AU}_$AT(t,e,i){this._$Ct=t,this._$AM=e,this._$Ci=i}_$AS(t,e){return this.update(t,e)}update(t,e){return this.render(...e)}};const gt={},mt=pt(class extends _t{constructor(){super(...arguments),this.ot=gt}render(t,e){return e()}update(t,[e,i]){if(Array.isArray(e)){if(Array.isArray(this.ot)&&this.ot.length===e.length&&e.every((t,e)=>t===this.ot[e]))return U}else if(this.ot===e)return U;return this.ot=Array.isArray(e)?Array.from(e):e,this.render(e,i)}}),{I:ft}=at,vt=t=>t,yt=()=>document.createComment(""),bt=(t,e,i)=>{const s=t._$AA.parentNode,n=void 0===e?t._$AB:e._$AA;if(void 0===i){const e=s.insertBefore(yt(),n),o=s.insertBefore(yt(),n);i=new ft(e,o,t,t.options)}else{const e=i._$AB.nextSibling,o=i._$AM,a=o!==t;if(a){let e;i._$AQ?.(t),i._$AM=t,void 0!==i._$AP&&(e=t._$AU)!==o._$AU&&i._$AP(e)}if(e!==n||a){let t=i._$AA;for(;t!==e;){const e=vt(t).nextSibling;vt(s).insertBefore(t,n),t=e}}}return i},wt=(t,e,i=t)=>(t._$AI(e,i),t),kt={},xt=(t,e=kt)=>t._$AH=e,$t=t=>{t._$AR(),t._$AA.remove()},St=(t,e,i)=>{const s=new Map;for(let n=e;n<=i;n++)s.set(t[n],n);return s},Mt=pt(class extends _t{constructor(t){if(super(t),t.type!==ut)throw Error("repeat() can only be used in text expressions")}dt(t,e,i){let s;void 0===i?i=e:void 0!==e&&(s=e);const n=[],o=[];let a=0;for(const e of t)n[a]=s?s(e,a):a,o[a]=i(e,a),a++;return{values:o,keys:n}}render(t,e,i){return this.dt(t,e,i).values}update(t,[e,i,s]){const n=(t=>t._$AH)(t),{values:o,keys:a}=this.dt(e,i,s);if(!Array.isArray(n))return this.ut=a,o;const r=this.ut??=[],l=[];let c,h,d=0,u=n.length-1,p=0,_=o.length-1;for(;d<=u&&p<=_;)if(null===n[d])d++;else if(null===n[u])u--;else if(r[d]===a[p])l[p]=wt(n[d],o[p]),d++,p++;else if(r[u]===a[_])l[_]=wt(n[u],o[_]),u--,_--;else if(r[d]===a[_])l[_]=wt(n[d],o[_]),bt(t,l[_+1],n[d]),d++,_--;else if(r[u]===a[p])l[p]=wt(n[u],o[p]),bt(t,n[d],n[u]),u--,p++;else if(void 0===c&&(c=St(a,p,_),h=St(r,d,u)),c.has(r[d]))if(c.has(r[u])){const e=h.get(a[p]),i=void 0!==e?n[e]:null;if(null===i){const e=bt(t,n[d]);wt(e,o[p]),l[p]=e}else l[p]=wt(i,o[p]),bt(t,n[d],i),n[e]=null;p++}else $t(n[u]),u--;else $t(n[d]),d++;for(;p<=_;){const e=bt(t,l[_+1]);wt(e,o[p]),l[p++]=e}for(;d<=u;){const t=n[d++];null!==t&&$t(t)}return this.ut=a,xt(t,l),U}}),Ct=new WeakMap;let Dt=0;class Tt extends ht{constructor(){super(...arguments),this.title="",this.icon="",this.wide=!1,this.dismissOnScrim=!1,this.hass=null,this._opener=null,this._focusRoot=null,this._useHaDialog=!1,this._closing=!1,this._overlays=[],this._titleId="hp-dialog-title-"+ ++Dt,this._focusInitial=()=>{const t=this._focusableElements(),e=t.find(t=>t.hasAttribute("autofocus"))||t[0]||(this._useHaDialog?null:this.renderRoot.querySelector(".close"))||this.renderRoot.querySelector(".surface")||this.renderRoot.querySelector("ha-dialog");e?.focus({preventScroll:!0})},this._requestClose=()=>{this._closing||(this._closing=!0,this.dispatchEvent(new CustomEvent("hp-close",{bubbles:!0,composed:!0})))},this._onKeyDown=t=>{if("Escape"===t.key){t.preventDefault(),t.stopImmediatePropagation(),this._pruneOverlays();const e=this._overlays[this._overlays.length-1];return e?void this._closeOverlay(e,"escape"):void this._requestClose()}if("Tab"!==t.key||this._useHaDialog)return;const e=this.renderRoot.querySelector(".close"),i=e?[e,...this._focusableElements()]:this._focusableElements();if(!i.length)return t.preventDefault(),void this.renderRoot.querySelector(".surface")?.focus({preventScroll:!0});const s=this._deepActiveElement(),n=i[0],o=i[i.length-1];!t.shiftKey||s!==n&&i.includes(s)?t.shiftKey||s!==o||(t.preventDefault(),n.focus()):(t.preventDefault(),o.focus())},this._onFallbackCancel=t=>{t.preventDefault(),this._requestClose()},this._onFallbackClick=t=>{this.dismissOnScrim&&t.target===t.currentTarget&&this._requestClose()}}connectedCallback(){super.connectedCallback(),this._opener=this._deepActiveElement();const t=this.getRootNode();this._focusRoot=t;const e=Ct.get(t)||{dialogs:new Set,opener:this._opener};e.dialogs.add(this),Ct.set(t,e),this._useHaDialog=!!customElements.get("ha-dialog"),this.addEventListener("keydown",this._onKeyDown,!0)}disconnectedCallback(){this.removeEventListener("keydown",this._onKeyDown,!0);const t=[...this._overlays];this._overlays=[];for(const e of t.reverse())e.close("disconnect");const e=this._focusRoot,i=this._opener;this._opener=null,this._focusRoot=null;const s=e?Ct.get(e):void 0;s?.dialogs.delete(this),super.disconnectedCallback(),e&&s&&requestAnimationFrame(()=>{const t=Ct.get(e);if(!t)return;if(!t.dialogs.size)return t.opener?.isConnected&&t.opener.focus({preventScroll:!0}),void Ct.delete(e);const s=i?.closest("hp-dialog");i?.isConnected&&s&&t.dialogs.has(s)&&i.focus({preventScroll:!0})})}firstUpdated(t){if(super.firstUpdated(t),!this._useHaDialog){const t=this.renderRoot.querySelector("dialog");t&&!t.open&&t.showModal()}queueMicrotask(()=>this._focusInitial())}_deepActiveElement(){let t=document.activeElement;for(;t?.shadowRoot?.activeElement;)t=t.shadowRoot.activeElement;return t&&t!==document.body?t:null}_focusableElements(){const t=["[autofocus]","a[href]","button:not([disabled])",'input:not([disabled]):not([type="hidden"])',"select:not([disabled])","textarea:not([disabled])",'[contenteditable="true"]','[tabindex]:not([tabindex="-1"])'].join(","),e=[],i=new Set,s=n=>{if(!i.has(n)){if(i.add(n),n instanceof HTMLElement){if(n.matches(t)&&e.push(n),n instanceof HTMLSlotElement){for(const t of n.assignedNodes({flatten:!0}))s(t);return}if(n.shadowRoot){for(const t of n.shadowRoot.childNodes)s(t);return}}for(const t of n.childNodes)s(t)}};for(const t of this.childNodes)s(t);const n=this.overlayPortal();return n&&s(n),e.filter(t=>{let e=t;for(;e;){const t=getComputedStyle(e);if(e.hidden||e.inert||"true"===e.getAttribute("aria-hidden")||"none"===t.display||"hidden"===t.visibility)return!1;if(e=e.assignedSlot||e.parentElement||(e.getRootNode()instanceof ShadowRoot?e.getRootNode().host:null),e===this)break}return!0})}_pruneOverlays(){this._overlays=this._overlays.filter(t=>t.owner.isConnected)}_closeOverlay(t,e){const i=this._overlays.findIndex(e=>e.token===t.token);i>=0&&this._overlays.splice(i,1),t.close(e)}registerOverlay(t){this._pruneOverlays();const e=this._overlays.find(e=>e.owner===t.owner);e&&this._overlays.splice(this._overlays.indexOf(e),1);const i=t.group||"transient";for(const t of[...this._overlays].reverse())t.group===i&&this._closeOverlay(t,"exclusive");const s={...t,group:i,token:Symbol("hp-overlay")};this._overlays.push(s);let n=!1;return()=>{if(n)return;n=!0;const t=this._overlays.findIndex(t=>t.token===s.token);t>=0&&this._overlays.splice(t,1)}}closeTransientOverlays(t="outside"){this._pruneOverlays();const e=[...this._overlays].filter(t=>"transient"===(t.group||"transient"));for(const i of e.reverse())this._closeOverlay(i,t);return e.length>0}overlayPortal(){return this.renderRoot.querySelector(".overlay-portal")}render(){const t=j` +globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="49963a7758df03d7aaaa3af3b9f198d629f4ca44af5c8ef9834c7afce5fda8ba";const t=globalThis,e=t.ShadowRoot&&(void 0===t.ShadyCSS||t.ShadyCSS.nativeShadow)&&"adoptedStyleSheets"in Document.prototype&&"replace"in CSSStyleSheet.prototype,i=Symbol(),s=new WeakMap;let n=class{constructor(t,e,s){if(this._$cssResult$=!0,s!==i)throw Error("CSSResult is not constructable. Use `unsafeCSS` or `css` instead.");this.cssText=t,this.t=e}get styleSheet(){let t=this.o;const i=this.t;if(e&&void 0===t){const e=void 0!==i&&1===i.length;e&&(t=s.get(i)),void 0===t&&((this.o=t=new CSSStyleSheet).replaceSync(this.cssText),e&&s.set(i,t))}return t}toString(){return this.cssText}};const o=(t,...e)=>{const s=1===t.length?t[0]:e.reduce((e,i,s)=>e+(t=>{if(!0===t._$cssResult$)return t.cssText;if("number"==typeof t)return t;throw Error("Value passed to 'css' function must be a 'css' function result: "+t+". Use 'unsafeCSS' to pass non-literal values, but take care to ensure page security.")})(i)+t[s+1],t[0]);return new n(s,t,i)},a=e?t=>t:t=>t instanceof CSSStyleSheet?(t=>{let e="";for(const i of t.cssRules)e+=i.cssText;return(t=>new n("string"==typeof t?t:t+"",void 0,i))(e)})(t):t,{is:r,defineProperty:l,getOwnPropertyDescriptor:c,getOwnPropertyNames:h,getOwnPropertySymbols:d,getPrototypeOf:u}=Object,p=globalThis,_=p.trustedTypes,g=_?_.emptyScript:"",m=p.reactiveElementPolyfillSupport,f=(t,e)=>t,v={toAttribute(t,e){switch(e){case Boolean:t=t?g:null;break;case Object:case Array:t=null==t?t:JSON.stringify(t)}return t},fromAttribute(t,e){let i=t;switch(e){case Boolean:i=null!==t;break;case Number:i=null===t?null:Number(t);break;case Object:case Array:try{i=JSON.parse(t)}catch(t){i=null}}return i}},y=(t,e)=>!r(t,e),b={attribute:!0,type:String,converter:v,reflect:!1,useDefault:!1,hasChanged:y};Symbol.metadata??=Symbol("metadata"),p.litPropertyMetadata??=new WeakMap;let w=class extends HTMLElement{static addInitializer(t){this._$Ei(),(this.l??=[]).push(t)}static get observedAttributes(){return this.finalize(),this._$Eh&&[...this._$Eh.keys()]}static createProperty(t,e=b){if(e.state&&(e.attribute=!1),this._$Ei(),this.prototype.hasOwnProperty(t)&&((e=Object.create(e)).wrapped=!0),this.elementProperties.set(t,e),!e.noAccessor){const i=Symbol(),s=this.getPropertyDescriptor(t,i,e);void 0!==s&&l(this.prototype,t,s)}}static getPropertyDescriptor(t,e,i){const{get:s,set:n}=c(this.prototype,t)??{get(){return this[e]},set(t){this[e]=t}};return{get:s,set(e){const o=s?.call(this);n?.call(this,e),this.requestUpdate(t,o,i)},configurable:!0,enumerable:!0}}static getPropertyOptions(t){return this.elementProperties.get(t)??b}static _$Ei(){if(this.hasOwnProperty(f("elementProperties")))return;const t=u(this);t.finalize(),void 0!==t.l&&(this.l=[...t.l]),this.elementProperties=new Map(t.elementProperties)}static finalize(){if(this.hasOwnProperty(f("finalized")))return;if(this.finalized=!0,this._$Ei(),this.hasOwnProperty(f("properties"))){const t=this.properties,e=[...h(t),...d(t)];for(const i of e)this.createProperty(i,t[i])}const t=this[Symbol.metadata];if(null!==t){const e=litPropertyMetadata.get(t);if(void 0!==e)for(const[t,i]of e)this.elementProperties.set(t,i)}this._$Eh=new Map;for(const[t,e]of this.elementProperties){const i=this._$Eu(t,e);void 0!==i&&this._$Eh.set(i,t)}this.elementStyles=this.finalizeStyles(this.styles)}static finalizeStyles(t){const e=[];if(Array.isArray(t)){const i=new Set(t.flat(1/0).reverse());for(const t of i)e.unshift(a(t))}else void 0!==t&&e.push(a(t));return e}static _$Eu(t,e){const i=e.attribute;return!1===i?void 0:"string"==typeof i?i:"string"==typeof t?t.toLowerCase():void 0}constructor(){super(),this._$Ep=void 0,this.isUpdatePending=!1,this.hasUpdated=!1,this._$Em=null,this._$Ev()}_$Ev(){this._$ES=new Promise(t=>this.enableUpdating=t),this._$AL=new Map,this._$E_(),this.requestUpdate(),this.constructor.l?.forEach(t=>t(this))}addController(t){(this._$EO??=new Set).add(t),void 0!==this.renderRoot&&this.isConnected&&t.hostConnected?.()}removeController(t){this._$EO?.delete(t)}_$E_(){const t=new Map,e=this.constructor.elementProperties;for(const i of e.keys())this.hasOwnProperty(i)&&(t.set(i,this[i]),delete this[i]);t.size>0&&(this._$Ep=t)}createRenderRoot(){const i=this.shadowRoot??this.attachShadow(this.constructor.shadowRootOptions);return((i,s)=>{if(e)i.adoptedStyleSheets=s.map(t=>t instanceof CSSStyleSheet?t:t.styleSheet);else for(const e of s){const s=document.createElement("style"),n=t.litNonce;void 0!==n&&s.setAttribute("nonce",n),s.textContent=e.cssText,i.appendChild(s)}})(i,this.constructor.elementStyles),i}connectedCallback(){this.renderRoot??=this.createRenderRoot(),this.enableUpdating(!0),this._$EO?.forEach(t=>t.hostConnected?.())}enableUpdating(t){}disconnectedCallback(){this._$EO?.forEach(t=>t.hostDisconnected?.())}attributeChangedCallback(t,e,i){this._$AK(t,i)}_$ET(t,e){const i=this.constructor.elementProperties.get(t),s=this.constructor._$Eu(t,i);if(void 0!==s&&!0===i.reflect){const n=(void 0!==i.converter?.toAttribute?i.converter:v).toAttribute(e,i.type);this._$Em=t,null==n?this.removeAttribute(s):this.setAttribute(s,n),this._$Em=null}}_$AK(t,e){const i=this.constructor,s=i._$Eh.get(t);if(void 0!==s&&this._$Em!==s){const t=i.getPropertyOptions(s),n="function"==typeof t.converter?{fromAttribute:t.converter}:void 0!==t.converter?.fromAttribute?t.converter:v;this._$Em=s;const o=n.fromAttribute(e,t.type);this[s]=o??this._$Ej?.get(s)??o,this._$Em=null}}requestUpdate(t,e,i,s=!1,n){if(void 0!==t){const o=this.constructor;if(!1===s&&(n=this[t]),i??=o.getPropertyOptions(t),!((i.hasChanged??y)(n,e)||i.useDefault&&i.reflect&&n===this._$Ej?.get(t)&&!this.hasAttribute(o._$Eu(t,i))))return;this.C(t,e,i)}!1===this.isUpdatePending&&(this._$ES=this._$EP())}C(t,e,{useDefault:i,reflect:s,wrapped:n},o){i&&!(this._$Ej??=new Map).has(t)&&(this._$Ej.set(t,o??e??this[t]),!0!==n||void 0!==o)||(this._$AL.has(t)||(this.hasUpdated||i||(e=void 0),this._$AL.set(t,e)),!0===s&&this._$Em!==t&&(this._$Eq??=new Set).add(t))}async _$EP(){this.isUpdatePending=!0;try{await this._$ES}catch(t){Promise.reject(t)}const t=this.scheduleUpdate();return null!=t&&await t,!this.isUpdatePending}scheduleUpdate(){return this.performUpdate()}performUpdate(){if(!this.isUpdatePending)return;if(!this.hasUpdated){if(this.renderRoot??=this.createRenderRoot(),this._$Ep){for(const[t,e]of this._$Ep)this[t]=e;this._$Ep=void 0}const t=this.constructor.elementProperties;if(t.size>0)for(const[e,i]of t){const{wrapped:t}=i,s=this[e];!0!==t||this._$AL.has(e)||void 0===s||this.C(e,void 0,i,s)}}let t=!1;const e=this._$AL;try{t=this.shouldUpdate(e),t?(this.willUpdate(e),this._$EO?.forEach(t=>t.hostUpdate?.()),this.update(e)):this._$EM()}catch(e){throw t=!1,this._$EM(),e}t&&this._$AE(e)}willUpdate(t){}_$AE(t){this._$EO?.forEach(t=>t.hostUpdated?.()),this.hasUpdated||(this.hasUpdated=!0,this.firstUpdated(t)),this.updated(t)}_$EM(){this._$AL=new Map,this.isUpdatePending=!1}get updateComplete(){return this.getUpdateComplete()}getUpdateComplete(){return this._$ES}shouldUpdate(t){return!0}update(t){this._$Eq&&=this._$Eq.forEach(t=>this._$ET(t,this[t])),this._$EM()}updated(t){}firstUpdated(t){}};w.elementStyles=[],w.shadowRootOptions={mode:"open"},w[f("elementProperties")]=new Map,w[f("finalized")]=new Map,m?.({ReactiveElement:w}),(p.reactiveElementVersions??=[]).push("2.1.2");const k=globalThis,x=t=>t,$=k.trustedTypes,S=$?$.createPolicy("lit-html",{createHTML:t=>t}):void 0,M="$lit$",C=`lit$${Math.random().toFixed(9).slice(2)}$`,D="?"+C,T=`<${D}>`,P=document,R=()=>P.createComment(""),A=t=>null===t||"object"!=typeof t&&"function"!=typeof t,I=Array.isArray,E="[ \t\n\f\r]",F=/<(?:(!--|\/[^a-zA-Z])|(\/?[a-zA-Z][^>\s]*)|(\/?$))/g,z=/-->/g,O=/>/g,H=RegExp(`>|${E}(?:([^\\s"'>=/]+)(${E}*=${E}*(?:[^ \t\n\f\r"'\`<>=]|("|')|))|$)`,"g"),N=/'/g,L=/"/g,B=/^(?:script|style|textarea|title)$/i,q=t=>(e,...i)=>({_$litType$:t,strings:e,values:i}),j=q(1),W=q(2),U=Symbol.for("lit-noChange"),G=Symbol.for("lit-nothing"),V=new WeakMap,K=P.createTreeWalker(P,129);function Y(t,e){if(!I(t)||!t.hasOwnProperty("raw"))throw Error("invalid template strings array");return void 0!==S?S.createHTML(e):e}const X=(t,e)=>{const i=t.length-1,s=[];let n,o=2===e?"":3===e?"":"",a=F;for(let e=0;e"===l[0]?(a=n??F,c=-1):void 0===l[1]?c=-2:(c=a.lastIndex-l[2].length,r=l[1],a=void 0===l[3]?H:'"'===l[3]?L:N):a===L||a===N?a=H:a===z||a===O?a=F:(a=H,n=void 0);const d=a===H&&t[e+1].startsWith("/>")?" ":"";o+=a===F?i+T:c>=0?(s.push(r),i.slice(0,c)+M+i.slice(c)+C+d):i+C+(-2===c?e:d)}return[Y(t,o+(t[i]||"")+(2===e?"":3===e?"":"")),s]};class J{constructor({strings:t,_$litType$:e},i){let s;this.parts=[];let n=0,o=0;const a=t.length-1,r=this.parts,[l,c]=X(t,e);if(this.el=J.createElement(l,i),K.currentNode=this.el.content,2===e||3===e){const t=this.el.content.firstChild;t.replaceWith(...t.childNodes)}for(;null!==(s=K.nextNode())&&r.length0){s.textContent=$?$.emptyScript:"";for(let i=0;iI(t)||"function"==typeof t?.[Symbol.iterator])(t)?this.k(t):this._(t)}O(t){return this._$AA.parentNode.insertBefore(t,this._$AB)}T(t){this._$AH!==t&&(this._$AR(),this._$AH=this.O(t))}_(t){this._$AH!==G&&A(this._$AH)?this._$AA.nextSibling.data=t:this.T(P.createTextNode(t)),this._$AH=t}$(t){const{values:e,_$litType$:i}=t,s="number"==typeof i?this._$AC(t):(void 0===i.el&&(i.el=J.createElement(Y(i.h,i.h[0]),this.options)),i);if(this._$AH?._$AD===s)this._$AH.p(e);else{const t=new Q(s,this),i=t.u(this.options);t.p(e),this.T(i),this._$AH=t}}_$AC(t){let e=V.get(t.strings);return void 0===e&&V.set(t.strings,e=new J(t)),e}k(t){I(this._$AH)||(this._$AH=[],this._$AR());const e=this._$AH;let i,s=0;for(const n of t)s===e.length?e.push(i=new tt(this.O(R()),this.O(R()),this,this.options)):i=e[s],i._$AI(n),s++;s2||""!==i[0]||""!==i[1]?(this._$AH=Array(i.length-1).fill(new String),this.strings=i):this._$AH=G}_$AI(t,e=this,i,s){const n=this.strings;let o=!1;if(void 0===n)t=Z(this,t,e,0),o=!A(t)||t!==this._$AH&&t!==U,o&&(this._$AH=t);else{const s=t;let a,r;for(t=n[0],a=0;a{const s=i?.renderBefore??e;let n=s._$litPart$;if(void 0===n){const t=i?.renderBefore??null;s._$litPart$=n=new tt(e.insertBefore(R(),t),t,void 0,i??{})}return n._$AI(t),n},ct=globalThis;let ht=class extends w{constructor(){super(...arguments),this.renderOptions={host:this},this._$Do=void 0}createRenderRoot(){const t=super.createRenderRoot();return this.renderOptions.renderBefore??=t.firstChild,t}update(t){const e=this.render();this.hasUpdated||(this.renderOptions.isConnected=this.isConnected),super.update(t),this._$Do=lt(e,this.renderRoot,this.renderOptions)}connectedCallback(){super.connectedCallback(),this._$Do?.setConnected(!0)}disconnectedCallback(){super.disconnectedCallback(),this._$Do?.setConnected(!1)}render(){return U}};ht._$litElement$=!0,ht.finalized=!0,ct.litElementHydrateSupport?.({LitElement:ht});const dt=ct.litElementPolyfillSupport;dt?.({LitElement:ht}),(ct.litElementVersions??=[]).push("4.2.2");const ut=2,pt=t=>(...e)=>({_$litDirective$:t,values:e});let _t=class{constructor(t){}get _$AU(){return this._$AM._$AU}_$AT(t,e,i){this._$Ct=t,this._$AM=e,this._$Ci=i}_$AS(t,e){return this.update(t,e)}update(t,e){return this.render(...e)}};const gt={},mt=pt(class extends _t{constructor(){super(...arguments),this.ot=gt}render(t,e){return e()}update(t,[e,i]){if(Array.isArray(e)){if(Array.isArray(this.ot)&&this.ot.length===e.length&&e.every((t,e)=>t===this.ot[e]))return U}else if(this.ot===e)return U;return this.ot=Array.isArray(e)?Array.from(e):e,this.render(e,i)}}),{I:ft}=at,vt=t=>t,yt=()=>document.createComment(""),bt=(t,e,i)=>{const s=t._$AA.parentNode,n=void 0===e?t._$AB:e._$AA;if(void 0===i){const e=s.insertBefore(yt(),n),o=s.insertBefore(yt(),n);i=new ft(e,o,t,t.options)}else{const e=i._$AB.nextSibling,o=i._$AM,a=o!==t;if(a){let e;i._$AQ?.(t),i._$AM=t,void 0!==i._$AP&&(e=t._$AU)!==o._$AU&&i._$AP(e)}if(e!==n||a){let t=i._$AA;for(;t!==e;){const e=vt(t).nextSibling;vt(s).insertBefore(t,n),t=e}}}return i},wt=(t,e,i=t)=>(t._$AI(e,i),t),kt={},xt=(t,e=kt)=>t._$AH=e,$t=t=>{t._$AR(),t._$AA.remove()},St=(t,e,i)=>{const s=new Map;for(let n=e;n<=i;n++)s.set(t[n],n);return s},Mt=pt(class extends _t{constructor(t){if(super(t),t.type!==ut)throw Error("repeat() can only be used in text expressions")}dt(t,e,i){let s;void 0===i?i=e:void 0!==e&&(s=e);const n=[],o=[];let a=0;for(const e of t)n[a]=s?s(e,a):a,o[a]=i(e,a),a++;return{values:o,keys:n}}render(t,e,i){return this.dt(t,e,i).values}update(t,[e,i,s]){const n=(t=>t._$AH)(t),{values:o,keys:a}=this.dt(e,i,s);if(!Array.isArray(n))return this.ut=a,o;const r=this.ut??=[],l=[];let c,h,d=0,u=n.length-1,p=0,_=o.length-1;for(;d<=u&&p<=_;)if(null===n[d])d++;else if(null===n[u])u--;else if(r[d]===a[p])l[p]=wt(n[d],o[p]),d++,p++;else if(r[u]===a[_])l[_]=wt(n[u],o[_]),u--,_--;else if(r[d]===a[_])l[_]=wt(n[d],o[_]),bt(t,l[_+1],n[d]),d++,_--;else if(r[u]===a[p])l[p]=wt(n[u],o[p]),bt(t,n[d],n[u]),u--,p++;else if(void 0===c&&(c=St(a,p,_),h=St(r,d,u)),c.has(r[d]))if(c.has(r[u])){const e=h.get(a[p]),i=void 0!==e?n[e]:null;if(null===i){const e=bt(t,n[d]);wt(e,o[p]),l[p]=e}else l[p]=wt(i,o[p]),bt(t,n[d],i),n[e]=null;p++}else $t(n[u]),u--;else $t(n[d]),d++;for(;p<=_;){const e=bt(t,l[_+1]);wt(e,o[p]),l[p++]=e}for(;d<=u;){const t=n[d++];null!==t&&$t(t)}return this.ut=a,xt(t,l),U}}),Ct=new WeakMap;let Dt=0;class Tt extends ht{constructor(){super(...arguments),this.title="",this.icon="",this.wide=!1,this.dismissOnScrim=!1,this.hass=null,this._opener=null,this._focusRoot=null,this._useHaDialog=!1,this._closing=!1,this._overlays=[],this._titleId="hp-dialog-title-"+ ++Dt,this._focusInitial=()=>{const t=this._focusableElements(),e=t.find(t=>t.hasAttribute("autofocus"))||t[0]||(this._useHaDialog?null:this.renderRoot.querySelector(".close"))||this.renderRoot.querySelector(".surface")||this.renderRoot.querySelector("ha-dialog");e?.focus({preventScroll:!0})},this._requestClose=()=>{this._closing||(this._closing=!0,this.dispatchEvent(new CustomEvent("hp-close",{bubbles:!0,composed:!0})))},this._onKeyDown=t=>{if("Escape"===t.key){t.preventDefault(),t.stopImmediatePropagation(),this._pruneOverlays();const e=this._overlays[this._overlays.length-1];return e?void this._closeOverlay(e,"escape"):void this._requestClose()}if("Tab"!==t.key||this._useHaDialog)return;const e=this.renderRoot.querySelector(".close"),i=e?[e,...this._focusableElements()]:this._focusableElements();if(!i.length)return t.preventDefault(),void this.renderRoot.querySelector(".surface")?.focus({preventScroll:!0});const s=this._deepActiveElement(),n=i[0],o=i[i.length-1];!t.shiftKey||s!==n&&i.includes(s)?t.shiftKey||s!==o||(t.preventDefault(),n.focus()):(t.preventDefault(),o.focus())},this._onFallbackCancel=t=>{t.preventDefault(),this._requestClose()},this._onFallbackClick=t=>{this.dismissOnScrim&&t.target===t.currentTarget&&this._requestClose()}}connectedCallback(){super.connectedCallback(),this._opener=this._deepActiveElement();const t=this.getRootNode();this._focusRoot=t;const e=Ct.get(t)||{dialogs:new Set,opener:this._opener};e.dialogs.add(this),Ct.set(t,e),this._useHaDialog=!!customElements.get("ha-dialog"),this.addEventListener("keydown",this._onKeyDown,!0)}disconnectedCallback(){this.removeEventListener("keydown",this._onKeyDown,!0);const t=[...this._overlays];this._overlays=[];for(const e of t.reverse())e.close("disconnect");const e=this._focusRoot,i=this._opener;this._opener=null,this._focusRoot=null;const s=e?Ct.get(e):void 0;s?.dialogs.delete(this),super.disconnectedCallback(),e&&s&&requestAnimationFrame(()=>{const t=Ct.get(e);if(!t)return;if(!t.dialogs.size)return t.opener?.isConnected&&t.opener.focus({preventScroll:!0}),void Ct.delete(e);const s=i?.closest("hp-dialog");i?.isConnected&&s&&t.dialogs.has(s)&&i.focus({preventScroll:!0})})}firstUpdated(t){if(super.firstUpdated(t),!this._useHaDialog){const t=this.renderRoot.querySelector("dialog");t&&!t.open&&t.showModal()}queueMicrotask(()=>this._focusInitial())}_deepActiveElement(){let t=document.activeElement;for(;t?.shadowRoot?.activeElement;)t=t.shadowRoot.activeElement;return t&&t!==document.body?t:null}_focusableElements(){const t=["[autofocus]","a[href]","button:not([disabled])",'input:not([disabled]):not([type="hidden"])',"select:not([disabled])","textarea:not([disabled])",'[contenteditable="true"]','[tabindex]:not([tabindex="-1"])'].join(","),e=[],i=new Set,s=n=>{if(!i.has(n)){if(i.add(n),n instanceof HTMLElement){if(n.matches(t)&&e.push(n),n instanceof HTMLSlotElement){for(const t of n.assignedNodes({flatten:!0}))s(t);return}if(n.shadowRoot){for(const t of n.shadowRoot.childNodes)s(t);return}}for(const t of n.childNodes)s(t)}};for(const t of this.childNodes)s(t);const n=this.overlayPortal();return n&&s(n),e.filter(t=>{let e=t;for(;e;){const t=getComputedStyle(e);if(e.hidden||e.inert||"true"===e.getAttribute("aria-hidden")||"none"===t.display||"hidden"===t.visibility)return!1;if(e=e.assignedSlot||e.parentElement||(e.getRootNode()instanceof ShadowRoot?e.getRootNode().host:null),e===this)break}return!0})}_pruneOverlays(){this._overlays=this._overlays.filter(t=>t.owner.isConnected)}_closeOverlay(t,e){const i=this._overlays.findIndex(e=>e.token===t.token);i>=0&&this._overlays.splice(i,1),t.close(e)}registerOverlay(t){this._pruneOverlays();const e=this._overlays.find(e=>e.owner===t.owner);e&&this._overlays.splice(this._overlays.indexOf(e),1);const i=t.group||"transient";for(const t of[...this._overlays].reverse())t.group===i&&this._closeOverlay(t,"exclusive");const s={...t,group:i,token:Symbol("hp-overlay")};this._overlays.push(s);let n=!1;return()=>{if(n)return;n=!0;const t=this._overlays.findIndex(t=>t.token===s.token);t>=0&&this._overlays.splice(t,1)}}closeTransientOverlays(t="outside"){this._pruneOverlays();const e=[...this._overlays].filter(t=>"transient"===(t.group||"transient"));for(const i of e.reverse())this._closeOverlay(i,t);return e.length>0}overlayPortal(){return this.renderRoot.querySelector(".overlay-portal")}render(){const t=j` ${this.icon?j``:G} ${this.title} `;return this._useHaDialog?j` `})} - `}const er={color:"#607d8b",opacity:1,widthCm:3.6,fill:!1,fillColor:"#607d8b",fillOpacity:.25},ir=(t,e=1)=>{const i=Number(t);return Number.isFinite(i)?Math.min(1,Math.max(0,i)):e},sr=t=>{let e=Number(t);return Number.isFinite(e)?(e=(e%360+360)%360,e>180?e-360:e):0};function nr(t,e,i){return sr(e)?[t.x,t.y]:i([t.x,t.y])}const or=(t,e,i)=>{const s=Number(t),n=Number.isFinite(e)&&e>0?e:5;return Number.isFinite(s)&&s>0?s/n*i:0},ar=(t,e,i)=>{const s=Number(t),n=Number.isFinite(e)&&e>0?e:5;return Number.isFinite(s)&&i>0?s/i*n:0},rr=(t,e,i,s=er.widthCm)=>{const n=Number(t?.width_cm);if(Number.isFinite(n)&&n>0)return n;const o=Number(t?.width);return Number.isFinite(o)&&o>0?ar(o,e,i):s};function lr(t,e){return{color:t.color,opacity:ir(t.opacity),width_cm:Math.max(.1,Math.min(100,Number(t.widthCm)||.1)),...e?{fill:t.fill,fill_color:t.fillColor,fill_opacity:ir(t.fillOpacity,.25)}:{}}}function cr(t){const e=t.x+t.w/2,i=t.y+t.h/2,s=sr(t.angle)*Math.PI/180,n=Math.cos(s),o=Math.sin(s),a=(t,s)=>{const a=t-e,r=s-i;return[e+a*n-r*o,i+a*o+r*n]};return[a(t.x,t.y),a(t.x+t.w,t.y),a(t.x+t.w,t.y+t.h),a(t.x,t.y+t.h)]}function hr(t){const e=cr(t),i=(t,e)=>[(t[0]+e[0])/2,(t[1]+e[1])/2],s=[(e[0][0]+e[2][0])/2,(e[0][1]+e[2][1])/2];return{points:[...e,i(e[0],e[1]),i(e[1],e[2]),i(e[2],e[3]),i(e[3],e[0]),s],segments:e.map((t,i)=>({a:t,b:e[(i+1)%4]}))}}function dr(t,e,i,s,n,o,a,r){const l=sr(t.angle)*Math.PI/180,c=Math.cos(l),h=Math.sin(l),d=-Math.sin(l),u=Math.cos(l),p=t.x+t.w/2,_=t.y+t.h/2,g=e>0?-t.w/2:t.w/2,m=i>0?-t.h/2:t.h/2,f=p+g*c+m*d,v=_+g*h+m*u,y=s-f,b=n-v;let w=(y*c+b*h)*(e>0?1:-1),k=(y*d+b*u)*(i>0?1:-1),x=null;if(o){const e=w/Math.max(t.w,r),i=k/Math.max(t.h,r);x=Math.max(r/Math.max(t.w,r),r/Math.max(t.h,r),e,i),w=t.w*x,k=t.h*x}if(a>0)if(o){const e=Math.max(1,Math.round(t.w/a)),i=Math.max(1,Math.round(t.h/a));if(Math.abs(t.w-e*a)<1e-6&&Math.abs(t.h-i*a)<1e-6){const s=(t,e)=>{let i=Math.abs(t),s=Math.abs(e);for(;s;)[i,s]=[s,i%s];return Math.max(1,i)},n=1/s(e,i),o=Math.max(r/t.w,r/t.h),a=Math.max(o,Math.round((x??1)/n)*n);w=t.w*a,k=t.h*a}else{t.w>=t.h?(w=Math.round(w/a)*a,k=w*(t.h/Math.max(t.w,r))):(k=Math.round(k/a)*a,w=k*(t.w/Math.max(t.h,r)))}}else w=Math.round(w/a)*a,k=Math.round(k/a)*a;w=Math.max(r,w),k=Math.max(r,k);return{x:f+(e>0?w/2:-w/2)*c+(i>0?k/2:-k/2)*d-w/2,y:v+(e>0?w/2:-w/2)*h+(i>0?k/2:-k/2)*u-k/2,w:w,h:k,angle:sr(t.angle)||void 0}}const ur=(t,e,i)=>{const s=i[0]-e[0],n=i[1]-e[1],o=s*s+n*n;if(o<1e-12)return[...e];const a=Math.max(0,Math.min(1,((t[0]-e[0])*s+(t[1]-e[1])*n)/o));return[e[0]+s*a,e[1]+n*a]};const pr=15;function _r(t,e){return Number.isFinite(t)&&t>0&&Number.isFinite(e)&&e>0&&t*e<3}function gr(t){return Number.isFinite(t)?Math.max(1,Math.min(100,t)):1}function mr(t,e){return!Number.isFinite(t)||t<=0?"":String(e?Math.round(t/2.54*100)/100:Math.round(100*t)/100)}function fr(t,e,i){const s=Number(e)>0?Number(e):5;return gr(t)/s*i}function vr(t,e){return e>0&&Number.isFinite(t)?Math.round(t/e)*e:t}function yr(t,e){let i=e[0]-t[0],s=e[1]-t[1];const n=Math.hypot(i,s);return n<1e-12?[1,0]:(i/=n,s/=n,(i<-1e-12||Math.abs(i)<=1e-12&&s<0)&&(i=-i,s=-s),[i,s])}function br(t,e,i){const s=vr((t[0]+e[0])/2,i),n=vr((t[1]+e[1])/2,i),[o,a]=yr(t,e);let r=Math.atan2(a,o);r<0&&(r+=Math.PI);const l=Math.round(1800*r)/1800,c=i>0&&i<.01?6:i<1?4:2;return`${s.toFixed(c)},${n.toFixed(c)}@${l.toFixed(4)}`}function wr(t,e,i,s){return 1===s?br(t,e,i):br([t[0]/s,t[1]/s],[e[0]/s,e[1]/s],i)}function kr(t,e){if(!Array.isArray(t.a)||!Array.isArray(t.b)||t.a.length<2||t.b.length<2)return null;const i=[Number(t.a[0]),Number(t.a[1]),Number(t.b[0]),Number(t.b[1])];if(!i.every(Number.isFinite))return null;const s=e>0?e:1;return[[i[0]*s,i[1]*s],[i[2]*s,i[3]*s]]}function xr(t,e,i,s,n){const o=n>0?n:1;return{key:wr(t,e,s,o),cm:gr(i),a:[t[0]/o,t[1]/o],b:[e[0]/o,e[1]/o]}}function $r(t,e){const i=e>0?e:1,s=[];for(const e of t){const t=e.key.lastIndexOf("@");if(t<0)continue;const[n,o]=e.key.slice(0,t).split(",").map(Number),a=Number(e.key.slice(t+1));[n,o,a].every(Number.isFinite)&&s.push({w:e,x:n*i,y:o*i,ang:a})}return s}function Sr(t,e){const[i,s]=yr(t,e);let n=Math.atan2(s,i);return n<0&&(n+=Math.PI),n}function Mr(t,e){let i=Math.abs(t-e);return i>Math.PI/2&&(i=Math.PI-i),i<.02}function Cr(t,e,i,s,n=1){if(!t?.length)return null;const o=wr(e,i,s,n),a=t.find(t=>t.key===o);if(a)return a;const r=n>0?n:1,l=(e[0]+i[0])/2,c=(e[1]+i[1])/2,h=Sr(e,i),d=Math.max(.5*s,1e-9)*r;for(const e of $r(t,r))if(Mr(e.ang,h)&&Math.hypot(e.x-l,e.y-c)<=d)return e.w;return null}function Dr(t,e,i,s,n=1){const o=Cr(t,e,i,s,n);if(o&&o.cm>0)return gr(o.cm);const a=function(t,e,i,s,n){if(!t?.length)return null;const o=n>0?n:1,a=Math.hypot(i[0]-e[0],i[1]-e[1]);if(a<1e-12)return null;const r=Sr(e,i),l=Math.max(.5*s,1e-9)*o;let c=null;for(const s of t){if(!(s.cm>0))continue;const t=kr(s,o);if(!t)continue;const n=Math.hypot(t[1][0]-t[0][0],t[1][1]-t[0][1]);if(n<1e-12||!Mr(Sr(t[0],t[1]),r))continue;if(sl(e[0],e[1],t[0][0],t[0][1],t[1][0],t[1][1])>l||sl(i[0],i[1],t[0][0],t[0][1],t[1][0],t[1][1])>l)continue;if(n+l(o.has(t.key)||(t=>{const e=kr(t,s);if(!e)return!1;const[i,o]=e,r=o[0]-i[0],c=o[1]-i[1],h=Math.hypot(r,c);if(h<=l)return!1;if(!a.some(t=>{const e=[t[0],t[1]],s=[t[2],t[3]];return Mr(Sr(i,o),Sr(e,s))&&sl(i[0],i[1],e[0],e[1],s[0],s[1])<=l&&sl(o[0],o[1],e[0],e[1],s[0],s[1])<=l}))return!1;const d=(n||[]).some(t=>{const e=[t[0],t[1]],s=[t[2],t[3]];if(!Mr(Sr(i,o),Sr(e,s)))return!1;const n=t=>Math.abs((t[0]-i[0])*c-(t[1]-i[1])*r)/h;if(n(e)>l||n(s)>l)return!1;const a=h*h,d=((e[0]-i[0])*r+(e[1]-i[1])*c)/a,u=((s[0]-i[0])*r+(s[1]-i[1])*c)/a;return Math.min(1,Math.max(d,u))-Math.max(0,Math.min(d,u))>l/h});return!d})(t))&&t.cm>=1&&t.cm<=100)}function Pr(t,e,i,s=8){const[n,o]=yr(t,e);let a=Math.atan2(o,n);a<0&&(a+=Math.PI);let r=i*Math.PI/180%Math.PI;r<0&&(r+=Math.PI);let l=Math.abs(a-r);return l>Math.PI/2&&(l=Math.PI-l),l<=s*Math.PI/180}function Rr(t,e,i,s,n=1){if(!t?.length)return[];if(e.length!==i.length)return t.slice();const o=new Map;for(let t=0;t0?n:1,r=Math.max(.5*s,1e-9)*a,l=new Set,c=[];for(const n of t){let t="",h=null;const d=kr(n,a);if(d)for(let n=0;nr||sl(d[1][0],d[1][1],o[0],o[1],l[0],l[1])>r)continue;const p=l[0]-o[0],_=l[1]-o[1],g=p*p+_*_;if(g<1e-18)continue;const m=t=>{const e=Math.max(0,Math.min(1,((t[0]-o[0])*p+(t[1]-o[1])*_)/g));return[c[0]+(u[0]-c[0])*e,c[1]+(u[1]-c[1])*e]};h=[m(d[0]),m(d[1])],t=wr(h[0],h[1],s,a);break}if(d||(t=o.get(n.key)||""),!t){const o=$r([n],a)[0];if(o)for(let n=0;n1.000001)continue;if(sl(o.x,o.y,l[0],l[1],c[0],c[1])>r)continue;const m=h[0]+(d[0]-h[0])*Math.max(0,Math.min(1,g)),f=h[1]+(d[1]-h[1])*Math.max(0,Math.min(1,g)),[v,y]=yr(h,d),b=Math.max(s*a,1e-6);t=wr([m-v*b,f-y*b],[m+v*b,f+y*b],s,a);break}}t||(t=n.key),l.has(t)||(l.add(t),c.push(h?xr(h[0],h[1],n.cm,s,a):{...n,key:t,cm:gr(n.cm)}))}return c}function Ar(t,e,i,s,n,o=1){const a=wr(e,i,n,o),r=(t||[]).filter(t=>t.key!==a);return null==s||s<1?r:[...r,xr(e,i,s,n,o)]}function Ir(t,e,i,s,n,o=[],a=1){let r=t?t.slice():[];for(const t of function(t,e,i,s,n=1,o=[]){const a=Xr(t,e,i,s,n,o);if(!a)return[];const r=[];for(let t=0;t0||(c=Ar(c,e,i,s,n,a)))}return c}function Fr(t){const{a:e,b:i,halfDepth:s}=t;if(!Array.isArray(e)||!Array.isArray(i)||e.length<2||i.length<2||![e[0],e[1],i[0],i[1]].every(Number.isFinite))return null;const n=i[0]-e[0],o=i[1]-e[1],a=Math.hypot(n,o);if(!(a>1e-9&&s>0&&Number.isFinite(s)))return null;const r=-o/a*s,l=n/a*s;return[[e[0]+r,e[1]+l],[i[0]+r,i[1]+l],[i[0]-r,i[1]-l],[e[0]-r,e[1]-l]]}function zr(t,e,i){return Math.hypot(t[0]-e[0],t[1]-e[1])<=i}function Or(t,e,i){const s=e.b[0]-e.a[0],n=e.b[1]-e.a[1],o=s*s+n*n;if(!(o>i*i))return!1;const a=((t[0]-e.a[0])*s+(t[1]-e.a[1])*n)/o;if(!(a>0&&a<1))return!1;const r=[e.a[0]+s*a,e.a[1]+n*a];return Math.hypot(t[0]-r[0],t[1]-r[1])<=i}function Hr(t,e,i,s){const n=Math.hypot(e,i);if(!(n>1e-9&&s>0))return;const o=[e/n,i/n],a=t.find(t=>Math.abs(t.u[0]*o[1]-t.u[1]*o[0])<1e-9&&t.u[0]*o[0]+t.u[1]*o[1]>1-1e-9);a?a.halfDepth=Math.max(a.halfDepth,s):t.push({u:o,halfDepth:s})}function Nr(t,e=1e-6){const i=(t||[]).filter(t=>t&&Array.isArray(t.a)&&Array.isArray(t.b)&&t.a.length>=2&&t.b.length>=2&&t.a.every(Number.isFinite)&&t.b.every(Number.isFinite)&&Number.isFinite(t.halfDepth)&&t.halfDepth>0&&Math.hypot(t.b[0]-t.a[0],t.b[1]-t.a[1])>1e-9);if(i.length<2)return[];const s=Math.max(Number.isFinite(e)?e:0,1e-9),n=i.flatMap(t=>[t.a,t.b]).map(t=>[t[0],t[1]]).sort((t,e)=>t[0]-e[0]||t[1]-e[1]),o=[];for(const t of n)o.some(e=>zr(e,t,s))||o.push(t);const a=[];for(const t of o){const e=[];for(const n of i)zr(t,n.a,s)?Hr(e,n.b[0]-n.a[0],n.b[1]-n.a[1],n.halfDepth):zr(t,n.b,s)?Hr(e,n.a[0]-n.b[0],n.a[1]-n.b[1],n.halfDepth):Or(t,n,s)&&(Hr(e,n.a[0]-t[0],n.a[1]-t[1],n.halfDepth),Hr(e,n.b[0]-t[0],n.b[1]-t[1],n.halfDepth));if(!(e.length<2)){e.sort((t,e)=>Math.atan2(t.u[1],t.u[0])-Math.atan2(e.u[1],e.u[0])||t.halfDepth-e.halfDepth);for(let i=0;is*s&&a.push(m)}}}return a}function Lr(t,e,i,s){if(!(e>0)||!t||t.length<2)return"";if(i&&t.length>=3){let i=t;const n=t[t.length-1];if(t.length>=4&&Math.hypot(t[0][0]-n[0],t[0][1]-n[1])<1e-9&&(i=t.slice(0,-1)),i.length>=3){const t=i.map((t,i)=>s?.[i]||e),n=_l(i,t),o=Vr(i,t);if(n&&o)return`${Kr(n)} ${Kr(Yr(o))}`}}const n=[];for(let i=0;i=1e-9&&r>0&&n.push({a:o,b:a,halfDepth:r})}const o=[...n.map(Fr).filter(t=>!!t),...Nr(n)],a=function(t){let e=null;try{for(const i of t){if(i.length<3)continue;const t=ol(i);e=e?si(e,t):[t]}return e}catch{return null}}(o);return a?hl(a):o.map(t=>Kr(t)).join(" ")}function Br(t,e,i,s,n=1){if(!i.length)return!1;const o=qr(s,n),a=(t[0]+e[0])/2,r=(t[1]+e[1])/2,[l,c]=yr(t,e);for(const t of i){const[e,i]=yr([t[0],t[1]],[t[2],t[3]]);if(!(Math.abs(l*i-c*e)>.05)&&sl(a,r,t[0],t[1],t[2],t[3])<=o)return!0}return!1}function qr(t,e){return Math.max(t*(e>0?e:1)*.04,1e-9)}function jr(t){let e=0;for(let i=0;it[1]!=l>t[1]&&t[0]<(r-o)*(t[1]-a)/(l-a+0)+o&&(i=!i)}return i}([c[0]+.001*r,c[1]+.001*l],t)||(r=-r,l=-l),[r,l]}function Ur(t,e){const i=t[0]*e[1]-t[1]*e[0],s=t[0]*e[0]+t[1]*e[1];return Math.abs(i)<1e-9&&s>0}function Gr(t,e,i,s){const n=e[0]*s[1]-e[1]*s[0];if(Math.abs(n)<1e-12)return null;const o=[i[0]-t[0],i[1]-t[1]],a=(o[0]*s[1]-o[1]*s[0])/n;return[t[0]+a*e[0],t[1]+a*e[1]]}function Vr(t,e){const i=t?.length||0;if(i<3||e.length!==i)return null;if(e.every(t=>!(t>0)))return t.map(t=>[t[0],t[1]]);const s=[];for(let n=0;n0||d>0)){s.push([t[n][0],t[n][1]]);continue}if(h>0!=d>0){const e=t[n],i=h>0?[e[0]+u*h,e[1]+p*h]:[e[0],e[1]],o=d>0?[e[0]+_*d,e[1]+g*d]:[e[0],e[1]];s.push(i),Math.hypot(o[0]-i[0],o[1]-i[1])>1e-9&&s.push(o);continue}if(Ur(b,w)){const e=t[n],i=[e[0]+u*h,e[1]+p*h],o=[e[0]+_*d,e[1]+g*d];s.push(i),Math.hypot(o[0]-i[0],o[1]-i[1])>1e-9&&s.push(o);continue}const $=Gr(k,b,x,w),S=Math.max(h,d,1e-9);if($){if(Math.hypot($[0]-t[n][0],$[1]-t[n][1])<=4*S){s.push($);continue}}h>0&&s.push([t[n][0]+u*h,t[n][1]+p*h]),d>0&&s.push([t[n][0]+_*d,t[n][1]+g*d]),h>0||d>0||s.push([t[n][0],t[n][1]])}return s.length>=3?s:null}function Kr(t,e=!0){if(!t.length)return"";let i=`M ${t[0][0]} ${t[0][1]}`;for(let e=1;et?.id===e),r=hi(a);if(!r||r.length<3)return null;const l=qr(s,n),c=[];for(const i of t||[]){if(!i||i.id===e)continue;const t=hi(i);if(t)for(const e of Cs(r,t,l))c.push([e[0],e[1]],[e[2],e[3]])}for(const t of i||[])c.push([t[0],t[1]],[t[2],t[3]]);for(const t of o||[]){const e=kr(t,n);e&&c.push(e[0],e[1])}const h=[],d=[];for(let t=0;tl)continue;const a=((t[0]-e[0])*(i[0]-e[0])+(t[1]-e[1])*(i[1]-e[1]))/(s*s);a<=n||a>=1-n||(o.some(t=>Math.abs(t-a)*s<=2*l)||o.push(a))}o.sort((t,e)=>t-e);for(const s of o)h.push([e[0]+(i[0]-e[0])*s,e[1]+(i[1]-e[1])*s]),d.push(t)}return{poly:h,parent:d,orig:r}}function Jr(t,e,i,s){const n=e.poly.length,o=new Array(n).fill(0);if(!t?.length)return o;const a=new Set,r=[];for(let l=0;l0?(o[l]=gr(c.cm),a.add(c.key)):r.push(l)}if(!r.length)return o;const l=s>0?s:1,c=Math.max(.5*i,1e-9)*l,h=$r(t,l).filter(t=>t.w.cm>0);for(let t=r.length-1;t>=0;t--){const i=r[t],s=e.poly[i],a=e.poly[(i+1)%n],d=Sr(s,a);let u=null;for(const t of h){const e=kr(t.w,l);if(!e||!Mr(Sr(e[0],e[1]),d))continue;if(sl(s[0],s[1],e[0][0],e[0][1],e[1][0],e[1][1])>c||sl(a[0],a[1],e[0][0],e[0][1],e[1][0],e[1][1])>c)continue;const i=Math.hypot(a[0]-s[0],a[1]-s[1]),n=Math.hypot(e[1][0]-e[0][0],e[1][1]-e[0][1]),o=Math.max(0,n-i);(!u||oc||sl(n[0],n[1],e[0][0],e[0][1],e[1][0],e[1][1])>c)continue;i=!0,o=Math.max(0,Math.hypot(e[1][0]-e[0][0],e[1][1]-e[0][1])-_)}else{if(sl(t.x,t.y,s[0],s[1],n[0],n[1])>c)continue;o=Math.hypot(t.x-d,t.y-u)}(!p||i&&!p.exact||i===p.exact&&ot?.id===e),n=hi(s);if(!n)return[];const o=[];for(const s of t||[]){if(!s||s.id===e)continue;const t=hi(s);if(t)for(const e of Cs(n,t,i))o.push(e)}return o}(t,e,qr(n,r)),h=function(t,e,i,s,n){const o=qr(s,n),a=[];for(let r=0;rsl(h,d,t[0],t[1],t[2],t[3])<=o);a.push(u?"shared":"outer")}return a}(l.poly,c,s,n,r),d=Jr(i,l,n,r),u=d.map((t,e)=>h[e]&&t>0?fr(t,o,a)/2:0);return{...l,kinds:h,cms:d,offsets:u}}function Qr(t,e,i,s,n,o,a=1){const r=[];for(const l of t||[]){if(!l?.id)continue;const c=Zr(t,l.id,e,i,s,n,o,a);if(c)for(let t=0;t0&&(r=Ar(r,t.a,t.b,t.cm,s,a));return r}function el(t,e,i,s,n,o,a=1){if(!e?.length)return[];const r=[],l=new Set;for(const c of Qr(t,e,i,s,n,o,a))!c.open&&c.cm>0&&!l.has(c.key)&&(l.add(c.key),r.push(c));const c=[];for(const r of t||[]){if(!r?.id)continue;const l=Zr(t,r.id,e,i,s,n,o,a);if(l)for(let t=0;t0)||null===l.kinds[i]){t++;continue}let o=t;for(;o+10&&c.push({a:[h[0],h[1]],b:[d[0],d[1]],key:wr(h,d,s,a),cm:n,len:u}),t=o+1}}}c.sort((t,e)=>e.len-t.len||t.key.localeCompare(e.key));const h=[],d=new Set,u=new Set,p=4*qr(s,a);for(const t of c){const e=r.filter(e=>!u.has(e.key)&&e.cm===t.cm&&Mr(Sr(e.a,e.b),Sr(t.a,t.b))&&sl(e.a[0],e.a[1],t.a[0],t.a[1],t.b[0],t.b[1])<=p&&sl(e.b[0],e.b[1],t.a[0],t.a[1],t.b[0],t.b[1])<=p);if(e.length){for(const t of e)u.add(t.key);d.has(t.key)||(d.add(t.key),h.push(xr(t.a,t.b,t.cm,s,a)))}}for(const t of r)u.has(t.key)||d.has(t.key)||(d.add(t.key),h.push(xr(t.a,t.b,t.cm,s,a)));return h}function il(t,e,i,s,n,o,a,r=1){const l=qr(n,r),c=(s[0]+s[2])/2,h=(s[1]+s[3])/2,d=Sr([s[0],s[1]],[s[2],s[3]]);let u=null;for(const s of Qr(t,e,i,n,o,a,r)){if(!Mr(Sr(s.a,s.b),d))continue;const t=sl(c,h,s.a[0],s.a[1],s.b[0],s.b[1]);t>4*l||(!u||tt?.id===e),c=hi(l);if(!c||c.length<3)return null;if(!i?.length)return c.map(t=>[t[0],t[1]]);const h=Zr(t,e,i,s,n,o,a,r);return h&&h.offsets.some(t=>t>0)&&Vr(h.poly,h.offsets)||c.map(t=>[t[0],t[1]])}function ol(t){const e=t.map(t=>[t[0],t[1]]);return e.push([t[0][0],t[0][1]]),[e]}function al(t,e=1){if(!Array.isArray(t)||t.length<3)return null;const i=Number.isFinite(e)&&e>0?e:1,s=1e-12*Math.max(1,i),n=[];for(const e of t){if(!Array.isArray(e)||e.length<2)return null;const t=Number(e[0]),i=Number(e[1]);if(!Number.isFinite(t)||!Number.isFinite(i))return null;const o=Math.round(t/s)*s,a=Math.round(i/s)*s;if(!Number.isFinite(o)||!Number.isFinite(a))return null;n.push([Object.is(o,-0)?0:o,Object.is(a,-0)?0:a])}return Math.abs(jr(n))>s*s?n:null}function rl(t,e,i,s){if(sl(t[0],t[1],e[0],e[1],i[0],i[1])>s)return!1;const n=i[0]-e[0],o=i[1]-e[1],a=(t[0]-e[0])*n+(t[1]-e[1])*o,r=n*n+o*o,l=s*Math.sqrt(r);return a>=-l&&a<=r+l}function ll(t,e,i){const s=[],n=[];for(let o=0;oi*i))continue;const d=i/Math.sqrt(h),u=[0,1];for(const t of e)for(const e of[t.a,t.b]){if(!rl(e,a,r,i))continue;const t=((e[0]-a[0])*l+(e[1]-a[1])*c)/h;t>d&&t<1-d&&u.push(t)}u.sort((t,e)=>t-e);const p=u.filter((t,e)=>0===e||Math.abs(t-u[e-1])>d);for(let t=0;t=3&&n.length===s.length?{poly:s,offsets:n}:null}function cl(t,e,i,s,n,o,a){const r=(t||[]).map(hi).filter(t=>!!t&&t.length>=3);if(!r.length)return null;let l=si(ol(r[0]));for(let t=1;t"outer"===t.kind&&t.half>0),h=4*qr(s,a);let d=null;for(const t of function(t){const e=[];for(const i of Array.isArray(t)?t:[])if(Array.isArray(i))for(const t of i){if(!Array.isArray(t)||t.length<4)continue;const i=t.slice(0,-1).map(t=>[t[0],t[1]]);i.length>=3&&e.push(i)}return e}(l)){const e=ll(t,c,h);if(!e||!e.offsets.some(t=>t>0))continue;const i=_l(e.poly,e.offsets),s=Vr(e.poly,e.offsets);if(!i||!s)continue;const n=oi(ol(i),ol(s));d=d?si(d,n):n}return{centre:l,shell:d||[]}}function hl(t){if(!t)return"";let e="";for(const i of t)if(Array.isArray(i))for(const t of i){if(!Array.isArray(t)||t.length<4)continue;const i=t.slice(0,t.length-1);i.length<3||(e+=(e?" ":"")+Kr(i.map(t=>[t[0],t[1]])))}return e}function dl(t,e,i,s=[],n,o,a,r=1,l=[]){if(!e?.length&&!l.length)return null;const c=[];let h=0;for(const s of t||[]){if(!s?.id)continue;const l=Zr(t,s.id,e,i,n,o,a,r);if(!l||l.poly.length<3||!l.offsets.some(t=>t>0))continue;for(const t of l.offsets)t>0&&(h=Math.max(h,2*t));const d=_l(l.poly,l.offsets),u=Vr(l.poly,l.offsets);d&&c.push({outset:d,inset:u})}for(const t of l){const e=t.map(t=>t[0]),i=t.map(t=>t[1]);if(e.length){const s=Math.min(Math.max(...e)-Math.min(...e),Math.max(...i)-Math.min(...i)),n=Math.min(...t.map((e,i)=>{const s=t[(i+1)%t.length];return Math.hypot(s[0]-e[0],s[1]-e[1])}));h=Math.max(h,t.length>16?s:n)}}const d=function(t,e,i,s,n,o,a){if(!e?.length||!i?.length)return[];const r=4*qr(s,a),l=new Map;for(const r of Qr(t,e,i,s,n,o,a))!r.open&&r.half>0&&!l.has(r.key)&&l.set(r.key,r);const c=[...l.values()];if(c.length<2)return[];const h=[];for(const t of i)for(const e of[[t[0],t[1]],[t[2],t[3]]])h.some(t=>Math.hypot(t[0]-e[0],t[1]-e[1])<=r)||h.push(e);const d=[],u=(t,e)=>{let i=0,s=0;if(Math.hypot(t.a[0]-e[0],t.a[1]-e[1])<=r)i=t.b[0]-t.a[0],s=t.b[1]-t.a[1];else{if(!(Math.hypot(t.b[0]-e[0],t.b[1]-e[1])<=r))return null;i=t.a[0]-t.b[0],s=t.a[1]-t.b[1]}const n=Math.hypot(i,s);return n>r?[i/n,s/n]:null};for(const t of h){const e=c.map(e=>({iv:e,u:u(e,t)})).filter(t=>!!t.u);for(let i=0;i4*_||d.push(a>0?[t.slice(),h,p,u]:[t.slice(),u,p,h])}}return d}(t,e,i,n,o,a,r),u=s.length?gl(t,e,i,n,o,a,r):null;try{const p=cl(t,e,i,n,o,a,r),_=p?p.shell?.length?si(p.centre,p.shell):p.centre:[],g=t=>{const e=ol(t.outset);return t.inset?oi(e,ol(t.inset)):e};let m=null;for(const t of c)try{const e=g(t);m=m?si(m,e):e}catch{}if(p)for(const s of pl(t,e,i,n,o,a,r))try{const t=ni(ol(s.quad),p.centre);m=m?si(m,t):t}catch{}m=function(t,e,i=1,s=si){let n=t;for(const t of e||[]){const e=al(t,i);if(e)try{const t=ol(e);n=n?s(n,t):t}catch{}}return n}(m,d,r),m&&p&&(m=ni(m,p.centre)),p?.shell?.length&&(m=m?si(m,p.shell):p.shell);for(const t of s){if(!(t.length>0))continue;const e=vl(u,t,!0);if(!e.negative&&!e.positive)continue;const i=t.angle*Math.PI/180,s=Math.cos(i),o=Math.sin(i),a=-o,l=s,c=t.length/2,d=1.25*Math.max(h,n*r),p=[[t.x-s*c-a*d,t.y-o*c-l*d],[t.x+s*c-a*d,t.y+o*c-l*d],[t.x+s*c+a*d,t.y+o*c+l*d],[t.x-s*c+a*d,t.y-o*c+l*d]];m&&(m=oi(m,ol(p)))}for(const t of l)t.length<3||(m=m?si(m,ol(t)):[ol(t)]);return{geom:m||[],paperGeom:_,depthUnits:h,openingIndex:u}}catch{return null}}function ul(t,e,i,s=[],n,o,a,r=1,l=[]){if(!e?.length&&!l.length)return null;const c=dl(t,e,i,s,n,o,a,r,l),h=c?hl(c.geom):"",d=c?hl(c.paperGeom):"";return c&&h?{d:h,paperD:d,depthUnits:c.depthUnits,fillRule:"evenodd"}:null}function pl(t,e,i,s,n,o,a=1){if(!e?.length)return[];const r=new Set,l=[];for(const c of t||[]){if(!c?.id)continue;const h=Zr(t,c.id,e,i,s,n,o,a);if(!h)continue;const d=h.poly;for(let t=0;t0))continue;const p=wr(e,i,s,a);if(r.has(p))continue;r.add(p);const _=fr(u,n,o),[g,m]=Wr(d,t),f=-g,v=-m,y=_/2,b=[[e[0]+f*y,e[1]+v*y],[i[0]+f*y,i[1]+v*y],[i[0]+g*y,i[1]+m*y],[e[0]+g*y,e[1]+m*y]];l.push({key:p,kind:c,cm:u,quad:b,a:[e[0],e[1]],b:[i[0],i[1]],depthUnits:_})}}return l}function _l(t,e){const i=t?.length||0;if(i<3||e.length!==i)return null;if(e.every(t=>!(t>0)))return t.map(t=>[t[0],t[1]]);Yr(t),e.slice().reverse();const s=[];for(let n=0;n0||r>0)){s.push([t[n][0],t[n][1]]);continue}if(a>0!=r>0){const e=t[n],i=a>0?[e[0]-l*a,e[1]-c*a]:[e[0],e[1]],o=r>0?[e[0]-h*r,e[1]-d*r]:[e[0],e[1]];s.push(i),Math.hypot(o[0]-i[0],o[1]-i[1])>1e-9&&s.push(o);continue}if(Ur(b,w)){const e=t[n],i=[e[0]-l*a,e[1]-c*a],o=[e[0]-h*r,e[1]-d*r];s.push(i),Math.hypot(o[0]-i[0],o[1]-i[1])>1e-9&&s.push(o);continue}const $=Gr(k,b,x,w),S=Math.max(a,r,1e-9);if($){if(Math.hypot($[0]-t[n][0],$[1]-t[n][1])<=4*S){s.push($);continue}}a>0&&s.push([t[n][0]-l*a,t[n][1]-c*a]),r>0&&s.push([t[n][0]-h*r,t[n][1]-d*r])}return s.length>=3?s:null}function gl(t,e,i,s,n,o,a=1){const r=[];for(const l of t||[]){if(!l?.id)continue;const c=Zr(t,l.id,e,i,s,n,o,a);if(!c)continue;const h=Math.abs(Pi(c.poly));for(let t=0;t[Math.max(e,t.x0),Math.min(i,t.x1)]).filter(t=>t[1]-t[0]>s).sort((t,e)=>t[0]-e[0]||t[1]-e[1]);if(!n.length)return{coverage:0,full:!1};let o=n[0][0],a=n[0][1],r=0,l=o<=e+s;for(let t=1;t=i-s,{coverage:r,full:l}}function fl(t,e){return Number(e.full)-Number(t.full)||t.faceDistance-e.faceDistance||t.area-e.area||t.roomId.localeCompare(e.roomId)}function vl(t,e,i=!1){const s=Number(e?.x),n=Number(e?.y),o=Number(e?.angle),a=Number(e?.length);if(!([s,n,o,a].every(Number.isFinite)&&a>0))return{negative:null,positive:null};const r=o*Math.PI/180,l=Math.cos(r),c=Math.sin(r),h=-c,d=l,u=a/2,p=Math.max(1e-9,t.adjacencyEps),_=new Map;let g=0;for(const e of t.edges){if(i&&!(e.half>0))continue;if(!Pr(e.a,e.b,o))continue;const[t,a]=yr(e.a,e.b);if(Math.abs((s-e.a[0])*a-(n-e.a[1])*t)>p)continue;const r=(e.a[0]-s)*l+(e.a[1]-n)*c,m=(e.b[0]-s)*l+(e.b[1]-n)*c,f=Math.max(-u,Math.min(r,m)),v=Math.min(u,Math.max(r,m));if(v-f<=p)continue;const y=e.inward[0]*h+e.inward[1]*d>=0?1:-1,b=((e.a[0]+e.b[0])/2-s)*h+((e.a[1]+e.b[1])/2-n)*d,w=Math.abs(b+y*e.half),k=`${y}|${e.roomId}`,x={x0:f,x1:v,half:e.half,cm:e.cm,key:e.key,axis:[t,a]},$=_.get(k);$?($.pieces.push(x),$.faceDistance=Math.min($.faceDistance,w)):_.set(k,{roomId:e.roomId,side:y,order:g++,pieces:[x],faceDistance:w,area:e.area,coverage:0,full:!1})}for(const t of _.values()){const e=ml(t.pieces,-u,u,p);t.coverage=e.coverage,t.full=e.full}const m=t=>{const e=[..._.values()].filter(e=>e.side===t&&e.coverage>p);return e.sort(fl),e[0]||null};return{negative:m(-1),positive:m(1)}}function yl(t,e){const i=vl(t,e),s=[i.negative,i.positive].filter(t=>!!t).sort((t,e)=>t.order-e.order);if(!s.length)return{ox:0,oy:0,cm:0,side:-1};const n=s[0],o=e.flip_v?-n.side:n.side,a=(-1===o?i.negative:i.positive)||n,r=[...a.pieces].sort((t,e)=>(t.x0<=0&&t.x1>=0?0:Math.min(Math.abs(t.x0),Math.abs(t.x1)))-(e.x0<=0&&e.x1>=0?0:Math.min(Math.abs(e.x0),Math.abs(e.x1)))||e.x1-e.x0-(t.x1-t.x0)||t.key.localeCompare(e.key))[0];if(!(r.half>0&&r.cm>0))return{ox:0,oy:0,cm:0,side:o};const l=e.angle*Math.PI/180,c=-Math.sin(l),h=Math.cos(l);return{ox:c*o*r.half,oy:h*o*r.half,cm:r.cm,side:o}}function bl(t,e){const i=1e-9,s=e.filter(t=>Number.isFinite(t.x0)&&Number.isFinite(t.x1)&&Number.isFinite(t.half)&&t.x1>t.x0&&t.half>0);if(!s.length)return"";const n=s.flatMap(t=>[t.x0,t.x1]).sort((t,e)=>t-e),o=[];for(const t of n){const e=o[o.length-1];(void 0===e||t>e+i)&&o.push(t)}const a=[];for(let t=0;t+1e+i))continue;const r=(e+n)/2,l=s.reduce((t,e)=>r>=e.x0-i&&r<=e.x1+i?Math.max(t,e.half):t,0);if(!(l>0))continue;const c=a[a.length-1];c&&e<=c.x1+i&&Math.abs(l-c.half)<=i?c.x1=n:a.push({x0:e,x1:n,half:l})}const r=[];for(const t of a){const e=r[r.length-1],s=e?.[e.length-1];s&&t.x0<=s.x1+i?(t.x0=s.x1,e.push(t)):r.push([t])}return r.map(e=>{const i=e[0],s=e[e.length-1],n=Math.min(.25*Math.min(...e.map(t=>t.half)),.75),o=-t*n,a=[];if(1===t){a.push(`M ${i.x0} ${o} L ${s.x1} ${o}`);for(let t=e.length-1;t>=0;t--){const i=e[t];a.push(`L ${i.x1} ${i.half} L ${i.x0} ${i.half}`)}}else{a.push(`M ${s.x1} ${o} L ${i.x0} ${o}`);for(const t of e)a.push(`L ${t.x0} ${-t.half} L ${t.x1} ${-t.half}`)}return a.push("Z"),a.join(" ")}).join(" ")}function wl(t,e,i,s){if(!s)return i;const n=t.angle*Math.PI/180,o=Math.cos(n),a=Math.sin(n),r=[],l=1e-9;for(const n of i){const[i,c]=n.axis,h=o*i+a*c;if(Math.abs(h)<=l)continue;const d=t.x*i+t.y*c,u=d+h*n.x0,p=d+h*n.x1,_=Math.min(u,p),g=Math.max(u,p),m=`${n.key}|${e}`,f=s.get(m)||[];let v=[[_,g]];for(const[t,e]of f){const i=[];for(const[s,n]of v)e<=s+l||t>=n-l?i.push([s,n]):(t>s+l&&i.push([s,Math.min(n,t)]),et[0]-e[0]||t[1]-e[1]),b=[];for(const t of y){const e=b[b.length-1];e&&t[0]<=e[1]+l?e[1]=Math.max(e[1],t[1]):b.push([t[0],t[1]])}s.set(m,b)}return r}function kl(t,e){const i=new Map;return e.map(e=>function(t,e,i){const s=vl(t,e,!0),n=s.negative,o=s.positive;if(!n&&!o)return null;let a;if(n&&o)a=[{candidate:n,side:-1},{candidate:o,side:1}];else{const t=n||o;a=[{candidate:t,side:-1},{candidate:t,side:1}]}const r=a.map(({candidate:t,side:s})=>({candidate:t,side:s,pieces:wl(e,s,t.pieces,i)})),l=r.map(({candidate:t,side:e,pieces:i})=>({side:e,roomId:t.roomId,d:bl(e,i)})),c=r.flatMap(({pieces:t})=>t);if(!c.length)return null;const h=Math.max(...c.map(t=>t.half));return{faces:l,minY:-h,maxY:h,wallKey:[...new Set(c.map(t=>t.key))].sort().join("|")}}(t,e,i))}const xl=150;function $l(t){return Number.isFinite(t)?Math.max(1,Math.min(xl,t)):1}function Sl(t){return((Number.isFinite(Number(t))?Number(t):0)%90+90)%90}const Ml=t=>{const e=t.map(t=>[t[0],t[1]]);return!e.length||e[0][0]===e[e.length-1][0]&&e[0][1]===e[e.length-1][1]||e.push([...e[0]]),[e]};function Cl(t){const e=[];for(const i of t||[])for(const t of i||[]){const i=(t||[]).filter(t=>Array.isArray(t)&&t.length>=2);i.length<4||e.push(`M ${i.slice(0,-1).map(t=>`${t[0]} ${t[1]}`).join(" L ")} Z`)}return e.join(" ")}function Dl(t,e,i,s,n){return Fr({a:t,b:e,halfDepth:fr(i,s,n)/2})}function Tl(t,e,i){const s=Number(e)>0?Number(e):5,n=$l(t.cm)/s*i,o=t.center[0],a=t.center[1];if("circle"===t.shape){const t=n/2;return Array.from({length:96},(e,i)=>{const s=i/96*Math.PI*2;return[o+Math.cos(s)*t,a+Math.sin(s)*t]})}const r=n/2,l=Sl(t.angle)*Math.PI/180,c=Math.cos(l),h=Math.sin(l);return[[-r,-r],[r,-r],[r,r],[-r,r]].map(([t,e])=>[o+t*c-e*h,a+t*h+e*c])}function Pl(t,e,i=1e-9){if(!e.length)return[t];let s=[Ml(t)];try{for(const t of e){const e=t.b[0]-t.a[0],n=t.b[1]-t.a[1],o=Math.hypot(e,n);if(!(o>i))continue;const a=e/o,r=n/o,l=-r,c=a,h=1.25*Math.max(Number(t.depth)||0,4*i),d=Math.max(2*i,1e-9*o),u=[[t.a[0]-a*d-l*h,t.a[1]-r*d-c*h],[t.b[0]+a*d-l*h,t.b[1]+r*d-c*h],[t.b[0]+a*d+l*h,t.b[1]+r*d+c*h],[t.a[0]-a*d+l*h,t.a[1]-r*d+c*h]];s=oi(s,Ml(u))}return Ol(s)}catch{return[t]}}function Rl(t,e,i,s=Math.max(2e-4*i,1e-9),n=[]){const o=[],a=[],r=new Map;for(const t of n){const e=r.get(t.hostId)||[];e.push(t),r.set(t.hostId,e)}const l=[],c=[],h=[];for(const s of t.room_drafts||[])for(let t=0;t+1Tl(t,e,i)),u=Nr([...o,...a],s).flatMap(t=>Pl(t,n,s));return{drafts:l,partitions:c,columns:d,patches:u,all:[...l,...h,...u,...d]}}function Al(t){try{const e=t.filter(t=>t.length>=3).map(t=>Ml(t));return e.length?si(e[0],...e.slice(1)):null}catch{return null}}const Il=t=>`M ${t.map(t=>`${t[0]} ${t[1]}`).join(" L ")} Z`;function El(t,e){const i=Al(t.filter(t=>t.length>=3)),s=Al(e.filter(t=>t.length>=3));if(!i)return[];if(!s)return[];try{return function(t){const e=[];for(const i of t||[]){if(zl([i])<=1e-6)continue;const t=[];for(const e of i||[]){const i=(e||[]).filter(t=>Array.isArray(t)&&t.length>=2);i.length<4||t.push(Il(i.slice(0,-1)))}t.length&&e.push(t.join(" "))}return e}(ni(i,s))}catch{return[]}}function Fl(t,e){if(!e.length)return[Ml(t)];try{const i=Al(e);if(i)return oi(Ml(t),i)}catch{}let i=[Ml(t)];for(const t of e)if(!(t.length<3))try{i=oi(i,Ml(t))}catch{}return i}function zl(t){let e=0;for(const i of t||[])if(i?.length){e+=Pi(i[0]||[]);for(let t=1;t=4&&e.push(t.slice(0,-1).map(t=>[t[0],t[1]]))}return e}function Hl(t,e){let i=!1;for(let s=0,n=e.length-1;st[1]!=l>t[1]&&t[0]<(r-o)*(t[1]-a)/(l-a||1e-12)+o&&(i=!i)}return i}function Nl(t,e,i){return function(t,e){for(const i of e||[]){const e=i?.[0];if(!e?.length||!Hl(t,e))continue;let s=!1;for(let e=1;eHl(t,e))}function Ll(t,e,i){if(Math.hypot(t.center[0]-e.center[0],t.center[1]-e.center[1])>i)return!1;if(Math.abs($l(t.cm)-$l(e.cm))>1e-6)return!1;if(t.shape!==e.shape)return!0;if("circle"===t.shape||"circle"===e.shape)return!0;const s=Math.abs(Sl(t.angle)-Sl(e.angle));return Math.min(s,90-s)<=1e-6}const Bl=1e3;function ql(t,e){const i=Number(t),s=Number.isFinite(i)&&i>0?i:1,n=s>=1?e:e*s,o=s>=1?e/s:e;return{x:(e-n)/2,y:(e-o)/2,w:n,h:o}}const jl=.01,Wl=100;function Ul(t,e=1e3){const i=ql(t?.plan_aspect,e),s=Number(t?.plan_scale),n=Number.isFinite(s)&&s>0?Math.min(Wl,Math.max(jl,s)):1,o=Number(t?.plan_scale_x),a=Number(t?.plan_scale_y),r=Number.isFinite(o)&&o>0?Math.min(Wl,Math.max(jl,o)):n,l=Number.isFinite(a)&&a>0?Math.min(Wl,Math.max(jl,a)):n,c=Number(t?.plan_x),h=Number(t?.plan_y),d=sr(t?.plan_angle);return{x:i.x+(Number.isFinite(c)?ic(c):0)*e,y:i.y+(Number.isFinite(h)?ic(h):0)*e,w:i.w*r,h:i.h*l,...d?{angle:d}:{}}}function Gl(t){if(null==t.x||null==t.y)return{x:t.x,y:t.y,w:t.w,h:t.h};const e=Number(t.w)||0,i=Number(t.h)||0;return{x:e<0?t.x+e:t.x,y:i<0?t.y+i:t.y,w:Math.abs(e),h:Math.abs(i)}}function Vl(t){return t&&Array.isArray(t.spaces)?t.spaces.map(t=>{const e=Bl,i=function(t){return Array.isArray(t)&&4===t.length&&t.every(t=>Number.isFinite(t))&&t[2]>1e-6&&t[3]>1e-6?t:[0,0,1,1]}(t.view_box);return{id:t.id,title:t.title,vb:[i[0]*Bl,i[1]*e,i[2]*Bl,i[3]*e],bg:t.plan_url?{href:Is(t.plan_url),...Ul(t,Bl)}:null,rooms:(t.rooms||[]).map(t=>{const i={...t,...Gl(t)};return{id:i.id,name:i.name,area:i.area??null,open_to:i.open_to||void 0,settings:i.settings||void 0,x:null!=i.x?i.x*Bl:void 0,y:null!=i.y?i.y*e:void 0,w:null!=i.w?i.w*Bl:void 0,h:null!=i.h?i.h*e:void 0,poly:i.poly?i.poly.map(t=>[t[0]*Bl,t[1]*e]):void 0}}),room_drafts:(t.room_drafts||[]).map(t=>({id:t.id,points:(t.points||[]).map(t=>[t[0]*Bl,t[1]*e]),segments:(t.segments||[]).map(t=>({cm:Number(t.cm)}))})),partitions:(t.partitions||[]).map(t=>({id:t.id,a:[t.a[0]*Bl,t.a[1]*e],b:[t.b[0]*Bl,t.b[1]*e],cm:Number(t.cm)})),wall_columns:(t.wall_columns||[]).map(t=>({id:t.id,shape:"circle"===t.shape?"circle":"square",center:[t.center[0]*Bl,t.center[1]*e],cm:Number(t.cm),..."circle"===t.shape?{}:{angle:Sl(t.angle)}}))}}):[]}const Kl=5e3,Yl=Kl*Bl,Xl=240,Jl=Bl/Xl,Zl=1/Xl;function Ql(t){if(!Number.isFinite(t))return t;const e=Math.round(t*Xl/Bl)*Bl/Xl;return Math.abs(e-t)<=1e-9*Jl?t:e}function tc(t){return{x:Ql(t.x),y:Ql(t.y)}}function ec(t){return Number.isFinite(t)?Math.min(Yl,Math.max(-Yl,t)):0}function ic(t){return Number.isFinite(t)?Math.min(Kl,Math.max(-Kl,t)):0}const sc=1/3,nc=200;function oc(t){let e=1/0,i=1/0,s=-1/0,n=-1/0;for(const o of t){const t=Number(o[0]),a=Number(o[1]);Number.isFinite(t)&&Number.isFinite(a)&&(ts&&(s=t),a>n&&(n=a))}return e>s?null:{minX:e,minY:i,maxX:s,maxY:n}}function ac(t){return t.poly&&t.poly.length?oc(t.poly):null==t.x||null==t.y?null:oc([[t.x,t.y],[t.x+(t.w||0),t.y+(t.h||0)]])}function rc(t,e){const i=[];for(const e of t.rooms||[]){const t=ac(e);t&&i.push(t)}if(t.bg){const e=oc(cr(t.bg));e&&i.push(e)}for(const t of e||[])if(Array.isArray(t)){const e=oc([t]);e&&i.push(e)}else i.push(t);return i}const lc=t=>{if(!t.length)return 0;const e=[...t].sort((t,e)=>t-e),i=e.length>>1;return e.length%2?e[i]:(e[i-1]+e[i])/2},cc=t=>{let e=1/0,i=1/0,s=-1/0,n=-1/0;for(const o of t)o.minXs&&(s=o.maxX),o.maxY>n&&(n=o.maxY);return e>s||i>n?null:{x:e,y:i,w:s-e,h:n-i}};function hc(t,e){let{x:i,y:s,w:n,h:o}=t;n<30&&(i=i+n/2-100,n=nc),o<30&&(s=s+o/2-100,o=nc);const a=Math.max(n,o)*e;return{x:i-a,y:s-a,w:n+2*a,h:o+2*a}}function dc(t,e={}){const i=e.pad??.05,s=e.k??10,n=e.minSpread??50,o=t.filter(t=>Number.isFinite(t.minX)&&Number.isFinite(t.minY)&&Number.isFinite(t.maxX)&&Number.isFinite(t.maxY)&&Math.abs(t.minX)<=Yl&&Math.abs(t.maxX)<=Yl&&Math.abs(t.minY)<=Yl&&Math.abs(t.maxY)<=Yl);if(!o.length)return{core:null,all:null,outliers:0};const a=cc(o);if(o.length<4){const t=hc(a,i);return{core:t,all:t,outliers:0}}const r=o.map(t=>(t.minX+t.maxX)/2),l=o.map(t=>(t.minY+t.maxY)/2),c=lc(r),h=lc(l),d=o.map((t,e)=>Math.max(Math.abs(r[e]-c),Math.abs(l[e]-h))),u=Math.max(((t,e)=>t.length?t[Math.min(t.length-1,Math.max(0,Math.round(e*(t.length-1))))]:0)([...d].sort((t,e)=>t-e),.75),n),p=d.map(t=>t>s*u),_=p.filter(Boolean).length,g=_&&_<=o.length*sc?o.filter((t,e)=>!p[e]):o;return{core:hc(cc(g)||a,i),all:hc(a,i),outliers:g===o?0:_}}function uc(t,e,i=.05){const s=dc(rc(t,e),{pad:i});if(s.core)return s.core;const n=t.vb&&4===t.vb.length&&t.vb[2]>0&&t.vb[3]>0?t.vb:[0,0,Bl,Bl];return{x:n[0],y:n[1],w:n[2],h:n[3]}}function pc(t){const e=uc(t);return{x:e.x+e.w/2,y:e.y+e.h/2}}function _c(t){const e=[];for(const i of t.rooms||[]){const t=ac(i);t&&e.push(t)}const i=dc(e,{pad:0}).core;return i?Math.max(Bl,Math.min(Yl,Math.max(i.w,i.h))):Bl}function gc(t,e,i,s=1){const n=Number(i),o=Number.isFinite(s)&&s>0?s:1;return!Number.isFinite(n)||n<=0?t*o:t*_c(e)*o/n}const mc=[1,2,5,10,20,50,100,200,500,1e3];function fc(t){if(t.poly&&t.poly.length){const e=t.poly.map(t=>t[0]),i=t.poly.map(t=>t[1]),s=Math.min(...e),n=Math.min(...i);return{x:s,y:n,w:Math.max(...e)-s,h:Math.max(...i)-n}}return{x:t.x??0,y:t.y??0,w:t.w??0,h:t.h??0}}function vc(t){if(t.poly){const e=t.poly.length;return[t.poly.reduce((t,e)=>t+e[0],0)/e,t.poly.reduce((t,e)=>t+e[1],0)/e]}return[t.x+t.w/2,t.y+.1*Math.min(t.w,t.h)]}const yc=["furniture","appliance","sanitary","other"],bc=[{id:"sofa",group:"furniture",w:220,h:90,g:[["r",0,0,1,1],["l",.09,.26,.91,.26],["l",.09,.26,.09,1],["l",.91,.26,.91,1],["l",.5,.26,.5,1]]},{id:"armchair",group:"furniture",w:90,h:85,g:[["r",0,0,1,1],["l",.14,.28,.86,.28],["l",.14,.28,.14,1],["l",.86,.28,.86,1]]},{id:"coffee_table",group:"furniture",w:110,h:60,g:[["r",0,0,1,1],["r",.08,.14,.84,.72]]},{id:"table_dining",group:"furniture",w:140,h:80,g:[["r",0,0,1,1],["r",.06,.11,.88,.78]]},{id:"table_round",group:"furniture",w:120,h:120,g:[["e",.5,.5,.5,.5],["e",.5,.5,.41,.41]]},{id:"chair",group:"furniture",w:45,h:45,g:[["r",0,0,1,.18],["r",.06,.18,.88,.8]]},{id:"desk",group:"furniture",w:120,h:60,g:[["r",0,0,1,1],["r",.63,.07,.31,.86],["l",.63,.5,.94,.5]]},{id:"bed_double",group:"furniture",w:160,h:200,g:[["r",0,0,1,1],["r",0,0,1,.07],["r",.06,.1,.4,.15],["r",.54,.1,.4,.15],["l",0,.33,1,.33]]},{id:"bed_single",group:"furniture",w:90,h:200,g:[["r",0,0,1,1],["r",0,0,1,.07],["r",.15,.1,.7,.15],["l",0,.33,1,.33]]},{id:"nightstand",group:"furniture",w:45,h:40,g:[["r",0,0,1,1],["r",.12,.14,.76,.33],["r",.12,.53,.76,.33]]},{id:"wardrobe",group:"furniture",w:100,h:60,g:[["r",0,0,1,1],["l",0,.72,1,.72],["l",.5,.72,.5,1]]},{id:"bookshelf",group:"furniture",w:80,h:30,g:[["r",0,0,1,1],["l",.34,0,.34,1],["l",.67,0,.67,1]]},{id:"fridge",group:"appliance",w:60,h:65,g:[["r",0,0,1,1],["l",0,.36,1,.36],["l",.83,.44,.83,.64]]},{id:"stove",group:"appliance",w:60,h:60,g:[["r",0,0,1,1],["e",.29,.31,.15,.15],["e",.71,.31,.15,.15],["e",.29,.71,.15,.15],["e",.71,.71,.15,.15]]},{id:"dishwasher",group:"appliance",w:60,h:60,g:[["r",0,0,1,1],["r",.1,.12,.8,.76],["e",.5,.5,.27,.27],["e",.5,.5,.13,.13]]},{id:"washer",group:"appliance",w:60,h:60,g:[["r",0,0,1,1],["l",.08,.17,.92,.17],["e",.5,.57,.3,.3],["e",.5,.57,.14,.14]]},{id:"dryer",group:"appliance",w:60,h:60,g:[["r",0,0,1,1],["l",.08,.17,.92,.17],["e",.5,.57,.3,.3],["p",.36,.5,.5,.64,.64,.5]]},{id:"tv",group:"appliance",w:120,h:30,g:[["r",0,0,1,.42],["l",.5,.42,.5,.72],["l",.3,.72,.7,.72]]},{id:"ac",group:"appliance",w:90,h:25,g:[["r",0,0,1,1],["l",.05,.55,.95,.55],["l",.05,.79,.95,.79]]},{id:"water_heater",group:"appliance",w:45,h:45,g:[["e",.5,.5,.5,.5],["e",.5,.5,.31,.31]]},{id:"toilet",group:"sanitary",w:40,h:70,g:[["r",.06,0,.88,.2],["e",.5,.58,.37,.35],["e",.5,.58,.22,.2]]},{id:"bathtub",group:"sanitary",w:170,h:75,g:[["r",0,0,1,1],["r",.05,.11,.77,.78],["e",.89,.5,.045,.1]]},{id:"shower",group:"sanitary",w:90,h:90,g:[["r",0,0,1,1],["l",0,0,1,1],["l",1,0,0,1],["e",.5,.5,.08,.08]]},{id:"sink",group:"sanitary",w:60,h:45,g:[["r",0,0,1,1],["e",.5,.6,.34,.3],["e",.5,.15,.07,.07]]},{id:"kitchen_sink",group:"sanitary",w:80,h:60,g:[["r",0,0,1,1],["r",.06,.24,.44,.64],["r",.54,.24,.4,.64],["e",.5,.12,.06,.06]]},{id:"bidet",group:"sanitary",w:40,h:55,g:[["e",.5,.5,.44,.5],["e",.5,.5,.26,.3]]},{id:"stairs",group:"other",w:100,h:280,g:[["r",0,0,1,1],["l",0,.111,1,.111],["l",0,.222,1,.222],["l",0,.333,1,.333],["l",0,.444,1,.444],["l",0,.556,1,.556],["l",0,.667,1,.667],["l",0,.778,1,.778],["l",0,.889,1,.889],["l",.5,.93,.5,.06],["p",.38,.16,.5,.06,.62,.16]]},{id:"fireplace",group:"other",w:120,h:40,g:[["r",0,0,1,1],["p",.22,1,.22,.42,.78,.42,.78,1]]},{id:"plant",group:"other",w:40,h:40,g:[["e",.5,.5,.22,.22],["l",.5,.28,.5,.02],["l",.5,.72,.5,.98],["l",.28,.5,.02,.5],["l",.72,.5,.98,.5],["l",.34,.34,.13,.13],["l",.66,.66,.87,.87],["l",.66,.34,.87,.13],["l",.34,.66,.13,.87]]},{id:"rug",group:"other",w:200,h:140,g:[["r",0,0,1,1],["r",.06,.09,.88,.82]]}],wc=new Map(bc.map(t=>[t.id,t]));function kc(t){return t&&wc.get(t)||null}function xc(t){return bc.filter(e=>e.group===t)}function $c(t,e,i=Jl,s=1e3){const n=Number(e)>0?Number(e):5;return(Number(t)||0)/n*i/s}const Sc=5e-4,Mc=Kl;function Cc(t){return Number.isFinite(t)?Math.max(Sc,Math.min(Mc,t)):Sc}const Dc=t=>{const e=Math.round(1e3*t)/1e3;return Object.is(e,-0)?"0":String(e)};function Tc(t,e,i){const s=kc(t);if(!(s&&e>0&&i>0))return"";const n=t=>Dc(t*e),o=t=>Dc(t*i),a=[];for(const t of s.g)if("r"===t[0]){const[,e,i,s,r]=t;a.push(`M${n(e)} ${o(i)}H${n(e+s)}V${o(i+r)}H${n(e)}Z`)}else if("l"===t[0]){const[,e,i,s,r]=t;a.push(`M${n(e)} ${o(i)}L${n(s)} ${o(r)}`)}else if("e"===t[0]){const[,s,r,l,c]=t;a.push(`M${n(s-l)} ${o(r)}A${Dc(l*e)} ${Dc(c*i)} 0 0 1 ${n(s+l)} ${o(r)}A${Dc(l*e)} ${Dc(c*i)} 0 0 1 ${n(s-l)} ${o(r)}Z`)}else{const e=t.slice(1);if(e.length<4)continue;let i=`M${n(e[0])} ${o(e[1])}`;for(let t=2;t+1{let e=(t%360+360)%360;return e>180&&(e-=360),e};function Rc(t,e,i,s,n,o=0){let a=null,r=n;for(const n of s){const[s,l,c,h]=n,d=c-s,u=h-l,p=d*d+u*u;if(!p)continue;const _=Math.sqrt(p);let g=((t-s)*d+(e-l)*u)/p;g=Math.max(0,Math.min(1,g));let m=s+g*d,f=l+g*u;const v=Math.hypot(t-m,e-f);if(!(v0){const t=Math.round(g*_/o)*o;m=s+t/_*d,f=l+t/_*u}a={cx:m+y*(i/2),cy:f+b*(i/2),angle:Pc(180*Math.atan2(-y,b)/Math.PI),dist:v}}return a}function Ac(t,e,i){const s=i;return{a:[t[0]/s,t[1]/s],b:[e[0]/s,e[1]/s]}}function Ic(t,e){const i=e;return[t.a[0]*i,t.a[1]*i,t.b[0]*i,t.b[1]*i]}function Ec(t){return Array.isArray(t)&&t.length>=2&&Number.isFinite(Number(t[0]))&&Number.isFinite(Number(t[1]))}function Fc(t){if(!Array.isArray(t))return[];const e=[];for(const i of t){if(!i||"object"!=typeof i)continue;const t=i;if(!Ec(t.a)||!Ec(t.b))continue;const s=[Number(t.a[0]),Number(t.a[1])],n=[Number(t.b[0]),Number(t.b[1])];Math.hypot(n[0]-s[0],n[1]-s[1])<.001||e.push({a:s,b:n})}return e}function zc(t,e){const i=e[0],s=e[1],n=e[2]-i,o=e[3]-s,a=n*n+o*o;if(a<1e-18){return{q:[i,s],t:0,d:Math.hypot(t[0]-i,t[1]-s)}}let r=((t[0]-i)*n+(t[1]-s)*o)/a;r=Math.max(0,Math.min(1,r));const l=[i+r*n,s+r*o];return{q:l,t:r,d:Math.hypot(t[0]-l[0],t[1]-l[1])}}function Oc(t,e){return zc(t,e).q}function Hc(t,e,i,s,n){const o=zc(t,e).q;let a=o,r=1/0;for(const t of i){const e=Math.hypot(o[0]-t[0],o[1]-t[1]);e<=n&&e0?s:1,g=Math.round(p/_)*_,m=Math.max(0,Math.min(u,g))/u;return[l+h*m,c+d*m]}function Nc(t,e){const i=[],s=(t||[]).filter(t=>t?.id);for(let t=0;tt?.id),a=Fc(e);if(a.length)return Kc(a,t,i,s).map(t=>Ic(t,i));if(!n)return[];const r=[],l=(t,e)=>(t.open_to||[]).includes(e.id)||(e.open_to||[]).includes(t.id);for(let t=0;tAc([t[0],t[1]],[t[2],t[3]],e))}function qc(t,e,i,s){for(const e of t||[])e.open_to&&delete e.open_to;if(!i.length)return;const n=(e||[]).filter(t=>t?.id);new Map(n.map(t=>[t.id,t]));const o=new Map((t||[]).filter(t=>t?.id).map(t=>[t.id,t])),a=(t,e)=>{const i=o.get(t),s=o.get(e);i&&s&&((i.open_to||[]).includes(e)||(i.open_to=[...i.open_to||[],e]),(s.open_to||[]).includes(t)||(s.open_to=[...s.open_to||[],t]))};for(let t=0;tNs(i,t)<4*s)){a(n[t].id,n[e].id);break}}}for(const e of t||[])e.open_to&&!e.open_to.length&&delete e.open_to}function jc(t,e,i,s=0){const n=e[2]-e[0],o=e[3]-e[1],a=Math.hypot(n,o);if(!(a>1e-9))return null;const r=n/a,l=o/a,c=(t[0]-e[0])*r+(t[1]-e[1])*l;if(c<-s||c>a+s)return null;return Math.abs((t[0]-e[0])*l-(t[1]-e[1])*r)>i?null:Ns(t,e)}function Wc(t,e,i){const s=t[2]-t[0],n=t[3]-t[1],o=e[2]-e[0],a=e[3]-e[1],r=Math.hypot(s,n),l=Math.hypot(o,a);return r>1e-9&&l>1e-9&&(!(Math.abs(s/r*(a/l)-n/r*(o/l))>1e-6)&&(Ns([e[0],e[1]],t)<=4*i||Ns([t[0],t[1]],e)<=4*i))}function Uc(t,e,i){if(!t.length)return null;t.sort((t,e)=>t.distance-e.distance);const s=t[0];for(let n=1;ne)break;if(o.semantic!==s.semantic||!Wc(s.seg,o.seg,i))return"ambiguous"}return s}function Gc(t,e,i,s,n=1,o=15){const a=function(t,e,i,s,n=1,o=15){const[a,r]=yr([e[0],e[1]],[e[2],e[3]]);let l=0,c=1/0;const h=[(e[0]+e[2])/2,(e[1]+e[3])/2];for(const e of i){const[i,o]=yr([e[0],e[1]],[e[2],e[3]]);if(Math.abs(a*o-r*i)>.05)continue;const d=Dr(t,[e[0],e[1]],[e[2],e[3]],s,n);if(!(d>0))continue;const u=[(e[0]+e[2])/2,(e[1]+e[3])/2],p=Math.hypot(u[0]-h[0],u[1]-h[1]);p0?l:o}(t,e,i,s,n,o);return Ar(t,[e[0],e[1]],[e[2],e[3]],a,s,n)}function Vc(t,e,i){const s=[[t[0],t[1]],[t[2],t[3]]],n=[(t[0]+t[2])/2,(t[1]+t[3])/2];for(const o of e)if(!(Ns(n,o)>Math.hypot(t[2]-t[0],t[3]-t[1])&&Ns([o[0],o[1]],t)>i))for(const e of[[o[0],o[1]],[o[2],o[3]]])Ns(e,t)<=2*i&&s.push(e);return s}function Kc(t,e,i,s){const n=Fc(t);if(!n.length)return[];const o=Nc(e,s);if(!o.length)return[];const a=[],r=Math.max(4*s,1e-6);for(const t of n){const e=Ic(t,i),n=e[0],l=e[1],c=e[2]-n,h=e[3]-l,d=Math.hypot(c,h);if(d4*s||o>4*s)continue;const a=(t[0]-n)*u+(t[1]-l)*p,c=(t[2]-n)*u+(t[3]-l)*p,h=Math.max(0,Math.min(a,c)),g=Math.min(d,Math.max(a,c));if(g-ht.lo-e.lo||t.hi-e.hi);const i=[];for(const t of e){const e=i[i.length-1];e&&t.lo<=e.hi+r?e.hi=Math.max(e.hi,t.hi):i.push({...t})}for(const e of i){const i=[n+u*e.lo,l+p*e.lo],s=[n+u*e.hi,l+p*e.hi];Math.hypot(s[0]-i[0],s[1]-i[1])i.pair===t&&Math.abs(i.ux*a-i.uy*o)<=1e-6&&Math.abs((e[0]-i.origin[0])*i.uy-(e[1]-i.origin[1])*i.ux)<=c&&Math.abs((e[2]-i.origin[0])*i.uy-(e[3]-i.origin[1])*i.ux)<=c);h||(h={pair:t,origin:[e[0],e[1]],ux:o,uy:a,ranges:[]},l.push(h));const d=(e[0]-h.origin[0])*h.ux+(e[1]-h.origin[1])*h.uy,u=(e[2]-h.origin[0])*h.ux+(e[3]-h.origin[1])*h.uy;h.ranges.push({lo:Math.min(d,u),hi:Math.max(d,u)})}const h=[];for(const t of l){t.ranges.sort((t,e)=>t.lo-e.lo||t.hi-e.hi);const e=[];for(const i of t.ranges){const t=e[e.length-1];t&&i.lo<=t.hi+r?t.hi=Math.max(t.hi,i.hi):e.push({...i})}for(const s of e){const e=[t.origin[0]+t.ux*s.lo,t.origin[1]+t.uy*s.lo],n=[t.origin[0]+t.ux*s.hi,t.origin[1]+t.uy*s.hi];Math.hypot(n[0]-e[0],n[1]-e[1])>=r&&h.push(Ac(e,n,i))}}return h}function Yc(t,e,i,s){const n=Fc(t);if(!n.length)return[];if(e.length!==i.length)return n;const o=[];for(const t of n){const n=Ic(t,s),a=[n[0],n[1]],r=[n[2],n[3]];let l=a,c=r;for(let t=0;t{const e=zc(t,[s[0],s[1],n[0],n[1]]);if(e.d>.001)return t;const i=h[0]-o[0],a=h[1]-o[1];return[o[0]+i*e.t,o[1]+a*e.t]};if(zc([(a[0]+r[0])/2,(a[1]+r[1])/2],[s[0],s[1],n[0],n[1]]).d<.01){l=d(a),c=d(r);break}}o.push(Ac(l,c,s))}return o}const Xc=15e3,Jc=2e3,Zc=new WeakMap;function Qc(t,e){let i=Zc.get(t);if(!i){const e=new Set;i={hiddenAt:"hidden"===t.visibilityState?Date.now():0,token:0,subscribers:e,onVisibility:()=>{const e=Zc.get(t);if(!e)return;const i=Date.now();if("hidden"===t.visibilityState){e.hiddenAt||(e.hiddenAt=i);const t={kind:"hidden",token:e.token,at:i,hiddenFor:0,long:!1};for(const i of[...e.subscribers])i(t);return}const s=e.hiddenAt?Math.max(0,i-e.hiddenAt):0;e.hiddenAt=0,e.token++;const n={kind:"visible",token:e.token,at:i,hiddenFor:s,long:s>=Xc};for(const t of[...e.subscribers])t(n)},onPageShow:e=>{const i=Zc.get(t);if(!i)return;const s=Date.now();i.token++;const n={kind:"pageshow",token:i.token,at:s,hiddenFor:0,long:!!e.persisted,persisted:!!e.persisted};for(const t of[...i.subscribers])t(n)}},Zc.set(t,i),t.addEventListener("visibilitychange",i.onVisibility),t.defaultView?.addEventListener("pageshow",i.onPageShow)}return i.subscribers.add(e),()=>{const i=Zc.get(t);i&&(i.subscribers.delete(e),i.subscribers.size||(t.removeEventListener("visibilitychange",i.onVisibility),t.defaultView?.removeEventListener("pageshow",i.onPageShow),Zc.delete(t)))}}const th={now:()=>Date.now(),setTimeout:(t,e)=>window.setTimeout(t,e),clearTimeout:t=>window.clearTimeout(t),requestAnimationFrame:t=>window.requestAnimationFrame(t),cancelAnimationFrame:t=>window.cancelAnimationFrame(t)};class eh{constructor(t,e=th){this.onChange=t,this.clock=e,this._state="steady",this._token=0,this._frameFingerprint="",this._hasCompleteFrame=!1,this._overlayPhase="none",this._recoveryReason=null,this._overlayTimer=0,this._overlayRaf=0,this._overlayOpaqueAt=0,this._barrierRafs=new Set,this._trace=[],this._disposed=!1}get state(){return this._state}get token(){return this._token}get frameFingerprint(){return this._frameFingerprint}get hasCompleteFrame(){return this._hasCompleteFrame}get overlayPhase(){return this._overlayPhase}get overlayVisible(){return"none"!==this._overlayPhase}get overlayBlocksInteraction(){return this.overlayVisible}get recoveryReason(){return this._recoveryReason}get trace(){return this._trace.map(t=>({...t,...t.stage?{stage:[...t.stage]}:{}}))}note(t,e={}){this.record(t,void 0,e)}record(t,e,i={}){this._trace.push({at:this.clock.now(),token:this._token,event:t,state:this._state,...e?{reason:e}:{},...i}),this._trace.length>80&&this._trace.splice(0,this._trace.length-80)}changed(){this._disposed||this.onChange()}adoptCompleteFrame(t){t&&(this._hasCompleteFrame=!0,this._frameFingerprint=t,this._state="steady",this._recoveryReason=null,this.clearOverlay(),this.record("frame-adopted"),this.changed())}markCompleteFrame(t){t&&(this._hasCompleteFrame=!0,this._frameFingerprint=t,this._state="steady",this._recoveryReason=null,this.clearOverlay(),this.record("frame-complete"),this.changed())}refreshCompleteFrame(t){!this._disposed&&this._hasCompleteFrame&&"steady"===this._state&&t&&t!==this._frameFingerprint&&(this._frameFingerprint=t,this.record("frame-refreshed"))}visibility(t){return"hidden"===t.kind?(this.record("visibility-hidden"),this._token):t.long||"visible"!==t.kind&&"pageshow"!==t.kind?this.beginCandidate("pageshow"===t.kind?"pageshow":"long-resume"):(this.record("pageshow"===t.kind?"pageshow-noop":"visibility-visible-quick"),this._token)}beginCandidate(t,e="plan"){return this._token++,this._recoveryReason=e,this._hasCompleteFrame?(this._state="connection"===e?"offline-stale":"holding",this.clearOverlay()):this.overlayVisible?this._state="overlay-visible":(this._state="overlay-pending",this.scheduleOverlay(e)),this.record("candidate-start",t),this.changed(),this._token}connectionLost(){return this.beginCandidate("connection-lost","connection")}candidateReady(t){return!this._disposed&&t===this._token&&(this._state="candidate-ready",this.record("candidate-ready"),this.changed(),!0)}async commitAfterPaint(t,e){if(this._disposed||t!==this._token)return!1;let i=!0;const s=(async()=>{for(await e.updateComplete();i&&!this._disposed&&t===this._token;)if(e.stageValid()&&e.assetsReady()){if(await this.nextFrame(),t!==this._token||!e.stageValid()||!e.assetsReady())continue;if(await this.nextFrame(),t===this._token&&e.stageValid()&&e.assetsReady())return!0}else await this.nextFrame();return!1})();let n=0;const o=new Promise(t=>{n=this.clock.setTimeout(()=>t({ready:!1,timedOut:!0}),Jc)}),a=await Promise.race([s.then(t=>({ready:t,timedOut:!1})),o]);return i=!1,this.clock.clearTimeout(n),!this._disposed&&t===this._token&&(!(!a.ready&&!a.timedOut)&&(a.ready?(this._hasCompleteFrame=!0,this._frameFingerprint=e.frameFingerprint(),this.record("paint-barrier"),this.finishOverlayAfterCommit(),!0):(this.record("paint-barrier-timeout"),this._hasCompleteFrame?(this._state="connection"===this._recoveryReason?"offline-stale":"steady",this.clearOverlay()):(this._state="recovery-error","opaque"!==this._overlayPhase&&this.showOverlayNow()),this.changed(),!1)))}retry(t=this._recoveryReason||"plan"){return this.beginCandidate("retry",t)}nextFrame(){return new Promise(t=>{const e=this.clock.requestAnimationFrame(()=>{this._barrierRafs.delete(e),t()});this._barrierRafs.add(e)})}scheduleOverlay(t){this.clearOverlayTimer(),this._recoveryReason=t,this._overlayTimer=this.clock.setTimeout(()=>{this._overlayTimer=0,this._hasCompleteFrame||"overlay-pending"!==this._state&&"candidate-ready"!==this._state||(this._state="overlay-visible",this._overlayPhase="entering",this.record("overlay-enter"),this.changed(),this._overlayRaf=this.clock.requestAnimationFrame(()=>{this._overlayRaf=0,"entering"===this._overlayPhase&&(this._overlayPhase="fading-in",this.changed(),this._overlayTimer=this.clock.setTimeout(()=>{this._overlayTimer=0,"fading-in"===this._overlayPhase&&(this._overlayPhase="opaque",this._overlayOpaqueAt=this.clock.now(),this.record("overlay-opaque"),this.changed())},150))}))},150)}showOverlayNow(){this.clearOverlayTimer(),this._overlayPhase="opaque",this._overlayOpaqueAt=this.clock.now(),this.record("overlay-error")}finishOverlayAfterCommit(){if(this.clearOverlayTimer(),"none"===this._overlayPhase||"entering"===this._overlayPhase||"fading-in"===this._overlayPhase)return this.clearOverlay(),this._state="steady",this._recoveryReason=null,this.record("candidate-committed"),void this.changed();const t=Math.max(0,this._overlayOpaqueAt+250-this.clock.now());this._overlayTimer=this.clock.setTimeout(()=>{this._overlayTimer=0,this._overlayPhase="leaving",this.record("overlay-leave"),this.changed(),this._overlayTimer=this.clock.setTimeout(()=>{this._overlayTimer=0,this._overlayPhase="none",this._state="steady",this._recoveryReason=null,this.record("candidate-committed"),this.changed()},180)},t)}clearOverlayTimer(){this._overlayTimer&&this.clock.clearTimeout(this._overlayTimer),this._overlayTimer=0}clearOverlay(){this.clearOverlayTimer(),this._overlayRaf&&this.clock.cancelAnimationFrame(this._overlayRaf),this._overlayRaf=0,this._overlayPhase="none",this._overlayOpaqueAt=0}dispose(){this._disposed=!0,this._token++,this.clearOverlay();for(const t of this._barrierRafs)this.clock.cancelAnimationFrame(t);this._barrierRafs.clear()}}function ih(t){let e=2166136261,i=2654435769;const s=new WeakSet,n=t=>{for(let s=0;s>>0)+(i>>>2)}},o=t=>{if(null===t)return void n("n");const e=typeof t;if("string"===e)return void n(`s${t.length}:${t}`);if("number"===e)return void n(`d${Number.isNaN(t)?"NaN":String(t)}`);if("boolean"===e)return void n(t?"t":"f");if("undefined"===e)return void n("u");if("object"!==e)return void n(`${e}:${String(t)}`);const i=t;if(s.has(i))n("[cycle]");else{if(s.add(i),Array.isArray(t)){n("[");for(const e of t)o(e);return n("]"),void s.delete(i)}n("{");for(const e of Object.keys(t).sort())n(e),o(t[e]);n("}"),s.delete(i)}};return o(t),`${(e>>>0).toString(16).padStart(8,"0")}${(i>>>0).toString(16).padStart(8,"0")}`}function sh(t){return ih(t)}const nh=new WeakMap;class oh{constructor(t,e=()=>Date.now()){this.onUpdate=t,this.now=e,this.fallbackAuthority={},this.referenceOwner={},this.referenced=new Set,this.queued=new Set,this.disposed=!1,this.sharedUpdate=()=>{this.disposed||this.onUpdate()}}bind(t){const e=((t,e)=>{const i=t?.connection||t?.callWS||e;return!i||"object"!=typeof i&&"function"!=typeof i?e:i})(t,this.fallbackAuthority);return this.shared&&this.authority===e||(this.shared&&(this.shared.listeners.delete(this.sharedUpdate),this.shared.references.delete(this.referenceOwner)),this.authority=e,this.shared=(t=>{let e=nh.get(t);return e||(e={signed:{},queued:new Set,inFlight:new Map,retry:new Map,listeners:new Set,settlers:new Set,references:new Map},nh.set(t,e)),e})(e),this.disposed||(this.shared.listeners.add(this.sharedUpdate),this.shared.references.set(this.referenceOwner,new Set(this.referenced)))),this.shared}start(t,e){this.disposed=!1,this.referenced=new Set(e());const i=this.bind(t());i.listeners.add(this.sharedUpdate),i.references.set(this.referenceOwner,new Set(this.referenced)),this.stopTimer(),this.resignTimer=setInterval(()=>this.resign(t(),e()),288e5)}dispose(){if(this.disposed=!0,this.stopTimer(),clearTimeout(this.batchTimer),this.shared){this.shared.listeners.delete(this.sharedUpdate),this.shared.references.delete(this.referenceOwner);for(const t of this.queued)this.shared.queued.delete(t)}this.queued.clear()}invalidate(t){const e=this.bind(t);clearTimeout(this.batchTimer),this.queued.clear(),e.queued.clear(),e.inFlight.clear(),e.retry.clear(),e.signed={}}stopTimer(){void 0!==this.resignTimer&&clearInterval(this.resignTimer),this.resignTimer=void 0}display(t,e){const i=Is(e);if(!i.startsWith("/api/houseplan/content/"))return i;const s=this.bind(t);this.referenced.add(i),s.references.set(this.referenceOwner,new Set(this.referenced));const n=s.signed[i],o=n?this.now()-n.at:1/0;return o{const e=[...this.queued];this.queued.clear();for(const t of e)i.queued.delete(t);this.sign(t,e)},30))}sign(t,e){if(!e.length||!t?.callWS)return;const i=this.bind(t);for(const s of function(t,e){const i=Math.max(1,Math.floor(e)),s=[];for(let e=0;e{const s=i.inFlight.get(t);return!(void 0!==s&&e-s<15e3)&&(i.inFlight.set(t,e),!0)});n.length&&t.callWS({type:"houseplan/content/sign",paths:n}).then(t=>{const e=this.now();let s=0,o=!1;for(const a of n){const n=t?.urls?.[a];if("string"==typeof n&&n){const t=i.signed[a];t?.loaded&&t.url!==n?(t.pending={url:n,at:e},this.preloadReplacement(i,a,n,e)):(i.signed[a]={url:n,at:e,loaded:t?.url===n&&!!t.loaded},o=!0),i.retry.delete(a),s++}else this.backOff(i,a)}if(s&&(this.trimShared(i),o))for(const t of[...i.listeners])t()}).catch(()=>{for(const t of n)this.backOff(i,t)}).finally(()=>{for(const t of n)i.inFlight.get(t)===e&&i.inFlight.delete(t);for(const t of[...i.settlers])t()})}}preloadReplacement(t,e,i,s){const n=()=>{const n=t.signed[e];if(n?.pending?.url===i){t.signed[e]={url:i,at:s,loaded:!0},t.retry.delete(e),this.trimShared(t);for(const e of[...t.listeners])e()}},o=()=>{const s=t.signed[e];s?.pending?.url===i&&(delete s.pending,this.backOff(t,e))};if("undefined"==typeof Image)return void n();const a=new Image;a.onload=()=>{("function"==typeof a.decode?a.decode():Promise.resolve()).then(n).catch(o)},a.onerror=o,a.src=i}preloadCurrentImage(t,e,i){if(i.loaded)return Promise.resolve(!0);if(i.preload)return i.preload;if("undefined"==typeof Image)return i.loaded=!0,Promise.resolve(!0);const s=i.url;return i.preload=new Promise(n=>{const o=new Image;let a=!1;const r=o=>{if(a)return;a=!0,clearTimeout(l);const r=t.signed[e];if(r===i&&delete r.preload,o&&r===i&&r.url===s){r.loaded=!0;for(const e of[...t.listeners])e();n(!0)}else o||r!==i||this.backOff(t,e),n(!1)};o.onload=()=>{("function"==typeof o.decode?o.decode():Promise.resolve()).then(()=>r(!0)).catch(()=>r(!1))},o.onerror=()=>r(!1);const l=setTimeout(()=>r(!1),Jc);o.src=s}),i.preload}prepareImage(t,e){const i=Is(e);if(!i.startsWith("/api/houseplan/content/"))return Promise.resolve(!0);const s=this.bind(t),n=()=>{const e=s.signed[i];if(e&&this.now()-e.atthis.now()&&!s.inFlight.has(i)&&!s.queued.has(i)?Promise.resolve(!1):null},o=n();return o?(a=o,new Promise(t=>{let e=!1;const i=i=>{e||(e=!0,clearTimeout(s),t(i))},s=setTimeout(()=>i(!1),Jc);a.then(i).catch(()=>i(!1))})):new Promise(t=>{let e=!1,i=null;const o=i=>{e||(e=!0,clearTimeout(r),s.settlers.delete(a),t(i))},a=()=>{e||i||(i=n(),i&&i.then(o).catch(()=>o(!1)))},r=setTimeout(()=>o(!1),Jc);s.settlers.add(a),a()});var a}backOff(t,e){const i=t.retry.get(e)?.delay||0,s=Math.min(6e4,i?2*i:2e3);t.retry.set(e,{notBefore:this.now()+s,delay:s})}trimShared(t){const e=Object.entries(t.signed);if(e.length<=512)return;const i=new Set(t.inFlight.keys());for(const e of t.references.values())for(const t of e)i.add(t);for(const[t,s]of e)(s.pending||s.preload)&&i.add(t);e.sort((t,e)=>e[1].at-t[1].at);const s=e.filter(([t])=>i.has(t));for(const t of e){if(s.length>=512)break;i.has(t[0])||s.push(t)}t.signed=Object.fromEntries(s)}resign(t,e){const i=this.bind(t);this.referenced=new Set(e),i.references.set(this.referenceOwner,new Set(this.referenced));const s=this.now(),n=new Set;for(const t of i.references.values())for(const e of t)n.add(e);const o={};for(const[t,e]of Object.entries(i.signed))n.has(t)&&s-e.at!!o[t]&&!o[t].pending))}markLoaded(t,e,i){const s=Is(e);if(!s.startsWith("/api/houseplan/content/"))return;const n=this.bind(t).signed[s];if(n&&(!i||n.url===i)&&!n.loaded){n.loaded=!0;for(const e of[...this.bind(t).listeners])e()}}isReady(t,e){const i=Is(e);if(!i.startsWith("/api/houseplan/content/"))return!0;const s=this.bind(t).signed[i];return!!s&&this.now()-s.at{if(null==t||""===t)return null;const e=Number(t);return Number.isFinite(e)?e:null},ch=t=>{const e=t,i=lh(Array.isArray(e)?e[0]:e?.x),s=lh(Array.isArray(e)?e[1]:e?.y);return null==i||null==s?null:[i,s]};function hh(t){if(!Array.isArray(t))return null;const e=[];for(const i of t){const t=ch(i);if(!t)return null;e.push(t)}if(e.length>1){const t=e[0],i=e[e.length-1];t[0]===i[0]&&t[1]===i[1]&&e.pop()}if(e.length<3)return null;let i=0,s=0,n=0;for(let t=0;tt+e[0],0)/e.length,e.reduce((t,e)=>t+e[1],0)/e.length]:[s/(3*i),n/(3*i)]}function dh(t){if(!Array.isArray(t))return null;const e=[];for(const i of t){const t=ch(i);if(!t)return null;e.push(t)}if(e.length>1){const t=e[0],i=e[e.length-1];t[0]===i[0]&&t[1]===i[1]&&e.pop()}const i=hh(e);if(!i)return null;const s=e.map(t=>t[0]),n=e.map(t=>t[1]);return{centroid:i,bbox:[Math.min(...s),Math.min(...n),Math.max(...s),Math.max(...n)]}}function uh(t){let e=t;if(e&&"object"==typeof e&&!Array.isArray(e)){const t=e;e=t.path??t.points??e}if(!Array.isArray(e)||!e.length)return[];let i=(e.some(t=>(t=>Array.isArray(t)?t.length>=2&&!Array.isArray(t[0])&&("object"!=typeof t[0]||null==t[0]):!!t&&"object"==typeof t&&("x"in t||"y"in t))(t))?[e]:e.filter(Array.isArray)).map(t=>t.map(ch).filter(t=>null!=t)).filter(t=>t.length>=2);i.length>64&&(i=i.slice(-64));if(i.reduce((t,e)=>t+e.length,0)<=4e3)return i.map(t=>t.slice());const s=4e3-2*i.length,n=i.map(t=>t.length-2),o=n.reduce((t,e)=>t+e,0),a=n.map(t=>s*t/o),r=a.map(Math.floor);let l=s-r.reduce((t,e)=>t+e,0);const c=a.map((t,e)=>({index:e,fraction:t-Math.floor(t)})).sort((t,e)=>e.fraction-t.fraction||t.index-e.index);for(let t=0;tfunction(t,e){if(e>=t.length)return t.slice();if(e<=2)return[t[0],t[t.length-1]];const i=[];for(let s=0;st.slice()),i=e[e.length-1];return i?(i.length>2?i.pop():e.pop(),e):[]}function gh(t){if(!t)return null;const e=t.vacuum_position||t.robot_position||null,i=e&&null!=lh(e.x)&&null!=lh(e.y)?{x:lh(e.x),y:lh(e.y),a:lh(e.a??e.angle??e.theta)}:null,s=uh(t.path?.path??t.path?.points??t.path),n=[],o=t.rooms,a=Array.isArray(o)?o.map((t,e)=>[String(t?.id??e),t]):o&&"object"==typeof o?Object.entries(o):[];for(const[t,e]of a){if(!e||"object"!=typeof e)continue;const i=String(e.name??e.label??"").trim(),s=[[lh(e.cx),lh(e.cy)],[lh(e.center?.x),lh(e.center?.y)],[lh(e.x),lh(e.y)]].find(([t,e])=>null!=t&&null!=e);let o=s?.[0]??null,a=s?.[1]??null;const r=dh(e.outline),l=lh(e.x0),c=lh(e.y0),h=lh(e.x1),d=lh(e.y1),u=(null!=l&&null!=c&&null!=h&&null!=d?[Math.min(l,h),Math.min(c,d),Math.max(l,h),Math.max(c,d)]:null)||r?.bbox||null;if(null!=o&&null!=a||!r||([o,a]=r.centroid),null!=o&&null!=a||!u||(o=(u[0]+u[2])/2,a=(u[1]+u[3])/2),i&&null!=o&&null!=a){const e={id:t,name:i,cx:o,cy:a};u&&([e.x0,e.y0,e.x1,e.y1]=u),n.push(e)}}const r=function(t){return String(t.map_name??t.current_map??t.map_index??t.selected_map??"default")}(t);return i||n.length||s.length?{pos:i,path:s,rooms:n,mapId:r}:null}function mh(t,e,i){if(!t||!e)return null;const s=e.attributes||{},n=t.split(".")[0]||"",o=null!=i?.platform?String(i.platform):null,a=!!ch(s.vacuum_position??s.robot_position),r=!(!s.rooms||"object"!=typeof s.rooms),l=uh(s.path?.path??s.path?.points??s.path).length>0,c=[s.map_name,s.current_map,s.map_index,s.selected_map].some(t=>null!=t),h="xiaomi_cloud_map_extractor"===o,d=r||l||c;let u=null;if(a?u="compatible":h?u="known_xcme_incomplete":d?u="partial":"camera"===n&&(u="camera"),!u)return null;const p=a?"camera"===n?300:200:h?100:d?50:0;return{entityId:t,name:String(s.friendly_name||t),platform:o,category:u,hasPosition:a,hasRooms:r,hasPath:l,hasMapId:c,score:p}}const fh=t=>t.toLowerCase().replace(/[\s_\-.,]+/g,"");function vh(t,e){const i=new Map(e.map(t=>[fh(t.name),t])),s=[],n=[];for(const e of t){const t=i.get(fh(e.name));t&&(s.push([[e.cx,e.cy],[t.cx,t.cy]]),n.push(e.name))}if(s.length<3)return null;const o=function(t){if(t.length<3)return null;let e=0,i=0,s=0,n=0,o=0,a=0,r=0,l=0,c=0,h=0,d=0,u=0;for(const[[p,_],[g,m]]of t){if(![p,_,g,m].every(Number.isFinite))return null;e+=p*p,i+=p*_,s+=p,n+=_*_,o+=_,a+=1,r+=p*g,l+=_*g,c+=g,h+=p*m,d+=_*m,u+=m}const p=[e,i,s,i,n,o,s,o,a],_=t=>{const[e,i,s,n,o,a,r,l,c]=p,h=e*(o*c-a*l)-i*(n*c-a*r)+s*(n*l-o*r);if(!Number.isFinite(h)||Math.abs(h)<1e-9)return null;const d=[(o*c-a*l)/h,(s*l-i*c)/h,(i*a-s*o)/h,(a*r-n*c)/h,(e*c-s*r)/h,(s*n-e*a)/h,(n*l-o*r)/h,(i*r-e*l)/h,(e*o-i*n)/h];return[d[0]*t[0]+d[1]*t[1]+d[2]*t[2],d[3]*t[0]+d[4]*t[1]+d[5]*t[2],d[6]*t[0]+d[7]*t[1]+d[8]*t[2]]},g=_([r,l,c]),m=_([h,d,u]);if(!g||!m)return null;const f=[g[0],g[1],g[2],m[0],m[1],m[2]];return f.every(Number.isFinite)?f:null}(s);return o?{matrix:o,matched:n,residual:rh(o,s)}:null}function yh(t,e,i){const s=t[t.length-1];if(s&&s[0]===e[0]&&s[1]===e[1])return t;if(t.push(e),t.length<=600)return t;let n=function(t,e){if(t.length<3)return t.slice();const i=new Uint8Array(t.length);i[0]=i[t.length-1]=1;const s=[[0,t.length-1]];for(;s.length;){const[n,o]=s.pop(),[a,r]=t[n],[l,c]=t[o],h=l-a,d=c-r,u=Math.hypot(h,d)||1e-9;let p=0,_=-1;for(let e=n+1;ep&&(p=i,_=e)}_>0&&p>e&&(i[_]=1,s.push([n,_],[_,o]))}const n=[];for(let e=0;e600&&(n=n.filter((t,e)=>e%2==0||e===n.length-1)),n}function bh(t){return"cleaning"===t||"returning"===t||"on"===t}const wh={0:[1,0],90:[0,1],180:[-1,0],270:[0,-1]};function kh(t){const[e,i]=wh[t.rot]||[1,0],s=t.mir?-1:1;return[t.s*e*s,-t.s*i,t.ox,t.s*i*s,t.s*e,t.oy]}function xh(t){const e=t[0]*t[4]-t[1]*t[3];if(!Number.isFinite(e)||Math.abs(e)<1e-12)return null;const i=e<0,s=Math.sqrt(Math.abs(e));let n=180*Math.atan2(-t[1],t[4])/Math.PI;return n=(90*Math.round(n/90)%360+360)%360,{ox:t[2],oy:t[5],s:s,rot:n,mir:i}}function $h(t,e,i,s){const[n,o]=ah(kh(e),i,s),a=kh({...t,ox:0,oy:0}),[r,l]=ah(a,i,s);return{...t,ox:n-r,oy:o-l}}function Sh(t){const e=t?.trail_mode;return"never"===e||"cleaning"===e||"always"===e?e:!1===t?.trail?"never":"cleaning"}const Mh={offStates:["off"],unknownUsesToggle:!0},Ch={light:Mh,switch:Mh,fan:Mh,humidifier:Mh,input_boolean:Mh,automation:Mh,remote:Mh,group:Mh,climate:{...Mh,featureMasks:{turn_on:256,turn_off:128,toggle:384}},media_player:{...Mh,featureMasks:{turn_on:128,turn_off:256,toggle:384}},siren:{...Mh,featureMasks:{turn_on:1,turn_off:2,toggle:3}},vacuum:{...Mh,featureMasks:{turn_on:1,turn_off:2,toggle:3}},water_heater:{...Mh,featureMasks:{turn_on:8,turn_off:8,toggle:8}},camera:{...Mh,featureMasks:{turn_on:1,turn_off:1,toggle:1}}};function Dh(t){return t.slice(0,t.indexOf("."))}function Th(t,e,i){if(!t?.services||"object"!=typeof t.services)return!1;const s=t.services?.[e];return!!s&&Object.prototype.hasOwnProperty.call(s,i)}function Ph(t,e,i){return Th(t,e,i)?{domain:e,service:i}:Th(t,"homeassistant",i)?{domain:"homeassistant",service:i}:null}function Rh(t,e){return t?.entities?.[e]||null}function Ah(t,e,i){const s=t?.states?.[i],n=Rh(e,i);return s?.attributes?.friendly_name||n?.name||n?.original_name||i}function Ih(t,e){const i=Rh(t,e);if(null!=i?.disabled_by)return!0;const s=i?.device_id?t?.devices?.[i.device_id]:null;return null!=s?.disabled_by}function Eh(t,e){const i=t?.attributes?.supported_features;if(null==i||""===i)return!1;const s=Number(i);return Number.isFinite(s)&&(s&e)===e}function Fh(t,e,i){const s=Dh(i);if("lock"===s||"alarm_control_panel"===s)return!0;if("cover"!==s)return!1;const n=t?.states?.[i],o=Rh(e,i),a=String(n?.attributes?.device_class||o?.device_class||o?.original_device_class||"");return Ui.has(a)}function zh(t,e,i,s,n){return{ref:i,entityId:s,name:s?Ah(t,e,s):null,reason:n}}function Oh(t,e,i,s,n,o=null){return{target:null,skipped:zh(t,e,i,s,n),semantics:o,nextEffect:null,command:null}}function Hh(t,e,i,s,n=i){const o=Dh(i);if("cover"!==o&&"valve"!==o)return function(t,e,i,s,n=i){const o=Dh(i),a=t?.states?.[i];if(Ih(e,i))return Oh(t,e,n,i,"ha-disabled","power");if(Fh(t,e,i))return Oh(t,e,n,i,"secure");if(!a)return Oh(t,e,n,i,"missing","power");if("unavailable"===a.state)return Oh(t,e,n,i,"unavailable","power");const r=Ch[o];if(!r)return Oh(t,e,n,i,"unsupported");let l,c;if("unknown"===a.state||""===a.state){if(!r.unknownUsesToggle)return Oh(t,e,n,i,"unsupported","power");l="toggle",c="toggle"}else r.offStates.includes(String(a.state))?(l="turn-on",c="turn_on"):(l="turn-off",c="turn_off");const h=r.featureMasks?.[c];if(h&&!Eh(a,h))return Oh(t,e,n,i,"unsupported","power");const d=Ph(t,o,c);return d?{target:{entityId:i,name:Ah(t,e,i),state:String(a.state||""),via:s},skipped:null,semantics:"power",nextEffect:l,command:{...d,data:{entity_id:i}}}:Oh(t,e,n,i,"unsupported","power")}(t,e,i,s,n);if(Ih(e,i))return Oh(t,e,n,i,"ha-disabled",o);if(Fh(t,e,i))return Oh(t,e,n,i,"secure",o);const a=t?.states?.[i];if(!a)return Oh(t,e,n,i,"missing",o);if("unavailable"===a.state)return Oh(t,e,n,i,"unavailable",o);const r=function(t,e,i){const s=String(i?.state||""),n="closed"===s?{service:`open_${e}`,effect:"open",feature:1}:"open"===s?{service:`close_${e}`,effect:"close",feature:2}:"opening"===s||"closing"===s?{service:`stop_${e}`,effect:"stop",feature:8}:null;return n&&Eh(i,n.feature)&&Th(t,e,n.service)?n:Eh(i,3)&&Th(t,e,"toggle")?{service:"toggle",effect:"toggle"}:null}(t,o,a);if(!r)return Oh(t,e,n,i,"unsupported",o);return{target:{entityId:i,name:Ah(t,e,i),state:String(a.state||""),via:s},skipped:null,semantics:o,nextEffect:r.effect,command:{domain:o,service:r.service,data:{entity_id:i}}}}function Nh(t){return"entity"===t.bindingKind?t.bindingRef&&Ms(t.bindingRef)?[t.bindingRef]:[]:"virtual"===t.bindingKind?[]:Zn(t)}function Lh(t){const e=t.marker?.toggle_entity;return e&&Nh(t).includes(e)?e:null}function Bh(t,e,i){const s=function(t,e){if("entity"===t.bindingKind&&t.bindingRef){const e=t.marker?.light_entity?Qn(t):null;return[...new Set([e,t.bindingRef].filter(t=>!!t))]}const i=t.entities.length?t.entities:t.allEntities||[],s=t.marker?.light_entity||t.primary&&Ms(t.primary)?Qn(t):null;return[...new Set([s,...Vn(e,i)].filter(t=>!!t))]}(i,e);if(!s.length)return null;const n="entity"===i.bindingKind?"binding":"device-role";if("binding"===n)return Hh(t,e,s[0],n);let o=null,a=null;for(const i of s){const s=Hh(t,e,i,n);if(s.command)return s;const r=s.skipped?.reason;if("missing"===r||"unavailable"===r||"secure"===r)return s;"ha-disabled"!==r?o||=s:a||=s}return o||a}function qh(t){const e=t.skipped?.reason;return"missing"===e?"unavailable":e||"unsupported"}function jh(t,e){return{origin:t,kind:"none",semantics:null,targets:[],skippedTargets:[],noneReason:e,nextEffect:null,command:null}}function Wh(t,e){return"cover"===t||"toggle"===t?"toggle":"more-info"===t||"run"===t||"info"===t?t:(null==t||""===t)&&"light"===e?"toggle":"info"}function Uh(t,e){return{origin:t,kind:"single",semantics:e.semantics,targets:e.target?[e.target]:[],skippedTargets:e.skipped?[e.skipped]:[],noneReason:e.command?null:qh(e),nextEffect:e.nextEffect,command:e.command}}function Gh(t,e,i,s=[]){const n=new Map,o=[],a=new Set,r=t=>{const e=`${t.ref}\n${t.entityId||""}\n${t.reason}`;a.has(e)||(a.add(e),o.push(t))};for(const t of s)r(t);for(const s of i){const i=Hh(t,e,s.entityId,s.via,s.ref);i.target?n.set(s.entityId,n.get(s.entityId)||i.target):i.skipped&&r(i.skipped)}const l=[...n.values()];if(!l.length)return{origin:"explicit-toggle",kind:"group",semantics:"group-power",targets:l,skippedTargets:o,noneReason:o.length&&o.every(t=>"secure"===t.reason)?"secure":"configured-targets-missing",nextEffect:null,command:null};const c=l.some(t=>"on"===t.state)?"turn_off":"turn_on",h=Ph(t,"homeassistant",c);return h?{origin:"explicit-toggle",kind:"group",semantics:"group-power",targets:l,skippedTargets:o,noneReason:null,nextEffect:"turn_on"===c?"turn-on":"turn-off",command:{...h,data:{entity_id:l.map(t=>t.entityId)}}}:{origin:"explicit-toggle",kind:"group",semantics:"group-power",targets:[],skippedTargets:[...o,...l.map(i=>zh(t,e,i.entityId,i.entityId,"unsupported"))],noneReason:"unsupported",nextEffect:null,command:null}}function Vh(t){return String(t.marker?.id||t.id||"")}function Kh(t){const{hass:e,device:i}=t,s=t.registryHass||e,n=function(t){return"toggle"===t.tapAction?"explicit-toggle":"cover"===t.tapAction?"legacy-cover":!t.tapAction&&t.primary?.startsWith("light.")?"default-light":null}(i);if(!n)return null;const o=i.marker;if("explicit-toggle"===n&&yn(o)){const e=String(o?.id||i.id||""),s=oo(t.devices).get(e);if(s)return function(t,e){const i=t.registryHass||t.hass;return Gh(t.hass,i,e.driverEids.map(t=>({entityId:t,via:"control-marker-driver",ref:`marker:${e.markerId}`})))}(t,s);const a=bn(o,t.virtualLights);return{origin:n,kind:"single",semantics:"power",targets:[{entityId:"",name:i.name,state:a?"on":"off",via:"virtual-light"}],skippedTargets:[],noneReason:null,nextEffect:a?"turn-off":"turn-on",command:null,operation:{kind:"virtual-light",markerId:o.id}}}if("explicit-toggle"===n){if(Xn(i.marker?.binding,i.marker?.controls??i.controls,i.entities).length)return function(t,e=null){const{hass:i,device:s,devices:n}=t,o=t.registryHass||i,a=Xn(s.marker?.binding,s.marker?.controls??s.controls,s.entities),r=t.lightSources||lo(i,n,null,t.virtualLights),l=new Map;for(const t of r){if(!t.key.startsWith("marker:"))continue;const e=l.get(t.key)||[];e.push(t),l.set(t.key,e)}const c=oo(n),h=new Map;for(const t of n){const e=String(t.marker?.id||t.id||"");e&&h.set(e,t)}const d=[],u=[];e&&d.push({entityId:e,via:"entity"===s.bindingKind?"binding":"device-role",ref:e});for(const t of a){if(!t.startsWith("marker:")){Ms(t)?d.push({entityId:t,via:"control-entity",ref:t}):u.push(zh(i,o,t,t.includes(".")?t:null,"unsupported"));continue}const e=l.get(t)||[];if(!e.length){const e=h.get(t.slice(7));if("ha_disabled"===e?.bindingStatus?.kind){const s=e.bindingStatus.allEntityIds[0]||null;u.push({ref:t,entityId:s,name:e.name||(s?Ah(i,o,s):null),reason:"ha-disabled"})}else u.push(zh(i,o,t,null,"missing"));continue}const n=[...new Set(e.flatMap(t=>t.serviceEids))];if(n.length){for(const e of n)d.push({entityId:e,via:"control-entity",ref:t});continue}const a=e.some(t=>t.passive),r=t.slice(7),p=Vh(s),_=c.get(r)?.controllers.find(t=>Vh(t.device)===p);if(a&&_?.driverEids.length)for(const e of _.driverEids)d.push({entityId:e,via:"control-marker-driver",ref:t});else u.push(zh(i,o,t,null,a?"missing":"unsupported"))}return Gh(i,o,d,u)}(t,Lh(i))}if("legacy-cover"===n){const t=i.entities.find(t=>t.startsWith("cover."))||i.allEntities?.find(t=>t.startsWith("cover."));return t?Uh(n,Hh(e,s,t,"device-role")):jh(n,"no-actionable-entity")}const a=Lh(i),r=a?Hh(e,s,a,"entity"===i.bindingKind?"binding":"device-role"):Bh(e,s,i);return r?Uh(n,r):jh(n,i.virtual||"virtual"===i.bindingKind?"no-actionable-entity":"no-binding")}function Yh(t){if(!t)return[];const e=Array.isArray(t.data.entity_id)?t.data.entity_id:[t.data.entity_id];return[...new Set(e)].sort()}function Xh(t){return t?t.operation?t.operation:t.command?{kind:"ha-service",command:t.command}:null:null}function Jh(t,e){const i=Xh(t),s=Xh(e);return!(!i||!s||i.kind!==s.kind)&&("virtual-light"===i.kind&&"virtual-light"===s.kind?i.markerId===s.markerId:"ha-service"===i.kind&&"ha-service"===s.kind&&function(t,e){const i=Yh(t),s=Yh(e);return i.length===s.length&&i.every((t,e)=>t===s[e])}(i.command,s.command))}const Zh=t=>!!t&&t.length>=2&&Number.isFinite(t[0])&&Number.isFinite(t[1]);function Qh(t,e=5,i=5){return fr(t.cm,e,i)/2}function td(t,e,i=1,s=5,n=5,o=0){const a=t.host;if(!a||"partition"!==a.kind||"string"!=typeof a.id||!a.id)return{resolved:null,reason:"invalid-host"};const r=e.find(t=>t.id===a.id);if(!r)return{resolved:null,reason:"missing-partition"};if(!Zh(r.a)||!Zh(r.b)||!Number.isFinite(a.t)||a.t<0||a.t>1)return{resolved:null,reason:"invalid-position"};const l=r.b[0]-r.a[0],c=r.b[1]-r.a[1],h=Math.hypot(l,c),d=Number(t.length)*i;if(!(h>1e-9&&d>0&&Number.isFinite(d)))return{resolved:null,reason:"invalid-length"};const u=a.t*h;if(u-d/2h-o+1e-9)return{resolved:null,reason:"does-not-fit"};const p=l/h,_=c/h;let g=180*Math.atan2(c,l)/Math.PI;return g>=90?g-=180:g<-90&&(g+=180),{reason:null,resolved:{opening:t,host:a,partition:r,center:[r.a[0]+l*a.t,r.a[1]+c*a.t],angle:g,length:d,depth:fr(r.cm,s,n),t:a.t,axis:{a:[r.a[0],r.a[1]],b:[r.b[0],r.b[1]],ux:p,uy:_,length:h}}}}function ed(t,e,i=1,s=5,n=5){return td(t,e,i,s,n,0)}function id(t,e,i=1,s=5,n=5){const o=t.host,a="partition"===o?.kind?e.find(t=>t.id===o.id):void 0;if(!a)return ed(t,e,i,s,n);const r=td(t,e,i,s,n,Qh(a,s,n));return"does-not-fit"===r.reason?{resolved:null,reason:"does-not-fit-jamb"}:r}function sd(t,e){return!t||(t.length!==e.length||t.host?.kind!==e.host?.kind||t.host?.id!==e.host?.id||t.host?.t!==e.host?.t)}function nd(t){const{center:e,length:i,axis:s,host:n}=t,o=i/2;return{hostId:n.id,a:[e[0]-s.ux*o,e[1]-s.uy*o],b:[e[0]+s.ux*o,e[1]+s.uy*o],depth:t.depth}}function od(t,e=!1){const i=e?1:-1,s=t.depth/2;return{ox:-t.axis.uy*i*s,oy:t.axis.ux*i*s,cm:t.partition.cm,side:i}}function ad(t,e,i){const{center:s,length:n,axis:o}=t,a=n/2,r=e.flatMap(t=>{if(!t.kind||t.open)return[];const e=t.b[0]-t.a[0],n=t.b[1]-t.a[1],r=Math.hypot(e,n);if(!(r>i))return[];const l=e/r,c=n/r;if(Math.abs(o.ux*c-o.uy*l)>1e-6)return[];if(Math.abs((s[0]-t.a[0])*c-(s[1]-t.a[1])*l)>i)return[];const h=t=>(t[0]-s[0])*o.ux+(t[1]-s[1])*o.uy,d=h(t.a),u=h(t.b),p=Math.max(-a,Math.min(d,u)),_=Math.min(a,Math.max(d,u));return _>=p-i?[[p,_]]:[]});if(!r.length)return!1;r.sort((t,e)=>t[0]-e[0]||t[1]-e[1]);let l=-a;for(const[t,e]of r){if(t>l+i)return!1;if(l=Math.max(l,e),l>=a-i)return!0}return!1}function rd(t,e,i){return{...t,x:e.center[0]/i,y:e.center[1]/i,angle:e.angle}}function ld(t){return!!t&&t.length>=2&&Number.isFinite(t[0])&&Number.isFinite(t[1])}function cd(t){return`${t[0].toFixed(6)},${t[1].toFixed(6)}`}function hd(t,e,i){return Math.abs(t[0]-e[0])_d(s,t,e)))continue;const t=cd(s);a.has(t)||a.set(t,{point:[s[0],s[1]],key:t})}}}return{segments:[...o.values()].sort((t,e)=>t.key.localeCompare(e.key)),endpoints:[...a.values()].sort((t,e)=>t.key.localeCompare(e.key))}}function md(t,e,i){return e.some(e=>ld(e)&&hd(t,e,i))}function fd(t,e,i){if(!i)return!0;const s=t-i.distance;return s<-1e-9||Math.abs(s)<=1e-9&&e.localeCompare(i.key)<0}function vd(t,e,i){const s=t.b[0]-t.a[0],n=t.b[1]-t.a[1],o=Math.hypot(s,n);if(!(o>0))return[...t.a];const a=s/o,r=n/o,l=Math.max(0,Math.min(o,(e[0]-t.a[0])*a+(e[1]-t.a[1])*r)),c=i>0?Math.max(0,Math.min(o,Math.round(l/i)*i)):l;return[t.a[0]+a*c,t.a[1]+r*c]}const yd=.001;function bd(t,e,i){const s=[];for(let n=0;n+1=0?e[n]:i;s.push({a:[o[0],o[1]],b:[a[0],a[1]],cm:r})}return s}function wd(t){return!!t&&t.length>=2&&Number.isFinite(t[0])&&Number.isFinite(t[1])}function kd(t,e,i,s){return t*s-e*i}function xd(t){let e=0;for(let i=0;it.localeCompare(e)),e[0]}function Dd(t,e,i){const s=[...t];for(let t=!0;t&&s.length>=3;){t=!1;for(let n=0;n=0){s.splice(n,1),t=!0;break}}}return s}function Td(t,e){const i=t.map(t=>Math.max(0,Math.min(1,t))).sort((t,e)=>t-e),s=[];for(const t of i)(!s.length||Math.abs(t-s[s.length-1])>e)&&s.push(t);return s}function Pd(t,e){return[t.a[0]+(t.b[0]-t.a[0])*e,t.a[1]+(t.b[1]-t.a[1])*e]}function Rd(t,e,i){const s=function(t,e){const i=e.b[0]-e.a[0],s=e.b[1]-e.a[1],n=i*i+s*s;return n>0?((t[0]-e.a[0])*i+(t[1]-e.a[1])*s)/n:0}(t,e);if(s<-i||s>1+i)return null;const n=Pd(e,s);return Math.hypot(n[0]-t[0],n[1]-t[1])<=i?Math.max(0,Math.min(1,s)):null}function Ad(t,e,i,s,n){const o=t.b[0]-t.a[0],a=t.b[1]-t.a[1],r=e.b[0]-e.a[0],l=e.b[1]-e.a[1],c=e.a[0]-t.a[0],h=e.a[1]-t.a[1],d=kd(o,a,r,l),u=Math.max(Math.hypot(o,a),Math.hypot(r,l),1);if(Math.abs(d)>n*u){const t=kd(c,h,r,l)/d,e=kd(c,h,o,a)/d;return void(t>=-n&&t<=1+n&&e>=-n&&e<=1+n&&(i.push(Math.max(0,Math.min(1,t))),s.push(Math.max(0,Math.min(1,e)))))}if(!(Math.abs(kd(c,h,o,a))>n*u)){for(const s of[e.a,e.b]){const e=Rd(s,t,n);null!=e&&i.push(e)}for(const i of[t.a,t.b]){const t=Rd(i,e,n);null!=t&&s.push(t)}}}function Id(t){let e=t+1|0;return e^=e<<13,e^=e>>>17,e^=e<<5,e>>>0}function Ed(t,e){return t.minY-e.minY||t.index-e.index}function Fd(t){return t.subtreeMaxY=Math.max(t.item.maxY,t.left?.subtreeMaxY??-1/0,t.right?.subtreeMaxY??-1/0),t}function zd(t){const e=t.right;return t.right=e.left,e.left=Fd(t),Fd(e)}function Od(t){const e=t.left;return t.left=e.right,e.right=Fd(t),Fd(e)}function Hd(t,e){return t?(Ed(e,t.item)<0?(t.left=Hd(t.left,e),t.left.priority0)t.right=Nd(t.right,e);else{if(!t.left)return t.right;if(!t.right)return t.left;t.left.priority=e&&Ld(t.left,e,i,s),t.item.minY<=i&&t.item.maxY>=e&&s.push(t.item),t.item.minY<=i&&Ld(t.right,e,i,s))}function Bd(t,e=.001){const i=Number.isFinite(e)&&e>0?e:yd,s=t.filter(t=>wd(t.a)&&wd(t.b)&&"string"==typeof t.key&&t.key.length>0&&Math.hypot(t.b[0]-t.a[0],t.b[1]-t.a[1])>i),n=s.map(()=>[0,1]);!function(t,e,i){const s=t.map((t,e)=>({index:e,minX:Math.min(t.a[0],t.b[0])-i,maxX:Math.max(t.a[0],t.b[0])+i,minY:Math.min(t.a[1],t.b[1])-i,maxY:Math.max(t.a[1],t.b[1])+i})),n=[...s].sort((t,e)=>t.minX-e.minX||t.minY-e.minY||t.index-e.index),o=[...s].sort((t,e)=>t.maxX-e.maxX||t.index-e.index),a=new Set;let r=null,l=0;for(const s of n){for(;lt.index-e.index);for(const o of n)Ad(t[o.index],t[s.index],e[o.index],e[s.index],i);a.add(s.index),r=Hd(r,s)}}(s,n,i);const o=new Map;for(let t=0;t({key:t,a:e.a,b:e.b,sourceKeys:[...e.sourceKeys].sort((t,e)=>t.localeCompare(e))})).sort((t,e)=>t.key.localeCompare(e.key))}const qd=1e-5;function jd(t){const e=t.map(()=>[]);for(let i=0;i=1-1e-9||u<=1e-9||u>=1-1e-9||(e[i].push(d),e[a].push(u))}}const i=[];for(let s=0;st-e),1];for(let t=1;t{const i=e[2]-e[0],s=e[3]-e[1],n=i*i+s*s;if(!(n>0))return Math.hypot(t[0]-e[0],t[1]-e[1]);const o=Math.max(0,Math.min(1,((t[0]-e[0])*i+(t[1]-e[1])*s)/n));return Math.hypot(t[0]-(e[0]+o*i),t[1]-(e[1]+o*s))},Gd=(t,e,i,s)=>{const n=s[2]-s[0],o=s[3]-s[1],a=e*o-i*n;if(Math.abs(a)<1e-12)return 1/0;const r=s[0]-t[0],l=s[1]-t[1],c=(r*o-l*n)/a;if(!(c>1e-9))return 1/0;const h=(r*i-l*e)/a;return h<-1e-9||h>1+1e-9?1/0:c};function Vd(t,e,i,s=96){if(!(e>0&&Number.isFinite(t[0])&&Number.isFinite(t[1])))return[];const n=[];for(const s of i){if(!s||s.length<4)continue;if(![s[0],s[1],s[2],s[3]].every(Number.isFinite))continue;const i=Ud(t,s);if(i<1e-7)return[];i>e||n.push(s)}const o=[],a=Math.max(12,Math.round(s));for(let t=0;tt-e);const l=[];let c=Number.NEGATIVE_INFINITY;for(const i of o){if(i-c<1e-9)continue;c=i;const s=Math.cos(i),o=Math.sin(i);let a=e;for(const e of n){const i=Gd(t,s,o,e);i=3?l:[]}class Kd extends ht{constructor(){super(...arguments),this._spaces=null,this._spacesLoading=!1}setConfig(t){this._config=t}async _loadSpaces(){if(!this._spaces&&!this._spacesLoading&&this.hass){this._spacesLoading=!0;try{const t=await this.hass.callWS({type:"houseplan/config/get"});this._spaces=(t?.config?.spaces||[]).map(t=>({value:t.id,label:t.title||t.id}))}catch{this._spaces=[]}finally{this._spacesLoading=!1}}}get _lang(){return sa(this.hass,this._config?.language)}get _schema(){const t=this._spaces||[],e=this._lang;return[{name:"title",selector:{text:{}}},t.length?{name:"default_floor",selector:{select:{mode:"dropdown",options:t}}}:{name:"default_floor",selector:{text:{}}},{name:"language",selector:{select:{mode:"dropdown",options:[{value:"",label:na(e,"editor.lang_auto")},{value:"en",label:na(e,"editor.lang_en")},{value:"ru",label:na(e,"editor.lang_ru")}]}}},{name:"icon_size",selector:{number:{min:1,max:6,step:.1,mode:"box"}}},{name:"show_temperature",selector:{boolean:{}}},{name:"live_states",selector:{boolean:{}}},{name:"show_signal",selector:{boolean:{}}},{name:"kiosk",selector:{boolean:{}}},{name:"cycle",selector:{number:{min:0,max:3600,step:5,mode:"box"}}}]}render(){if(!this.hass||!this._config)return G;this._loadSpaces();const t=this._lang,e={title:na(t,"editor.title"),default_floor:na(t,"editor.default_floor"),language:na(t,"editor.language"),icon_size:na(t,"editor.icon_size"),show_temperature:na(t,"editor.show_temperature"),live_states:na(t,"editor.live_states"),show_signal:na(t,"editor.show_signal"),kiosk:na(t,"editor.kiosk"),cycle:na(t,"editor.cycle")};return j``}const er={color:"#607d8b",opacity:1,widthCm:3.6,fill:!1,fillColor:"#607d8b",fillOpacity:.25},ir=(t,e=1)=>{const i=Number(t);return Number.isFinite(i)?Math.min(1,Math.max(0,i)):e},sr=t=>{let e=Number(t);return Number.isFinite(e)?(e=(e%360+360)%360,e>180?e-360:e):0};function nr(t,e,i){return sr(e)?[t.x,t.y]:i([t.x,t.y])}const or=(t,e,i)=>{const s=Number(t),n=Number.isFinite(e)&&e>0?e:5;return Number.isFinite(s)&&s>0?s/n*i:0},ar=(t,e,i)=>{const s=Number(t),n=Number.isFinite(e)&&e>0?e:5;return Number.isFinite(s)&&i>0?s/i*n:0},rr=(t,e,i,s=er.widthCm)=>{const n=Number(t?.width_cm);if(Number.isFinite(n)&&n>0)return n;const o=Number(t?.width);return Number.isFinite(o)&&o>0?ar(o,e,i):s};function lr(t,e){return{color:t.color,opacity:ir(t.opacity),width_cm:Math.max(.1,Math.min(100,Number(t.widthCm)||.1)),...e?{fill:t.fill,fill_color:t.fillColor,fill_opacity:ir(t.fillOpacity,.25)}:{}}}function cr(t){const e=t.x+t.w/2,i=t.y+t.h/2,s=sr(t.angle)*Math.PI/180,n=Math.cos(s),o=Math.sin(s),a=(t,s)=>{const a=t-e,r=s-i;return[e+a*n-r*o,i+a*o+r*n]};return[a(t.x,t.y),a(t.x+t.w,t.y),a(t.x+t.w,t.y+t.h),a(t.x,t.y+t.h)]}function hr(t){const e=cr(t),i=(t,e)=>[(t[0]+e[0])/2,(t[1]+e[1])/2],s=[(e[0][0]+e[2][0])/2,(e[0][1]+e[2][1])/2];return{points:[...e,i(e[0],e[1]),i(e[1],e[2]),i(e[2],e[3]),i(e[3],e[0]),s],segments:e.map((t,i)=>({a:t,b:e[(i+1)%4]}))}}function dr(t,e,i,s,n,o,a,r){const l=sr(t.angle)*Math.PI/180,c=Math.cos(l),h=Math.sin(l),d=-Math.sin(l),u=Math.cos(l),p=t.x+t.w/2,_=t.y+t.h/2,g=e>0?-t.w/2:t.w/2,m=i>0?-t.h/2:t.h/2,f=p+g*c+m*d,v=_+g*h+m*u,y=s-f,b=n-v;let w=(y*c+b*h)*(e>0?1:-1),k=(y*d+b*u)*(i>0?1:-1),x=null;if(o){const e=w/Math.max(t.w,r),i=k/Math.max(t.h,r);x=Math.max(r/Math.max(t.w,r),r/Math.max(t.h,r),e,i),w=t.w*x,k=t.h*x}if(a>0)if(o){const e=Math.max(1,Math.round(t.w/a)),i=Math.max(1,Math.round(t.h/a));if(Math.abs(t.w-e*a)<1e-6&&Math.abs(t.h-i*a)<1e-6){const s=(t,e)=>{let i=Math.abs(t),s=Math.abs(e);for(;s;)[i,s]=[s,i%s];return Math.max(1,i)},n=1/s(e,i),o=Math.max(r/t.w,r/t.h),a=Math.max(o,Math.round((x??1)/n)*n);w=t.w*a,k=t.h*a}else{t.w>=t.h?(w=Math.round(w/a)*a,k=w*(t.h/Math.max(t.w,r))):(k=Math.round(k/a)*a,w=k*(t.w/Math.max(t.h,r)))}}else w=Math.round(w/a)*a,k=Math.round(k/a)*a;w=Math.max(r,w),k=Math.max(r,k);return{x:f+(e>0?w/2:-w/2)*c+(i>0?k/2:-k/2)*d-w/2,y:v+(e>0?w/2:-w/2)*h+(i>0?k/2:-k/2)*u-k/2,w:w,h:k,angle:sr(t.angle)||void 0}}const ur=(t,e,i)=>{const s=i[0]-e[0],n=i[1]-e[1],o=s*s+n*n;if(o<1e-12)return[...e];const a=Math.max(0,Math.min(1,((t[0]-e[0])*s+(t[1]-e[1])*n)/o));return[e[0]+s*a,e[1]+n*a]};const pr=15;function _r(t,e){return Number.isFinite(t)&&t>0&&Number.isFinite(e)&&e>0&&t*e<3}function gr(t){return Number.isFinite(t)?Math.max(1,Math.min(100,t)):1}function mr(t,e){return!Number.isFinite(t)||t<=0?"":String(e?Math.round(t/2.54*100)/100:Math.round(100*t)/100)}function fr(t,e,i){const s=Number(e)>0?Number(e):5;return gr(t)/s*i}function vr(t,e){return e>0&&Number.isFinite(t)?Math.round(t/e)*e:t}function yr(t,e){let i=e[0]-t[0],s=e[1]-t[1];const n=Math.hypot(i,s);return n<1e-12?[1,0]:(i/=n,s/=n,(i<-1e-12||Math.abs(i)<=1e-12&&s<0)&&(i=-i,s=-s),[i,s])}function br(t,e,i){const s=vr((t[0]+e[0])/2,i),n=vr((t[1]+e[1])/2,i),[o,a]=yr(t,e);let r=Math.atan2(a,o);r<0&&(r+=Math.PI);const l=Math.round(1800*r)/1800,c=i>0&&i<.01?6:i<1?4:2;return`${s.toFixed(c)},${n.toFixed(c)}@${l.toFixed(4)}`}function wr(t,e,i,s){return 1===s?br(t,e,i):br([t[0]/s,t[1]/s],[e[0]/s,e[1]/s],i)}function kr(t,e){if(!Array.isArray(t.a)||!Array.isArray(t.b)||t.a.length<2||t.b.length<2)return null;const i=[Number(t.a[0]),Number(t.a[1]),Number(t.b[0]),Number(t.b[1])];if(!i.every(Number.isFinite))return null;const s=e>0?e:1;return[[i[0]*s,i[1]*s],[i[2]*s,i[3]*s]]}function xr(t,e,i,s,n){const o=n>0?n:1;return{key:wr(t,e,s,o),cm:gr(i),a:[t[0]/o,t[1]/o],b:[e[0]/o,e[1]/o]}}function $r(t,e){const i=e>0?e:1,s=[];for(const e of t){const t=e.key.lastIndexOf("@");if(t<0)continue;const[n,o]=e.key.slice(0,t).split(",").map(Number),a=Number(e.key.slice(t+1));[n,o,a].every(Number.isFinite)&&s.push({w:e,x:n*i,y:o*i,ang:a})}return s}function Sr(t,e){const[i,s]=yr(t,e);let n=Math.atan2(s,i);return n<0&&(n+=Math.PI),n}function Mr(t,e){let i=Math.abs(t-e);return i>Math.PI/2&&(i=Math.PI-i),i<.02}function Cr(t,e,i,s,n=1){if(!t?.length)return null;const o=wr(e,i,s,n),a=t.find(t=>t.key===o);if(a)return a;const r=n>0?n:1,l=(e[0]+i[0])/2,c=(e[1]+i[1])/2,h=Sr(e,i),d=Math.max(.5*s,1e-9)*r;for(const e of $r(t,r))if(Mr(e.ang,h)&&Math.hypot(e.x-l,e.y-c)<=d)return e.w;return null}function Dr(t,e,i,s,n=1){const o=Cr(t,e,i,s,n);if(o&&o.cm>0)return gr(o.cm);const a=function(t,e,i,s,n){if(!t?.length)return null;const o=n>0?n:1,a=Math.hypot(i[0]-e[0],i[1]-e[1]);if(a<1e-12)return null;const r=Sr(e,i),l=Math.max(.5*s,1e-9)*o;let c=null;for(const s of t){if(!(s.cm>0))continue;const t=kr(s,o);if(!t)continue;const n=Math.hypot(t[1][0]-t[0][0],t[1][1]-t[0][1]);if(n<1e-12||!Mr(Sr(t[0],t[1]),r))continue;if(sl(e[0],e[1],t[0][0],t[0][1],t[1][0],t[1][1])>l||sl(i[0],i[1],t[0][0],t[0][1],t[1][0],t[1][1])>l)continue;if(n+l(o.has(t.key)||(t=>{const e=kr(t,s);if(!e)return!1;const[i,o]=e,r=o[0]-i[0],c=o[1]-i[1],h=Math.hypot(r,c);if(h<=l)return!1;if(!a.some(t=>{const e=[t[0],t[1]],s=[t[2],t[3]];return Mr(Sr(i,o),Sr(e,s))&&sl(i[0],i[1],e[0],e[1],s[0],s[1])<=l&&sl(o[0],o[1],e[0],e[1],s[0],s[1])<=l}))return!1;const d=(n||[]).some(t=>{const e=[t[0],t[1]],s=[t[2],t[3]];if(!Mr(Sr(i,o),Sr(e,s)))return!1;const n=t=>Math.abs((t[0]-i[0])*c-(t[1]-i[1])*r)/h;if(n(e)>l||n(s)>l)return!1;const a=h*h,d=((e[0]-i[0])*r+(e[1]-i[1])*c)/a,u=((s[0]-i[0])*r+(s[1]-i[1])*c)/a;return Math.min(1,Math.max(d,u))-Math.max(0,Math.min(d,u))>l/h});return!d})(t))&&t.cm>=1&&t.cm<=100)}function Pr(t,e,i,s=8){const[n,o]=yr(t,e);let a=Math.atan2(o,n);a<0&&(a+=Math.PI);let r=i*Math.PI/180%Math.PI;r<0&&(r+=Math.PI);let l=Math.abs(a-r);return l>Math.PI/2&&(l=Math.PI-l),l<=s*Math.PI/180}function Rr(t,e,i,s,n=1){if(!t?.length)return[];if(e.length!==i.length)return t.slice();const o=new Map;for(let t=0;t0?n:1,r=Math.max(.5*s,1e-9)*a,l=new Set,c=[];for(const n of t){let t="",h=null;const d=kr(n,a);if(d)for(let n=0;nr||sl(d[1][0],d[1][1],o[0],o[1],l[0],l[1])>r)continue;const p=l[0]-o[0],_=l[1]-o[1],g=p*p+_*_;if(g<1e-18)continue;const m=t=>{const e=Math.max(0,Math.min(1,((t[0]-o[0])*p+(t[1]-o[1])*_)/g));return[c[0]+(u[0]-c[0])*e,c[1]+(u[1]-c[1])*e]};h=[m(d[0]),m(d[1])],t=wr(h[0],h[1],s,a);break}if(d||(t=o.get(n.key)||""),!t){const o=$r([n],a)[0];if(o)for(let n=0;n1.000001)continue;if(sl(o.x,o.y,l[0],l[1],c[0],c[1])>r)continue;const m=h[0]+(d[0]-h[0])*Math.max(0,Math.min(1,g)),f=h[1]+(d[1]-h[1])*Math.max(0,Math.min(1,g)),[v,y]=yr(h,d),b=Math.max(s*a,1e-6);t=wr([m-v*b,f-y*b],[m+v*b,f+y*b],s,a);break}}t||(t=n.key),l.has(t)||(l.add(t),c.push(h?xr(h[0],h[1],n.cm,s,a):{...n,key:t,cm:gr(n.cm)}))}return c}function Ar(t,e,i,s,n,o=1){const a=wr(e,i,n,o),r=(t||[]).filter(t=>t.key!==a);return null==s||s<1?r:[...r,xr(e,i,s,n,o)]}function Ir(t,e,i,s,n,o=[],a=1){let r=t?t.slice():[];for(const t of function(t,e,i,s,n=1,o=[]){const a=Xr(t,e,i,s,n,o);if(!a)return[];const r=[];for(let t=0;t0||(c=Ar(c,e,i,s,n,a)))}return c}function Fr(t){const{a:e,b:i,halfDepth:s}=t;if(!Array.isArray(e)||!Array.isArray(i)||e.length<2||i.length<2||![e[0],e[1],i[0],i[1]].every(Number.isFinite))return null;const n=i[0]-e[0],o=i[1]-e[1],a=Math.hypot(n,o);if(!(a>1e-9&&s>0&&Number.isFinite(s)))return null;const r=-o/a*s,l=n/a*s;return[[e[0]+r,e[1]+l],[i[0]+r,i[1]+l],[i[0]-r,i[1]-l],[e[0]-r,e[1]-l]]}function zr(t,e,i){return Math.hypot(t[0]-e[0],t[1]-e[1])<=i}function Or(t,e,i){const s=e.b[0]-e.a[0],n=e.b[1]-e.a[1],o=s*s+n*n;if(!(o>i*i))return!1;const a=((t[0]-e.a[0])*s+(t[1]-e.a[1])*n)/o;if(!(a>0&&a<1))return!1;const r=[e.a[0]+s*a,e.a[1]+n*a];return Math.hypot(t[0]-r[0],t[1]-r[1])<=i}function Hr(t,e,i,s){const n=Math.hypot(e,i);if(!(n>1e-9&&s>0))return;const o=[e/n,i/n],a=t.find(t=>Math.abs(t.u[0]*o[1]-t.u[1]*o[0])<1e-9&&t.u[0]*o[0]+t.u[1]*o[1]>1-1e-9);a?a.halfDepth=Math.max(a.halfDepth,s):t.push({u:o,halfDepth:s})}function Nr(t,e=1e-6){const i=(t||[]).filter(t=>t&&Array.isArray(t.a)&&Array.isArray(t.b)&&t.a.length>=2&&t.b.length>=2&&t.a.every(Number.isFinite)&&t.b.every(Number.isFinite)&&Number.isFinite(t.halfDepth)&&t.halfDepth>0&&Math.hypot(t.b[0]-t.a[0],t.b[1]-t.a[1])>1e-9);if(i.length<2)return[];const s=Math.max(Number.isFinite(e)?e:0,1e-9),n=i.flatMap(t=>[t.a,t.b]).map(t=>[t[0],t[1]]).sort((t,e)=>t[0]-e[0]||t[1]-e[1]),o=[];for(const t of n)o.some(e=>zr(e,t,s))||o.push(t);const a=[];for(const t of o){const e=[];for(const n of i)zr(t,n.a,s)?Hr(e,n.b[0]-n.a[0],n.b[1]-n.a[1],n.halfDepth):zr(t,n.b,s)?Hr(e,n.a[0]-n.b[0],n.a[1]-n.b[1],n.halfDepth):Or(t,n,s)&&(Hr(e,n.a[0]-t[0],n.a[1]-t[1],n.halfDepth),Hr(e,n.b[0]-t[0],n.b[1]-t[1],n.halfDepth));if(!(e.length<2)){e.sort((t,e)=>Math.atan2(t.u[1],t.u[0])-Math.atan2(e.u[1],e.u[0])||t.halfDepth-e.halfDepth);for(let i=0;is*s&&a.push(m)}}}return a}function Lr(t,e,i,s){if(!(e>0)||!t||t.length<2)return"";if(i&&t.length>=3){let i=t;const n=t[t.length-1];if(t.length>=4&&Math.hypot(t[0][0]-n[0],t[0][1]-n[1])<1e-9&&(i=t.slice(0,-1)),i.length>=3){const t=i.map((t,i)=>s?.[i]||e),n=_l(i,t),o=Vr(i,t);if(n&&o)return`${Kr(n)} ${Kr(Yr(o))}`}}const n=[];for(let i=0;i=1e-9&&r>0&&n.push({a:o,b:a,halfDepth:r})}const o=[...n.map(Fr).filter(t=>!!t),...Nr(n)],a=function(t){let e=null;try{for(const i of t){if(i.length<3)continue;const t=ol(i);e=e?si(e,t):[t]}return e}catch{return null}}(o);return a?hl(a):o.map(t=>Kr(t)).join(" ")}function Br(t,e,i,s,n=1){if(!i.length)return!1;const o=qr(s,n),a=(t[0]+e[0])/2,r=(t[1]+e[1])/2,[l,c]=yr(t,e);for(const t of i){const[e,i]=yr([t[0],t[1]],[t[2],t[3]]);if(!(Math.abs(l*i-c*e)>.05)&&sl(a,r,t[0],t[1],t[2],t[3])<=o)return!0}return!1}function qr(t,e){return Math.max(t*(e>0?e:1)*.04,1e-9)}function jr(t){let e=0;for(let i=0;it[1]!=l>t[1]&&t[0]<(r-o)*(t[1]-a)/(l-a+0)+o&&(i=!i)}return i}([c[0]+.001*r,c[1]+.001*l],t)||(r=-r,l=-l),[r,l]}function Ur(t,e){const i=t[0]*e[1]-t[1]*e[0],s=t[0]*e[0]+t[1]*e[1];return Math.abs(i)<1e-9&&s>0}function Gr(t,e,i,s){const n=e[0]*s[1]-e[1]*s[0];if(Math.abs(n)<1e-12)return null;const o=[i[0]-t[0],i[1]-t[1]],a=(o[0]*s[1]-o[1]*s[0])/n;return[t[0]+a*e[0],t[1]+a*e[1]]}function Vr(t,e){const i=t?.length||0;if(i<3||e.length!==i)return null;if(e.every(t=>!(t>0)))return t.map(t=>[t[0],t[1]]);const s=[];for(let n=0;n0||d>0)){s.push([t[n][0],t[n][1]]);continue}if(h>0!=d>0){const e=t[n],i=h>0?[e[0]+u*h,e[1]+p*h]:[e[0],e[1]],o=d>0?[e[0]+_*d,e[1]+g*d]:[e[0],e[1]];s.push(i),Math.hypot(o[0]-i[0],o[1]-i[1])>1e-9&&s.push(o);continue}if(Ur(b,w)){const e=t[n],i=[e[0]+u*h,e[1]+p*h],o=[e[0]+_*d,e[1]+g*d];s.push(i),Math.hypot(o[0]-i[0],o[1]-i[1])>1e-9&&s.push(o);continue}const $=Gr(k,b,x,w),S=Math.max(h,d,1e-9);if($){if(Math.hypot($[0]-t[n][0],$[1]-t[n][1])<=4*S){s.push($);continue}}h>0&&s.push([t[n][0]+u*h,t[n][1]+p*h]),d>0&&s.push([t[n][0]+_*d,t[n][1]+g*d]),h>0||d>0||s.push([t[n][0],t[n][1]])}return s.length>=3?s:null}function Kr(t,e=!0){if(!t.length)return"";let i=`M ${t[0][0]} ${t[0][1]}`;for(let e=1;et?.id===e),r=hi(a);if(!r||r.length<3)return null;const l=qr(s,n),c=[];for(const i of t||[]){if(!i||i.id===e)continue;const t=hi(i);if(t)for(const e of Cs(r,t,l))c.push([e[0],e[1]],[e[2],e[3]])}for(const t of i||[])c.push([t[0],t[1]],[t[2],t[3]]);for(const t of o||[]){const e=kr(t,n);e&&c.push(e[0],e[1])}const h=[],d=[];for(let t=0;tl)continue;const a=((t[0]-e[0])*(i[0]-e[0])+(t[1]-e[1])*(i[1]-e[1]))/(s*s);a<=n||a>=1-n||(o.some(t=>Math.abs(t-a)*s<=2*l)||o.push(a))}o.sort((t,e)=>t-e);for(const s of o)h.push([e[0]+(i[0]-e[0])*s,e[1]+(i[1]-e[1])*s]),d.push(t)}return{poly:h,parent:d,orig:r}}function Jr(t,e,i,s){const n=e.poly.length,o=new Array(n).fill(0);if(!t?.length)return o;const a=new Set,r=[];for(let l=0;l0?(o[l]=gr(c.cm),a.add(c.key)):r.push(l)}if(!r.length)return o;const l=s>0?s:1,c=Math.max(.5*i,1e-9)*l,h=$r(t,l).filter(t=>t.w.cm>0);for(let t=r.length-1;t>=0;t--){const i=r[t],s=e.poly[i],a=e.poly[(i+1)%n],d=Sr(s,a);let u=null;for(const t of h){const e=kr(t.w,l);if(!e||!Mr(Sr(e[0],e[1]),d))continue;if(sl(s[0],s[1],e[0][0],e[0][1],e[1][0],e[1][1])>c||sl(a[0],a[1],e[0][0],e[0][1],e[1][0],e[1][1])>c)continue;const i=Math.hypot(a[0]-s[0],a[1]-s[1]),n=Math.hypot(e[1][0]-e[0][0],e[1][1]-e[0][1]),o=Math.max(0,n-i);(!u||oc||sl(n[0],n[1],e[0][0],e[0][1],e[1][0],e[1][1])>c)continue;i=!0,o=Math.max(0,Math.hypot(e[1][0]-e[0][0],e[1][1]-e[0][1])-_)}else{if(sl(t.x,t.y,s[0],s[1],n[0],n[1])>c)continue;o=Math.hypot(t.x-d,t.y-u)}(!p||i&&!p.exact||i===p.exact&&ot?.id===e),n=hi(s);if(!n)return[];const o=[];for(const s of t||[]){if(!s||s.id===e)continue;const t=hi(s);if(t)for(const e of Cs(n,t,i))o.push(e)}return o}(t,e,qr(n,r)),h=function(t,e,i,s,n){const o=qr(s,n),a=[];for(let r=0;rsl(h,d,t[0],t[1],t[2],t[3])<=o);a.push(u?"shared":"outer")}return a}(l.poly,c,s,n,r),d=Jr(i,l,n,r),u=d.map((t,e)=>h[e]&&t>0?fr(t,o,a)/2:0);return{...l,kinds:h,cms:d,offsets:u}}function Qr(t,e,i,s,n,o,a=1){const r=[];for(const l of t||[]){if(!l?.id)continue;const c=Zr(t,l.id,e,i,s,n,o,a);if(c)for(let t=0;t0&&(r=Ar(r,t.a,t.b,t.cm,s,a));return r}function el(t,e,i,s,n,o,a=1){if(!e?.length)return[];const r=[],l=new Set;for(const c of Qr(t,e,i,s,n,o,a))!c.open&&c.cm>0&&!l.has(c.key)&&(l.add(c.key),r.push(c));const c=[];for(const r of t||[]){if(!r?.id)continue;const l=Zr(t,r.id,e,i,s,n,o,a);if(l)for(let t=0;t0)||null===l.kinds[i]){t++;continue}let o=t;for(;o+10&&c.push({a:[h[0],h[1]],b:[d[0],d[1]],key:wr(h,d,s,a),cm:n,len:u}),t=o+1}}}c.sort((t,e)=>e.len-t.len||t.key.localeCompare(e.key));const h=[],d=new Set,u=new Set,p=4*qr(s,a);for(const t of c){const e=r.filter(e=>!u.has(e.key)&&e.cm===t.cm&&Mr(Sr(e.a,e.b),Sr(t.a,t.b))&&sl(e.a[0],e.a[1],t.a[0],t.a[1],t.b[0],t.b[1])<=p&&sl(e.b[0],e.b[1],t.a[0],t.a[1],t.b[0],t.b[1])<=p);if(e.length){for(const t of e)u.add(t.key);d.has(t.key)||(d.add(t.key),h.push(xr(t.a,t.b,t.cm,s,a)))}}for(const t of r)u.has(t.key)||d.has(t.key)||(d.add(t.key),h.push(xr(t.a,t.b,t.cm,s,a)));return h}function il(t,e,i,s,n,o,a,r=1){const l=qr(n,r),c=(s[0]+s[2])/2,h=(s[1]+s[3])/2,d=Sr([s[0],s[1]],[s[2],s[3]]);let u=null;for(const s of Qr(t,e,i,n,o,a,r)){if(!Mr(Sr(s.a,s.b),d))continue;const t=sl(c,h,s.a[0],s.a[1],s.b[0],s.b[1]);t>4*l||(!u||tt?.id===e),c=hi(l);if(!c||c.length<3)return null;if(!i?.length)return c.map(t=>[t[0],t[1]]);const h=Zr(t,e,i,s,n,o,a,r);return h&&h.offsets.some(t=>t>0)&&Vr(h.poly,h.offsets)||c.map(t=>[t[0],t[1]])}function ol(t){const e=t.map(t=>[t[0],t[1]]);return e.push([t[0][0],t[0][1]]),[e]}function al(t,e=1){if(!Array.isArray(t)||t.length<3)return null;const i=Number.isFinite(e)&&e>0?e:1,s=1e-12*Math.max(1,i),n=[];for(const e of t){if(!Array.isArray(e)||e.length<2)return null;const t=Number(e[0]),i=Number(e[1]);if(!Number.isFinite(t)||!Number.isFinite(i))return null;const o=Math.round(t/s)*s,a=Math.round(i/s)*s;if(!Number.isFinite(o)||!Number.isFinite(a))return null;n.push([Object.is(o,-0)?0:o,Object.is(a,-0)?0:a])}return Math.abs(jr(n))>s*s?n:null}function rl(t,e,i,s){if(sl(t[0],t[1],e[0],e[1],i[0],i[1])>s)return!1;const n=i[0]-e[0],o=i[1]-e[1],a=(t[0]-e[0])*n+(t[1]-e[1])*o,r=n*n+o*o,l=s*Math.sqrt(r);return a>=-l&&a<=r+l}function ll(t,e,i){const s=[],n=[];for(let o=0;oi*i))continue;const d=i/Math.sqrt(h),u=[0,1];for(const t of e)for(const e of[t.a,t.b]){if(!rl(e,a,r,i))continue;const t=((e[0]-a[0])*l+(e[1]-a[1])*c)/h;t>d&&t<1-d&&u.push(t)}u.sort((t,e)=>t-e);const p=u.filter((t,e)=>0===e||Math.abs(t-u[e-1])>d);for(let t=0;t=3&&n.length===s.length?{poly:s,offsets:n}:null}function cl(t,e,i,s,n,o,a){const r=(t||[]).map(hi).filter(t=>!!t&&t.length>=3);if(!r.length)return null;let l=si(ol(r[0]));for(let t=1;t"outer"===t.kind&&t.half>0),h=4*qr(s,a);let d=null;for(const t of function(t){const e=[];for(const i of Array.isArray(t)?t:[])if(Array.isArray(i))for(const t of i){if(!Array.isArray(t)||t.length<4)continue;const i=t.slice(0,-1).map(t=>[t[0],t[1]]);i.length>=3&&e.push(i)}return e}(l)){const e=ll(t,c,h);if(!e||!e.offsets.some(t=>t>0))continue;const i=_l(e.poly,e.offsets),s=Vr(e.poly,e.offsets);if(!i||!s)continue;const n=oi(ol(i),ol(s));d=d?si(d,n):n}return{centre:l,shell:d||[]}}function hl(t){if(!t)return"";let e="";for(const i of t)if(Array.isArray(i))for(const t of i){if(!Array.isArray(t)||t.length<4)continue;const i=t.slice(0,t.length-1);i.length<3||(e+=(e?" ":"")+Kr(i.map(t=>[t[0],t[1]])))}return e}function dl(t,e,i,s=[],n,o,a,r=1,l=[]){if(!e?.length&&!l.length)return null;const c=[];let h=0;for(const s of t||[]){if(!s?.id)continue;const l=Zr(t,s.id,e,i,n,o,a,r);if(!l||l.poly.length<3||!l.offsets.some(t=>t>0))continue;for(const t of l.offsets)t>0&&(h=Math.max(h,2*t));const d=_l(l.poly,l.offsets),u=Vr(l.poly,l.offsets);d&&c.push({outset:d,inset:u})}for(const t of l){const e=t.map(t=>t[0]),i=t.map(t=>t[1]);if(e.length){const s=Math.min(Math.max(...e)-Math.min(...e),Math.max(...i)-Math.min(...i)),n=Math.min(...t.map((e,i)=>{const s=t[(i+1)%t.length];return Math.hypot(s[0]-e[0],s[1]-e[1])}));h=Math.max(h,t.length>16?s:n)}}const d=function(t,e,i,s,n,o,a){if(!e?.length||!i?.length)return[];const r=4*qr(s,a),l=new Map;for(const r of Qr(t,e,i,s,n,o,a))!r.open&&r.half>0&&!l.has(r.key)&&l.set(r.key,r);const c=[...l.values()];if(c.length<2)return[];const h=[];for(const t of i)for(const e of[[t[0],t[1]],[t[2],t[3]]])h.some(t=>Math.hypot(t[0]-e[0],t[1]-e[1])<=r)||h.push(e);const d=[],u=(t,e)=>{let i=0,s=0;if(Math.hypot(t.a[0]-e[0],t.a[1]-e[1])<=r)i=t.b[0]-t.a[0],s=t.b[1]-t.a[1];else{if(!(Math.hypot(t.b[0]-e[0],t.b[1]-e[1])<=r))return null;i=t.a[0]-t.b[0],s=t.a[1]-t.b[1]}const n=Math.hypot(i,s);return n>r?[i/n,s/n]:null};for(const t of h){const e=c.map(e=>({iv:e,u:u(e,t)})).filter(t=>!!t.u);for(let i=0;i4*_||d.push(a>0?[t.slice(),h,p,u]:[t.slice(),u,p,h])}}return d}(t,e,i,n,o,a,r),u=s.length?gl(t,e,i,n,o,a,r):null;try{const p=cl(t,e,i,n,o,a,r),_=p?p.shell?.length?si(p.centre,p.shell):p.centre:[],g=t=>{const e=ol(t.outset);return t.inset?oi(e,ol(t.inset)):e};let m=null;for(const t of c)try{const e=g(t);m=m?si(m,e):e}catch{}if(p)for(const s of pl(t,e,i,n,o,a,r))try{const t=ni(ol(s.quad),p.centre);m=m?si(m,t):t}catch{}m=function(t,e,i=1,s=si){let n=t;for(const t of e||[]){const e=al(t,i);if(e)try{const t=ol(e);n=n?s(n,t):t}catch{}}return n}(m,d,r),m&&p&&(m=ni(m,p.centre)),p?.shell?.length&&(m=m?si(m,p.shell):p.shell);for(const t of s){if(!(t.length>0))continue;const e=vl(u,t,!0);if(!e.negative&&!e.positive)continue;const i=t.angle*Math.PI/180,s=Math.cos(i),o=Math.sin(i),a=-o,l=s,c=t.length/2,d=1.25*Math.max(h,n*r),p=[[t.x-s*c-a*d,t.y-o*c-l*d],[t.x+s*c-a*d,t.y+o*c-l*d],[t.x+s*c+a*d,t.y+o*c+l*d],[t.x-s*c+a*d,t.y-o*c+l*d]];m&&(m=oi(m,ol(p)))}for(const t of l)t.length<3||(m=m?si(m,ol(t)):[ol(t)]);return{geom:m||[],paperGeom:_,depthUnits:h,openingIndex:u}}catch{return null}}function ul(t,e,i,s=[],n,o,a,r=1,l=[]){if(!e?.length&&!l.length)return null;const c=dl(t,e,i,s,n,o,a,r,l),h=c?hl(c.geom):"",d=c?hl(c.paperGeom):"";return c&&h?{d:h,paperD:d,depthUnits:c.depthUnits,fillRule:"evenodd"}:null}function pl(t,e,i,s,n,o,a=1){if(!e?.length)return[];const r=new Set,l=[];for(const c of t||[]){if(!c?.id)continue;const h=Zr(t,c.id,e,i,s,n,o,a);if(!h)continue;const d=h.poly;for(let t=0;t0))continue;const p=wr(e,i,s,a);if(r.has(p))continue;r.add(p);const _=fr(u,n,o),[g,m]=Wr(d,t),f=-g,v=-m,y=_/2,b=[[e[0]+f*y,e[1]+v*y],[i[0]+f*y,i[1]+v*y],[i[0]+g*y,i[1]+m*y],[e[0]+g*y,e[1]+m*y]];l.push({key:p,kind:c,cm:u,quad:b,a:[e[0],e[1]],b:[i[0],i[1]],depthUnits:_})}}return l}function _l(t,e){const i=t?.length||0;if(i<3||e.length!==i)return null;if(e.every(t=>!(t>0)))return t.map(t=>[t[0],t[1]]);Yr(t),e.slice().reverse();const s=[];for(let n=0;n0||r>0)){s.push([t[n][0],t[n][1]]);continue}if(a>0!=r>0){const e=t[n],i=a>0?[e[0]-l*a,e[1]-c*a]:[e[0],e[1]],o=r>0?[e[0]-h*r,e[1]-d*r]:[e[0],e[1]];s.push(i),Math.hypot(o[0]-i[0],o[1]-i[1])>1e-9&&s.push(o);continue}if(Ur(b,w)){const e=t[n],i=[e[0]-l*a,e[1]-c*a],o=[e[0]-h*r,e[1]-d*r];s.push(i),Math.hypot(o[0]-i[0],o[1]-i[1])>1e-9&&s.push(o);continue}const $=Gr(k,b,x,w),S=Math.max(a,r,1e-9);if($){if(Math.hypot($[0]-t[n][0],$[1]-t[n][1])<=4*S){s.push($);continue}}a>0&&s.push([t[n][0]-l*a,t[n][1]-c*a]),r>0&&s.push([t[n][0]-h*r,t[n][1]-d*r])}return s.length>=3?s:null}function gl(t,e,i,s,n,o,a=1){const r=[];for(const l of t||[]){if(!l?.id)continue;const c=Zr(t,l.id,e,i,s,n,o,a);if(!c)continue;const h=Math.abs(Pi(c.poly));for(let t=0;t[Math.max(e,t.x0),Math.min(i,t.x1)]).filter(t=>t[1]-t[0]>s).sort((t,e)=>t[0]-e[0]||t[1]-e[1]);if(!n.length)return{coverage:0,full:!1};let o=n[0][0],a=n[0][1],r=0,l=o<=e+s;for(let t=1;t=i-s,{coverage:r,full:l}}function fl(t,e){return Number(e.full)-Number(t.full)||t.faceDistance-e.faceDistance||t.area-e.area||t.roomId.localeCompare(e.roomId)}function vl(t,e,i=!1){const s=Number(e?.x),n=Number(e?.y),o=Number(e?.angle),a=Number(e?.length);if(!([s,n,o,a].every(Number.isFinite)&&a>0))return{negative:null,positive:null};const r=o*Math.PI/180,l=Math.cos(r),c=Math.sin(r),h=-c,d=l,u=a/2,p=Math.max(1e-9,t.adjacencyEps),_=new Map;let g=0;for(const e of t.edges){if(i&&!(e.half>0))continue;if(!Pr(e.a,e.b,o))continue;const[t,a]=yr(e.a,e.b);if(Math.abs((s-e.a[0])*a-(n-e.a[1])*t)>p)continue;const r=(e.a[0]-s)*l+(e.a[1]-n)*c,m=(e.b[0]-s)*l+(e.b[1]-n)*c,f=Math.max(-u,Math.min(r,m)),v=Math.min(u,Math.max(r,m));if(v-f<=p)continue;const y=e.inward[0]*h+e.inward[1]*d>=0?1:-1,b=((e.a[0]+e.b[0])/2-s)*h+((e.a[1]+e.b[1])/2-n)*d,w=Math.abs(b+y*e.half),k=`${y}|${e.roomId}`,x={x0:f,x1:v,half:e.half,cm:e.cm,key:e.key,axis:[t,a]},$=_.get(k);$?($.pieces.push(x),$.faceDistance=Math.min($.faceDistance,w)):_.set(k,{roomId:e.roomId,side:y,order:g++,pieces:[x],faceDistance:w,area:e.area,coverage:0,full:!1})}for(const t of _.values()){const e=ml(t.pieces,-u,u,p);t.coverage=e.coverage,t.full=e.full}const m=t=>{const e=[..._.values()].filter(e=>e.side===t&&e.coverage>p);return e.sort(fl),e[0]||null};return{negative:m(-1),positive:m(1)}}function yl(t,e){const i=vl(t,e),s=[i.negative,i.positive].filter(t=>!!t).sort((t,e)=>t.order-e.order);if(!s.length)return{ox:0,oy:0,cm:0,side:-1};const n=s[0],o=e.flip_v?-n.side:n.side,a=(-1===o?i.negative:i.positive)||n,r=[...a.pieces].sort((t,e)=>(t.x0<=0&&t.x1>=0?0:Math.min(Math.abs(t.x0),Math.abs(t.x1)))-(e.x0<=0&&e.x1>=0?0:Math.min(Math.abs(e.x0),Math.abs(e.x1)))||e.x1-e.x0-(t.x1-t.x0)||t.key.localeCompare(e.key))[0];if(!(r.half>0&&r.cm>0))return{ox:0,oy:0,cm:0,side:o};const l=e.angle*Math.PI/180,c=-Math.sin(l),h=Math.cos(l);return{ox:c*o*r.half,oy:h*o*r.half,cm:r.cm,side:o}}function bl(t,e){const i=1e-9,s=e.filter(t=>Number.isFinite(t.x0)&&Number.isFinite(t.x1)&&Number.isFinite(t.half)&&t.x1>t.x0&&t.half>0);if(!s.length)return"";const n=s.flatMap(t=>[t.x0,t.x1]).sort((t,e)=>t-e),o=[];for(const t of n){const e=o[o.length-1];(void 0===e||t>e+i)&&o.push(t)}const a=[];for(let t=0;t+1e+i))continue;const r=(e+n)/2,l=s.reduce((t,e)=>r>=e.x0-i&&r<=e.x1+i?Math.max(t,e.half):t,0);if(!(l>0))continue;const c=a[a.length-1];c&&e<=c.x1+i&&Math.abs(l-c.half)<=i?c.x1=n:a.push({x0:e,x1:n,half:l})}const r=[];for(const t of a){const e=r[r.length-1],s=e?.[e.length-1];s&&t.x0<=s.x1+i?(t.x0=s.x1,e.push(t)):r.push([t])}return r.map(e=>{const i=e[0],s=e[e.length-1],n=Math.min(.25*Math.min(...e.map(t=>t.half)),.75),o=-t*n,a=[];if(1===t){a.push(`M ${i.x0} ${o} L ${s.x1} ${o}`);for(let t=e.length-1;t>=0;t--){const i=e[t];a.push(`L ${i.x1} ${i.half} L ${i.x0} ${i.half}`)}}else{a.push(`M ${s.x1} ${o} L ${i.x0} ${o}`);for(const t of e)a.push(`L ${t.x0} ${-t.half} L ${t.x1} ${-t.half}`)}return a.push("Z"),a.join(" ")}).join(" ")}function wl(t,e,i,s){if(!s)return i;const n=t.angle*Math.PI/180,o=Math.cos(n),a=Math.sin(n),r=[],l=1e-9;for(const n of i){const[i,c]=n.axis,h=o*i+a*c;if(Math.abs(h)<=l)continue;const d=t.x*i+t.y*c,u=d+h*n.x0,p=d+h*n.x1,_=Math.min(u,p),g=Math.max(u,p),m=`${n.key}|${e}`,f=s.get(m)||[];let v=[[_,g]];for(const[t,e]of f){const i=[];for(const[s,n]of v)e<=s+l||t>=n-l?i.push([s,n]):(t>s+l&&i.push([s,Math.min(n,t)]),et[0]-e[0]||t[1]-e[1]),b=[];for(const t of y){const e=b[b.length-1];e&&t[0]<=e[1]+l?e[1]=Math.max(e[1],t[1]):b.push([t[0],t[1]])}s.set(m,b)}return r}function kl(t,e){const i=new Map;return e.map(e=>function(t,e,i){const s=vl(t,e,!0),n=s.negative,o=s.positive;if(!n&&!o)return null;let a;if(n&&o)a=[{candidate:n,side:-1},{candidate:o,side:1}];else{const t=n||o;a=[{candidate:t,side:-1},{candidate:t,side:1}]}const r=a.map(({candidate:t,side:s})=>({candidate:t,side:s,pieces:wl(e,s,t.pieces,i)})),l=r.map(({candidate:t,side:e,pieces:i})=>({side:e,roomId:t.roomId,d:bl(e,i)})),c=r.flatMap(({pieces:t})=>t);if(!c.length)return null;const h=Math.max(...c.map(t=>t.half));return{faces:l,minY:-h,maxY:h,wallKey:[...new Set(c.map(t=>t.key))].sort().join("|")}}(t,e,i))}const xl=150;function $l(t){return Number.isFinite(t)?Math.max(1,Math.min(xl,t)):1}function Sl(t){return((Number.isFinite(Number(t))?Number(t):0)%90+90)%90}const Ml=t=>{const e=t.map(t=>[t[0],t[1]]);return!e.length||e[0][0]===e[e.length-1][0]&&e[0][1]===e[e.length-1][1]||e.push([...e[0]]),[e]};function Cl(t){const e=[];for(const i of t||[])for(const t of i||[]){const i=(t||[]).filter(t=>Array.isArray(t)&&t.length>=2);i.length<4||e.push(`M ${i.slice(0,-1).map(t=>`${t[0]} ${t[1]}`).join(" L ")} Z`)}return e.join(" ")}function Dl(t,e,i,s,n){return Fr({a:t,b:e,halfDepth:fr(i,s,n)/2})}function Tl(t,e,i){const s=Number(e)>0?Number(e):5,n=$l(t.cm)/s*i,o=t.center[0],a=t.center[1];if("circle"===t.shape){const t=n/2;return Array.from({length:96},(e,i)=>{const s=i/96*Math.PI*2;return[o+Math.cos(s)*t,a+Math.sin(s)*t]})}const r=n/2,l=Sl(t.angle)*Math.PI/180,c=Math.cos(l),h=Math.sin(l);return[[-r,-r],[r,-r],[r,r],[-r,r]].map(([t,e])=>[o+t*c-e*h,a+t*h+e*c])}function Pl(t,e,i=1e-9){if(!e.length)return[t];let s=[Ml(t)];try{for(const t of e){const e=t.b[0]-t.a[0],n=t.b[1]-t.a[1],o=Math.hypot(e,n);if(!(o>i))continue;const a=e/o,r=n/o,l=-r,c=a,h=1.25*Math.max(Number(t.depth)||0,4*i),d=Math.max(2*i,1e-9*o),u=[[t.a[0]-a*d-l*h,t.a[1]-r*d-c*h],[t.b[0]+a*d-l*h,t.b[1]+r*d-c*h],[t.b[0]+a*d+l*h,t.b[1]+r*d+c*h],[t.a[0]-a*d+l*h,t.a[1]-r*d+c*h]];s=oi(s,Ml(u))}return Ol(s)}catch{return[t]}}function Rl(t,e,i,s=Math.max(2e-4*i,1e-9),n=[]){const o=[],a=[],r=new Map;for(const t of n){const e=r.get(t.hostId)||[];e.push(t),r.set(t.hostId,e)}const l=[],c=[],h=[];for(const s of t.room_drafts||[])for(let t=0;t+1Tl(t,e,i)),u=Nr([...o,...a],s).flatMap(t=>Pl(t,n,s));return{drafts:l,partitions:c,columns:d,patches:u,all:[...l,...h,...u,...d]}}function Al(t){try{const e=t.filter(t=>t.length>=3).map(t=>Ml(t));return e.length?si(e[0],...e.slice(1)):null}catch{return null}}const Il=t=>`M ${t.map(t=>`${t[0]} ${t[1]}`).join(" L ")} Z`;function El(t,e){const i=Al(t.filter(t=>t.length>=3)),s=Al(e.filter(t=>t.length>=3));if(!i)return[];if(!s)return[];try{return function(t){const e=[];for(const i of t||[]){if(zl([i])<=1e-6)continue;const t=[];for(const e of i||[]){const i=(e||[]).filter(t=>Array.isArray(t)&&t.length>=2);i.length<4||t.push(Il(i.slice(0,-1)))}t.length&&e.push(t.join(" "))}return e}(ni(i,s))}catch{return[]}}function Fl(t,e){if(!e.length)return[Ml(t)];try{const i=Al(e);if(i)return oi(Ml(t),i)}catch{}let i=[Ml(t)];for(const t of e)if(!(t.length<3))try{i=oi(i,Ml(t))}catch{}return i}function zl(t){let e=0;for(const i of t||[])if(i?.length){e+=Pi(i[0]||[]);for(let t=1;t=4&&e.push(t.slice(0,-1).map(t=>[t[0],t[1]]))}return e}function Hl(t,e){let i=!1;for(let s=0,n=e.length-1;st[1]!=l>t[1]&&t[0]<(r-o)*(t[1]-a)/(l-a||1e-12)+o&&(i=!i)}return i}function Nl(t,e,i){return function(t,e){for(const i of e||[]){const e=i?.[0];if(!e?.length||!Hl(t,e))continue;let s=!1;for(let e=1;eHl(t,e))}function Ll(t,e,i){if(Math.hypot(t.center[0]-e.center[0],t.center[1]-e.center[1])>i)return!1;if(Math.abs($l(t.cm)-$l(e.cm))>1e-6)return!1;if(t.shape!==e.shape)return!0;if("circle"===t.shape||"circle"===e.shape)return!0;const s=Math.abs(Sl(t.angle)-Sl(e.angle));return Math.min(s,90-s)<=1e-6}const Bl=1e3;function ql(t,e){const i=Number(t),s=Number.isFinite(i)&&i>0?i:1,n=s>=1?e:e*s,o=s>=1?e/s:e;return{x:(e-n)/2,y:(e-o)/2,w:n,h:o}}const jl=.01,Wl=100;function Ul(t,e=1e3){const i=ql(t?.plan_aspect,e),s=Number(t?.plan_scale),n=Number.isFinite(s)&&s>0?Math.min(Wl,Math.max(jl,s)):1,o=Number(t?.plan_scale_x),a=Number(t?.plan_scale_y),r=Number.isFinite(o)&&o>0?Math.min(Wl,Math.max(jl,o)):n,l=Number.isFinite(a)&&a>0?Math.min(Wl,Math.max(jl,a)):n,c=Number(t?.plan_x),h=Number(t?.plan_y),d=sr(t?.plan_angle);return{x:i.x+(Number.isFinite(c)?ic(c):0)*e,y:i.y+(Number.isFinite(h)?ic(h):0)*e,w:i.w*r,h:i.h*l,...d?{angle:d}:{}}}function Gl(t){if(null==t.x||null==t.y)return{x:t.x,y:t.y,w:t.w,h:t.h};const e=Number(t.w)||0,i=Number(t.h)||0;return{x:e<0?t.x+e:t.x,y:i<0?t.y+i:t.y,w:Math.abs(e),h:Math.abs(i)}}function Vl(t){return t&&Array.isArray(t.spaces)?t.spaces.map(t=>{const e=Bl,i=function(t){return Array.isArray(t)&&4===t.length&&t.every(t=>Number.isFinite(t))&&t[2]>1e-6&&t[3]>1e-6?t:[0,0,1,1]}(t.view_box);return{id:t.id,title:t.title,vb:[i[0]*Bl,i[1]*e,i[2]*Bl,i[3]*e],bg:t.plan_url?{href:Is(t.plan_url),...Ul(t,Bl)}:null,rooms:(t.rooms||[]).map(t=>{const i={...t,...Gl(t)};return{id:i.id,name:i.name,area:i.area??null,open_to:i.open_to||void 0,settings:i.settings||void 0,x:null!=i.x?i.x*Bl:void 0,y:null!=i.y?i.y*e:void 0,w:null!=i.w?i.w*Bl:void 0,h:null!=i.h?i.h*e:void 0,poly:i.poly?i.poly.map(t=>[t[0]*Bl,t[1]*e]):void 0}}),room_drafts:(t.room_drafts||[]).map(t=>({id:t.id,points:(t.points||[]).map(t=>[t[0]*Bl,t[1]*e]),segments:(t.segments||[]).map(t=>({cm:Number(t.cm)}))})),partitions:(t.partitions||[]).map(t=>({id:t.id,a:[t.a[0]*Bl,t.a[1]*e],b:[t.b[0]*Bl,t.b[1]*e],cm:Number(t.cm)})),wall_columns:(t.wall_columns||[]).map(t=>({id:t.id,shape:"circle"===t.shape?"circle":"square",center:[t.center[0]*Bl,t.center[1]*e],cm:Number(t.cm),..."circle"===t.shape?{}:{angle:Sl(t.angle)}}))}}):[]}const Kl=5e3,Yl=Kl*Bl,Xl=240,Jl=Bl/Xl,Zl=1/Xl;function Ql(t){if(!Number.isFinite(t))return t;const e=Math.round(t*Xl/Bl)*Bl/Xl;return Math.abs(e-t)<=1e-9*Jl?t:e}function tc(t){return{x:Ql(t.x),y:Ql(t.y)}}function ec(t){return Number.isFinite(t)?Math.min(Yl,Math.max(-Yl,t)):0}function ic(t){return Number.isFinite(t)?Math.min(Kl,Math.max(-Kl,t)):0}const sc=1/3,nc=200;function oc(t){let e=1/0,i=1/0,s=-1/0,n=-1/0;for(const o of t){const t=Number(o[0]),a=Number(o[1]);Number.isFinite(t)&&Number.isFinite(a)&&(ts&&(s=t),a>n&&(n=a))}return e>s?null:{minX:e,minY:i,maxX:s,maxY:n}}function ac(t){return t.poly&&t.poly.length?oc(t.poly):null==t.x||null==t.y?null:oc([[t.x,t.y],[t.x+(t.w||0),t.y+(t.h||0)]])}function rc(t,e){const i=[];for(const e of t.rooms||[]){const t=ac(e);t&&i.push(t)}if(t.bg){const e=oc(cr(t.bg));e&&i.push(e)}for(const t of e||[])if(Array.isArray(t)){const e=oc([t]);e&&i.push(e)}else i.push(t);return i}const lc=t=>{if(!t.length)return 0;const e=[...t].sort((t,e)=>t-e),i=e.length>>1;return e.length%2?e[i]:(e[i-1]+e[i])/2},cc=t=>{let e=1/0,i=1/0,s=-1/0,n=-1/0;for(const o of t)o.minXs&&(s=o.maxX),o.maxY>n&&(n=o.maxY);return e>s||i>n?null:{x:e,y:i,w:s-e,h:n-i}};function hc(t,e){let{x:i,y:s,w:n,h:o}=t;n<30&&(i=i+n/2-100,n=nc),o<30&&(s=s+o/2-100,o=nc);const a=Math.max(n,o)*e;return{x:i-a,y:s-a,w:n+2*a,h:o+2*a}}function dc(t,e={}){const i=e.pad??.05,s=e.k??10,n=e.minSpread??50,o=t.filter(t=>Number.isFinite(t.minX)&&Number.isFinite(t.minY)&&Number.isFinite(t.maxX)&&Number.isFinite(t.maxY)&&Math.abs(t.minX)<=Yl&&Math.abs(t.maxX)<=Yl&&Math.abs(t.minY)<=Yl&&Math.abs(t.maxY)<=Yl);if(!o.length)return{core:null,all:null,outliers:0};const a=cc(o);if(o.length<4){const t=hc(a,i);return{core:t,all:t,outliers:0}}const r=o.map(t=>(t.minX+t.maxX)/2),l=o.map(t=>(t.minY+t.maxY)/2),c=lc(r),h=lc(l),d=o.map((t,e)=>Math.max(Math.abs(r[e]-c),Math.abs(l[e]-h))),u=Math.max(((t,e)=>t.length?t[Math.min(t.length-1,Math.max(0,Math.round(e*(t.length-1))))]:0)([...d].sort((t,e)=>t-e),.75),n),p=d.map(t=>t>s*u),_=p.filter(Boolean).length,g=_&&_<=o.length*sc?o.filter((t,e)=>!p[e]):o;return{core:hc(cc(g)||a,i),all:hc(a,i),outliers:g===o?0:_}}function uc(t,e,i=.05){const s=dc(rc(t,e),{pad:i});if(s.core)return s.core;const n=t.vb&&4===t.vb.length&&t.vb[2]>0&&t.vb[3]>0?t.vb:[0,0,Bl,Bl];return{x:n[0],y:n[1],w:n[2],h:n[3]}}function pc(t){const e=uc(t);return{x:e.x+e.w/2,y:e.y+e.h/2}}function _c(t){const e=[];for(const i of t.rooms||[]){const t=ac(i);t&&e.push(t)}const i=dc(e,{pad:0}).core;return i?Math.max(Bl,Math.min(Yl,Math.max(i.w,i.h))):Bl}function gc(t,e,i,s=1){const n=Number(i),o=Number.isFinite(s)&&s>0?s:1;return!Number.isFinite(n)||n<=0?t*o:t*_c(e)*o/n}const mc=[1,2,5,10,20,50,100,200,500,1e3];function fc(t){if(t.poly&&t.poly.length){const e=t.poly.map(t=>t[0]),i=t.poly.map(t=>t[1]),s=Math.min(...e),n=Math.min(...i);return{x:s,y:n,w:Math.max(...e)-s,h:Math.max(...i)-n}}return{x:t.x??0,y:t.y??0,w:t.w??0,h:t.h??0}}function vc(t,e,i,s){const n=i["rl_"+(t.id||"")];if(n&&n.s===e)return{x:n.x*Bl,y:n.y*Bl};const o=function(t){if(t.poly){const e=t.poly.length;return[t.poly.reduce((t,e)=>t+e[0],0)/e,t.poly.reduce((t,e)=>t+e[1],0)/e]}return[t.x+t.w/2,t.y+.1*Math.min(t.w,t.h)]}(t);return tc({x:o[0],y:o[1]})}const yc=["furniture","appliance","sanitary","other"],bc=[{id:"sofa",group:"furniture",w:220,h:90,g:[["r",0,0,1,1],["l",.09,.26,.91,.26],["l",.09,.26,.09,1],["l",.91,.26,.91,1],["l",.5,.26,.5,1]]},{id:"armchair",group:"furniture",w:90,h:85,g:[["r",0,0,1,1],["l",.14,.28,.86,.28],["l",.14,.28,.14,1],["l",.86,.28,.86,1]]},{id:"coffee_table",group:"furniture",w:110,h:60,g:[["r",0,0,1,1],["r",.08,.14,.84,.72]]},{id:"table_dining",group:"furniture",w:140,h:80,g:[["r",0,0,1,1],["r",.06,.11,.88,.78]]},{id:"table_round",group:"furniture",w:120,h:120,g:[["e",.5,.5,.5,.5],["e",.5,.5,.41,.41]]},{id:"chair",group:"furniture",w:45,h:45,g:[["r",0,0,1,.18],["r",.06,.18,.88,.8]]},{id:"desk",group:"furniture",w:120,h:60,g:[["r",0,0,1,1],["r",.63,.07,.31,.86],["l",.63,.5,.94,.5]]},{id:"bed_double",group:"furniture",w:160,h:200,g:[["r",0,0,1,1],["r",0,0,1,.07],["r",.06,.1,.4,.15],["r",.54,.1,.4,.15],["l",0,.33,1,.33]]},{id:"bed_single",group:"furniture",w:90,h:200,g:[["r",0,0,1,1],["r",0,0,1,.07],["r",.15,.1,.7,.15],["l",0,.33,1,.33]]},{id:"nightstand",group:"furniture",w:45,h:40,g:[["r",0,0,1,1],["r",.12,.14,.76,.33],["r",.12,.53,.76,.33]]},{id:"wardrobe",group:"furniture",w:100,h:60,g:[["r",0,0,1,1],["l",0,.72,1,.72],["l",.5,.72,.5,1]]},{id:"bookshelf",group:"furniture",w:80,h:30,g:[["r",0,0,1,1],["l",.34,0,.34,1],["l",.67,0,.67,1]]},{id:"fridge",group:"appliance",w:60,h:65,g:[["r",0,0,1,1],["l",0,.36,1,.36],["l",.83,.44,.83,.64]]},{id:"stove",group:"appliance",w:60,h:60,g:[["r",0,0,1,1],["e",.29,.31,.15,.15],["e",.71,.31,.15,.15],["e",.29,.71,.15,.15],["e",.71,.71,.15,.15]]},{id:"dishwasher",group:"appliance",w:60,h:60,g:[["r",0,0,1,1],["r",.1,.12,.8,.76],["e",.5,.5,.27,.27],["e",.5,.5,.13,.13]]},{id:"washer",group:"appliance",w:60,h:60,g:[["r",0,0,1,1],["l",.08,.17,.92,.17],["e",.5,.57,.3,.3],["e",.5,.57,.14,.14]]},{id:"dryer",group:"appliance",w:60,h:60,g:[["r",0,0,1,1],["l",.08,.17,.92,.17],["e",.5,.57,.3,.3],["p",.36,.5,.5,.64,.64,.5]]},{id:"tv",group:"appliance",w:120,h:30,g:[["r",0,0,1,.42],["l",.5,.42,.5,.72],["l",.3,.72,.7,.72]]},{id:"ac",group:"appliance",w:90,h:25,g:[["r",0,0,1,1],["l",.05,.55,.95,.55],["l",.05,.79,.95,.79]]},{id:"water_heater",group:"appliance",w:45,h:45,g:[["e",.5,.5,.5,.5],["e",.5,.5,.31,.31]]},{id:"toilet",group:"sanitary",w:40,h:70,g:[["r",.06,0,.88,.2],["e",.5,.58,.37,.35],["e",.5,.58,.22,.2]]},{id:"bathtub",group:"sanitary",w:170,h:75,g:[["r",0,0,1,1],["r",.05,.11,.77,.78],["e",.89,.5,.045,.1]]},{id:"shower",group:"sanitary",w:90,h:90,g:[["r",0,0,1,1],["l",0,0,1,1],["l",1,0,0,1],["e",.5,.5,.08,.08]]},{id:"sink",group:"sanitary",w:60,h:45,g:[["r",0,0,1,1],["e",.5,.6,.34,.3],["e",.5,.15,.07,.07]]},{id:"kitchen_sink",group:"sanitary",w:80,h:60,g:[["r",0,0,1,1],["r",.06,.24,.44,.64],["r",.54,.24,.4,.64],["e",.5,.12,.06,.06]]},{id:"bidet",group:"sanitary",w:40,h:55,g:[["e",.5,.5,.44,.5],["e",.5,.5,.26,.3]]},{id:"stairs",group:"other",w:100,h:280,g:[["r",0,0,1,1],["l",0,.111,1,.111],["l",0,.222,1,.222],["l",0,.333,1,.333],["l",0,.444,1,.444],["l",0,.556,1,.556],["l",0,.667,1,.667],["l",0,.778,1,.778],["l",0,.889,1,.889],["l",.5,.93,.5,.06],["p",.38,.16,.5,.06,.62,.16]]},{id:"fireplace",group:"other",w:120,h:40,g:[["r",0,0,1,1],["p",.22,1,.22,.42,.78,.42,.78,1]]},{id:"plant",group:"other",w:40,h:40,g:[["e",.5,.5,.22,.22],["l",.5,.28,.5,.02],["l",.5,.72,.5,.98],["l",.28,.5,.02,.5],["l",.72,.5,.98,.5],["l",.34,.34,.13,.13],["l",.66,.66,.87,.87],["l",.66,.34,.87,.13],["l",.34,.66,.13,.87]]},{id:"rug",group:"other",w:200,h:140,g:[["r",0,0,1,1],["r",.06,.09,.88,.82]]}],wc=new Map(bc.map(t=>[t.id,t]));function kc(t){return t&&wc.get(t)||null}function xc(t){return bc.filter(e=>e.group===t)}function $c(t,e,i=Jl,s=1e3){const n=Number(e)>0?Number(e):5;return(Number(t)||0)/n*i/s}const Sc=5e-4,Mc=Kl;function Cc(t){return Number.isFinite(t)?Math.max(Sc,Math.min(Mc,t)):Sc}const Dc=t=>{const e=Math.round(1e3*t)/1e3;return Object.is(e,-0)?"0":String(e)};function Tc(t,e,i){const s=kc(t);if(!(s&&e>0&&i>0))return"";const n=t=>Dc(t*e),o=t=>Dc(t*i),a=[];for(const t of s.g)if("r"===t[0]){const[,e,i,s,r]=t;a.push(`M${n(e)} ${o(i)}H${n(e+s)}V${o(i+r)}H${n(e)}Z`)}else if("l"===t[0]){const[,e,i,s,r]=t;a.push(`M${n(e)} ${o(i)}L${n(s)} ${o(r)}`)}else if("e"===t[0]){const[,s,r,l,c]=t;a.push(`M${n(s-l)} ${o(r)}A${Dc(l*e)} ${Dc(c*i)} 0 0 1 ${n(s+l)} ${o(r)}A${Dc(l*e)} ${Dc(c*i)} 0 0 1 ${n(s-l)} ${o(r)}Z`)}else{const e=t.slice(1);if(e.length<4)continue;let i=`M${n(e[0])} ${o(e[1])}`;for(let t=2;t+1{let e=(t%360+360)%360;return e>180&&(e-=360),e};function Rc(t,e,i,s,n,o=0){let a=null,r=n;for(const n of s){const[s,l,c,h]=n,d=c-s,u=h-l,p=d*d+u*u;if(!p)continue;const _=Math.sqrt(p);let g=((t-s)*d+(e-l)*u)/p;g=Math.max(0,Math.min(1,g));let m=s+g*d,f=l+g*u;const v=Math.hypot(t-m,e-f);if(!(v0){const t=Math.round(g*_/o)*o;m=s+t/_*d,f=l+t/_*u}a={cx:m+y*(i/2),cy:f+b*(i/2),angle:Pc(180*Math.atan2(-y,b)/Math.PI),dist:v}}return a}function Ac(t,e,i){const s=i;return{a:[t[0]/s,t[1]/s],b:[e[0]/s,e[1]/s]}}function Ic(t,e){const i=e;return[t.a[0]*i,t.a[1]*i,t.b[0]*i,t.b[1]*i]}function Ec(t){return Array.isArray(t)&&t.length>=2&&Number.isFinite(Number(t[0]))&&Number.isFinite(Number(t[1]))}function Fc(t){if(!Array.isArray(t))return[];const e=[];for(const i of t){if(!i||"object"!=typeof i)continue;const t=i;if(!Ec(t.a)||!Ec(t.b))continue;const s=[Number(t.a[0]),Number(t.a[1])],n=[Number(t.b[0]),Number(t.b[1])];Math.hypot(n[0]-s[0],n[1]-s[1])<.001||e.push({a:s,b:n})}return e}function zc(t,e){const i=e[0],s=e[1],n=e[2]-i,o=e[3]-s,a=n*n+o*o;if(a<1e-18){return{q:[i,s],t:0,d:Math.hypot(t[0]-i,t[1]-s)}}let r=((t[0]-i)*n+(t[1]-s)*o)/a;r=Math.max(0,Math.min(1,r));const l=[i+r*n,s+r*o];return{q:l,t:r,d:Math.hypot(t[0]-l[0],t[1]-l[1])}}function Oc(t,e){return zc(t,e).q}function Hc(t,e,i,s,n){const o=zc(t,e).q;let a=o,r=1/0;for(const t of i){const e=Math.hypot(o[0]-t[0],o[1]-t[1]);e<=n&&e0?s:1,g=Math.round(p/_)*_,m=Math.max(0,Math.min(u,g))/u;return[l+h*m,c+d*m]}function Nc(t,e){const i=[],s=(t||[]).filter(t=>t?.id);for(let t=0;tt?.id),a=Fc(e);if(a.length)return Kc(a,t,i,s).map(t=>Ic(t,i));if(!n)return[];const r=[],l=(t,e)=>(t.open_to||[]).includes(e.id)||(e.open_to||[]).includes(t.id);for(let t=0;tAc([t[0],t[1]],[t[2],t[3]],e))}function qc(t,e,i,s){for(const e of t||[])e.open_to&&delete e.open_to;if(!i.length)return;const n=(e||[]).filter(t=>t?.id);new Map(n.map(t=>[t.id,t]));const o=new Map((t||[]).filter(t=>t?.id).map(t=>[t.id,t])),a=(t,e)=>{const i=o.get(t),s=o.get(e);i&&s&&((i.open_to||[]).includes(e)||(i.open_to=[...i.open_to||[],e]),(s.open_to||[]).includes(t)||(s.open_to=[...s.open_to||[],t]))};for(let t=0;tNs(i,t)<4*s)){a(n[t].id,n[e].id);break}}}for(const e of t||[])e.open_to&&!e.open_to.length&&delete e.open_to}function jc(t,e,i,s=0){const n=e[2]-e[0],o=e[3]-e[1],a=Math.hypot(n,o);if(!(a>1e-9))return null;const r=n/a,l=o/a,c=(t[0]-e[0])*r+(t[1]-e[1])*l;if(c<-s||c>a+s)return null;return Math.abs((t[0]-e[0])*l-(t[1]-e[1])*r)>i?null:Ns(t,e)}function Wc(t,e,i){const s=t[2]-t[0],n=t[3]-t[1],o=e[2]-e[0],a=e[3]-e[1],r=Math.hypot(s,n),l=Math.hypot(o,a);return r>1e-9&&l>1e-9&&(!(Math.abs(s/r*(a/l)-n/r*(o/l))>1e-6)&&(Ns([e[0],e[1]],t)<=4*i||Ns([t[0],t[1]],e)<=4*i))}function Uc(t,e,i){if(!t.length)return null;t.sort((t,e)=>t.distance-e.distance);const s=t[0];for(let n=1;ne)break;if(o.semantic!==s.semantic||!Wc(s.seg,o.seg,i))return"ambiguous"}return s}function Gc(t,e,i,s,n=1,o=15){const a=function(t,e,i,s,n=1,o=15){const[a,r]=yr([e[0],e[1]],[e[2],e[3]]);let l=0,c=1/0;const h=[(e[0]+e[2])/2,(e[1]+e[3])/2];for(const e of i){const[i,o]=yr([e[0],e[1]],[e[2],e[3]]);if(Math.abs(a*o-r*i)>.05)continue;const d=Dr(t,[e[0],e[1]],[e[2],e[3]],s,n);if(!(d>0))continue;const u=[(e[0]+e[2])/2,(e[1]+e[3])/2],p=Math.hypot(u[0]-h[0],u[1]-h[1]);p0?l:o}(t,e,i,s,n,o);return Ar(t,[e[0],e[1]],[e[2],e[3]],a,s,n)}function Vc(t,e,i){const s=[[t[0],t[1]],[t[2],t[3]]],n=[(t[0]+t[2])/2,(t[1]+t[3])/2];for(const o of e)if(!(Ns(n,o)>Math.hypot(t[2]-t[0],t[3]-t[1])&&Ns([o[0],o[1]],t)>i))for(const e of[[o[0],o[1]],[o[2],o[3]]])Ns(e,t)<=2*i&&s.push(e);return s}function Kc(t,e,i,s){const n=Fc(t);if(!n.length)return[];const o=Nc(e,s);if(!o.length)return[];const a=[],r=Math.max(4*s,1e-6);for(const t of n){const e=Ic(t,i),n=e[0],l=e[1],c=e[2]-n,h=e[3]-l,d=Math.hypot(c,h);if(d4*s||o>4*s)continue;const a=(t[0]-n)*u+(t[1]-l)*p,c=(t[2]-n)*u+(t[3]-l)*p,h=Math.max(0,Math.min(a,c)),g=Math.min(d,Math.max(a,c));if(g-ht.lo-e.lo||t.hi-e.hi);const i=[];for(const t of e){const e=i[i.length-1];e&&t.lo<=e.hi+r?e.hi=Math.max(e.hi,t.hi):i.push({...t})}for(const e of i){const i=[n+u*e.lo,l+p*e.lo],s=[n+u*e.hi,l+p*e.hi];Math.hypot(s[0]-i[0],s[1]-i[1])i.pair===t&&Math.abs(i.ux*a-i.uy*o)<=1e-6&&Math.abs((e[0]-i.origin[0])*i.uy-(e[1]-i.origin[1])*i.ux)<=c&&Math.abs((e[2]-i.origin[0])*i.uy-(e[3]-i.origin[1])*i.ux)<=c);h||(h={pair:t,origin:[e[0],e[1]],ux:o,uy:a,ranges:[]},l.push(h));const d=(e[0]-h.origin[0])*h.ux+(e[1]-h.origin[1])*h.uy,u=(e[2]-h.origin[0])*h.ux+(e[3]-h.origin[1])*h.uy;h.ranges.push({lo:Math.min(d,u),hi:Math.max(d,u)})}const h=[];for(const t of l){t.ranges.sort((t,e)=>t.lo-e.lo||t.hi-e.hi);const e=[];for(const i of t.ranges){const t=e[e.length-1];t&&i.lo<=t.hi+r?t.hi=Math.max(t.hi,i.hi):e.push({...i})}for(const s of e){const e=[t.origin[0]+t.ux*s.lo,t.origin[1]+t.uy*s.lo],n=[t.origin[0]+t.ux*s.hi,t.origin[1]+t.uy*s.hi];Math.hypot(n[0]-e[0],n[1]-e[1])>=r&&h.push(Ac(e,n,i))}}return h}function Yc(t,e,i,s){const n=Fc(t);if(!n.length)return[];if(e.length!==i.length)return n;const o=[];for(const t of n){const n=Ic(t,s),a=[n[0],n[1]],r=[n[2],n[3]];let l=a,c=r;for(let t=0;t{const e=zc(t,[s[0],s[1],n[0],n[1]]);if(e.d>.001)return t;const i=h[0]-o[0],a=h[1]-o[1];return[o[0]+i*e.t,o[1]+a*e.t]};if(zc([(a[0]+r[0])/2,(a[1]+r[1])/2],[s[0],s[1],n[0],n[1]]).d<.01){l=d(a),c=d(r);break}}o.push(Ac(l,c,s))}return o}const Xc=15e3,Jc=2e3,Zc=new WeakMap;function Qc(t,e){let i=Zc.get(t);if(!i){const e=new Set;i={hiddenAt:"hidden"===t.visibilityState?Date.now():0,token:0,subscribers:e,onVisibility:()=>{const e=Zc.get(t);if(!e)return;const i=Date.now();if("hidden"===t.visibilityState){e.hiddenAt||(e.hiddenAt=i);const t={kind:"hidden",token:e.token,at:i,hiddenFor:0,long:!1};for(const i of[...e.subscribers])i(t);return}const s=e.hiddenAt?Math.max(0,i-e.hiddenAt):0;e.hiddenAt=0,e.token++;const n={kind:"visible",token:e.token,at:i,hiddenFor:s,long:s>=Xc};for(const t of[...e.subscribers])t(n)},onPageShow:e=>{const i=Zc.get(t);if(!i)return;const s=Date.now();i.token++;const n={kind:"pageshow",token:i.token,at:s,hiddenFor:0,long:!!e.persisted,persisted:!!e.persisted};for(const t of[...i.subscribers])t(n)}},Zc.set(t,i),t.addEventListener("visibilitychange",i.onVisibility),t.defaultView?.addEventListener("pageshow",i.onPageShow)}return i.subscribers.add(e),()=>{const i=Zc.get(t);i&&(i.subscribers.delete(e),i.subscribers.size||(t.removeEventListener("visibilitychange",i.onVisibility),t.defaultView?.removeEventListener("pageshow",i.onPageShow),Zc.delete(t)))}}const th={now:()=>Date.now(),setTimeout:(t,e)=>window.setTimeout(t,e),clearTimeout:t=>window.clearTimeout(t),requestAnimationFrame:t=>window.requestAnimationFrame(t),cancelAnimationFrame:t=>window.cancelAnimationFrame(t)};class eh{constructor(t,e=th){this.onChange=t,this.clock=e,this._state="steady",this._token=0,this._frameFingerprint="",this._hasCompleteFrame=!1,this._overlayPhase="none",this._recoveryReason=null,this._overlayTimer=0,this._overlayRaf=0,this._overlayOpaqueAt=0,this._barrierRafs=new Set,this._trace=[],this._disposed=!1}get state(){return this._state}get token(){return this._token}get frameFingerprint(){return this._frameFingerprint}get hasCompleteFrame(){return this._hasCompleteFrame}get overlayPhase(){return this._overlayPhase}get overlayVisible(){return"none"!==this._overlayPhase}get overlayBlocksInteraction(){return this.overlayVisible}get recoveryReason(){return this._recoveryReason}get trace(){return this._trace.map(t=>({...t,...t.stage?{stage:[...t.stage]}:{}}))}note(t,e={}){this.record(t,void 0,e)}record(t,e,i={}){this._trace.push({at:this.clock.now(),token:this._token,event:t,state:this._state,...e?{reason:e}:{},...i}),this._trace.length>80&&this._trace.splice(0,this._trace.length-80)}changed(){this._disposed||this.onChange()}adoptCompleteFrame(t){t&&(this._hasCompleteFrame=!0,this._frameFingerprint=t,this._state="steady",this._recoveryReason=null,this.clearOverlay(),this.record("frame-adopted"),this.changed())}markCompleteFrame(t){t&&(this._hasCompleteFrame=!0,this._frameFingerprint=t,this._state="steady",this._recoveryReason=null,this.clearOverlay(),this.record("frame-complete"),this.changed())}refreshCompleteFrame(t){!this._disposed&&this._hasCompleteFrame&&"steady"===this._state&&t&&t!==this._frameFingerprint&&(this._frameFingerprint=t,this.record("frame-refreshed"))}visibility(t){return"hidden"===t.kind?(this.record("visibility-hidden"),this._token):t.long||"visible"!==t.kind&&"pageshow"!==t.kind?this.beginCandidate("pageshow"===t.kind?"pageshow":"long-resume"):(this.record("pageshow"===t.kind?"pageshow-noop":"visibility-visible-quick"),this._token)}beginCandidate(t,e="plan"){return this._token++,this._recoveryReason=e,this._hasCompleteFrame?(this._state="connection"===e?"offline-stale":"holding",this.clearOverlay()):this.overlayVisible?this._state="overlay-visible":(this._state="overlay-pending",this.scheduleOverlay(e)),this.record("candidate-start",t),this.changed(),this._token}connectionLost(){return this.beginCandidate("connection-lost","connection")}candidateReady(t){return!this._disposed&&t===this._token&&(this._state="candidate-ready",this.record("candidate-ready"),this.changed(),!0)}async commitAfterPaint(t,e){if(this._disposed||t!==this._token)return!1;let i=!0;const s=(async()=>{for(await e.updateComplete();i&&!this._disposed&&t===this._token;)if(e.stageValid()&&e.assetsReady()){if(await this.nextFrame(),t!==this._token||!e.stageValid()||!e.assetsReady())continue;if(await this.nextFrame(),t===this._token&&e.stageValid()&&e.assetsReady())return!0}else await this.nextFrame();return!1})();let n=0;const o=new Promise(t=>{n=this.clock.setTimeout(()=>t({ready:!1,timedOut:!0}),Jc)}),a=await Promise.race([s.then(t=>({ready:t,timedOut:!1})),o]);return i=!1,this.clock.clearTimeout(n),!this._disposed&&t===this._token&&(!(!a.ready&&!a.timedOut)&&(a.ready?(this._hasCompleteFrame=!0,this._frameFingerprint=e.frameFingerprint(),this.record("paint-barrier"),this.finishOverlayAfterCommit(),!0):(this.record("paint-barrier-timeout"),this._hasCompleteFrame?(this._state="connection"===this._recoveryReason?"offline-stale":"steady",this.clearOverlay()):(this._state="recovery-error","opaque"!==this._overlayPhase&&this.showOverlayNow()),this.changed(),!1)))}retry(t=this._recoveryReason||"plan"){return this.beginCandidate("retry",t)}nextFrame(){return new Promise(t=>{const e=this.clock.requestAnimationFrame(()=>{this._barrierRafs.delete(e),t()});this._barrierRafs.add(e)})}scheduleOverlay(t){this.clearOverlayTimer(),this._recoveryReason=t,this._overlayTimer=this.clock.setTimeout(()=>{this._overlayTimer=0,this._hasCompleteFrame||"overlay-pending"!==this._state&&"candidate-ready"!==this._state||(this._state="overlay-visible",this._overlayPhase="entering",this.record("overlay-enter"),this.changed(),this._overlayRaf=this.clock.requestAnimationFrame(()=>{this._overlayRaf=0,"entering"===this._overlayPhase&&(this._overlayPhase="fading-in",this.changed(),this._overlayTimer=this.clock.setTimeout(()=>{this._overlayTimer=0,"fading-in"===this._overlayPhase&&(this._overlayPhase="opaque",this._overlayOpaqueAt=this.clock.now(),this.record("overlay-opaque"),this.changed())},150))}))},150)}showOverlayNow(){this.clearOverlayTimer(),this._overlayPhase="opaque",this._overlayOpaqueAt=this.clock.now(),this.record("overlay-error")}finishOverlayAfterCommit(){if(this.clearOverlayTimer(),"none"===this._overlayPhase||"entering"===this._overlayPhase||"fading-in"===this._overlayPhase)return this.clearOverlay(),this._state="steady",this._recoveryReason=null,this.record("candidate-committed"),void this.changed();const t=Math.max(0,this._overlayOpaqueAt+250-this.clock.now());this._overlayTimer=this.clock.setTimeout(()=>{this._overlayTimer=0,this._overlayPhase="leaving",this.record("overlay-leave"),this.changed(),this._overlayTimer=this.clock.setTimeout(()=>{this._overlayTimer=0,this._overlayPhase="none",this._state="steady",this._recoveryReason=null,this.record("candidate-committed"),this.changed()},180)},t)}clearOverlayTimer(){this._overlayTimer&&this.clock.clearTimeout(this._overlayTimer),this._overlayTimer=0}clearOverlay(){this.clearOverlayTimer(),this._overlayRaf&&this.clock.cancelAnimationFrame(this._overlayRaf),this._overlayRaf=0,this._overlayPhase="none",this._overlayOpaqueAt=0}dispose(){this._disposed=!0,this._token++,this.clearOverlay();for(const t of this._barrierRafs)this.clock.cancelAnimationFrame(t);this._barrierRafs.clear()}}function ih(t){let e=2166136261,i=2654435769;const s=new WeakSet,n=t=>{for(let s=0;s>>0)+(i>>>2)}},o=t=>{if(null===t)return void n("n");const e=typeof t;if("string"===e)return void n(`s${t.length}:${t}`);if("number"===e)return void n(`d${Number.isNaN(t)?"NaN":String(t)}`);if("boolean"===e)return void n(t?"t":"f");if("undefined"===e)return void n("u");if("object"!==e)return void n(`${e}:${String(t)}`);const i=t;if(s.has(i))n("[cycle]");else{if(s.add(i),Array.isArray(t)){n("[");for(const e of t)o(e);return n("]"),void s.delete(i)}n("{");for(const e of Object.keys(t).sort())n(e),o(t[e]);n("}"),s.delete(i)}};return o(t),`${(e>>>0).toString(16).padStart(8,"0")}${(i>>>0).toString(16).padStart(8,"0")}`}function sh(t){return ih(t)}const nh=new WeakMap;class oh{constructor(t,e=()=>Date.now()){this.onUpdate=t,this.now=e,this.fallbackAuthority={},this.referenceOwner={},this.referenced=new Set,this.queued=new Set,this.disposed=!1,this.sharedUpdate=()=>{this.disposed||this.onUpdate()}}bind(t){const e=((t,e)=>{const i=t?.connection||t?.callWS||e;return!i||"object"!=typeof i&&"function"!=typeof i?e:i})(t,this.fallbackAuthority);return this.shared&&this.authority===e||(this.shared&&(this.shared.listeners.delete(this.sharedUpdate),this.shared.references.delete(this.referenceOwner)),this.authority=e,this.shared=(t=>{let e=nh.get(t);return e||(e={signed:{},queued:new Set,inFlight:new Map,retry:new Map,listeners:new Set,settlers:new Set,references:new Map},nh.set(t,e)),e})(e),this.disposed||(this.shared.listeners.add(this.sharedUpdate),this.shared.references.set(this.referenceOwner,new Set(this.referenced)))),this.shared}start(t,e){this.disposed=!1,this.referenced=new Set(e());const i=this.bind(t());i.listeners.add(this.sharedUpdate),i.references.set(this.referenceOwner,new Set(this.referenced)),this.stopTimer(),this.resignTimer=setInterval(()=>this.resign(t(),e()),288e5)}dispose(){if(this.disposed=!0,this.stopTimer(),clearTimeout(this.batchTimer),this.shared){this.shared.listeners.delete(this.sharedUpdate),this.shared.references.delete(this.referenceOwner);for(const t of this.queued)this.shared.queued.delete(t)}this.queued.clear()}invalidate(t){const e=this.bind(t);clearTimeout(this.batchTimer),this.queued.clear(),e.queued.clear(),e.inFlight.clear(),e.retry.clear(),e.signed={}}stopTimer(){void 0!==this.resignTimer&&clearInterval(this.resignTimer),this.resignTimer=void 0}display(t,e){const i=Is(e);if(!i.startsWith("/api/houseplan/content/"))return i;const s=this.bind(t);this.referenced.add(i),s.references.set(this.referenceOwner,new Set(this.referenced));const n=s.signed[i],o=n?this.now()-n.at:1/0;return o{const e=[...this.queued];this.queued.clear();for(const t of e)i.queued.delete(t);this.sign(t,e)},30))}sign(t,e){if(!e.length||!t?.callWS)return;const i=this.bind(t);for(const s of function(t,e){const i=Math.max(1,Math.floor(e)),s=[];for(let e=0;e{const s=i.inFlight.get(t);return!(void 0!==s&&e-s<15e3)&&(i.inFlight.set(t,e),!0)});n.length&&t.callWS({type:"houseplan/content/sign",paths:n}).then(t=>{const e=this.now();let s=0,o=!1;for(const a of n){const n=t?.urls?.[a];if("string"==typeof n&&n){const t=i.signed[a];t?.loaded&&t.url!==n?(t.pending={url:n,at:e},this.preloadReplacement(i,a,n,e)):(i.signed[a]={url:n,at:e,loaded:t?.url===n&&!!t.loaded},o=!0),i.retry.delete(a),s++}else this.backOff(i,a)}if(s&&(this.trimShared(i),o))for(const t of[...i.listeners])t()}).catch(()=>{for(const t of n)this.backOff(i,t)}).finally(()=>{for(const t of n)i.inFlight.get(t)===e&&i.inFlight.delete(t);for(const t of[...i.settlers])t()})}}preloadReplacement(t,e,i,s){const n=()=>{const n=t.signed[e];if(n?.pending?.url===i){t.signed[e]={url:i,at:s,loaded:!0},t.retry.delete(e),this.trimShared(t);for(const e of[...t.listeners])e()}},o=()=>{const s=t.signed[e];s?.pending?.url===i&&(delete s.pending,this.backOff(t,e))};if("undefined"==typeof Image)return void n();const a=new Image;a.onload=()=>{("function"==typeof a.decode?a.decode():Promise.resolve()).then(n).catch(o)},a.onerror=o,a.src=i}preloadCurrentImage(t,e,i){if(i.loaded)return Promise.resolve(!0);if(i.preload)return i.preload;if("undefined"==typeof Image)return i.loaded=!0,Promise.resolve(!0);const s=i.url;return i.preload=new Promise(n=>{const o=new Image;let a=!1;const r=o=>{if(a)return;a=!0,clearTimeout(l);const r=t.signed[e];if(r===i&&delete r.preload,o&&r===i&&r.url===s){r.loaded=!0;for(const e of[...t.listeners])e();n(!0)}else o||r!==i||this.backOff(t,e),n(!1)};o.onload=()=>{("function"==typeof o.decode?o.decode():Promise.resolve()).then(()=>r(!0)).catch(()=>r(!1))},o.onerror=()=>r(!1);const l=setTimeout(()=>r(!1),Jc);o.src=s}),i.preload}prepareImage(t,e){const i=Is(e);if(!i.startsWith("/api/houseplan/content/"))return Promise.resolve(!0);const s=this.bind(t),n=()=>{const e=s.signed[i];if(e&&this.now()-e.atthis.now()&&!s.inFlight.has(i)&&!s.queued.has(i)?Promise.resolve(!1):null},o=n();return o?(a=o,new Promise(t=>{let e=!1;const i=i=>{e||(e=!0,clearTimeout(s),t(i))},s=setTimeout(()=>i(!1),Jc);a.then(i).catch(()=>i(!1))})):new Promise(t=>{let e=!1,i=null;const o=i=>{e||(e=!0,clearTimeout(r),s.settlers.delete(a),t(i))},a=()=>{e||i||(i=n(),i&&i.then(o).catch(()=>o(!1)))},r=setTimeout(()=>o(!1),Jc);s.settlers.add(a),a()});var a}backOff(t,e){const i=t.retry.get(e)?.delay||0,s=Math.min(6e4,i?2*i:2e3);t.retry.set(e,{notBefore:this.now()+s,delay:s})}trimShared(t){const e=Object.entries(t.signed);if(e.length<=512)return;const i=new Set(t.inFlight.keys());for(const e of t.references.values())for(const t of e)i.add(t);for(const[t,s]of e)(s.pending||s.preload)&&i.add(t);e.sort((t,e)=>e[1].at-t[1].at);const s=e.filter(([t])=>i.has(t));for(const t of e){if(s.length>=512)break;i.has(t[0])||s.push(t)}t.signed=Object.fromEntries(s)}resign(t,e){const i=this.bind(t);this.referenced=new Set(e),i.references.set(this.referenceOwner,new Set(this.referenced));const s=this.now(),n=new Set;for(const t of i.references.values())for(const e of t)n.add(e);const o={};for(const[t,e]of Object.entries(i.signed))n.has(t)&&s-e.at!!o[t]&&!o[t].pending))}markLoaded(t,e,i){const s=Is(e);if(!s.startsWith("/api/houseplan/content/"))return;const n=this.bind(t).signed[s];if(n&&(!i||n.url===i)&&!n.loaded){n.loaded=!0;for(const e of[...this.bind(t).listeners])e()}}isReady(t,e){const i=Is(e);if(!i.startsWith("/api/houseplan/content/"))return!0;const s=this.bind(t).signed[i];return!!s&&this.now()-s.at{if(null==t||""===t)return null;const e=Number(t);return Number.isFinite(e)?e:null},ch=t=>{const e=t,i=lh(Array.isArray(e)?e[0]:e?.x),s=lh(Array.isArray(e)?e[1]:e?.y);return null==i||null==s?null:[i,s]};function hh(t){if(!Array.isArray(t))return null;const e=[];for(const i of t){const t=ch(i);if(!t)return null;e.push(t)}if(e.length>1){const t=e[0],i=e[e.length-1];t[0]===i[0]&&t[1]===i[1]&&e.pop()}if(e.length<3)return null;let i=0,s=0,n=0;for(let t=0;tt+e[0],0)/e.length,e.reduce((t,e)=>t+e[1],0)/e.length]:[s/(3*i),n/(3*i)]}function dh(t){if(!Array.isArray(t))return null;const e=[];for(const i of t){const t=ch(i);if(!t)return null;e.push(t)}if(e.length>1){const t=e[0],i=e[e.length-1];t[0]===i[0]&&t[1]===i[1]&&e.pop()}const i=hh(e);if(!i)return null;const s=e.map(t=>t[0]),n=e.map(t=>t[1]);return{centroid:i,bbox:[Math.min(...s),Math.min(...n),Math.max(...s),Math.max(...n)]}}function uh(t){let e=t;if(e&&"object"==typeof e&&!Array.isArray(e)){const t=e;e=t.path??t.points??e}if(!Array.isArray(e)||!e.length)return[];let i=(e.some(t=>(t=>Array.isArray(t)?t.length>=2&&!Array.isArray(t[0])&&("object"!=typeof t[0]||null==t[0]):!!t&&"object"==typeof t&&("x"in t||"y"in t))(t))?[e]:e.filter(Array.isArray)).map(t=>t.map(ch).filter(t=>null!=t)).filter(t=>t.length>=2);i.length>64&&(i=i.slice(-64));if(i.reduce((t,e)=>t+e.length,0)<=4e3)return i.map(t=>t.slice());const s=4e3-2*i.length,n=i.map(t=>t.length-2),o=n.reduce((t,e)=>t+e,0),a=n.map(t=>s*t/o),r=a.map(Math.floor);let l=s-r.reduce((t,e)=>t+e,0);const c=a.map((t,e)=>({index:e,fraction:t-Math.floor(t)})).sort((t,e)=>e.fraction-t.fraction||t.index-e.index);for(let t=0;tfunction(t,e){if(e>=t.length)return t.slice();if(e<=2)return[t[0],t[t.length-1]];const i=[];for(let s=0;st.slice()),i=e[e.length-1];return i?(i.length>2?i.pop():e.pop(),e):[]}function gh(t){if(!t)return null;const e=t.vacuum_position||t.robot_position||null,i=e&&null!=lh(e.x)&&null!=lh(e.y)?{x:lh(e.x),y:lh(e.y),a:lh(e.a??e.angle??e.theta)}:null,s=uh(t.path?.path??t.path?.points??t.path),n=[],o=t.rooms,a=Array.isArray(o)?o.map((t,e)=>[String(t?.id??e),t]):o&&"object"==typeof o?Object.entries(o):[];for(const[t,e]of a){if(!e||"object"!=typeof e)continue;const i=String(e.name??e.label??"").trim(),s=[[lh(e.cx),lh(e.cy)],[lh(e.center?.x),lh(e.center?.y)],[lh(e.x),lh(e.y)]].find(([t,e])=>null!=t&&null!=e);let o=s?.[0]??null,a=s?.[1]??null;const r=dh(e.outline),l=lh(e.x0),c=lh(e.y0),h=lh(e.x1),d=lh(e.y1),u=(null!=l&&null!=c&&null!=h&&null!=d?[Math.min(l,h),Math.min(c,d),Math.max(l,h),Math.max(c,d)]:null)||r?.bbox||null;if(null!=o&&null!=a||!r||([o,a]=r.centroid),null!=o&&null!=a||!u||(o=(u[0]+u[2])/2,a=(u[1]+u[3])/2),i&&null!=o&&null!=a){const e={id:t,name:i,cx:o,cy:a};u&&([e.x0,e.y0,e.x1,e.y1]=u),n.push(e)}}const r=function(t){return String(t.map_name??t.current_map??t.map_index??t.selected_map??"default")}(t);return i||n.length||s.length?{pos:i,path:s,rooms:n,mapId:r}:null}function mh(t,e,i){if(!t||!e)return null;const s=e.attributes||{},n=t.split(".")[0]||"",o=null!=i?.platform?String(i.platform):null,a=!!ch(s.vacuum_position??s.robot_position),r=!(!s.rooms||"object"!=typeof s.rooms),l=uh(s.path?.path??s.path?.points??s.path).length>0,c=[s.map_name,s.current_map,s.map_index,s.selected_map].some(t=>null!=t),h="xiaomi_cloud_map_extractor"===o,d=r||l||c;let u=null;if(a?u="compatible":h?u="known_xcme_incomplete":d?u="partial":"camera"===n&&(u="camera"),!u)return null;const p=a?"camera"===n?300:200:h?100:d?50:0;return{entityId:t,name:String(s.friendly_name||t),platform:o,category:u,hasPosition:a,hasRooms:r,hasPath:l,hasMapId:c,score:p}}const fh=t=>t.toLowerCase().replace(/[\s_\-.,]+/g,"");function vh(t,e){const i=new Map(e.map(t=>[fh(t.name),t])),s=[],n=[];for(const e of t){const t=i.get(fh(e.name));t&&(s.push([[e.cx,e.cy],[t.cx,t.cy]]),n.push(e.name))}if(s.length<3)return null;const o=function(t){if(t.length<3)return null;let e=0,i=0,s=0,n=0,o=0,a=0,r=0,l=0,c=0,h=0,d=0,u=0;for(const[[p,_],[g,m]]of t){if(![p,_,g,m].every(Number.isFinite))return null;e+=p*p,i+=p*_,s+=p,n+=_*_,o+=_,a+=1,r+=p*g,l+=_*g,c+=g,h+=p*m,d+=_*m,u+=m}const p=[e,i,s,i,n,o,s,o,a],_=t=>{const[e,i,s,n,o,a,r,l,c]=p,h=e*(o*c-a*l)-i*(n*c-a*r)+s*(n*l-o*r);if(!Number.isFinite(h)||Math.abs(h)<1e-9)return null;const d=[(o*c-a*l)/h,(s*l-i*c)/h,(i*a-s*o)/h,(a*r-n*c)/h,(e*c-s*r)/h,(s*n-e*a)/h,(n*l-o*r)/h,(i*r-e*l)/h,(e*o-i*n)/h];return[d[0]*t[0]+d[1]*t[1]+d[2]*t[2],d[3]*t[0]+d[4]*t[1]+d[5]*t[2],d[6]*t[0]+d[7]*t[1]+d[8]*t[2]]},g=_([r,l,c]),m=_([h,d,u]);if(!g||!m)return null;const f=[g[0],g[1],g[2],m[0],m[1],m[2]];return f.every(Number.isFinite)?f:null}(s);return o?{matrix:o,matched:n,residual:rh(o,s)}:null}function yh(t,e,i){const s=t[t.length-1];if(s&&s[0]===e[0]&&s[1]===e[1])return t;if(t.push(e),t.length<=600)return t;let n=function(t,e){if(t.length<3)return t.slice();const i=new Uint8Array(t.length);i[0]=i[t.length-1]=1;const s=[[0,t.length-1]];for(;s.length;){const[n,o]=s.pop(),[a,r]=t[n],[l,c]=t[o],h=l-a,d=c-r,u=Math.hypot(h,d)||1e-9;let p=0,_=-1;for(let e=n+1;ep&&(p=i,_=e)}_>0&&p>e&&(i[_]=1,s.push([n,_],[_,o]))}const n=[];for(let e=0;e600&&(n=n.filter((t,e)=>e%2==0||e===n.length-1)),n}function bh(t){return"cleaning"===t||"returning"===t||"on"===t}const wh={0:[1,0],90:[0,1],180:[-1,0],270:[0,-1]};function kh(t){const[e,i]=wh[t.rot]||[1,0],s=t.mir?-1:1;return[t.s*e*s,-t.s*i,t.ox,t.s*i*s,t.s*e,t.oy]}function xh(t){const e=t[0]*t[4]-t[1]*t[3];if(!Number.isFinite(e)||Math.abs(e)<1e-12)return null;const i=e<0,s=Math.sqrt(Math.abs(e));let n=180*Math.atan2(-t[1],t[4])/Math.PI;return n=(90*Math.round(n/90)%360+360)%360,{ox:t[2],oy:t[5],s:s,rot:n,mir:i}}function $h(t,e,i,s){const[n,o]=ah(kh(e),i,s),a=kh({...t,ox:0,oy:0}),[r,l]=ah(a,i,s);return{...t,ox:n-r,oy:o-l}}function Sh(t){const e=t?.trail_mode;return"never"===e||"cleaning"===e||"always"===e?e:!1===t?.trail?"never":"cleaning"}const Mh={offStates:["off"],unknownUsesToggle:!0},Ch={light:Mh,switch:Mh,fan:Mh,humidifier:Mh,input_boolean:Mh,automation:Mh,remote:Mh,group:Mh,climate:{...Mh,featureMasks:{turn_on:256,turn_off:128,toggle:384}},media_player:{...Mh,featureMasks:{turn_on:128,turn_off:256,toggle:384}},siren:{...Mh,featureMasks:{turn_on:1,turn_off:2,toggle:3}},vacuum:{...Mh,featureMasks:{turn_on:1,turn_off:2,toggle:3}},water_heater:{...Mh,featureMasks:{turn_on:8,turn_off:8,toggle:8}},camera:{...Mh,featureMasks:{turn_on:1,turn_off:1,toggle:1}}};function Dh(t){return t.slice(0,t.indexOf("."))}function Th(t,e,i){if(!t?.services||"object"!=typeof t.services)return!1;const s=t.services?.[e];return!!s&&Object.prototype.hasOwnProperty.call(s,i)}function Ph(t,e,i){return Th(t,e,i)?{domain:e,service:i}:Th(t,"homeassistant",i)?{domain:"homeassistant",service:i}:null}function Rh(t,e){return t?.entities?.[e]||null}function Ah(t,e,i){const s=t?.states?.[i],n=Rh(e,i);return s?.attributes?.friendly_name||n?.name||n?.original_name||i}function Ih(t,e){const i=Rh(t,e);if(null!=i?.disabled_by)return!0;const s=i?.device_id?t?.devices?.[i.device_id]:null;return null!=s?.disabled_by}function Eh(t,e){const i=t?.attributes?.supported_features;if(null==i||""===i)return!1;const s=Number(i);return Number.isFinite(s)&&(s&e)===e}function Fh(t,e,i){const s=Dh(i);if("lock"===s||"alarm_control_panel"===s)return!0;if("cover"!==s)return!1;const n=t?.states?.[i],o=Rh(e,i),a=String(n?.attributes?.device_class||o?.device_class||o?.original_device_class||"");return Ui.has(a)}function zh(t,e,i,s,n){return{ref:i,entityId:s,name:s?Ah(t,e,s):null,reason:n}}function Oh(t,e,i,s,n,o=null){return{target:null,skipped:zh(t,e,i,s,n),semantics:o,nextEffect:null,command:null}}function Hh(t,e,i,s,n=i){const o=Dh(i);if("cover"!==o&&"valve"!==o)return function(t,e,i,s,n=i){const o=Dh(i),a=t?.states?.[i];if(Ih(e,i))return Oh(t,e,n,i,"ha-disabled","power");if(Fh(t,e,i))return Oh(t,e,n,i,"secure");if(!a)return Oh(t,e,n,i,"missing","power");if("unavailable"===a.state)return Oh(t,e,n,i,"unavailable","power");const r=Ch[o];if(!r)return Oh(t,e,n,i,"unsupported");let l,c;if("unknown"===a.state||""===a.state){if(!r.unknownUsesToggle)return Oh(t,e,n,i,"unsupported","power");l="toggle",c="toggle"}else r.offStates.includes(String(a.state))?(l="turn-on",c="turn_on"):(l="turn-off",c="turn_off");const h=r.featureMasks?.[c];if(h&&!Eh(a,h))return Oh(t,e,n,i,"unsupported","power");const d=Ph(t,o,c);return d?{target:{entityId:i,name:Ah(t,e,i),state:String(a.state||""),via:s},skipped:null,semantics:"power",nextEffect:l,command:{...d,data:{entity_id:i}}}:Oh(t,e,n,i,"unsupported","power")}(t,e,i,s,n);if(Ih(e,i))return Oh(t,e,n,i,"ha-disabled",o);if(Fh(t,e,i))return Oh(t,e,n,i,"secure",o);const a=t?.states?.[i];if(!a)return Oh(t,e,n,i,"missing",o);if("unavailable"===a.state)return Oh(t,e,n,i,"unavailable",o);const r=function(t,e,i){const s=String(i?.state||""),n="closed"===s?{service:`open_${e}`,effect:"open",feature:1}:"open"===s?{service:`close_${e}`,effect:"close",feature:2}:"opening"===s||"closing"===s?{service:`stop_${e}`,effect:"stop",feature:8}:null;return n&&Eh(i,n.feature)&&Th(t,e,n.service)?n:Eh(i,3)&&Th(t,e,"toggle")?{service:"toggle",effect:"toggle"}:null}(t,o,a);if(!r)return Oh(t,e,n,i,"unsupported",o);return{target:{entityId:i,name:Ah(t,e,i),state:String(a.state||""),via:s},skipped:null,semantics:o,nextEffect:r.effect,command:{domain:o,service:r.service,data:{entity_id:i}}}}function Nh(t){return"entity"===t.bindingKind?t.bindingRef&&Ms(t.bindingRef)?[t.bindingRef]:[]:"virtual"===t.bindingKind?[]:Zn(t)}function Lh(t){const e=t.marker?.toggle_entity;return e&&Nh(t).includes(e)?e:null}function Bh(t,e,i){const s=function(t,e){if("entity"===t.bindingKind&&t.bindingRef){const e=t.marker?.light_entity?Qn(t):null;return[...new Set([e,t.bindingRef].filter(t=>!!t))]}const i=t.entities.length?t.entities:t.allEntities||[],s=t.marker?.light_entity||t.primary&&Ms(t.primary)?Qn(t):null;return[...new Set([s,...Vn(e,i)].filter(t=>!!t))]}(i,e);if(!s.length)return null;const n="entity"===i.bindingKind?"binding":"device-role";if("binding"===n)return Hh(t,e,s[0],n);let o=null,a=null;for(const i of s){const s=Hh(t,e,i,n);if(s.command)return s;const r=s.skipped?.reason;if("missing"===r||"unavailable"===r||"secure"===r)return s;"ha-disabled"!==r?o||=s:a||=s}return o||a}function qh(t){const e=t.skipped?.reason;return"missing"===e?"unavailable":e||"unsupported"}function jh(t,e){return{origin:t,kind:"none",semantics:null,targets:[],skippedTargets:[],noneReason:e,nextEffect:null,command:null}}function Wh(t,e){return"cover"===t||"toggle"===t?"toggle":"more-info"===t||"run"===t||"info"===t?t:(null==t||""===t)&&"light"===e?"toggle":"info"}function Uh(t,e){return{origin:t,kind:"single",semantics:e.semantics,targets:e.target?[e.target]:[],skippedTargets:e.skipped?[e.skipped]:[],noneReason:e.command?null:qh(e),nextEffect:e.nextEffect,command:e.command}}function Gh(t,e,i,s=[]){const n=new Map,o=[],a=new Set,r=t=>{const e=`${t.ref}\n${t.entityId||""}\n${t.reason}`;a.has(e)||(a.add(e),o.push(t))};for(const t of s)r(t);for(const s of i){const i=Hh(t,e,s.entityId,s.via,s.ref);i.target?n.set(s.entityId,n.get(s.entityId)||i.target):i.skipped&&r(i.skipped)}const l=[...n.values()];if(!l.length)return{origin:"explicit-toggle",kind:"group",semantics:"group-power",targets:l,skippedTargets:o,noneReason:o.length&&o.every(t=>"secure"===t.reason)?"secure":"configured-targets-missing",nextEffect:null,command:null};const c=l.some(t=>"on"===t.state)?"turn_off":"turn_on",h=Ph(t,"homeassistant",c);return h?{origin:"explicit-toggle",kind:"group",semantics:"group-power",targets:l,skippedTargets:o,noneReason:null,nextEffect:"turn_on"===c?"turn-on":"turn-off",command:{...h,data:{entity_id:l.map(t=>t.entityId)}}}:{origin:"explicit-toggle",kind:"group",semantics:"group-power",targets:[],skippedTargets:[...o,...l.map(i=>zh(t,e,i.entityId,i.entityId,"unsupported"))],noneReason:"unsupported",nextEffect:null,command:null}}function Vh(t){return String(t.marker?.id||t.id||"")}function Kh(t){const{hass:e,device:i}=t,s=t.registryHass||e,n=function(t){return"toggle"===t.tapAction?"explicit-toggle":"cover"===t.tapAction?"legacy-cover":!t.tapAction&&t.primary?.startsWith("light.")?"default-light":null}(i);if(!n)return null;const o=i.marker;if("explicit-toggle"===n&&yn(o)){const e=String(o?.id||i.id||""),s=oo(t.devices).get(e);if(s)return function(t,e){const i=t.registryHass||t.hass;return Gh(t.hass,i,e.driverEids.map(t=>({entityId:t,via:"control-marker-driver",ref:`marker:${e.markerId}`})))}(t,s);const a=bn(o,t.virtualLights);return{origin:n,kind:"single",semantics:"power",targets:[{entityId:"",name:i.name,state:a?"on":"off",via:"virtual-light"}],skippedTargets:[],noneReason:null,nextEffect:a?"turn-off":"turn-on",command:null,operation:{kind:"virtual-light",markerId:o.id}}}if("explicit-toggle"===n){if(Xn(i.marker?.binding,i.marker?.controls??i.controls,i.entities).length)return function(t,e=null){const{hass:i,device:s,devices:n}=t,o=t.registryHass||i,a=Xn(s.marker?.binding,s.marker?.controls??s.controls,s.entities),r=t.lightSources||lo(i,n,null,t.virtualLights),l=new Map;for(const t of r){if(!t.key.startsWith("marker:"))continue;const e=l.get(t.key)||[];e.push(t),l.set(t.key,e)}const c=oo(n),h=new Map;for(const t of n){const e=String(t.marker?.id||t.id||"");e&&h.set(e,t)}const d=[],u=[];e&&d.push({entityId:e,via:"entity"===s.bindingKind?"binding":"device-role",ref:e});for(const t of a){if(!t.startsWith("marker:")){Ms(t)?d.push({entityId:t,via:"control-entity",ref:t}):u.push(zh(i,o,t,t.includes(".")?t:null,"unsupported"));continue}const e=l.get(t)||[];if(!e.length){const e=h.get(t.slice(7));if("ha_disabled"===e?.bindingStatus?.kind){const s=e.bindingStatus.allEntityIds[0]||null;u.push({ref:t,entityId:s,name:e.name||(s?Ah(i,o,s):null),reason:"ha-disabled"})}else u.push(zh(i,o,t,null,"missing"));continue}const n=[...new Set(e.flatMap(t=>t.serviceEids))];if(n.length){for(const e of n)d.push({entityId:e,via:"control-entity",ref:t});continue}const a=e.some(t=>t.passive),r=t.slice(7),p=Vh(s),_=c.get(r)?.controllers.find(t=>Vh(t.device)===p);if(a&&_?.driverEids.length)for(const e of _.driverEids)d.push({entityId:e,via:"control-marker-driver",ref:t});else u.push(zh(i,o,t,null,a?"missing":"unsupported"))}return Gh(i,o,d,u)}(t,Lh(i))}if("legacy-cover"===n){const t=i.entities.find(t=>t.startsWith("cover."))||i.allEntities?.find(t=>t.startsWith("cover."));return t?Uh(n,Hh(e,s,t,"device-role")):jh(n,"no-actionable-entity")}const a=Lh(i),r=a?Hh(e,s,a,"entity"===i.bindingKind?"binding":"device-role"):Bh(e,s,i);return r?Uh(n,r):jh(n,i.virtual||"virtual"===i.bindingKind?"no-actionable-entity":"no-binding")}function Yh(t){if(!t)return[];const e=Array.isArray(t.data.entity_id)?t.data.entity_id:[t.data.entity_id];return[...new Set(e)].sort()}function Xh(t){return t?t.operation?t.operation:t.command?{kind:"ha-service",command:t.command}:null:null}function Jh(t,e){const i=Xh(t),s=Xh(e);return!(!i||!s||i.kind!==s.kind)&&("virtual-light"===i.kind&&"virtual-light"===s.kind?i.markerId===s.markerId:"ha-service"===i.kind&&"ha-service"===s.kind&&function(t,e){const i=Yh(t),s=Yh(e);return i.length===s.length&&i.every((t,e)=>t===s[e])}(i.command,s.command))}const Zh=t=>!!t&&t.length>=2&&Number.isFinite(t[0])&&Number.isFinite(t[1]);function Qh(t,e=5,i=5){return fr(t.cm,e,i)/2}function td(t,e,i=1,s=5,n=5,o=0){const a=t.host;if(!a||"partition"!==a.kind||"string"!=typeof a.id||!a.id)return{resolved:null,reason:"invalid-host"};const r=e.find(t=>t.id===a.id);if(!r)return{resolved:null,reason:"missing-partition"};if(!Zh(r.a)||!Zh(r.b)||!Number.isFinite(a.t)||a.t<0||a.t>1)return{resolved:null,reason:"invalid-position"};const l=r.b[0]-r.a[0],c=r.b[1]-r.a[1],h=Math.hypot(l,c),d=Number(t.length)*i;if(!(h>1e-9&&d>0&&Number.isFinite(d)))return{resolved:null,reason:"invalid-length"};const u=a.t*h;if(u-d/2h-o+1e-9)return{resolved:null,reason:"does-not-fit"};const p=l/h,_=c/h;let g=180*Math.atan2(c,l)/Math.PI;return g>=90?g-=180:g<-90&&(g+=180),{reason:null,resolved:{opening:t,host:a,partition:r,center:[r.a[0]+l*a.t,r.a[1]+c*a.t],angle:g,length:d,depth:fr(r.cm,s,n),t:a.t,axis:{a:[r.a[0],r.a[1]],b:[r.b[0],r.b[1]],ux:p,uy:_,length:h}}}}function ed(t,e,i=1,s=5,n=5){return td(t,e,i,s,n,0)}function id(t,e,i=1,s=5,n=5){const o=t.host,a="partition"===o?.kind?e.find(t=>t.id===o.id):void 0;if(!a)return ed(t,e,i,s,n);const r=td(t,e,i,s,n,Qh(a,s,n));return"does-not-fit"===r.reason?{resolved:null,reason:"does-not-fit-jamb"}:r}function sd(t,e){return!t||(t.length!==e.length||t.host?.kind!==e.host?.kind||t.host?.id!==e.host?.id||t.host?.t!==e.host?.t)}function nd(t){const{center:e,length:i,axis:s,host:n}=t,o=i/2;return{hostId:n.id,a:[e[0]-s.ux*o,e[1]-s.uy*o],b:[e[0]+s.ux*o,e[1]+s.uy*o],depth:t.depth}}function od(t,e=!1){const i=e?1:-1,s=t.depth/2;return{ox:-t.axis.uy*i*s,oy:t.axis.ux*i*s,cm:t.partition.cm,side:i}}function ad(t,e,i){const{center:s,length:n,axis:o}=t,a=n/2,r=e.flatMap(t=>{if(!t.kind||t.open)return[];const e=t.b[0]-t.a[0],n=t.b[1]-t.a[1],r=Math.hypot(e,n);if(!(r>i))return[];const l=e/r,c=n/r;if(Math.abs(o.ux*c-o.uy*l)>1e-6)return[];if(Math.abs((s[0]-t.a[0])*c-(s[1]-t.a[1])*l)>i)return[];const h=t=>(t[0]-s[0])*o.ux+(t[1]-s[1])*o.uy,d=h(t.a),u=h(t.b),p=Math.max(-a,Math.min(d,u)),_=Math.min(a,Math.max(d,u));return _>=p-i?[[p,_]]:[]});if(!r.length)return!1;r.sort((t,e)=>t[0]-e[0]||t[1]-e[1]);let l=-a;for(const[t,e]of r){if(t>l+i)return!1;if(l=Math.max(l,e),l>=a-i)return!0}return!1}function rd(t,e,i){return{...t,x:e.center[0]/i,y:e.center[1]/i,angle:e.angle}}function ld(t){return!!t&&t.length>=2&&Number.isFinite(t[0])&&Number.isFinite(t[1])}function cd(t){return`${t[0].toFixed(6)},${t[1].toFixed(6)}`}function hd(t,e,i){return Math.abs(t[0]-e[0])_d(s,t,e)))continue;const t=cd(s);a.has(t)||a.set(t,{point:[s[0],s[1]],key:t})}}}return{segments:[...o.values()].sort((t,e)=>t.key.localeCompare(e.key)),endpoints:[...a.values()].sort((t,e)=>t.key.localeCompare(e.key))}}function md(t,e,i){return e.some(e=>ld(e)&&hd(t,e,i))}function fd(t,e,i){if(!i)return!0;const s=t-i.distance;return s<-1e-9||Math.abs(s)<=1e-9&&e.localeCompare(i.key)<0}function vd(t,e,i){const s=t.b[0]-t.a[0],n=t.b[1]-t.a[1],o=Math.hypot(s,n);if(!(o>0))return[...t.a];const a=s/o,r=n/o,l=Math.max(0,Math.min(o,(e[0]-t.a[0])*a+(e[1]-t.a[1])*r)),c=i>0?Math.max(0,Math.min(o,Math.round(l/i)*i)):l;return[t.a[0]+a*c,t.a[1]+r*c]}const yd=.001;function bd(t,e,i){const s=[];for(let n=0;n+1=0?e[n]:i;s.push({a:[o[0],o[1]],b:[a[0],a[1]],cm:r})}return s}function wd(t){return!!t&&t.length>=2&&Number.isFinite(t[0])&&Number.isFinite(t[1])}function kd(t,e,i,s){return t*s-e*i}function xd(t){let e=0;for(let i=0;it.localeCompare(e)),e[0]}function Dd(t,e,i){const s=[...t];for(let t=!0;t&&s.length>=3;){t=!1;for(let n=0;n=0){s.splice(n,1),t=!0;break}}}return s}function Td(t,e){const i=t.map(t=>Math.max(0,Math.min(1,t))).sort((t,e)=>t-e),s=[];for(const t of i)(!s.length||Math.abs(t-s[s.length-1])>e)&&s.push(t);return s}function Pd(t,e){return[t.a[0]+(t.b[0]-t.a[0])*e,t.a[1]+(t.b[1]-t.a[1])*e]}function Rd(t,e,i){const s=function(t,e){const i=e.b[0]-e.a[0],s=e.b[1]-e.a[1],n=i*i+s*s;return n>0?((t[0]-e.a[0])*i+(t[1]-e.a[1])*s)/n:0}(t,e);if(s<-i||s>1+i)return null;const n=Pd(e,s);return Math.hypot(n[0]-t[0],n[1]-t[1])<=i?Math.max(0,Math.min(1,s)):null}function Ad(t,e,i,s,n){const o=t.b[0]-t.a[0],a=t.b[1]-t.a[1],r=e.b[0]-e.a[0],l=e.b[1]-e.a[1],c=e.a[0]-t.a[0],h=e.a[1]-t.a[1],d=kd(o,a,r,l),u=Math.max(Math.hypot(o,a),Math.hypot(r,l),1);if(Math.abs(d)>n*u){const t=kd(c,h,r,l)/d,e=kd(c,h,o,a)/d;return void(t>=-n&&t<=1+n&&e>=-n&&e<=1+n&&(i.push(Math.max(0,Math.min(1,t))),s.push(Math.max(0,Math.min(1,e)))))}if(!(Math.abs(kd(c,h,o,a))>n*u)){for(const s of[e.a,e.b]){const e=Rd(s,t,n);null!=e&&i.push(e)}for(const i of[t.a,t.b]){const t=Rd(i,e,n);null!=t&&s.push(t)}}}function Id(t){let e=t+1|0;return e^=e<<13,e^=e>>>17,e^=e<<5,e>>>0}function Ed(t,e){return t.minY-e.minY||t.index-e.index}function Fd(t){return t.subtreeMaxY=Math.max(t.item.maxY,t.left?.subtreeMaxY??-1/0,t.right?.subtreeMaxY??-1/0),t}function zd(t){const e=t.right;return t.right=e.left,e.left=Fd(t),Fd(e)}function Od(t){const e=t.left;return t.left=e.right,e.right=Fd(t),Fd(e)}function Hd(t,e){return t?(Ed(e,t.item)<0?(t.left=Hd(t.left,e),t.left.priority0)t.right=Nd(t.right,e);else{if(!t.left)return t.right;if(!t.right)return t.left;t.left.priority=e&&Ld(t.left,e,i,s),t.item.minY<=i&&t.item.maxY>=e&&s.push(t.item),t.item.minY<=i&&Ld(t.right,e,i,s))}function Bd(t,e=.001){const i=Number.isFinite(e)&&e>0?e:yd,s=t.filter(t=>wd(t.a)&&wd(t.b)&&"string"==typeof t.key&&t.key.length>0&&Math.hypot(t.b[0]-t.a[0],t.b[1]-t.a[1])>i),n=s.map(()=>[0,1]);!function(t,e,i){const s=t.map((t,e)=>({index:e,minX:Math.min(t.a[0],t.b[0])-i,maxX:Math.max(t.a[0],t.b[0])+i,minY:Math.min(t.a[1],t.b[1])-i,maxY:Math.max(t.a[1],t.b[1])+i})),n=[...s].sort((t,e)=>t.minX-e.minX||t.minY-e.minY||t.index-e.index),o=[...s].sort((t,e)=>t.maxX-e.maxX||t.index-e.index),a=new Set;let r=null,l=0;for(const s of n){for(;lt.index-e.index);for(const o of n)Ad(t[o.index],t[s.index],e[o.index],e[s.index],i);a.add(s.index),r=Hd(r,s)}}(s,n,i);const o=new Map;for(let t=0;t({key:t,a:e.a,b:e.b,sourceKeys:[...e.sourceKeys].sort((t,e)=>t.localeCompare(e))})).sort((t,e)=>t.key.localeCompare(e.key))}const qd=1e-5;function jd(t){const e=t.map(()=>[]);for(let i=0;i=1-1e-9||u<=1e-9||u>=1-1e-9||(e[i].push(d),e[a].push(u))}}const i=[];for(let s=0;st-e),1];for(let t=1;t{const i=e[2]-e[0],s=e[3]-e[1],n=i*i+s*s;if(!(n>0))return Math.hypot(t[0]-e[0],t[1]-e[1]);const o=Math.max(0,Math.min(1,((t[0]-e[0])*i+(t[1]-e[1])*s)/n));return Math.hypot(t[0]-(e[0]+o*i),t[1]-(e[1]+o*s))},Gd=(t,e,i,s)=>{const n=s[2]-s[0],o=s[3]-s[1],a=e*o-i*n;if(Math.abs(a)<1e-12)return 1/0;const r=s[0]-t[0],l=s[1]-t[1],c=(r*o-l*n)/a;if(!(c>1e-9))return 1/0;const h=(r*i-l*e)/a;return h<-1e-9||h>1+1e-9?1/0:c};function Vd(t,e,i,s=96){if(!(e>0&&Number.isFinite(t[0])&&Number.isFinite(t[1])))return[];const n=[];for(const s of i){if(!s||s.length<4)continue;if(![s[0],s[1],s[2],s[3]].every(Number.isFinite))continue;const i=Ud(t,s);if(i<1e-7)return[];i>e||n.push(s)}const o=[],a=Math.max(12,Math.round(s));for(let t=0;tt-e);const l=[];let c=Number.NEGATIVE_INFINITY;for(const i of o){if(i-c<1e-9)continue;c=i;const s=Math.cos(i),o=Math.sin(i);let a=e;for(const e of n){const i=Gd(t,s,o,e);i=3?l:[]}class Kd extends ht{constructor(){super(...arguments),this._spaces=null,this._spacesLoading=!1}setConfig(t){this._config=t}async _loadSpaces(){if(!this._spaces&&!this._spacesLoading&&this.hass){this._spacesLoading=!0;try{const t=await this.hass.callWS({type:"houseplan/config/get"});this._spaces=(t?.config?.spaces||[]).map(t=>({value:t.id,label:t.title||t.id}))}catch{this._spaces=[]}finally{this._spacesLoading=!1}}}get _lang(){return sa(this.hass,this._config?.language)}get _schema(){const t=this._spaces||[],e=this._lang;return[{name:"title",selector:{text:{}}},t.length?{name:"default_floor",selector:{select:{mode:"dropdown",options:t}}}:{name:"default_floor",selector:{text:{}}},{name:"language",selector:{select:{mode:"dropdown",options:[{value:"",label:na(e,"editor.lang_auto")},{value:"en",label:na(e,"editor.lang_en")},{value:"ru",label:na(e,"editor.lang_ru")}]}}},{name:"icon_size",selector:{number:{min:1,max:6,step:.1,mode:"box"}}},{name:"show_temperature",selector:{boolean:{}}},{name:"live_states",selector:{boolean:{}}},{name:"show_signal",selector:{boolean:{}}},{name:"kiosk",selector:{boolean:{}}},{name:"cycle",selector:{number:{min:0,max:3600,step:5,mode:"box"}}}]}render(){if(!this.hass||!this._config)return G;this._loadSpaces();const t=this._lang,e={title:na(t,"editor.title"),default_floor:na(t,"editor.default_floor"),language:na(t,"editor.language"),icon_size:na(t,"editor.icon_size"),show_temperature:na(t,"editor.show_temperature"),live_states:na(t,"editor.live_states"),show_signal:na(t,"editor.show_signal"),kiosk:na(t,"editor.kiosk"),cycle:na(t,"editor.cycle")};return j`{const e=vc(t);return W`${t.name}`}),T=lo(a,c,null,t.virtualLights),P=c.map(s=>{const n=function(t,e,i,s,n){const o=e[t.id];return o&&o.s===t.space?{x:o.x*Bl,y:o.y*Bl}:s[t.id]?s[t.id]:tc(pc(n))}(s,t.layout,t.cfg,h,e),o=(n.x-y[0])/y[2]*100,l=(n.y-y[1])/y[3]*100,d=i.showLqi??!1!==t.showSignal,u=t.presentations?.get(hu(s.id,d))||au(a,s,{liveStates:!1!==t.liveStates,showTemperature:!1!==t.showTemperature,showSignal:d,activityRuntime:t.activityRuntime?.get(s.id),sourceDetails:!1,lightDevices:c,lightSources:T,registryHass:r,reducedMotion:t.reducedMotion}),p=[`left:${o}%`,`top:${l}%`,...jo(u)],_=[s.name,"none"!==u.pulse.kind?na(t.lang,`marker.pulse_a11y_${u.pulse.reason}`):"",To(u.valueBadge)].filter(Boolean).join(", ");return j`
`),C=new Map;for(const t of e.rooms)if(t.id){const e=b.get(t)||null;C.set(t.id,Fs(i.glow,t)&&(!e||e.opacity<=0)?{color:s.glow_base.c,opacity:s.glow_base.a,mode:"glow"}:null)}const D=lo(a,c,null,t.virtualLights),T=c.map(s=>{const n=function(t,e,i,s,n){const o=e[t.id];return o&&o.s===t.space?{x:o.x*Bl,y:o.y*Bl}:s[t.id]?s[t.id]:tc(pc(n))}(s,t.layout,t.cfg,h,e),o=(n.x-y[0])/y[2]*100,l=(n.y-y[1])/y[3]*100,d=i.showLqi??!1!==t.showSignal,u=t.presentations?.get(hu(s.id,d))||au(a,s,{liveStates:!1!==t.liveStates,showTemperature:!1!==t.showTemperature,showSignal:d,activityRuntime:t.activityRuntime?.get(s.id),sourceDetails:!1,lightDevices:c,lightSources:D,registryHass:r,reducedMotion:t.reducedMotion}),p=[`left:${o}%`,`top:${l}%`,...jo(u)],_=[s.name,"none"!==u.pulse.kind?na(t.lang,`marker.pulse_a11y_${u.pulse.reason}`):"",To(u.valueBadge)].filter(Boolean).join(", ");return j`
${Wo(u,{})} -
`}),R=i.showNames?e.rooms.filter(t=>t.name).map(s=>{const n=function(t,e,i){const s=i["rl_"+(t.id||"")];if(s&&s.s===e)return{x:s.x*Bl,y:s.y*Bl};const n=vc(t);return tc({x:n[0],y:n[1]})}(s,e.id,t.layout,t.cfg),o=(n.x-y[0])/y[2]*100,a=(n.y-y[1])/y[3]*100,r=Math.min(1,i.opacity+.25);return j`
`}),P=i.showNames?e.rooms.filter(t=>t.name).map(s=>{const n=vc(s,e.id,t.layout,t.cfg),o=(n.x-y[0])/y[2]*100,a=(n.y-y[1])/y[3]*100,r=Math.min(1,i.opacity+.25);return j`
${s.name}
`}):[],A=e.bg?t.displayUrl?t.displayUrl(e.bg.href):e.bg.href:"",I=t.cfg.spaces.find(e=>e.id===t.spaceId)?.settings||{},E="daynight"===Ya(t.cfg?.settings,I)?Ha(a,t.dayCycleNow??new Date):null,F=hs(t.cfg?.settings,i),z=!!(p.length||f.length&&i.showBorders),O=z?ih(k.length?{rooms:e.rooms,walls:p,extras:f,cellCm:_,passages:k.map(t=>({x:t.rx,y:t.ry,angle:t.angle,length:t.rlen})),hostedCompositeOpenings:$}:{rooms:e.rooms,walls:p,extras:f,cellCm:_}):"",H=z?function(t,e,i,s){let n=uu.get(t);n||(n=new Map,uu.set(t,n));const o=n.get(e);if(o?.fingerprint===i)return o.value;const a=s();return n.set(e,{fingerprint:i,value:a}),a}(t.cfg,e.id,O,()=>ul(e.rooms,p,[],[...k.filter(t=>!t.host).map(t=>({x:t.rx,y:t.ry,angle:t.angle,length:t.rlen})),...$],Zl,_,Jl,Bl,f)):null,N=k.length&&p.length?function(t,e,i,s,n,o,a,r=1){return[n,o,a,r].every(Number.isFinite)&&o>0&&r>0&&i?.length?kl(gl(t,i,s,n,o,a,r),e):e.map(()=>null)}(e.rooms,k.map(t=>({x:t.rx,y:t.ry,angle:t.angle,length:t.rlen})),p,[],Zl,_,Jl,Bl):k.map(()=>null),L=k.length?du({openings:k,geometries:N,fillsByRoomId:w,idPrefix:`${e.id}-static-data`,groupClass:"opening-tunnels static-opening-tunnels",dataLayer:"data"}):G,B=k.length?du({openings:k,geometries:N,fillsByRoomId:C,idPrefix:`${e.id}-static-glow`,groupClass:"opening-tunnels glow-base-tunnels static-opening-tunnels",dataLayer:"glow-base"}):G,q=p.length&&H?.paperD?[{path:H.paperD}]:di(e.rooms),U=i.showBorders?H:null,V=t.stageWidth&&y[2]?t.stageWidth/y[2]:1,K=!!U&&_r(U.depthUnits,V),Y=i.color||"#607d8b",X=i.hideOpenings?[]:g.map(t=>{const e=t.opening,i="passage"!==e.type&&e.contact?a.states?.[e.contact]?.state:null,s=gi(e.type,i,!!e.invert),n=s>0&&!!e.contact,o="gate"===e.type?!e.flip_v:!!e.flip_v,r={type:e.type,length:t.length,angle:t.angle,amount:s,flipH:!!e.flip_h,flipV:!!e.flip_v,base:Y,tone:n?"var(--hp-open)":Y,cellCm:_,gridPitch:Jl,face:od(t,o)};return W`${s.name}
`}):[],R=e.bg?t.displayUrl?t.displayUrl(e.bg.href):e.bg.href:"",A=t.cfg.spaces.find(e=>e.id===t.spaceId)?.settings||{},I="daynight"===Ya(t.cfg?.settings,A)?Ha(a,t.dayCycleNow??new Date):null,E=hs(t.cfg?.settings,i),F=!!(p.length||f.length&&i.showBorders),z=F?ih(k.length?{rooms:e.rooms,walls:p,extras:f,cellCm:_,passages:k.map(t=>({x:t.rx,y:t.ry,angle:t.angle,length:t.rlen})),hostedCompositeOpenings:$}:{rooms:e.rooms,walls:p,extras:f,cellCm:_}):"",O=F?function(t,e,i,s){let n=uu.get(t);n||(n=new Map,uu.set(t,n));const o=n.get(e);if(o?.fingerprint===i)return o.value;const a=s();return n.set(e,{fingerprint:i,value:a}),a}(t.cfg,e.id,z,()=>ul(e.rooms,p,[],[...k.filter(t=>!t.host).map(t=>({x:t.rx,y:t.ry,angle:t.angle,length:t.rlen})),...$],Zl,_,Jl,Bl,f)):null,H=k.length&&p.length?function(t,e,i,s,n,o,a,r=1){return[n,o,a,r].every(Number.isFinite)&&o>0&&r>0&&i?.length?kl(gl(t,i,s,n,o,a,r),e):e.map(()=>null)}(e.rooms,k.map(t=>({x:t.rx,y:t.ry,angle:t.angle,length:t.rlen})),p,[],Zl,_,Jl,Bl):k.map(()=>null),N=k.length?du({openings:k,geometries:H,fillsByRoomId:w,idPrefix:`${e.id}-static-data`,groupClass:"opening-tunnels static-opening-tunnels",dataLayer:"data"}):G,L=k.length?du({openings:k,geometries:H,fillsByRoomId:C,idPrefix:`${e.id}-static-glow`,groupClass:"opening-tunnels glow-base-tunnels static-opening-tunnels",dataLayer:"glow-base"}):G,B=p.length&&O?.paperD?[{path:O.paperD}]:di(e.rooms),q=i.showBorders?O:null,U=t.stageWidth&&y[2]?t.stageWidth/y[2]:1,V=!!q&&_r(q.depthUnits,U),K=i.color||"#607d8b",Y=i.hideOpenings?[]:g.map(t=>{const e=t.opening,i="passage"!==e.type&&e.contact?a.states?.[e.contact]?.state:null,s=gi(e.type,i,!!e.invert),n=s>0&&!!e.contact,o="gate"===e.type?!e.flip_v:!!e.flip_v,r={type:e.type,length:t.length,angle:t.angle,amount:s,flipH:!!e.flip_h,flipV:!!e.flip_v,base:K,tone:n?"var(--hp-open)":K,cellCm:_,gridPitch:Jl,face:od(t,o)};return W` ${Xd(r)} `});return j` -
- ${tr(E)} + style="aspect-ratio:${y[2]}/${y[3]}${E?";background:"+E:""};--wall-fill:${s.wall_fill.c};--wall-fill-op:${s.wall_fill.a}${I?`;${Qa(I)}`:""}"> + ${tr(I)} - ${U?W` + ${q?W` - + `:G} - ${q.map(t=>"path"in t?W``:"poly"in t?W``:W``)} - ${A?W`t.assetLoaded?.(e.bg.href,A)} + ${B.map(t=>"path"in t?W``:"poly"in t?W``:W``)} + ${R?W`t.assetLoaded?.(e.bg.href,R)} transform=${e.bg.angle?`rotate(${e.bg.angle} ${e.bg.x+e.bg.w/2} ${e.bg.y+e.bg.h/2})`:G} preserveAspectRatio="none" />`:G} ${S} - ${L} + ${N} ${M.length?W``:G} - ${B} - ${D} - ${U?W` - + - + `:G} - ${X} + ${Y} ${""} -
${P}${R}
+
${T}${P}
`}let mu=null,fu=null,vu=0,yu=-1,bu=null,wu=[];const ku=new Set,xu=(t,e)=>{"function"==typeof t&&e.push(t)};function $u(){if(mu)return mu;try{const t=JSON.parse(localStorage.getItem("houseplan_card_cfg_v1")||"null");if(t&&t.config&&Array.isArray(t.config.spaces)){const e=t.layout||{};return{config:t.config,rev:t.rev||0,configFingerprint:t.config_fingerprint||ih(t.config),layout:e,layoutRev:t.layout_rev||0,layoutFingerprint:t.layout_fingerprint||ih(e),virtualLights:gn(t.virtual_lights,t.rev||0)}}}catch{}return null}function Su(t,e=!1){if(e&&(mu=null,vu++,fu))return fu.catch(()=>null).then(()=>Su(t,!1));if(mu)return Promise.resolve(mu);if(fu)return yu!==vu?fu.catch(()=>null).then(()=>Su(t,!1)):fu;return yu=vu,fu=async function(t,e){const[i,s]=await Promise.all([t.callWS({type:"houseplan/config/get"}),t.callWS({type:"houseplan/layout/get"})]),n=i?.rev??0,o=mu?mn(mu.virtualLights,i?.virtual_lights,n,!!i&&"virtual_lights"in i):gn(i?.virtual_lights,n),a={config:i?.config??null,rev:n,configFingerprint:ih(i?.config??null),layout:s?.layout??{},layoutRev:s?.rev??0,layoutFingerprint:ih(s?.layout??{}),virtualLights:o};e===vu&&(mu=a);const r=t.connection;if(r?.subscribeEvents&&bu!==r){for(const t of wu)t();wu=[],bu=r;const t=()=>{mu=null,vu++,ku.forEach(t=>t())},e=[];try{if(xu(await r.subscribeEvents(t,"houseplan_config_updated"),e),xu(await r.subscribeEvents(t,"houseplan_layout_updated"),e),xu(await r.subscribeEvents(t=>{if(mu){const e=wn(mu.virtualLights,t?.data);if(e===mu.virtualLights)return;mu={...mu,virtualLights:e}}else vu++;ku.forEach(t=>t())},"houseplan_virtual_light_updated"),e),bu===r)wu=e;else for(const t of e)t()}catch{for(const t of e)t();bu===r&&(bu=null)}}return a}(t,vu).finally(()=>{fu=null,yu=-1}),fu}const Mu=3300;function Cu(t,e){return{sources:t,last:Object.fromEntries(e.map(t=>[t.eid,t.state])),flashTs:0,flashKind:null,timer:0,gen:0,expiresAt:0,alarmActive:"alarm"===dn(e).status}}function Du(t,e,i,s){s(t.timer);const n=Cu(e,i);Object.assign(t,n)}function Tu(t,e,i,s,n){t.flashTs&&i-t.flashTs"transition"===t.activity)&&(i(t.timer),t.flashTs=0,t.flashKind=null,t.expiresAt=0);if("alarm"===dn(e).status){t.alarmActive||(i(t.timer),t.flashTs=0,t.flashKind=null,t.expiresAt=0);for(const i of e)t.last[i.eid]=i.state;return t.alarmActive=!0,null}if(t.alarmActive){for(const i of e)t.last[i.eid]=i.state;return t.alarmActive=!1,null}let s=null;for(const i of e){const e=un(t.last[i.eid],i);("event"===e||!s&&e)&&(s=e),t.last[i.eid]=i.state}return s}class Ru extends ht{constructor(){super(...arguments),this._spaces=null,this._spacesLoading=!1}setConfig(t){this._config=t}async _loadSpaces(){if(!this._spaces&&!this._spacesLoading&&this.hass){this._spacesLoading=!0;try{const t=await this.hass.callWS({type:"houseplan/config/get"});this._spaces=(t?.config?.spaces||[]).map(t=>({value:t.id,label:t.title||t.id}))}catch{this._spaces=[]}finally{this._spacesLoading=!1}}}get _lang(){return sa(this.hass,this._config?.language)}get _schema(){const t=this._spaces||[];return[t.length?{name:"space",selector:{select:{mode:"dropdown",options:t}}}:{name:"space",selector:{text:{}}},{name:"title",selector:{text:{}}},{name:"show_button",selector:{boolean:{}}},{name:"button_label",selector:{text:{}}},{name:"button_target",selector:{text:{}}},{name:"icon_size",selector:{number:{min:1,max:6,step:.1,mode:"box"}}},{name:"show_temperature",selector:{boolean:{}}},{name:"live_states",selector:{boolean:{}}},{name:"show_signal",selector:{boolean:{}}}]}render(){if(!this.hass||!this._config)return G;this._loadSpaces();const t=this._lang,e={space:na(t,"editor.space"),title:na(t,"editor.title"),show_button:na(t,"editor.show_button"),button_label:na(t,"editor.button_label"),button_target:na(t,"editor.button_target"),icon_size:na(t,"editor.icon_size"),show_temperature:na(t,"editor.show_temperature"),live_states:na(t,"editor.live_states"),show_signal:na(t,"editor.show_signal")};return j``:W``});return W``}_renderSvgRoomLabels(t,e){return"iso"===this._renderProjection||t.bg||e.showNames||this._markup?W``:W`${t.rooms.map(t=>{const e=this._roomCenter(t);return W`${t.name}`})}`}_renderWallBodies(t){if("iso"===this._renderProjection)return W``;if(t&&!t.showBorders&&("view"===this._mode||"devices"===this._mode))return W``;const e=this._wallUnionGeometry();if(!e)return W``;const i=this._stageEl,s=this._viewOr(this._baseVb()),n=i&&i.clientWidth&&s.w?i.clientWidth/s.w:1,o=t?.color||"#607d8b",a=_r(e.depthUnits,n),r=this._fillColors.wall_fill;return W` + fill=${a.color} fill-opacity=${a.opacity} pointer-events="none">`});return W``}_renderWallBodies(t){if("iso"===this._renderProjection)return W``;if(t&&!t.showBorders&&("view"===this._mode||"devices"===this._mode))return W``;const e=this._wallUnionGeometry();if(!e)return W``;const i=this._stageEl,s=this._viewOr(this._baseVb()),n=i&&i.clientWidth&&s.w?i.clientWidth/s.w:1,o=t?.color||"#607d8b",a=_r(e.depthUnits,n),r=this._fillColors.wall_fill;return W` @@ -5560,7 +5547,6 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="51c4bdb005b2539779085578bcce5ee1b4b3 ${this._renderOpeningTunnelFills(i,u)} ${this._renderGlowBaseRooms(i,p)} ${this._renderOpeningTunnelFills(i,p,"glow-base")} - ${this._renderSvgRoomLabels(i,c)} ${A?this._renderGlowLayer(i,c):G} ${this._renderSunRays(i)} ${this._editing?W`${this._renderMeasureLabel(f)}
`:G} diff --git a/dist/houseplan-card.js b/dist/houseplan-card.js index f9ecb54e..aefea4d6 100755 --- a/dist/houseplan-card.js +++ b/dist/houseplan-card.js @@ -1,4 +1,4 @@ -globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="51c4bdb005b2539779085578bcce5ee1b4b3e3137542ef1aeb440232344c3105";const t=globalThis,e=t.ShadowRoot&&(void 0===t.ShadyCSS||t.ShadyCSS.nativeShadow)&&"adoptedStyleSheets"in Document.prototype&&"replace"in CSSStyleSheet.prototype,i=Symbol(),s=new WeakMap;let n=class{constructor(t,e,s){if(this._$cssResult$=!0,s!==i)throw Error("CSSResult is not constructable. Use `unsafeCSS` or `css` instead.");this.cssText=t,this.t=e}get styleSheet(){let t=this.o;const i=this.t;if(e&&void 0===t){const e=void 0!==i&&1===i.length;e&&(t=s.get(i)),void 0===t&&((this.o=t=new CSSStyleSheet).replaceSync(this.cssText),e&&s.set(i,t))}return t}toString(){return this.cssText}};const o=(t,...e)=>{const s=1===t.length?t[0]:e.reduce((e,i,s)=>e+(t=>{if(!0===t._$cssResult$)return t.cssText;if("number"==typeof t)return t;throw Error("Value passed to 'css' function must be a 'css' function result: "+t+". Use 'unsafeCSS' to pass non-literal values, but take care to ensure page security.")})(i)+t[s+1],t[0]);return new n(s,t,i)},a=e?t=>t:t=>t instanceof CSSStyleSheet?(t=>{let e="";for(const i of t.cssRules)e+=i.cssText;return(t=>new n("string"==typeof t?t:t+"",void 0,i))(e)})(t):t,{is:r,defineProperty:l,getOwnPropertyDescriptor:c,getOwnPropertyNames:h,getOwnPropertySymbols:d,getPrototypeOf:u}=Object,p=globalThis,_=p.trustedTypes,g=_?_.emptyScript:"",m=p.reactiveElementPolyfillSupport,f=(t,e)=>t,v={toAttribute(t,e){switch(e){case Boolean:t=t?g:null;break;case Object:case Array:t=null==t?t:JSON.stringify(t)}return t},fromAttribute(t,e){let i=t;switch(e){case Boolean:i=null!==t;break;case Number:i=null===t?null:Number(t);break;case Object:case Array:try{i=JSON.parse(t)}catch(t){i=null}}return i}},y=(t,e)=>!r(t,e),b={attribute:!0,type:String,converter:v,reflect:!1,useDefault:!1,hasChanged:y};Symbol.metadata??=Symbol("metadata"),p.litPropertyMetadata??=new WeakMap;let w=class extends HTMLElement{static addInitializer(t){this._$Ei(),(this.l??=[]).push(t)}static get observedAttributes(){return this.finalize(),this._$Eh&&[...this._$Eh.keys()]}static createProperty(t,e=b){if(e.state&&(e.attribute=!1),this._$Ei(),this.prototype.hasOwnProperty(t)&&((e=Object.create(e)).wrapped=!0),this.elementProperties.set(t,e),!e.noAccessor){const i=Symbol(),s=this.getPropertyDescriptor(t,i,e);void 0!==s&&l(this.prototype,t,s)}}static getPropertyDescriptor(t,e,i){const{get:s,set:n}=c(this.prototype,t)??{get(){return this[e]},set(t){this[e]=t}};return{get:s,set(e){const o=s?.call(this);n?.call(this,e),this.requestUpdate(t,o,i)},configurable:!0,enumerable:!0}}static getPropertyOptions(t){return this.elementProperties.get(t)??b}static _$Ei(){if(this.hasOwnProperty(f("elementProperties")))return;const t=u(this);t.finalize(),void 0!==t.l&&(this.l=[...t.l]),this.elementProperties=new Map(t.elementProperties)}static finalize(){if(this.hasOwnProperty(f("finalized")))return;if(this.finalized=!0,this._$Ei(),this.hasOwnProperty(f("properties"))){const t=this.properties,e=[...h(t),...d(t)];for(const i of e)this.createProperty(i,t[i])}const t=this[Symbol.metadata];if(null!==t){const e=litPropertyMetadata.get(t);if(void 0!==e)for(const[t,i]of e)this.elementProperties.set(t,i)}this._$Eh=new Map;for(const[t,e]of this.elementProperties){const i=this._$Eu(t,e);void 0!==i&&this._$Eh.set(i,t)}this.elementStyles=this.finalizeStyles(this.styles)}static finalizeStyles(t){const e=[];if(Array.isArray(t)){const i=new Set(t.flat(1/0).reverse());for(const t of i)e.unshift(a(t))}else void 0!==t&&e.push(a(t));return e}static _$Eu(t,e){const i=e.attribute;return!1===i?void 0:"string"==typeof i?i:"string"==typeof t?t.toLowerCase():void 0}constructor(){super(),this._$Ep=void 0,this.isUpdatePending=!1,this.hasUpdated=!1,this._$Em=null,this._$Ev()}_$Ev(){this._$ES=new Promise(t=>this.enableUpdating=t),this._$AL=new Map,this._$E_(),this.requestUpdate(),this.constructor.l?.forEach(t=>t(this))}addController(t){(this._$EO??=new Set).add(t),void 0!==this.renderRoot&&this.isConnected&&t.hostConnected?.()}removeController(t){this._$EO?.delete(t)}_$E_(){const t=new Map,e=this.constructor.elementProperties;for(const i of e.keys())this.hasOwnProperty(i)&&(t.set(i,this[i]),delete this[i]);t.size>0&&(this._$Ep=t)}createRenderRoot(){const i=this.shadowRoot??this.attachShadow(this.constructor.shadowRootOptions);return((i,s)=>{if(e)i.adoptedStyleSheets=s.map(t=>t instanceof CSSStyleSheet?t:t.styleSheet);else for(const e of s){const s=document.createElement("style"),n=t.litNonce;void 0!==n&&s.setAttribute("nonce",n),s.textContent=e.cssText,i.appendChild(s)}})(i,this.constructor.elementStyles),i}connectedCallback(){this.renderRoot??=this.createRenderRoot(),this.enableUpdating(!0),this._$EO?.forEach(t=>t.hostConnected?.())}enableUpdating(t){}disconnectedCallback(){this._$EO?.forEach(t=>t.hostDisconnected?.())}attributeChangedCallback(t,e,i){this._$AK(t,i)}_$ET(t,e){const i=this.constructor.elementProperties.get(t),s=this.constructor._$Eu(t,i);if(void 0!==s&&!0===i.reflect){const n=(void 0!==i.converter?.toAttribute?i.converter:v).toAttribute(e,i.type);this._$Em=t,null==n?this.removeAttribute(s):this.setAttribute(s,n),this._$Em=null}}_$AK(t,e){const i=this.constructor,s=i._$Eh.get(t);if(void 0!==s&&this._$Em!==s){const t=i.getPropertyOptions(s),n="function"==typeof t.converter?{fromAttribute:t.converter}:void 0!==t.converter?.fromAttribute?t.converter:v;this._$Em=s;const o=n.fromAttribute(e,t.type);this[s]=o??this._$Ej?.get(s)??o,this._$Em=null}}requestUpdate(t,e,i,s=!1,n){if(void 0!==t){const o=this.constructor;if(!1===s&&(n=this[t]),i??=o.getPropertyOptions(t),!((i.hasChanged??y)(n,e)||i.useDefault&&i.reflect&&n===this._$Ej?.get(t)&&!this.hasAttribute(o._$Eu(t,i))))return;this.C(t,e,i)}!1===this.isUpdatePending&&(this._$ES=this._$EP())}C(t,e,{useDefault:i,reflect:s,wrapped:n},o){i&&!(this._$Ej??=new Map).has(t)&&(this._$Ej.set(t,o??e??this[t]),!0!==n||void 0!==o)||(this._$AL.has(t)||(this.hasUpdated||i||(e=void 0),this._$AL.set(t,e)),!0===s&&this._$Em!==t&&(this._$Eq??=new Set).add(t))}async _$EP(){this.isUpdatePending=!0;try{await this._$ES}catch(t){Promise.reject(t)}const t=this.scheduleUpdate();return null!=t&&await t,!this.isUpdatePending}scheduleUpdate(){return this.performUpdate()}performUpdate(){if(!this.isUpdatePending)return;if(!this.hasUpdated){if(this.renderRoot??=this.createRenderRoot(),this._$Ep){for(const[t,e]of this._$Ep)this[t]=e;this._$Ep=void 0}const t=this.constructor.elementProperties;if(t.size>0)for(const[e,i]of t){const{wrapped:t}=i,s=this[e];!0!==t||this._$AL.has(e)||void 0===s||this.C(e,void 0,i,s)}}let t=!1;const e=this._$AL;try{t=this.shouldUpdate(e),t?(this.willUpdate(e),this._$EO?.forEach(t=>t.hostUpdate?.()),this.update(e)):this._$EM()}catch(e){throw t=!1,this._$EM(),e}t&&this._$AE(e)}willUpdate(t){}_$AE(t){this._$EO?.forEach(t=>t.hostUpdated?.()),this.hasUpdated||(this.hasUpdated=!0,this.firstUpdated(t)),this.updated(t)}_$EM(){this._$AL=new Map,this.isUpdatePending=!1}get updateComplete(){return this.getUpdateComplete()}getUpdateComplete(){return this._$ES}shouldUpdate(t){return!0}update(t){this._$Eq&&=this._$Eq.forEach(t=>this._$ET(t,this[t])),this._$EM()}updated(t){}firstUpdated(t){}};w.elementStyles=[],w.shadowRootOptions={mode:"open"},w[f("elementProperties")]=new Map,w[f("finalized")]=new Map,m?.({ReactiveElement:w}),(p.reactiveElementVersions??=[]).push("2.1.2");const k=globalThis,x=t=>t,$=k.trustedTypes,S=$?$.createPolicy("lit-html",{createHTML:t=>t}):void 0,M="$lit$",C=`lit$${Math.random().toFixed(9).slice(2)}$`,D="?"+C,T=`<${D}>`,P=document,R=()=>P.createComment(""),A=t=>null===t||"object"!=typeof t&&"function"!=typeof t,I=Array.isArray,E="[ \t\n\f\r]",F=/<(?:(!--|\/[^a-zA-Z])|(\/?[a-zA-Z][^>\s]*)|(\/?$))/g,z=/-->/g,O=/>/g,H=RegExp(`>|${E}(?:([^\\s"'>=/]+)(${E}*=${E}*(?:[^ \t\n\f\r"'\`<>=]|("|')|))|$)`,"g"),N=/'/g,L=/"/g,B=/^(?:script|style|textarea|title)$/i,q=t=>(e,...i)=>({_$litType$:t,strings:e,values:i}),j=q(1),W=q(2),U=Symbol.for("lit-noChange"),G=Symbol.for("lit-nothing"),V=new WeakMap,K=P.createTreeWalker(P,129);function Y(t,e){if(!I(t)||!t.hasOwnProperty("raw"))throw Error("invalid template strings array");return void 0!==S?S.createHTML(e):e}const X=(t,e)=>{const i=t.length-1,s=[];let n,o=2===e?"":3===e?"":"",a=F;for(let e=0;e"===l[0]?(a=n??F,c=-1):void 0===l[1]?c=-2:(c=a.lastIndex-l[2].length,r=l[1],a=void 0===l[3]?H:'"'===l[3]?L:N):a===L||a===N?a=H:a===z||a===O?a=F:(a=H,n=void 0);const d=a===H&&t[e+1].startsWith("/>")?" ":"";o+=a===F?i+T:c>=0?(s.push(r),i.slice(0,c)+M+i.slice(c)+C+d):i+C+(-2===c?e:d)}return[Y(t,o+(t[i]||"")+(2===e?"":3===e?"":"")),s]};class J{constructor({strings:t,_$litType$:e},i){let s;this.parts=[];let n=0,o=0;const a=t.length-1,r=this.parts,[l,c]=X(t,e);if(this.el=J.createElement(l,i),K.currentNode=this.el.content,2===e||3===e){const t=this.el.content.firstChild;t.replaceWith(...t.childNodes)}for(;null!==(s=K.nextNode())&&r.length0){s.textContent=$?$.emptyScript:"";for(let i=0;iI(t)||"function"==typeof t?.[Symbol.iterator])(t)?this.k(t):this._(t)}O(t){return this._$AA.parentNode.insertBefore(t,this._$AB)}T(t){this._$AH!==t&&(this._$AR(),this._$AH=this.O(t))}_(t){this._$AH!==G&&A(this._$AH)?this._$AA.nextSibling.data=t:this.T(P.createTextNode(t)),this._$AH=t}$(t){const{values:e,_$litType$:i}=t,s="number"==typeof i?this._$AC(t):(void 0===i.el&&(i.el=J.createElement(Y(i.h,i.h[0]),this.options)),i);if(this._$AH?._$AD===s)this._$AH.p(e);else{const t=new Q(s,this),i=t.u(this.options);t.p(e),this.T(i),this._$AH=t}}_$AC(t){let e=V.get(t.strings);return void 0===e&&V.set(t.strings,e=new J(t)),e}k(t){I(this._$AH)||(this._$AH=[],this._$AR());const e=this._$AH;let i,s=0;for(const n of t)s===e.length?e.push(i=new tt(this.O(R()),this.O(R()),this,this.options)):i=e[s],i._$AI(n),s++;s2||""!==i[0]||""!==i[1]?(this._$AH=Array(i.length-1).fill(new String),this.strings=i):this._$AH=G}_$AI(t,e=this,i,s){const n=this.strings;let o=!1;if(void 0===n)t=Z(this,t,e,0),o=!A(t)||t!==this._$AH&&t!==U,o&&(this._$AH=t);else{const s=t;let a,r;for(t=n[0],a=0;a{const s=i?.renderBefore??e;let n=s._$litPart$;if(void 0===n){const t=i?.renderBefore??null;s._$litPart$=n=new tt(e.insertBefore(R(),t),t,void 0,i??{})}return n._$AI(t),n},ct=globalThis;let ht=class extends w{constructor(){super(...arguments),this.renderOptions={host:this},this._$Do=void 0}createRenderRoot(){const t=super.createRenderRoot();return this.renderOptions.renderBefore??=t.firstChild,t}update(t){const e=this.render();this.hasUpdated||(this.renderOptions.isConnected=this.isConnected),super.update(t),this._$Do=lt(e,this.renderRoot,this.renderOptions)}connectedCallback(){super.connectedCallback(),this._$Do?.setConnected(!0)}disconnectedCallback(){super.disconnectedCallback(),this._$Do?.setConnected(!1)}render(){return U}};ht._$litElement$=!0,ht.finalized=!0,ct.litElementHydrateSupport?.({LitElement:ht});const dt=ct.litElementPolyfillSupport;dt?.({LitElement:ht}),(ct.litElementVersions??=[]).push("4.2.2");const ut=2,pt=t=>(...e)=>({_$litDirective$:t,values:e});let _t=class{constructor(t){}get _$AU(){return this._$AM._$AU}_$AT(t,e,i){this._$Ct=t,this._$AM=e,this._$Ci=i}_$AS(t,e){return this.update(t,e)}update(t,e){return this.render(...e)}};const gt={},mt=pt(class extends _t{constructor(){super(...arguments),this.ot=gt}render(t,e){return e()}update(t,[e,i]){if(Array.isArray(e)){if(Array.isArray(this.ot)&&this.ot.length===e.length&&e.every((t,e)=>t===this.ot[e]))return U}else if(this.ot===e)return U;return this.ot=Array.isArray(e)?Array.from(e):e,this.render(e,i)}}),{I:ft}=at,vt=t=>t,yt=()=>document.createComment(""),bt=(t,e,i)=>{const s=t._$AA.parentNode,n=void 0===e?t._$AB:e._$AA;if(void 0===i){const e=s.insertBefore(yt(),n),o=s.insertBefore(yt(),n);i=new ft(e,o,t,t.options)}else{const e=i._$AB.nextSibling,o=i._$AM,a=o!==t;if(a){let e;i._$AQ?.(t),i._$AM=t,void 0!==i._$AP&&(e=t._$AU)!==o._$AU&&i._$AP(e)}if(e!==n||a){let t=i._$AA;for(;t!==e;){const e=vt(t).nextSibling;vt(s).insertBefore(t,n),t=e}}}return i},wt=(t,e,i=t)=>(t._$AI(e,i),t),kt={},xt=(t,e=kt)=>t._$AH=e,$t=t=>{t._$AR(),t._$AA.remove()},St=(t,e,i)=>{const s=new Map;for(let n=e;n<=i;n++)s.set(t[n],n);return s},Mt=pt(class extends _t{constructor(t){if(super(t),t.type!==ut)throw Error("repeat() can only be used in text expressions")}dt(t,e,i){let s;void 0===i?i=e:void 0!==e&&(s=e);const n=[],o=[];let a=0;for(const e of t)n[a]=s?s(e,a):a,o[a]=i(e,a),a++;return{values:o,keys:n}}render(t,e,i){return this.dt(t,e,i).values}update(t,[e,i,s]){const n=(t=>t._$AH)(t),{values:o,keys:a}=this.dt(e,i,s);if(!Array.isArray(n))return this.ut=a,o;const r=this.ut??=[],l=[];let c,h,d=0,u=n.length-1,p=0,_=o.length-1;for(;d<=u&&p<=_;)if(null===n[d])d++;else if(null===n[u])u--;else if(r[d]===a[p])l[p]=wt(n[d],o[p]),d++,p++;else if(r[u]===a[_])l[_]=wt(n[u],o[_]),u--,_--;else if(r[d]===a[_])l[_]=wt(n[d],o[_]),bt(t,l[_+1],n[d]),d++,_--;else if(r[u]===a[p])l[p]=wt(n[u],o[p]),bt(t,n[d],n[u]),u--,p++;else if(void 0===c&&(c=St(a,p,_),h=St(r,d,u)),c.has(r[d]))if(c.has(r[u])){const e=h.get(a[p]),i=void 0!==e?n[e]:null;if(null===i){const e=bt(t,n[d]);wt(e,o[p]),l[p]=e}else l[p]=wt(i,o[p]),bt(t,n[d],i),n[e]=null;p++}else $t(n[u]),u--;else $t(n[d]),d++;for(;p<=_;){const e=bt(t,l[_+1]);wt(e,o[p]),l[p++]=e}for(;d<=u;){const t=n[d++];null!==t&&$t(t)}return this.ut=a,xt(t,l),U}}),Ct=new WeakMap;let Dt=0;class Tt extends ht{constructor(){super(...arguments),this.title="",this.icon="",this.wide=!1,this.dismissOnScrim=!1,this.hass=null,this._opener=null,this._focusRoot=null,this._useHaDialog=!1,this._closing=!1,this._overlays=[],this._titleId="hp-dialog-title-"+ ++Dt,this._focusInitial=()=>{const t=this._focusableElements(),e=t.find(t=>t.hasAttribute("autofocus"))||t[0]||(this._useHaDialog?null:this.renderRoot.querySelector(".close"))||this.renderRoot.querySelector(".surface")||this.renderRoot.querySelector("ha-dialog");e?.focus({preventScroll:!0})},this._requestClose=()=>{this._closing||(this._closing=!0,this.dispatchEvent(new CustomEvent("hp-close",{bubbles:!0,composed:!0})))},this._onKeyDown=t=>{if("Escape"===t.key){t.preventDefault(),t.stopImmediatePropagation(),this._pruneOverlays();const e=this._overlays[this._overlays.length-1];return e?void this._closeOverlay(e,"escape"):void this._requestClose()}if("Tab"!==t.key||this._useHaDialog)return;const e=this.renderRoot.querySelector(".close"),i=e?[e,...this._focusableElements()]:this._focusableElements();if(!i.length)return t.preventDefault(),void this.renderRoot.querySelector(".surface")?.focus({preventScroll:!0});const s=this._deepActiveElement(),n=i[0],o=i[i.length-1];!t.shiftKey||s!==n&&i.includes(s)?t.shiftKey||s!==o||(t.preventDefault(),n.focus()):(t.preventDefault(),o.focus())},this._onFallbackCancel=t=>{t.preventDefault(),this._requestClose()},this._onFallbackClick=t=>{this.dismissOnScrim&&t.target===t.currentTarget&&this._requestClose()}}connectedCallback(){super.connectedCallback(),this._opener=this._deepActiveElement();const t=this.getRootNode();this._focusRoot=t;const e=Ct.get(t)||{dialogs:new Set,opener:this._opener};e.dialogs.add(this),Ct.set(t,e),this._useHaDialog=!!customElements.get("ha-dialog"),this.addEventListener("keydown",this._onKeyDown,!0)}disconnectedCallback(){this.removeEventListener("keydown",this._onKeyDown,!0);const t=[...this._overlays];this._overlays=[];for(const e of t.reverse())e.close("disconnect");const e=this._focusRoot,i=this._opener;this._opener=null,this._focusRoot=null;const s=e?Ct.get(e):void 0;s?.dialogs.delete(this),super.disconnectedCallback(),e&&s&&requestAnimationFrame(()=>{const t=Ct.get(e);if(!t)return;if(!t.dialogs.size)return t.opener?.isConnected&&t.opener.focus({preventScroll:!0}),void Ct.delete(e);const s=i?.closest("hp-dialog");i?.isConnected&&s&&t.dialogs.has(s)&&i.focus({preventScroll:!0})})}firstUpdated(t){if(super.firstUpdated(t),!this._useHaDialog){const t=this.renderRoot.querySelector("dialog");t&&!t.open&&t.showModal()}queueMicrotask(()=>this._focusInitial())}_deepActiveElement(){let t=document.activeElement;for(;t?.shadowRoot?.activeElement;)t=t.shadowRoot.activeElement;return t&&t!==document.body?t:null}_focusableElements(){const t=["[autofocus]","a[href]","button:not([disabled])",'input:not([disabled]):not([type="hidden"])',"select:not([disabled])","textarea:not([disabled])",'[contenteditable="true"]','[tabindex]:not([tabindex="-1"])'].join(","),e=[],i=new Set,s=n=>{if(!i.has(n)){if(i.add(n),n instanceof HTMLElement){if(n.matches(t)&&e.push(n),n instanceof HTMLSlotElement){for(const t of n.assignedNodes({flatten:!0}))s(t);return}if(n.shadowRoot){for(const t of n.shadowRoot.childNodes)s(t);return}}for(const t of n.childNodes)s(t)}};for(const t of this.childNodes)s(t);const n=this.overlayPortal();return n&&s(n),e.filter(t=>{let e=t;for(;e;){const t=getComputedStyle(e);if(e.hidden||e.inert||"true"===e.getAttribute("aria-hidden")||"none"===t.display||"hidden"===t.visibility)return!1;if(e=e.assignedSlot||e.parentElement||(e.getRootNode()instanceof ShadowRoot?e.getRootNode().host:null),e===this)break}return!0})}_pruneOverlays(){this._overlays=this._overlays.filter(t=>t.owner.isConnected)}_closeOverlay(t,e){const i=this._overlays.findIndex(e=>e.token===t.token);i>=0&&this._overlays.splice(i,1),t.close(e)}registerOverlay(t){this._pruneOverlays();const e=this._overlays.find(e=>e.owner===t.owner);e&&this._overlays.splice(this._overlays.indexOf(e),1);const i=t.group||"transient";for(const t of[...this._overlays].reverse())t.group===i&&this._closeOverlay(t,"exclusive");const s={...t,group:i,token:Symbol("hp-overlay")};this._overlays.push(s);let n=!1;return()=>{if(n)return;n=!0;const t=this._overlays.findIndex(t=>t.token===s.token);t>=0&&this._overlays.splice(t,1)}}closeTransientOverlays(t="outside"){this._pruneOverlays();const e=[...this._overlays].filter(t=>"transient"===(t.group||"transient"));for(const i of e.reverse())this._closeOverlay(i,t);return e.length>0}overlayPortal(){return this.renderRoot.querySelector(".overlay-portal")}render(){const t=j` +globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="49963a7758df03d7aaaa3af3b9f198d629f4ca44af5c8ef9834c7afce5fda8ba";const t=globalThis,e=t.ShadowRoot&&(void 0===t.ShadyCSS||t.ShadyCSS.nativeShadow)&&"adoptedStyleSheets"in Document.prototype&&"replace"in CSSStyleSheet.prototype,i=Symbol(),s=new WeakMap;let n=class{constructor(t,e,s){if(this._$cssResult$=!0,s!==i)throw Error("CSSResult is not constructable. Use `unsafeCSS` or `css` instead.");this.cssText=t,this.t=e}get styleSheet(){let t=this.o;const i=this.t;if(e&&void 0===t){const e=void 0!==i&&1===i.length;e&&(t=s.get(i)),void 0===t&&((this.o=t=new CSSStyleSheet).replaceSync(this.cssText),e&&s.set(i,t))}return t}toString(){return this.cssText}};const o=(t,...e)=>{const s=1===t.length?t[0]:e.reduce((e,i,s)=>e+(t=>{if(!0===t._$cssResult$)return t.cssText;if("number"==typeof t)return t;throw Error("Value passed to 'css' function must be a 'css' function result: "+t+". Use 'unsafeCSS' to pass non-literal values, but take care to ensure page security.")})(i)+t[s+1],t[0]);return new n(s,t,i)},a=e?t=>t:t=>t instanceof CSSStyleSheet?(t=>{let e="";for(const i of t.cssRules)e+=i.cssText;return(t=>new n("string"==typeof t?t:t+"",void 0,i))(e)})(t):t,{is:r,defineProperty:l,getOwnPropertyDescriptor:c,getOwnPropertyNames:h,getOwnPropertySymbols:d,getPrototypeOf:u}=Object,p=globalThis,_=p.trustedTypes,g=_?_.emptyScript:"",m=p.reactiveElementPolyfillSupport,f=(t,e)=>t,v={toAttribute(t,e){switch(e){case Boolean:t=t?g:null;break;case Object:case Array:t=null==t?t:JSON.stringify(t)}return t},fromAttribute(t,e){let i=t;switch(e){case Boolean:i=null!==t;break;case Number:i=null===t?null:Number(t);break;case Object:case Array:try{i=JSON.parse(t)}catch(t){i=null}}return i}},y=(t,e)=>!r(t,e),b={attribute:!0,type:String,converter:v,reflect:!1,useDefault:!1,hasChanged:y};Symbol.metadata??=Symbol("metadata"),p.litPropertyMetadata??=new WeakMap;let w=class extends HTMLElement{static addInitializer(t){this._$Ei(),(this.l??=[]).push(t)}static get observedAttributes(){return this.finalize(),this._$Eh&&[...this._$Eh.keys()]}static createProperty(t,e=b){if(e.state&&(e.attribute=!1),this._$Ei(),this.prototype.hasOwnProperty(t)&&((e=Object.create(e)).wrapped=!0),this.elementProperties.set(t,e),!e.noAccessor){const i=Symbol(),s=this.getPropertyDescriptor(t,i,e);void 0!==s&&l(this.prototype,t,s)}}static getPropertyDescriptor(t,e,i){const{get:s,set:n}=c(this.prototype,t)??{get(){return this[e]},set(t){this[e]=t}};return{get:s,set(e){const o=s?.call(this);n?.call(this,e),this.requestUpdate(t,o,i)},configurable:!0,enumerable:!0}}static getPropertyOptions(t){return this.elementProperties.get(t)??b}static _$Ei(){if(this.hasOwnProperty(f("elementProperties")))return;const t=u(this);t.finalize(),void 0!==t.l&&(this.l=[...t.l]),this.elementProperties=new Map(t.elementProperties)}static finalize(){if(this.hasOwnProperty(f("finalized")))return;if(this.finalized=!0,this._$Ei(),this.hasOwnProperty(f("properties"))){const t=this.properties,e=[...h(t),...d(t)];for(const i of e)this.createProperty(i,t[i])}const t=this[Symbol.metadata];if(null!==t){const e=litPropertyMetadata.get(t);if(void 0!==e)for(const[t,i]of e)this.elementProperties.set(t,i)}this._$Eh=new Map;for(const[t,e]of this.elementProperties){const i=this._$Eu(t,e);void 0!==i&&this._$Eh.set(i,t)}this.elementStyles=this.finalizeStyles(this.styles)}static finalizeStyles(t){const e=[];if(Array.isArray(t)){const i=new Set(t.flat(1/0).reverse());for(const t of i)e.unshift(a(t))}else void 0!==t&&e.push(a(t));return e}static _$Eu(t,e){const i=e.attribute;return!1===i?void 0:"string"==typeof i?i:"string"==typeof t?t.toLowerCase():void 0}constructor(){super(),this._$Ep=void 0,this.isUpdatePending=!1,this.hasUpdated=!1,this._$Em=null,this._$Ev()}_$Ev(){this._$ES=new Promise(t=>this.enableUpdating=t),this._$AL=new Map,this._$E_(),this.requestUpdate(),this.constructor.l?.forEach(t=>t(this))}addController(t){(this._$EO??=new Set).add(t),void 0!==this.renderRoot&&this.isConnected&&t.hostConnected?.()}removeController(t){this._$EO?.delete(t)}_$E_(){const t=new Map,e=this.constructor.elementProperties;for(const i of e.keys())this.hasOwnProperty(i)&&(t.set(i,this[i]),delete this[i]);t.size>0&&(this._$Ep=t)}createRenderRoot(){const i=this.shadowRoot??this.attachShadow(this.constructor.shadowRootOptions);return((i,s)=>{if(e)i.adoptedStyleSheets=s.map(t=>t instanceof CSSStyleSheet?t:t.styleSheet);else for(const e of s){const s=document.createElement("style"),n=t.litNonce;void 0!==n&&s.setAttribute("nonce",n),s.textContent=e.cssText,i.appendChild(s)}})(i,this.constructor.elementStyles),i}connectedCallback(){this.renderRoot??=this.createRenderRoot(),this.enableUpdating(!0),this._$EO?.forEach(t=>t.hostConnected?.())}enableUpdating(t){}disconnectedCallback(){this._$EO?.forEach(t=>t.hostDisconnected?.())}attributeChangedCallback(t,e,i){this._$AK(t,i)}_$ET(t,e){const i=this.constructor.elementProperties.get(t),s=this.constructor._$Eu(t,i);if(void 0!==s&&!0===i.reflect){const n=(void 0!==i.converter?.toAttribute?i.converter:v).toAttribute(e,i.type);this._$Em=t,null==n?this.removeAttribute(s):this.setAttribute(s,n),this._$Em=null}}_$AK(t,e){const i=this.constructor,s=i._$Eh.get(t);if(void 0!==s&&this._$Em!==s){const t=i.getPropertyOptions(s),n="function"==typeof t.converter?{fromAttribute:t.converter}:void 0!==t.converter?.fromAttribute?t.converter:v;this._$Em=s;const o=n.fromAttribute(e,t.type);this[s]=o??this._$Ej?.get(s)??o,this._$Em=null}}requestUpdate(t,e,i,s=!1,n){if(void 0!==t){const o=this.constructor;if(!1===s&&(n=this[t]),i??=o.getPropertyOptions(t),!((i.hasChanged??y)(n,e)||i.useDefault&&i.reflect&&n===this._$Ej?.get(t)&&!this.hasAttribute(o._$Eu(t,i))))return;this.C(t,e,i)}!1===this.isUpdatePending&&(this._$ES=this._$EP())}C(t,e,{useDefault:i,reflect:s,wrapped:n},o){i&&!(this._$Ej??=new Map).has(t)&&(this._$Ej.set(t,o??e??this[t]),!0!==n||void 0!==o)||(this._$AL.has(t)||(this.hasUpdated||i||(e=void 0),this._$AL.set(t,e)),!0===s&&this._$Em!==t&&(this._$Eq??=new Set).add(t))}async _$EP(){this.isUpdatePending=!0;try{await this._$ES}catch(t){Promise.reject(t)}const t=this.scheduleUpdate();return null!=t&&await t,!this.isUpdatePending}scheduleUpdate(){return this.performUpdate()}performUpdate(){if(!this.isUpdatePending)return;if(!this.hasUpdated){if(this.renderRoot??=this.createRenderRoot(),this._$Ep){for(const[t,e]of this._$Ep)this[t]=e;this._$Ep=void 0}const t=this.constructor.elementProperties;if(t.size>0)for(const[e,i]of t){const{wrapped:t}=i,s=this[e];!0!==t||this._$AL.has(e)||void 0===s||this.C(e,void 0,i,s)}}let t=!1;const e=this._$AL;try{t=this.shouldUpdate(e),t?(this.willUpdate(e),this._$EO?.forEach(t=>t.hostUpdate?.()),this.update(e)):this._$EM()}catch(e){throw t=!1,this._$EM(),e}t&&this._$AE(e)}willUpdate(t){}_$AE(t){this._$EO?.forEach(t=>t.hostUpdated?.()),this.hasUpdated||(this.hasUpdated=!0,this.firstUpdated(t)),this.updated(t)}_$EM(){this._$AL=new Map,this.isUpdatePending=!1}get updateComplete(){return this.getUpdateComplete()}getUpdateComplete(){return this._$ES}shouldUpdate(t){return!0}update(t){this._$Eq&&=this._$Eq.forEach(t=>this._$ET(t,this[t])),this._$EM()}updated(t){}firstUpdated(t){}};w.elementStyles=[],w.shadowRootOptions={mode:"open"},w[f("elementProperties")]=new Map,w[f("finalized")]=new Map,m?.({ReactiveElement:w}),(p.reactiveElementVersions??=[]).push("2.1.2");const k=globalThis,x=t=>t,$=k.trustedTypes,S=$?$.createPolicy("lit-html",{createHTML:t=>t}):void 0,M="$lit$",C=`lit$${Math.random().toFixed(9).slice(2)}$`,D="?"+C,T=`<${D}>`,P=document,R=()=>P.createComment(""),A=t=>null===t||"object"!=typeof t&&"function"!=typeof t,I=Array.isArray,E="[ \t\n\f\r]",F=/<(?:(!--|\/[^a-zA-Z])|(\/?[a-zA-Z][^>\s]*)|(\/?$))/g,z=/-->/g,O=/>/g,H=RegExp(`>|${E}(?:([^\\s"'>=/]+)(${E}*=${E}*(?:[^ \t\n\f\r"'\`<>=]|("|')|))|$)`,"g"),N=/'/g,L=/"/g,B=/^(?:script|style|textarea|title)$/i,q=t=>(e,...i)=>({_$litType$:t,strings:e,values:i}),j=q(1),W=q(2),U=Symbol.for("lit-noChange"),G=Symbol.for("lit-nothing"),V=new WeakMap,K=P.createTreeWalker(P,129);function Y(t,e){if(!I(t)||!t.hasOwnProperty("raw"))throw Error("invalid template strings array");return void 0!==S?S.createHTML(e):e}const X=(t,e)=>{const i=t.length-1,s=[];let n,o=2===e?"":3===e?"":"",a=F;for(let e=0;e"===l[0]?(a=n??F,c=-1):void 0===l[1]?c=-2:(c=a.lastIndex-l[2].length,r=l[1],a=void 0===l[3]?H:'"'===l[3]?L:N):a===L||a===N?a=H:a===z||a===O?a=F:(a=H,n=void 0);const d=a===H&&t[e+1].startsWith("/>")?" ":"";o+=a===F?i+T:c>=0?(s.push(r),i.slice(0,c)+M+i.slice(c)+C+d):i+C+(-2===c?e:d)}return[Y(t,o+(t[i]||"")+(2===e?"":3===e?"":"")),s]};class J{constructor({strings:t,_$litType$:e},i){let s;this.parts=[];let n=0,o=0;const a=t.length-1,r=this.parts,[l,c]=X(t,e);if(this.el=J.createElement(l,i),K.currentNode=this.el.content,2===e||3===e){const t=this.el.content.firstChild;t.replaceWith(...t.childNodes)}for(;null!==(s=K.nextNode())&&r.length0){s.textContent=$?$.emptyScript:"";for(let i=0;iI(t)||"function"==typeof t?.[Symbol.iterator])(t)?this.k(t):this._(t)}O(t){return this._$AA.parentNode.insertBefore(t,this._$AB)}T(t){this._$AH!==t&&(this._$AR(),this._$AH=this.O(t))}_(t){this._$AH!==G&&A(this._$AH)?this._$AA.nextSibling.data=t:this.T(P.createTextNode(t)),this._$AH=t}$(t){const{values:e,_$litType$:i}=t,s="number"==typeof i?this._$AC(t):(void 0===i.el&&(i.el=J.createElement(Y(i.h,i.h[0]),this.options)),i);if(this._$AH?._$AD===s)this._$AH.p(e);else{const t=new Q(s,this),i=t.u(this.options);t.p(e),this.T(i),this._$AH=t}}_$AC(t){let e=V.get(t.strings);return void 0===e&&V.set(t.strings,e=new J(t)),e}k(t){I(this._$AH)||(this._$AH=[],this._$AR());const e=this._$AH;let i,s=0;for(const n of t)s===e.length?e.push(i=new tt(this.O(R()),this.O(R()),this,this.options)):i=e[s],i._$AI(n),s++;s2||""!==i[0]||""!==i[1]?(this._$AH=Array(i.length-1).fill(new String),this.strings=i):this._$AH=G}_$AI(t,e=this,i,s){const n=this.strings;let o=!1;if(void 0===n)t=Z(this,t,e,0),o=!A(t)||t!==this._$AH&&t!==U,o&&(this._$AH=t);else{const s=t;let a,r;for(t=n[0],a=0;a{const s=i?.renderBefore??e;let n=s._$litPart$;if(void 0===n){const t=i?.renderBefore??null;s._$litPart$=n=new tt(e.insertBefore(R(),t),t,void 0,i??{})}return n._$AI(t),n},ct=globalThis;let ht=class extends w{constructor(){super(...arguments),this.renderOptions={host:this},this._$Do=void 0}createRenderRoot(){const t=super.createRenderRoot();return this.renderOptions.renderBefore??=t.firstChild,t}update(t){const e=this.render();this.hasUpdated||(this.renderOptions.isConnected=this.isConnected),super.update(t),this._$Do=lt(e,this.renderRoot,this.renderOptions)}connectedCallback(){super.connectedCallback(),this._$Do?.setConnected(!0)}disconnectedCallback(){super.disconnectedCallback(),this._$Do?.setConnected(!1)}render(){return U}};ht._$litElement$=!0,ht.finalized=!0,ct.litElementHydrateSupport?.({LitElement:ht});const dt=ct.litElementPolyfillSupport;dt?.({LitElement:ht}),(ct.litElementVersions??=[]).push("4.2.2");const ut=2,pt=t=>(...e)=>({_$litDirective$:t,values:e});let _t=class{constructor(t){}get _$AU(){return this._$AM._$AU}_$AT(t,e,i){this._$Ct=t,this._$AM=e,this._$Ci=i}_$AS(t,e){return this.update(t,e)}update(t,e){return this.render(...e)}};const gt={},mt=pt(class extends _t{constructor(){super(...arguments),this.ot=gt}render(t,e){return e()}update(t,[e,i]){if(Array.isArray(e)){if(Array.isArray(this.ot)&&this.ot.length===e.length&&e.every((t,e)=>t===this.ot[e]))return U}else if(this.ot===e)return U;return this.ot=Array.isArray(e)?Array.from(e):e,this.render(e,i)}}),{I:ft}=at,vt=t=>t,yt=()=>document.createComment(""),bt=(t,e,i)=>{const s=t._$AA.parentNode,n=void 0===e?t._$AB:e._$AA;if(void 0===i){const e=s.insertBefore(yt(),n),o=s.insertBefore(yt(),n);i=new ft(e,o,t,t.options)}else{const e=i._$AB.nextSibling,o=i._$AM,a=o!==t;if(a){let e;i._$AQ?.(t),i._$AM=t,void 0!==i._$AP&&(e=t._$AU)!==o._$AU&&i._$AP(e)}if(e!==n||a){let t=i._$AA;for(;t!==e;){const e=vt(t).nextSibling;vt(s).insertBefore(t,n),t=e}}}return i},wt=(t,e,i=t)=>(t._$AI(e,i),t),kt={},xt=(t,e=kt)=>t._$AH=e,$t=t=>{t._$AR(),t._$AA.remove()},St=(t,e,i)=>{const s=new Map;for(let n=e;n<=i;n++)s.set(t[n],n);return s},Mt=pt(class extends _t{constructor(t){if(super(t),t.type!==ut)throw Error("repeat() can only be used in text expressions")}dt(t,e,i){let s;void 0===i?i=e:void 0!==e&&(s=e);const n=[],o=[];let a=0;for(const e of t)n[a]=s?s(e,a):a,o[a]=i(e,a),a++;return{values:o,keys:n}}render(t,e,i){return this.dt(t,e,i).values}update(t,[e,i,s]){const n=(t=>t._$AH)(t),{values:o,keys:a}=this.dt(e,i,s);if(!Array.isArray(n))return this.ut=a,o;const r=this.ut??=[],l=[];let c,h,d=0,u=n.length-1,p=0,_=o.length-1;for(;d<=u&&p<=_;)if(null===n[d])d++;else if(null===n[u])u--;else if(r[d]===a[p])l[p]=wt(n[d],o[p]),d++,p++;else if(r[u]===a[_])l[_]=wt(n[u],o[_]),u--,_--;else if(r[d]===a[_])l[_]=wt(n[d],o[_]),bt(t,l[_+1],n[d]),d++,_--;else if(r[u]===a[p])l[p]=wt(n[u],o[p]),bt(t,n[d],n[u]),u--,p++;else if(void 0===c&&(c=St(a,p,_),h=St(r,d,u)),c.has(r[d]))if(c.has(r[u])){const e=h.get(a[p]),i=void 0!==e?n[e]:null;if(null===i){const e=bt(t,n[d]);wt(e,o[p]),l[p]=e}else l[p]=wt(i,o[p]),bt(t,n[d],i),n[e]=null;p++}else $t(n[u]),u--;else $t(n[d]),d++;for(;p<=_;){const e=bt(t,l[_+1]);wt(e,o[p]),l[p++]=e}for(;d<=u;){const t=n[d++];null!==t&&$t(t)}return this.ut=a,xt(t,l),U}}),Ct=new WeakMap;let Dt=0;class Tt extends ht{constructor(){super(...arguments),this.title="",this.icon="",this.wide=!1,this.dismissOnScrim=!1,this.hass=null,this._opener=null,this._focusRoot=null,this._useHaDialog=!1,this._closing=!1,this._overlays=[],this._titleId="hp-dialog-title-"+ ++Dt,this._focusInitial=()=>{const t=this._focusableElements(),e=t.find(t=>t.hasAttribute("autofocus"))||t[0]||(this._useHaDialog?null:this.renderRoot.querySelector(".close"))||this.renderRoot.querySelector(".surface")||this.renderRoot.querySelector("ha-dialog");e?.focus({preventScroll:!0})},this._requestClose=()=>{this._closing||(this._closing=!0,this.dispatchEvent(new CustomEvent("hp-close",{bubbles:!0,composed:!0})))},this._onKeyDown=t=>{if("Escape"===t.key){t.preventDefault(),t.stopImmediatePropagation(),this._pruneOverlays();const e=this._overlays[this._overlays.length-1];return e?void this._closeOverlay(e,"escape"):void this._requestClose()}if("Tab"!==t.key||this._useHaDialog)return;const e=this.renderRoot.querySelector(".close"),i=e?[e,...this._focusableElements()]:this._focusableElements();if(!i.length)return t.preventDefault(),void this.renderRoot.querySelector(".surface")?.focus({preventScroll:!0});const s=this._deepActiveElement(),n=i[0],o=i[i.length-1];!t.shiftKey||s!==n&&i.includes(s)?t.shiftKey||s!==o||(t.preventDefault(),n.focus()):(t.preventDefault(),o.focus())},this._onFallbackCancel=t=>{t.preventDefault(),this._requestClose()},this._onFallbackClick=t=>{this.dismissOnScrim&&t.target===t.currentTarget&&this._requestClose()}}connectedCallback(){super.connectedCallback(),this._opener=this._deepActiveElement();const t=this.getRootNode();this._focusRoot=t;const e=Ct.get(t)||{dialogs:new Set,opener:this._opener};e.dialogs.add(this),Ct.set(t,e),this._useHaDialog=!!customElements.get("ha-dialog"),this.addEventListener("keydown",this._onKeyDown,!0)}disconnectedCallback(){this.removeEventListener("keydown",this._onKeyDown,!0);const t=[...this._overlays];this._overlays=[];for(const e of t.reverse())e.close("disconnect");const e=this._focusRoot,i=this._opener;this._opener=null,this._focusRoot=null;const s=e?Ct.get(e):void 0;s?.dialogs.delete(this),super.disconnectedCallback(),e&&s&&requestAnimationFrame(()=>{const t=Ct.get(e);if(!t)return;if(!t.dialogs.size)return t.opener?.isConnected&&t.opener.focus({preventScroll:!0}),void Ct.delete(e);const s=i?.closest("hp-dialog");i?.isConnected&&s&&t.dialogs.has(s)&&i.focus({preventScroll:!0})})}firstUpdated(t){if(super.firstUpdated(t),!this._useHaDialog){const t=this.renderRoot.querySelector("dialog");t&&!t.open&&t.showModal()}queueMicrotask(()=>this._focusInitial())}_deepActiveElement(){let t=document.activeElement;for(;t?.shadowRoot?.activeElement;)t=t.shadowRoot.activeElement;return t&&t!==document.body?t:null}_focusableElements(){const t=["[autofocus]","a[href]","button:not([disabled])",'input:not([disabled]):not([type="hidden"])',"select:not([disabled])","textarea:not([disabled])",'[contenteditable="true"]','[tabindex]:not([tabindex="-1"])'].join(","),e=[],i=new Set,s=n=>{if(!i.has(n)){if(i.add(n),n instanceof HTMLElement){if(n.matches(t)&&e.push(n),n instanceof HTMLSlotElement){for(const t of n.assignedNodes({flatten:!0}))s(t);return}if(n.shadowRoot){for(const t of n.shadowRoot.childNodes)s(t);return}}for(const t of n.childNodes)s(t)}};for(const t of this.childNodes)s(t);const n=this.overlayPortal();return n&&s(n),e.filter(t=>{let e=t;for(;e;){const t=getComputedStyle(e);if(e.hidden||e.inert||"true"===e.getAttribute("aria-hidden")||"none"===t.display||"hidden"===t.visibility)return!1;if(e=e.assignedSlot||e.parentElement||(e.getRootNode()instanceof ShadowRoot?e.getRootNode().host:null),e===this)break}return!0})}_pruneOverlays(){this._overlays=this._overlays.filter(t=>t.owner.isConnected)}_closeOverlay(t,e){const i=this._overlays.findIndex(e=>e.token===t.token);i>=0&&this._overlays.splice(i,1),t.close(e)}registerOverlay(t){this._pruneOverlays();const e=this._overlays.find(e=>e.owner===t.owner);e&&this._overlays.splice(this._overlays.indexOf(e),1);const i=t.group||"transient";for(const t of[...this._overlays].reverse())t.group===i&&this._closeOverlay(t,"exclusive");const s={...t,group:i,token:Symbol("hp-overlay")};this._overlays.push(s);let n=!1;return()=>{if(n)return;n=!0;const t=this._overlays.findIndex(t=>t.token===s.token);t>=0&&this._overlays.splice(t,1)}}closeTransientOverlays(t="outside"){this._pruneOverlays();const e=[...this._overlays].filter(t=>"transient"===(t.group||"transient"));for(const i of e.reverse())this._closeOverlay(i,t);return e.length>0}overlayPortal(){return this.renderRoot.querySelector(".overlay-portal")}render(){const t=j` ${this.icon?j``:G} ${this.title} `;return this._useHaDialog?j` `})} - `}const er={color:"#607d8b",opacity:1,widthCm:3.6,fill:!1,fillColor:"#607d8b",fillOpacity:.25},ir=(t,e=1)=>{const i=Number(t);return Number.isFinite(i)?Math.min(1,Math.max(0,i)):e},sr=t=>{let e=Number(t);return Number.isFinite(e)?(e=(e%360+360)%360,e>180?e-360:e):0};function nr(t,e,i){return sr(e)?[t.x,t.y]:i([t.x,t.y])}const or=(t,e,i)=>{const s=Number(t),n=Number.isFinite(e)&&e>0?e:5;return Number.isFinite(s)&&s>0?s/n*i:0},ar=(t,e,i)=>{const s=Number(t),n=Number.isFinite(e)&&e>0?e:5;return Number.isFinite(s)&&i>0?s/i*n:0},rr=(t,e,i,s=er.widthCm)=>{const n=Number(t?.width_cm);if(Number.isFinite(n)&&n>0)return n;const o=Number(t?.width);return Number.isFinite(o)&&o>0?ar(o,e,i):s};function lr(t,e){return{color:t.color,opacity:ir(t.opacity),width_cm:Math.max(.1,Math.min(100,Number(t.widthCm)||.1)),...e?{fill:t.fill,fill_color:t.fillColor,fill_opacity:ir(t.fillOpacity,.25)}:{}}}function cr(t){const e=t.x+t.w/2,i=t.y+t.h/2,s=sr(t.angle)*Math.PI/180,n=Math.cos(s),o=Math.sin(s),a=(t,s)=>{const a=t-e,r=s-i;return[e+a*n-r*o,i+a*o+r*n]};return[a(t.x,t.y),a(t.x+t.w,t.y),a(t.x+t.w,t.y+t.h),a(t.x,t.y+t.h)]}function hr(t){const e=cr(t),i=(t,e)=>[(t[0]+e[0])/2,(t[1]+e[1])/2],s=[(e[0][0]+e[2][0])/2,(e[0][1]+e[2][1])/2];return{points:[...e,i(e[0],e[1]),i(e[1],e[2]),i(e[2],e[3]),i(e[3],e[0]),s],segments:e.map((t,i)=>({a:t,b:e[(i+1)%4]}))}}function dr(t,e,i,s,n,o,a,r){const l=sr(t.angle)*Math.PI/180,c=Math.cos(l),h=Math.sin(l),d=-Math.sin(l),u=Math.cos(l),p=t.x+t.w/2,_=t.y+t.h/2,g=e>0?-t.w/2:t.w/2,m=i>0?-t.h/2:t.h/2,f=p+g*c+m*d,v=_+g*h+m*u,y=s-f,b=n-v;let w=(y*c+b*h)*(e>0?1:-1),k=(y*d+b*u)*(i>0?1:-1),x=null;if(o){const e=w/Math.max(t.w,r),i=k/Math.max(t.h,r);x=Math.max(r/Math.max(t.w,r),r/Math.max(t.h,r),e,i),w=t.w*x,k=t.h*x}if(a>0)if(o){const e=Math.max(1,Math.round(t.w/a)),i=Math.max(1,Math.round(t.h/a));if(Math.abs(t.w-e*a)<1e-6&&Math.abs(t.h-i*a)<1e-6){const s=(t,e)=>{let i=Math.abs(t),s=Math.abs(e);for(;s;)[i,s]=[s,i%s];return Math.max(1,i)},n=1/s(e,i),o=Math.max(r/t.w,r/t.h),a=Math.max(o,Math.round((x??1)/n)*n);w=t.w*a,k=t.h*a}else{t.w>=t.h?(w=Math.round(w/a)*a,k=w*(t.h/Math.max(t.w,r))):(k=Math.round(k/a)*a,w=k*(t.w/Math.max(t.h,r)))}}else w=Math.round(w/a)*a,k=Math.round(k/a)*a;w=Math.max(r,w),k=Math.max(r,k);return{x:f+(e>0?w/2:-w/2)*c+(i>0?k/2:-k/2)*d-w/2,y:v+(e>0?w/2:-w/2)*h+(i>0?k/2:-k/2)*u-k/2,w:w,h:k,angle:sr(t.angle)||void 0}}const ur=(t,e,i)=>{const s=i[0]-e[0],n=i[1]-e[1],o=s*s+n*n;if(o<1e-12)return[...e];const a=Math.max(0,Math.min(1,((t[0]-e[0])*s+(t[1]-e[1])*n)/o));return[e[0]+s*a,e[1]+n*a]};const pr=15;function _r(t,e){return Number.isFinite(t)&&t>0&&Number.isFinite(e)&&e>0&&t*e<3}function gr(t){return Number.isFinite(t)?Math.max(1,Math.min(100,t)):1}function mr(t,e){return!Number.isFinite(t)||t<=0?"":String(e?Math.round(t/2.54*100)/100:Math.round(100*t)/100)}function fr(t,e,i){const s=Number(e)>0?Number(e):5;return gr(t)/s*i}function vr(t,e){return e>0&&Number.isFinite(t)?Math.round(t/e)*e:t}function yr(t,e){let i=e[0]-t[0],s=e[1]-t[1];const n=Math.hypot(i,s);return n<1e-12?[1,0]:(i/=n,s/=n,(i<-1e-12||Math.abs(i)<=1e-12&&s<0)&&(i=-i,s=-s),[i,s])}function br(t,e,i){const s=vr((t[0]+e[0])/2,i),n=vr((t[1]+e[1])/2,i),[o,a]=yr(t,e);let r=Math.atan2(a,o);r<0&&(r+=Math.PI);const l=Math.round(1800*r)/1800,c=i>0&&i<.01?6:i<1?4:2;return`${s.toFixed(c)},${n.toFixed(c)}@${l.toFixed(4)}`}function wr(t,e,i,s){return 1===s?br(t,e,i):br([t[0]/s,t[1]/s],[e[0]/s,e[1]/s],i)}function kr(t,e){if(!Array.isArray(t.a)||!Array.isArray(t.b)||t.a.length<2||t.b.length<2)return null;const i=[Number(t.a[0]),Number(t.a[1]),Number(t.b[0]),Number(t.b[1])];if(!i.every(Number.isFinite))return null;const s=e>0?e:1;return[[i[0]*s,i[1]*s],[i[2]*s,i[3]*s]]}function xr(t,e,i,s,n){const o=n>0?n:1;return{key:wr(t,e,s,o),cm:gr(i),a:[t[0]/o,t[1]/o],b:[e[0]/o,e[1]/o]}}function $r(t,e){const i=e>0?e:1,s=[];for(const e of t){const t=e.key.lastIndexOf("@");if(t<0)continue;const[n,o]=e.key.slice(0,t).split(",").map(Number),a=Number(e.key.slice(t+1));[n,o,a].every(Number.isFinite)&&s.push({w:e,x:n*i,y:o*i,ang:a})}return s}function Sr(t,e){const[i,s]=yr(t,e);let n=Math.atan2(s,i);return n<0&&(n+=Math.PI),n}function Mr(t,e){let i=Math.abs(t-e);return i>Math.PI/2&&(i=Math.PI-i),i<.02}function Cr(t,e,i,s,n=1){if(!t?.length)return null;const o=wr(e,i,s,n),a=t.find(t=>t.key===o);if(a)return a;const r=n>0?n:1,l=(e[0]+i[0])/2,c=(e[1]+i[1])/2,h=Sr(e,i),d=Math.max(.5*s,1e-9)*r;for(const e of $r(t,r))if(Mr(e.ang,h)&&Math.hypot(e.x-l,e.y-c)<=d)return e.w;return null}function Dr(t,e,i,s,n=1){const o=Cr(t,e,i,s,n);if(o&&o.cm>0)return gr(o.cm);const a=function(t,e,i,s,n){if(!t?.length)return null;const o=n>0?n:1,a=Math.hypot(i[0]-e[0],i[1]-e[1]);if(a<1e-12)return null;const r=Sr(e,i),l=Math.max(.5*s,1e-9)*o;let c=null;for(const s of t){if(!(s.cm>0))continue;const t=kr(s,o);if(!t)continue;const n=Math.hypot(t[1][0]-t[0][0],t[1][1]-t[0][1]);if(n<1e-12||!Mr(Sr(t[0],t[1]),r))continue;if(sl(e[0],e[1],t[0][0],t[0][1],t[1][0],t[1][1])>l||sl(i[0],i[1],t[0][0],t[0][1],t[1][0],t[1][1])>l)continue;if(n+l(o.has(t.key)||(t=>{const e=kr(t,s);if(!e)return!1;const[i,o]=e,r=o[0]-i[0],c=o[1]-i[1],h=Math.hypot(r,c);if(h<=l)return!1;if(!a.some(t=>{const e=[t[0],t[1]],s=[t[2],t[3]];return Mr(Sr(i,o),Sr(e,s))&&sl(i[0],i[1],e[0],e[1],s[0],s[1])<=l&&sl(o[0],o[1],e[0],e[1],s[0],s[1])<=l}))return!1;const d=(n||[]).some(t=>{const e=[t[0],t[1]],s=[t[2],t[3]];if(!Mr(Sr(i,o),Sr(e,s)))return!1;const n=t=>Math.abs((t[0]-i[0])*c-(t[1]-i[1])*r)/h;if(n(e)>l||n(s)>l)return!1;const a=h*h,d=((e[0]-i[0])*r+(e[1]-i[1])*c)/a,u=((s[0]-i[0])*r+(s[1]-i[1])*c)/a;return Math.min(1,Math.max(d,u))-Math.max(0,Math.min(d,u))>l/h});return!d})(t))&&t.cm>=1&&t.cm<=100)}function Pr(t,e,i,s=8){const[n,o]=yr(t,e);let a=Math.atan2(o,n);a<0&&(a+=Math.PI);let r=i*Math.PI/180%Math.PI;r<0&&(r+=Math.PI);let l=Math.abs(a-r);return l>Math.PI/2&&(l=Math.PI-l),l<=s*Math.PI/180}function Rr(t,e,i,s,n=1){if(!t?.length)return[];if(e.length!==i.length)return t.slice();const o=new Map;for(let t=0;t0?n:1,r=Math.max(.5*s,1e-9)*a,l=new Set,c=[];for(const n of t){let t="",h=null;const d=kr(n,a);if(d)for(let n=0;nr||sl(d[1][0],d[1][1],o[0],o[1],l[0],l[1])>r)continue;const p=l[0]-o[0],_=l[1]-o[1],g=p*p+_*_;if(g<1e-18)continue;const m=t=>{const e=Math.max(0,Math.min(1,((t[0]-o[0])*p+(t[1]-o[1])*_)/g));return[c[0]+(u[0]-c[0])*e,c[1]+(u[1]-c[1])*e]};h=[m(d[0]),m(d[1])],t=wr(h[0],h[1],s,a);break}if(d||(t=o.get(n.key)||""),!t){const o=$r([n],a)[0];if(o)for(let n=0;n1.000001)continue;if(sl(o.x,o.y,l[0],l[1],c[0],c[1])>r)continue;const m=h[0]+(d[0]-h[0])*Math.max(0,Math.min(1,g)),f=h[1]+(d[1]-h[1])*Math.max(0,Math.min(1,g)),[v,y]=yr(h,d),b=Math.max(s*a,1e-6);t=wr([m-v*b,f-y*b],[m+v*b,f+y*b],s,a);break}}t||(t=n.key),l.has(t)||(l.add(t),c.push(h?xr(h[0],h[1],n.cm,s,a):{...n,key:t,cm:gr(n.cm)}))}return c}function Ar(t,e,i,s,n,o=1){const a=wr(e,i,n,o),r=(t||[]).filter(t=>t.key!==a);return null==s||s<1?r:[...r,xr(e,i,s,n,o)]}function Ir(t,e,i,s,n,o=[],a=1){let r=t?t.slice():[];for(const t of function(t,e,i,s,n=1,o=[]){const a=Xr(t,e,i,s,n,o);if(!a)return[];const r=[];for(let t=0;t0||(c=Ar(c,e,i,s,n,a)))}return c}function Fr(t){const{a:e,b:i,halfDepth:s}=t;if(!Array.isArray(e)||!Array.isArray(i)||e.length<2||i.length<2||![e[0],e[1],i[0],i[1]].every(Number.isFinite))return null;const n=i[0]-e[0],o=i[1]-e[1],a=Math.hypot(n,o);if(!(a>1e-9&&s>0&&Number.isFinite(s)))return null;const r=-o/a*s,l=n/a*s;return[[e[0]+r,e[1]+l],[i[0]+r,i[1]+l],[i[0]-r,i[1]-l],[e[0]-r,e[1]-l]]}function zr(t,e,i){return Math.hypot(t[0]-e[0],t[1]-e[1])<=i}function Or(t,e,i){const s=e.b[0]-e.a[0],n=e.b[1]-e.a[1],o=s*s+n*n;if(!(o>i*i))return!1;const a=((t[0]-e.a[0])*s+(t[1]-e.a[1])*n)/o;if(!(a>0&&a<1))return!1;const r=[e.a[0]+s*a,e.a[1]+n*a];return Math.hypot(t[0]-r[0],t[1]-r[1])<=i}function Hr(t,e,i,s){const n=Math.hypot(e,i);if(!(n>1e-9&&s>0))return;const o=[e/n,i/n],a=t.find(t=>Math.abs(t.u[0]*o[1]-t.u[1]*o[0])<1e-9&&t.u[0]*o[0]+t.u[1]*o[1]>1-1e-9);a?a.halfDepth=Math.max(a.halfDepth,s):t.push({u:o,halfDepth:s})}function Nr(t,e=1e-6){const i=(t||[]).filter(t=>t&&Array.isArray(t.a)&&Array.isArray(t.b)&&t.a.length>=2&&t.b.length>=2&&t.a.every(Number.isFinite)&&t.b.every(Number.isFinite)&&Number.isFinite(t.halfDepth)&&t.halfDepth>0&&Math.hypot(t.b[0]-t.a[0],t.b[1]-t.a[1])>1e-9);if(i.length<2)return[];const s=Math.max(Number.isFinite(e)?e:0,1e-9),n=i.flatMap(t=>[t.a,t.b]).map(t=>[t[0],t[1]]).sort((t,e)=>t[0]-e[0]||t[1]-e[1]),o=[];for(const t of n)o.some(e=>zr(e,t,s))||o.push(t);const a=[];for(const t of o){const e=[];for(const n of i)zr(t,n.a,s)?Hr(e,n.b[0]-n.a[0],n.b[1]-n.a[1],n.halfDepth):zr(t,n.b,s)?Hr(e,n.a[0]-n.b[0],n.a[1]-n.b[1],n.halfDepth):Or(t,n,s)&&(Hr(e,n.a[0]-t[0],n.a[1]-t[1],n.halfDepth),Hr(e,n.b[0]-t[0],n.b[1]-t[1],n.halfDepth));if(!(e.length<2)){e.sort((t,e)=>Math.atan2(t.u[1],t.u[0])-Math.atan2(e.u[1],e.u[0])||t.halfDepth-e.halfDepth);for(let i=0;is*s&&a.push(m)}}}return a}function Lr(t,e,i,s){if(!(e>0)||!t||t.length<2)return"";if(i&&t.length>=3){let i=t;const n=t[t.length-1];if(t.length>=4&&Math.hypot(t[0][0]-n[0],t[0][1]-n[1])<1e-9&&(i=t.slice(0,-1)),i.length>=3){const t=i.map((t,i)=>s?.[i]||e),n=_l(i,t),o=Vr(i,t);if(n&&o)return`${Kr(n)} ${Kr(Yr(o))}`}}const n=[];for(let i=0;i=1e-9&&r>0&&n.push({a:o,b:a,halfDepth:r})}const o=[...n.map(Fr).filter(t=>!!t),...Nr(n)],a=function(t){let e=null;try{for(const i of t){if(i.length<3)continue;const t=ol(i);e=e?si(e,t):[t]}return e}catch{return null}}(o);return a?hl(a):o.map(t=>Kr(t)).join(" ")}function Br(t,e,i,s,n=1){if(!i.length)return!1;const o=qr(s,n),a=(t[0]+e[0])/2,r=(t[1]+e[1])/2,[l,c]=yr(t,e);for(const t of i){const[e,i]=yr([t[0],t[1]],[t[2],t[3]]);if(!(Math.abs(l*i-c*e)>.05)&&sl(a,r,t[0],t[1],t[2],t[3])<=o)return!0}return!1}function qr(t,e){return Math.max(t*(e>0?e:1)*.04,1e-9)}function jr(t){let e=0;for(let i=0;it[1]!=l>t[1]&&t[0]<(r-o)*(t[1]-a)/(l-a+0)+o&&(i=!i)}return i}([c[0]+.001*r,c[1]+.001*l],t)||(r=-r,l=-l),[r,l]}function Ur(t,e){const i=t[0]*e[1]-t[1]*e[0],s=t[0]*e[0]+t[1]*e[1];return Math.abs(i)<1e-9&&s>0}function Gr(t,e,i,s){const n=e[0]*s[1]-e[1]*s[0];if(Math.abs(n)<1e-12)return null;const o=[i[0]-t[0],i[1]-t[1]],a=(o[0]*s[1]-o[1]*s[0])/n;return[t[0]+a*e[0],t[1]+a*e[1]]}function Vr(t,e){const i=t?.length||0;if(i<3||e.length!==i)return null;if(e.every(t=>!(t>0)))return t.map(t=>[t[0],t[1]]);const s=[];for(let n=0;n0||d>0)){s.push([t[n][0],t[n][1]]);continue}if(h>0!=d>0){const e=t[n],i=h>0?[e[0]+u*h,e[1]+p*h]:[e[0],e[1]],o=d>0?[e[0]+_*d,e[1]+g*d]:[e[0],e[1]];s.push(i),Math.hypot(o[0]-i[0],o[1]-i[1])>1e-9&&s.push(o);continue}if(Ur(b,w)){const e=t[n],i=[e[0]+u*h,e[1]+p*h],o=[e[0]+_*d,e[1]+g*d];s.push(i),Math.hypot(o[0]-i[0],o[1]-i[1])>1e-9&&s.push(o);continue}const $=Gr(k,b,x,w),S=Math.max(h,d,1e-9);if($){if(Math.hypot($[0]-t[n][0],$[1]-t[n][1])<=4*S){s.push($);continue}}h>0&&s.push([t[n][0]+u*h,t[n][1]+p*h]),d>0&&s.push([t[n][0]+_*d,t[n][1]+g*d]),h>0||d>0||s.push([t[n][0],t[n][1]])}return s.length>=3?s:null}function Kr(t,e=!0){if(!t.length)return"";let i=`M ${t[0][0]} ${t[0][1]}`;for(let e=1;et?.id===e),r=hi(a);if(!r||r.length<3)return null;const l=qr(s,n),c=[];for(const i of t||[]){if(!i||i.id===e)continue;const t=hi(i);if(t)for(const e of Cs(r,t,l))c.push([e[0],e[1]],[e[2],e[3]])}for(const t of i||[])c.push([t[0],t[1]],[t[2],t[3]]);for(const t of o||[]){const e=kr(t,n);e&&c.push(e[0],e[1])}const h=[],d=[];for(let t=0;tl)continue;const a=((t[0]-e[0])*(i[0]-e[0])+(t[1]-e[1])*(i[1]-e[1]))/(s*s);a<=n||a>=1-n||(o.some(t=>Math.abs(t-a)*s<=2*l)||o.push(a))}o.sort((t,e)=>t-e);for(const s of o)h.push([e[0]+(i[0]-e[0])*s,e[1]+(i[1]-e[1])*s]),d.push(t)}return{poly:h,parent:d,orig:r}}function Jr(t,e,i,s){const n=e.poly.length,o=new Array(n).fill(0);if(!t?.length)return o;const a=new Set,r=[];for(let l=0;l0?(o[l]=gr(c.cm),a.add(c.key)):r.push(l)}if(!r.length)return o;const l=s>0?s:1,c=Math.max(.5*i,1e-9)*l,h=$r(t,l).filter(t=>t.w.cm>0);for(let t=r.length-1;t>=0;t--){const i=r[t],s=e.poly[i],a=e.poly[(i+1)%n],d=Sr(s,a);let u=null;for(const t of h){const e=kr(t.w,l);if(!e||!Mr(Sr(e[0],e[1]),d))continue;if(sl(s[0],s[1],e[0][0],e[0][1],e[1][0],e[1][1])>c||sl(a[0],a[1],e[0][0],e[0][1],e[1][0],e[1][1])>c)continue;const i=Math.hypot(a[0]-s[0],a[1]-s[1]),n=Math.hypot(e[1][0]-e[0][0],e[1][1]-e[0][1]),o=Math.max(0,n-i);(!u||oc||sl(n[0],n[1],e[0][0],e[0][1],e[1][0],e[1][1])>c)continue;i=!0,o=Math.max(0,Math.hypot(e[1][0]-e[0][0],e[1][1]-e[0][1])-_)}else{if(sl(t.x,t.y,s[0],s[1],n[0],n[1])>c)continue;o=Math.hypot(t.x-d,t.y-u)}(!p||i&&!p.exact||i===p.exact&&ot?.id===e),n=hi(s);if(!n)return[];const o=[];for(const s of t||[]){if(!s||s.id===e)continue;const t=hi(s);if(t)for(const e of Cs(n,t,i))o.push(e)}return o}(t,e,qr(n,r)),h=function(t,e,i,s,n){const o=qr(s,n),a=[];for(let r=0;rsl(h,d,t[0],t[1],t[2],t[3])<=o);a.push(u?"shared":"outer")}return a}(l.poly,c,s,n,r),d=Jr(i,l,n,r),u=d.map((t,e)=>h[e]&&t>0?fr(t,o,a)/2:0);return{...l,kinds:h,cms:d,offsets:u}}function Qr(t,e,i,s,n,o,a=1){const r=[];for(const l of t||[]){if(!l?.id)continue;const c=Zr(t,l.id,e,i,s,n,o,a);if(c)for(let t=0;t0&&(r=Ar(r,t.a,t.b,t.cm,s,a));return r}function el(t,e,i,s,n,o,a=1){if(!e?.length)return[];const r=[],l=new Set;for(const c of Qr(t,e,i,s,n,o,a))!c.open&&c.cm>0&&!l.has(c.key)&&(l.add(c.key),r.push(c));const c=[];for(const r of t||[]){if(!r?.id)continue;const l=Zr(t,r.id,e,i,s,n,o,a);if(l)for(let t=0;t0)||null===l.kinds[i]){t++;continue}let o=t;for(;o+10&&c.push({a:[h[0],h[1]],b:[d[0],d[1]],key:wr(h,d,s,a),cm:n,len:u}),t=o+1}}}c.sort((t,e)=>e.len-t.len||t.key.localeCompare(e.key));const h=[],d=new Set,u=new Set,p=4*qr(s,a);for(const t of c){const e=r.filter(e=>!u.has(e.key)&&e.cm===t.cm&&Mr(Sr(e.a,e.b),Sr(t.a,t.b))&&sl(e.a[0],e.a[1],t.a[0],t.a[1],t.b[0],t.b[1])<=p&&sl(e.b[0],e.b[1],t.a[0],t.a[1],t.b[0],t.b[1])<=p);if(e.length){for(const t of e)u.add(t.key);d.has(t.key)||(d.add(t.key),h.push(xr(t.a,t.b,t.cm,s,a)))}}for(const t of r)u.has(t.key)||d.has(t.key)||(d.add(t.key),h.push(xr(t.a,t.b,t.cm,s,a)));return h}function il(t,e,i,s,n,o,a,r=1){const l=qr(n,r),c=(s[0]+s[2])/2,h=(s[1]+s[3])/2,d=Sr([s[0],s[1]],[s[2],s[3]]);let u=null;for(const s of Qr(t,e,i,n,o,a,r)){if(!Mr(Sr(s.a,s.b),d))continue;const t=sl(c,h,s.a[0],s.a[1],s.b[0],s.b[1]);t>4*l||(!u||tt?.id===e),c=hi(l);if(!c||c.length<3)return null;if(!i?.length)return c.map(t=>[t[0],t[1]]);const h=Zr(t,e,i,s,n,o,a,r);return h&&h.offsets.some(t=>t>0)&&Vr(h.poly,h.offsets)||c.map(t=>[t[0],t[1]])}function ol(t){const e=t.map(t=>[t[0],t[1]]);return e.push([t[0][0],t[0][1]]),[e]}function al(t,e=1){if(!Array.isArray(t)||t.length<3)return null;const i=Number.isFinite(e)&&e>0?e:1,s=1e-12*Math.max(1,i),n=[];for(const e of t){if(!Array.isArray(e)||e.length<2)return null;const t=Number(e[0]),i=Number(e[1]);if(!Number.isFinite(t)||!Number.isFinite(i))return null;const o=Math.round(t/s)*s,a=Math.round(i/s)*s;if(!Number.isFinite(o)||!Number.isFinite(a))return null;n.push([Object.is(o,-0)?0:o,Object.is(a,-0)?0:a])}return Math.abs(jr(n))>s*s?n:null}function rl(t,e,i,s){if(sl(t[0],t[1],e[0],e[1],i[0],i[1])>s)return!1;const n=i[0]-e[0],o=i[1]-e[1],a=(t[0]-e[0])*n+(t[1]-e[1])*o,r=n*n+o*o,l=s*Math.sqrt(r);return a>=-l&&a<=r+l}function ll(t,e,i){const s=[],n=[];for(let o=0;oi*i))continue;const d=i/Math.sqrt(h),u=[0,1];for(const t of e)for(const e of[t.a,t.b]){if(!rl(e,a,r,i))continue;const t=((e[0]-a[0])*l+(e[1]-a[1])*c)/h;t>d&&t<1-d&&u.push(t)}u.sort((t,e)=>t-e);const p=u.filter((t,e)=>0===e||Math.abs(t-u[e-1])>d);for(let t=0;t=3&&n.length===s.length?{poly:s,offsets:n}:null}function cl(t,e,i,s,n,o,a){const r=(t||[]).map(hi).filter(t=>!!t&&t.length>=3);if(!r.length)return null;let l=si(ol(r[0]));for(let t=1;t"outer"===t.kind&&t.half>0),h=4*qr(s,a);let d=null;for(const t of function(t){const e=[];for(const i of Array.isArray(t)?t:[])if(Array.isArray(i))for(const t of i){if(!Array.isArray(t)||t.length<4)continue;const i=t.slice(0,-1).map(t=>[t[0],t[1]]);i.length>=3&&e.push(i)}return e}(l)){const e=ll(t,c,h);if(!e||!e.offsets.some(t=>t>0))continue;const i=_l(e.poly,e.offsets),s=Vr(e.poly,e.offsets);if(!i||!s)continue;const n=oi(ol(i),ol(s));d=d?si(d,n):n}return{centre:l,shell:d||[]}}function hl(t){if(!t)return"";let e="";for(const i of t)if(Array.isArray(i))for(const t of i){if(!Array.isArray(t)||t.length<4)continue;const i=t.slice(0,t.length-1);i.length<3||(e+=(e?" ":"")+Kr(i.map(t=>[t[0],t[1]])))}return e}function dl(t,e,i,s=[],n,o,a,r=1,l=[]){if(!e?.length&&!l.length)return null;const c=[];let h=0;for(const s of t||[]){if(!s?.id)continue;const l=Zr(t,s.id,e,i,n,o,a,r);if(!l||l.poly.length<3||!l.offsets.some(t=>t>0))continue;for(const t of l.offsets)t>0&&(h=Math.max(h,2*t));const d=_l(l.poly,l.offsets),u=Vr(l.poly,l.offsets);d&&c.push({outset:d,inset:u})}for(const t of l){const e=t.map(t=>t[0]),i=t.map(t=>t[1]);if(e.length){const s=Math.min(Math.max(...e)-Math.min(...e),Math.max(...i)-Math.min(...i)),n=Math.min(...t.map((e,i)=>{const s=t[(i+1)%t.length];return Math.hypot(s[0]-e[0],s[1]-e[1])}));h=Math.max(h,t.length>16?s:n)}}const d=function(t,e,i,s,n,o,a){if(!e?.length||!i?.length)return[];const r=4*qr(s,a),l=new Map;for(const r of Qr(t,e,i,s,n,o,a))!r.open&&r.half>0&&!l.has(r.key)&&l.set(r.key,r);const c=[...l.values()];if(c.length<2)return[];const h=[];for(const t of i)for(const e of[[t[0],t[1]],[t[2],t[3]]])h.some(t=>Math.hypot(t[0]-e[0],t[1]-e[1])<=r)||h.push(e);const d=[],u=(t,e)=>{let i=0,s=0;if(Math.hypot(t.a[0]-e[0],t.a[1]-e[1])<=r)i=t.b[0]-t.a[0],s=t.b[1]-t.a[1];else{if(!(Math.hypot(t.b[0]-e[0],t.b[1]-e[1])<=r))return null;i=t.a[0]-t.b[0],s=t.a[1]-t.b[1]}const n=Math.hypot(i,s);return n>r?[i/n,s/n]:null};for(const t of h){const e=c.map(e=>({iv:e,u:u(e,t)})).filter(t=>!!t.u);for(let i=0;i4*_||d.push(a>0?[t.slice(),h,p,u]:[t.slice(),u,p,h])}}return d}(t,e,i,n,o,a,r),u=s.length?gl(t,e,i,n,o,a,r):null;try{const p=cl(t,e,i,n,o,a,r),_=p?p.shell?.length?si(p.centre,p.shell):p.centre:[],g=t=>{const e=ol(t.outset);return t.inset?oi(e,ol(t.inset)):e};let m=null;for(const t of c)try{const e=g(t);m=m?si(m,e):e}catch{}if(p)for(const s of pl(t,e,i,n,o,a,r))try{const t=ni(ol(s.quad),p.centre);m=m?si(m,t):t}catch{}m=function(t,e,i=1,s=si){let n=t;for(const t of e||[]){const e=al(t,i);if(e)try{const t=ol(e);n=n?s(n,t):t}catch{}}return n}(m,d,r),m&&p&&(m=ni(m,p.centre)),p?.shell?.length&&(m=m?si(m,p.shell):p.shell);for(const t of s){if(!(t.length>0))continue;const e=vl(u,t,!0);if(!e.negative&&!e.positive)continue;const i=t.angle*Math.PI/180,s=Math.cos(i),o=Math.sin(i),a=-o,l=s,c=t.length/2,d=1.25*Math.max(h,n*r),p=[[t.x-s*c-a*d,t.y-o*c-l*d],[t.x+s*c-a*d,t.y+o*c-l*d],[t.x+s*c+a*d,t.y+o*c+l*d],[t.x-s*c+a*d,t.y-o*c+l*d]];m&&(m=oi(m,ol(p)))}for(const t of l)t.length<3||(m=m?si(m,ol(t)):[ol(t)]);return{geom:m||[],paperGeom:_,depthUnits:h,openingIndex:u}}catch{return null}}function ul(t,e,i,s=[],n,o,a,r=1,l=[]){if(!e?.length&&!l.length)return null;const c=dl(t,e,i,s,n,o,a,r,l),h=c?hl(c.geom):"",d=c?hl(c.paperGeom):"";return c&&h?{d:h,paperD:d,depthUnits:c.depthUnits,fillRule:"evenodd"}:null}function pl(t,e,i,s,n,o,a=1){if(!e?.length)return[];const r=new Set,l=[];for(const c of t||[]){if(!c?.id)continue;const h=Zr(t,c.id,e,i,s,n,o,a);if(!h)continue;const d=h.poly;for(let t=0;t0))continue;const p=wr(e,i,s,a);if(r.has(p))continue;r.add(p);const _=fr(u,n,o),[g,m]=Wr(d,t),f=-g,v=-m,y=_/2,b=[[e[0]+f*y,e[1]+v*y],[i[0]+f*y,i[1]+v*y],[i[0]+g*y,i[1]+m*y],[e[0]+g*y,e[1]+m*y]];l.push({key:p,kind:c,cm:u,quad:b,a:[e[0],e[1]],b:[i[0],i[1]],depthUnits:_})}}return l}function _l(t,e){const i=t?.length||0;if(i<3||e.length!==i)return null;if(e.every(t=>!(t>0)))return t.map(t=>[t[0],t[1]]);Yr(t),e.slice().reverse();const s=[];for(let n=0;n0||r>0)){s.push([t[n][0],t[n][1]]);continue}if(a>0!=r>0){const e=t[n],i=a>0?[e[0]-l*a,e[1]-c*a]:[e[0],e[1]],o=r>0?[e[0]-h*r,e[1]-d*r]:[e[0],e[1]];s.push(i),Math.hypot(o[0]-i[0],o[1]-i[1])>1e-9&&s.push(o);continue}if(Ur(b,w)){const e=t[n],i=[e[0]-l*a,e[1]-c*a],o=[e[0]-h*r,e[1]-d*r];s.push(i),Math.hypot(o[0]-i[0],o[1]-i[1])>1e-9&&s.push(o);continue}const $=Gr(k,b,x,w),S=Math.max(a,r,1e-9);if($){if(Math.hypot($[0]-t[n][0],$[1]-t[n][1])<=4*S){s.push($);continue}}a>0&&s.push([t[n][0]-l*a,t[n][1]-c*a]),r>0&&s.push([t[n][0]-h*r,t[n][1]-d*r])}return s.length>=3?s:null}function gl(t,e,i,s,n,o,a=1){const r=[];for(const l of t||[]){if(!l?.id)continue;const c=Zr(t,l.id,e,i,s,n,o,a);if(!c)continue;const h=Math.abs(Pi(c.poly));for(let t=0;t[Math.max(e,t.x0),Math.min(i,t.x1)]).filter(t=>t[1]-t[0]>s).sort((t,e)=>t[0]-e[0]||t[1]-e[1]);if(!n.length)return{coverage:0,full:!1};let o=n[0][0],a=n[0][1],r=0,l=o<=e+s;for(let t=1;t=i-s,{coverage:r,full:l}}function fl(t,e){return Number(e.full)-Number(t.full)||t.faceDistance-e.faceDistance||t.area-e.area||t.roomId.localeCompare(e.roomId)}function vl(t,e,i=!1){const s=Number(e?.x),n=Number(e?.y),o=Number(e?.angle),a=Number(e?.length);if(!([s,n,o,a].every(Number.isFinite)&&a>0))return{negative:null,positive:null};const r=o*Math.PI/180,l=Math.cos(r),c=Math.sin(r),h=-c,d=l,u=a/2,p=Math.max(1e-9,t.adjacencyEps),_=new Map;let g=0;for(const e of t.edges){if(i&&!(e.half>0))continue;if(!Pr(e.a,e.b,o))continue;const[t,a]=yr(e.a,e.b);if(Math.abs((s-e.a[0])*a-(n-e.a[1])*t)>p)continue;const r=(e.a[0]-s)*l+(e.a[1]-n)*c,m=(e.b[0]-s)*l+(e.b[1]-n)*c,f=Math.max(-u,Math.min(r,m)),v=Math.min(u,Math.max(r,m));if(v-f<=p)continue;const y=e.inward[0]*h+e.inward[1]*d>=0?1:-1,b=((e.a[0]+e.b[0])/2-s)*h+((e.a[1]+e.b[1])/2-n)*d,w=Math.abs(b+y*e.half),k=`${y}|${e.roomId}`,x={x0:f,x1:v,half:e.half,cm:e.cm,key:e.key,axis:[t,a]},$=_.get(k);$?($.pieces.push(x),$.faceDistance=Math.min($.faceDistance,w)):_.set(k,{roomId:e.roomId,side:y,order:g++,pieces:[x],faceDistance:w,area:e.area,coverage:0,full:!1})}for(const t of _.values()){const e=ml(t.pieces,-u,u,p);t.coverage=e.coverage,t.full=e.full}const m=t=>{const e=[..._.values()].filter(e=>e.side===t&&e.coverage>p);return e.sort(fl),e[0]||null};return{negative:m(-1),positive:m(1)}}function yl(t,e){const i=vl(t,e),s=[i.negative,i.positive].filter(t=>!!t).sort((t,e)=>t.order-e.order);if(!s.length)return{ox:0,oy:0,cm:0,side:-1};const n=s[0],o=e.flip_v?-n.side:n.side,a=(-1===o?i.negative:i.positive)||n,r=[...a.pieces].sort((t,e)=>(t.x0<=0&&t.x1>=0?0:Math.min(Math.abs(t.x0),Math.abs(t.x1)))-(e.x0<=0&&e.x1>=0?0:Math.min(Math.abs(e.x0),Math.abs(e.x1)))||e.x1-e.x0-(t.x1-t.x0)||t.key.localeCompare(e.key))[0];if(!(r.half>0&&r.cm>0))return{ox:0,oy:0,cm:0,side:o};const l=e.angle*Math.PI/180,c=-Math.sin(l),h=Math.cos(l);return{ox:c*o*r.half,oy:h*o*r.half,cm:r.cm,side:o}}function bl(t,e){const i=1e-9,s=e.filter(t=>Number.isFinite(t.x0)&&Number.isFinite(t.x1)&&Number.isFinite(t.half)&&t.x1>t.x0&&t.half>0);if(!s.length)return"";const n=s.flatMap(t=>[t.x0,t.x1]).sort((t,e)=>t-e),o=[];for(const t of n){const e=o[o.length-1];(void 0===e||t>e+i)&&o.push(t)}const a=[];for(let t=0;t+1e+i))continue;const r=(e+n)/2,l=s.reduce((t,e)=>r>=e.x0-i&&r<=e.x1+i?Math.max(t,e.half):t,0);if(!(l>0))continue;const c=a[a.length-1];c&&e<=c.x1+i&&Math.abs(l-c.half)<=i?c.x1=n:a.push({x0:e,x1:n,half:l})}const r=[];for(const t of a){const e=r[r.length-1],s=e?.[e.length-1];s&&t.x0<=s.x1+i?(t.x0=s.x1,e.push(t)):r.push([t])}return r.map(e=>{const i=e[0],s=e[e.length-1],n=Math.min(.25*Math.min(...e.map(t=>t.half)),.75),o=-t*n,a=[];if(1===t){a.push(`M ${i.x0} ${o} L ${s.x1} ${o}`);for(let t=e.length-1;t>=0;t--){const i=e[t];a.push(`L ${i.x1} ${i.half} L ${i.x0} ${i.half}`)}}else{a.push(`M ${s.x1} ${o} L ${i.x0} ${o}`);for(const t of e)a.push(`L ${t.x0} ${-t.half} L ${t.x1} ${-t.half}`)}return a.push("Z"),a.join(" ")}).join(" ")}function wl(t,e,i,s){if(!s)return i;const n=t.angle*Math.PI/180,o=Math.cos(n),a=Math.sin(n),r=[],l=1e-9;for(const n of i){const[i,c]=n.axis,h=o*i+a*c;if(Math.abs(h)<=l)continue;const d=t.x*i+t.y*c,u=d+h*n.x0,p=d+h*n.x1,_=Math.min(u,p),g=Math.max(u,p),m=`${n.key}|${e}`,f=s.get(m)||[];let v=[[_,g]];for(const[t,e]of f){const i=[];for(const[s,n]of v)e<=s+l||t>=n-l?i.push([s,n]):(t>s+l&&i.push([s,Math.min(n,t)]),et[0]-e[0]||t[1]-e[1]),b=[];for(const t of y){const e=b[b.length-1];e&&t[0]<=e[1]+l?e[1]=Math.max(e[1],t[1]):b.push([t[0],t[1]])}s.set(m,b)}return r}function kl(t,e){const i=new Map;return e.map(e=>function(t,e,i){const s=vl(t,e,!0),n=s.negative,o=s.positive;if(!n&&!o)return null;let a;if(n&&o)a=[{candidate:n,side:-1},{candidate:o,side:1}];else{const t=n||o;a=[{candidate:t,side:-1},{candidate:t,side:1}]}const r=a.map(({candidate:t,side:s})=>({candidate:t,side:s,pieces:wl(e,s,t.pieces,i)})),l=r.map(({candidate:t,side:e,pieces:i})=>({side:e,roomId:t.roomId,d:bl(e,i)})),c=r.flatMap(({pieces:t})=>t);if(!c.length)return null;const h=Math.max(...c.map(t=>t.half));return{faces:l,minY:-h,maxY:h,wallKey:[...new Set(c.map(t=>t.key))].sort().join("|")}}(t,e,i))}const xl=150;function $l(t){return Number.isFinite(t)?Math.max(1,Math.min(xl,t)):1}function Sl(t){return((Number.isFinite(Number(t))?Number(t):0)%90+90)%90}const Ml=t=>{const e=t.map(t=>[t[0],t[1]]);return!e.length||e[0][0]===e[e.length-1][0]&&e[0][1]===e[e.length-1][1]||e.push([...e[0]]),[e]};function Cl(t){const e=[];for(const i of t||[])for(const t of i||[]){const i=(t||[]).filter(t=>Array.isArray(t)&&t.length>=2);i.length<4||e.push(`M ${i.slice(0,-1).map(t=>`${t[0]} ${t[1]}`).join(" L ")} Z`)}return e.join(" ")}function Dl(t,e,i,s,n){return Fr({a:t,b:e,halfDepth:fr(i,s,n)/2})}function Tl(t,e,i){const s=Number(e)>0?Number(e):5,n=$l(t.cm)/s*i,o=t.center[0],a=t.center[1];if("circle"===t.shape){const t=n/2;return Array.from({length:96},(e,i)=>{const s=i/96*Math.PI*2;return[o+Math.cos(s)*t,a+Math.sin(s)*t]})}const r=n/2,l=Sl(t.angle)*Math.PI/180,c=Math.cos(l),h=Math.sin(l);return[[-r,-r],[r,-r],[r,r],[-r,r]].map(([t,e])=>[o+t*c-e*h,a+t*h+e*c])}function Pl(t,e,i=1e-9){if(!e.length)return[t];let s=[Ml(t)];try{for(const t of e){const e=t.b[0]-t.a[0],n=t.b[1]-t.a[1],o=Math.hypot(e,n);if(!(o>i))continue;const a=e/o,r=n/o,l=-r,c=a,h=1.25*Math.max(Number(t.depth)||0,4*i),d=Math.max(2*i,1e-9*o),u=[[t.a[0]-a*d-l*h,t.a[1]-r*d-c*h],[t.b[0]+a*d-l*h,t.b[1]+r*d-c*h],[t.b[0]+a*d+l*h,t.b[1]+r*d+c*h],[t.a[0]-a*d+l*h,t.a[1]-r*d+c*h]];s=oi(s,Ml(u))}return Ol(s)}catch{return[t]}}function Rl(t,e,i,s=Math.max(2e-4*i,1e-9),n=[]){const o=[],a=[],r=new Map;for(const t of n){const e=r.get(t.hostId)||[];e.push(t),r.set(t.hostId,e)}const l=[],c=[],h=[];for(const s of t.room_drafts||[])for(let t=0;t+1Tl(t,e,i)),u=Nr([...o,...a],s).flatMap(t=>Pl(t,n,s));return{drafts:l,partitions:c,columns:d,patches:u,all:[...l,...h,...u,...d]}}function Al(t){try{const e=t.filter(t=>t.length>=3).map(t=>Ml(t));return e.length?si(e[0],...e.slice(1)):null}catch{return null}}const Il=t=>`M ${t.map(t=>`${t[0]} ${t[1]}`).join(" L ")} Z`;function El(t,e){const i=Al(t.filter(t=>t.length>=3)),s=Al(e.filter(t=>t.length>=3));if(!i)return[];if(!s)return[];try{return function(t){const e=[];for(const i of t||[]){if(zl([i])<=1e-6)continue;const t=[];for(const e of i||[]){const i=(e||[]).filter(t=>Array.isArray(t)&&t.length>=2);i.length<4||t.push(Il(i.slice(0,-1)))}t.length&&e.push(t.join(" "))}return e}(ni(i,s))}catch{return[]}}function Fl(t,e){if(!e.length)return[Ml(t)];try{const i=Al(e);if(i)return oi(Ml(t),i)}catch{}let i=[Ml(t)];for(const t of e)if(!(t.length<3))try{i=oi(i,Ml(t))}catch{}return i}function zl(t){let e=0;for(const i of t||[])if(i?.length){e+=Pi(i[0]||[]);for(let t=1;t=4&&e.push(t.slice(0,-1).map(t=>[t[0],t[1]]))}return e}function Hl(t,e){let i=!1;for(let s=0,n=e.length-1;st[1]!=l>t[1]&&t[0]<(r-o)*(t[1]-a)/(l-a||1e-12)+o&&(i=!i)}return i}function Nl(t,e,i){return function(t,e){for(const i of e||[]){const e=i?.[0];if(!e?.length||!Hl(t,e))continue;let s=!1;for(let e=1;eHl(t,e))}function Ll(t,e,i){if(Math.hypot(t.center[0]-e.center[0],t.center[1]-e.center[1])>i)return!1;if(Math.abs($l(t.cm)-$l(e.cm))>1e-6)return!1;if(t.shape!==e.shape)return!0;if("circle"===t.shape||"circle"===e.shape)return!0;const s=Math.abs(Sl(t.angle)-Sl(e.angle));return Math.min(s,90-s)<=1e-6}const Bl=1e3;function ql(t,e){const i=Number(t),s=Number.isFinite(i)&&i>0?i:1,n=s>=1?e:e*s,o=s>=1?e/s:e;return{x:(e-n)/2,y:(e-o)/2,w:n,h:o}}const jl=.01,Wl=100;function Ul(t,e=1e3){const i=ql(t?.plan_aspect,e),s=Number(t?.plan_scale),n=Number.isFinite(s)&&s>0?Math.min(Wl,Math.max(jl,s)):1,o=Number(t?.plan_scale_x),a=Number(t?.plan_scale_y),r=Number.isFinite(o)&&o>0?Math.min(Wl,Math.max(jl,o)):n,l=Number.isFinite(a)&&a>0?Math.min(Wl,Math.max(jl,a)):n,c=Number(t?.plan_x),h=Number(t?.plan_y),d=sr(t?.plan_angle);return{x:i.x+(Number.isFinite(c)?ic(c):0)*e,y:i.y+(Number.isFinite(h)?ic(h):0)*e,w:i.w*r,h:i.h*l,...d?{angle:d}:{}}}function Gl(t){if(null==t.x||null==t.y)return{x:t.x,y:t.y,w:t.w,h:t.h};const e=Number(t.w)||0,i=Number(t.h)||0;return{x:e<0?t.x+e:t.x,y:i<0?t.y+i:t.y,w:Math.abs(e),h:Math.abs(i)}}function Vl(t){return t&&Array.isArray(t.spaces)?t.spaces.map(t=>{const e=Bl,i=function(t){return Array.isArray(t)&&4===t.length&&t.every(t=>Number.isFinite(t))&&t[2]>1e-6&&t[3]>1e-6?t:[0,0,1,1]}(t.view_box);return{id:t.id,title:t.title,vb:[i[0]*Bl,i[1]*e,i[2]*Bl,i[3]*e],bg:t.plan_url?{href:Is(t.plan_url),...Ul(t,Bl)}:null,rooms:(t.rooms||[]).map(t=>{const i={...t,...Gl(t)};return{id:i.id,name:i.name,area:i.area??null,open_to:i.open_to||void 0,settings:i.settings||void 0,x:null!=i.x?i.x*Bl:void 0,y:null!=i.y?i.y*e:void 0,w:null!=i.w?i.w*Bl:void 0,h:null!=i.h?i.h*e:void 0,poly:i.poly?i.poly.map(t=>[t[0]*Bl,t[1]*e]):void 0}}),room_drafts:(t.room_drafts||[]).map(t=>({id:t.id,points:(t.points||[]).map(t=>[t[0]*Bl,t[1]*e]),segments:(t.segments||[]).map(t=>({cm:Number(t.cm)}))})),partitions:(t.partitions||[]).map(t=>({id:t.id,a:[t.a[0]*Bl,t.a[1]*e],b:[t.b[0]*Bl,t.b[1]*e],cm:Number(t.cm)})),wall_columns:(t.wall_columns||[]).map(t=>({id:t.id,shape:"circle"===t.shape?"circle":"square",center:[t.center[0]*Bl,t.center[1]*e],cm:Number(t.cm),..."circle"===t.shape?{}:{angle:Sl(t.angle)}}))}}):[]}const Kl=5e3,Yl=Kl*Bl,Xl=240,Jl=Bl/Xl,Zl=1/Xl;function Ql(t){if(!Number.isFinite(t))return t;const e=Math.round(t*Xl/Bl)*Bl/Xl;return Math.abs(e-t)<=1e-9*Jl?t:e}function tc(t){return{x:Ql(t.x),y:Ql(t.y)}}function ec(t){return Number.isFinite(t)?Math.min(Yl,Math.max(-Yl,t)):0}function ic(t){return Number.isFinite(t)?Math.min(Kl,Math.max(-Kl,t)):0}const sc=1/3,nc=200;function oc(t){let e=1/0,i=1/0,s=-1/0,n=-1/0;for(const o of t){const t=Number(o[0]),a=Number(o[1]);Number.isFinite(t)&&Number.isFinite(a)&&(ts&&(s=t),a>n&&(n=a))}return e>s?null:{minX:e,minY:i,maxX:s,maxY:n}}function ac(t){return t.poly&&t.poly.length?oc(t.poly):null==t.x||null==t.y?null:oc([[t.x,t.y],[t.x+(t.w||0),t.y+(t.h||0)]])}function rc(t,e){const i=[];for(const e of t.rooms||[]){const t=ac(e);t&&i.push(t)}if(t.bg){const e=oc(cr(t.bg));e&&i.push(e)}for(const t of e||[])if(Array.isArray(t)){const e=oc([t]);e&&i.push(e)}else i.push(t);return i}const lc=t=>{if(!t.length)return 0;const e=[...t].sort((t,e)=>t-e),i=e.length>>1;return e.length%2?e[i]:(e[i-1]+e[i])/2},cc=t=>{let e=1/0,i=1/0,s=-1/0,n=-1/0;for(const o of t)o.minXs&&(s=o.maxX),o.maxY>n&&(n=o.maxY);return e>s||i>n?null:{x:e,y:i,w:s-e,h:n-i}};function hc(t,e){let{x:i,y:s,w:n,h:o}=t;n<30&&(i=i+n/2-100,n=nc),o<30&&(s=s+o/2-100,o=nc);const a=Math.max(n,o)*e;return{x:i-a,y:s-a,w:n+2*a,h:o+2*a}}function dc(t,e={}){const i=e.pad??.05,s=e.k??10,n=e.minSpread??50,o=t.filter(t=>Number.isFinite(t.minX)&&Number.isFinite(t.minY)&&Number.isFinite(t.maxX)&&Number.isFinite(t.maxY)&&Math.abs(t.minX)<=Yl&&Math.abs(t.maxX)<=Yl&&Math.abs(t.minY)<=Yl&&Math.abs(t.maxY)<=Yl);if(!o.length)return{core:null,all:null,outliers:0};const a=cc(o);if(o.length<4){const t=hc(a,i);return{core:t,all:t,outliers:0}}const r=o.map(t=>(t.minX+t.maxX)/2),l=o.map(t=>(t.minY+t.maxY)/2),c=lc(r),h=lc(l),d=o.map((t,e)=>Math.max(Math.abs(r[e]-c),Math.abs(l[e]-h))),u=Math.max(((t,e)=>t.length?t[Math.min(t.length-1,Math.max(0,Math.round(e*(t.length-1))))]:0)([...d].sort((t,e)=>t-e),.75),n),p=d.map(t=>t>s*u),_=p.filter(Boolean).length,g=_&&_<=o.length*sc?o.filter((t,e)=>!p[e]):o;return{core:hc(cc(g)||a,i),all:hc(a,i),outliers:g===o?0:_}}function uc(t,e,i=.05){const s=dc(rc(t,e),{pad:i});if(s.core)return s.core;const n=t.vb&&4===t.vb.length&&t.vb[2]>0&&t.vb[3]>0?t.vb:[0,0,Bl,Bl];return{x:n[0],y:n[1],w:n[2],h:n[3]}}function pc(t){const e=uc(t);return{x:e.x+e.w/2,y:e.y+e.h/2}}function _c(t){const e=[];for(const i of t.rooms||[]){const t=ac(i);t&&e.push(t)}const i=dc(e,{pad:0}).core;return i?Math.max(Bl,Math.min(Yl,Math.max(i.w,i.h))):Bl}function gc(t,e,i,s=1){const n=Number(i),o=Number.isFinite(s)&&s>0?s:1;return!Number.isFinite(n)||n<=0?t*o:t*_c(e)*o/n}const mc=[1,2,5,10,20,50,100,200,500,1e3];function fc(t){if(t.poly&&t.poly.length){const e=t.poly.map(t=>t[0]),i=t.poly.map(t=>t[1]),s=Math.min(...e),n=Math.min(...i);return{x:s,y:n,w:Math.max(...e)-s,h:Math.max(...i)-n}}return{x:t.x??0,y:t.y??0,w:t.w??0,h:t.h??0}}function vc(t){if(t.poly){const e=t.poly.length;return[t.poly.reduce((t,e)=>t+e[0],0)/e,t.poly.reduce((t,e)=>t+e[1],0)/e]}return[t.x+t.w/2,t.y+.1*Math.min(t.w,t.h)]}const yc=["furniture","appliance","sanitary","other"],bc=[{id:"sofa",group:"furniture",w:220,h:90,g:[["r",0,0,1,1],["l",.09,.26,.91,.26],["l",.09,.26,.09,1],["l",.91,.26,.91,1],["l",.5,.26,.5,1]]},{id:"armchair",group:"furniture",w:90,h:85,g:[["r",0,0,1,1],["l",.14,.28,.86,.28],["l",.14,.28,.14,1],["l",.86,.28,.86,1]]},{id:"coffee_table",group:"furniture",w:110,h:60,g:[["r",0,0,1,1],["r",.08,.14,.84,.72]]},{id:"table_dining",group:"furniture",w:140,h:80,g:[["r",0,0,1,1],["r",.06,.11,.88,.78]]},{id:"table_round",group:"furniture",w:120,h:120,g:[["e",.5,.5,.5,.5],["e",.5,.5,.41,.41]]},{id:"chair",group:"furniture",w:45,h:45,g:[["r",0,0,1,.18],["r",.06,.18,.88,.8]]},{id:"desk",group:"furniture",w:120,h:60,g:[["r",0,0,1,1],["r",.63,.07,.31,.86],["l",.63,.5,.94,.5]]},{id:"bed_double",group:"furniture",w:160,h:200,g:[["r",0,0,1,1],["r",0,0,1,.07],["r",.06,.1,.4,.15],["r",.54,.1,.4,.15],["l",0,.33,1,.33]]},{id:"bed_single",group:"furniture",w:90,h:200,g:[["r",0,0,1,1],["r",0,0,1,.07],["r",.15,.1,.7,.15],["l",0,.33,1,.33]]},{id:"nightstand",group:"furniture",w:45,h:40,g:[["r",0,0,1,1],["r",.12,.14,.76,.33],["r",.12,.53,.76,.33]]},{id:"wardrobe",group:"furniture",w:100,h:60,g:[["r",0,0,1,1],["l",0,.72,1,.72],["l",.5,.72,.5,1]]},{id:"bookshelf",group:"furniture",w:80,h:30,g:[["r",0,0,1,1],["l",.34,0,.34,1],["l",.67,0,.67,1]]},{id:"fridge",group:"appliance",w:60,h:65,g:[["r",0,0,1,1],["l",0,.36,1,.36],["l",.83,.44,.83,.64]]},{id:"stove",group:"appliance",w:60,h:60,g:[["r",0,0,1,1],["e",.29,.31,.15,.15],["e",.71,.31,.15,.15],["e",.29,.71,.15,.15],["e",.71,.71,.15,.15]]},{id:"dishwasher",group:"appliance",w:60,h:60,g:[["r",0,0,1,1],["r",.1,.12,.8,.76],["e",.5,.5,.27,.27],["e",.5,.5,.13,.13]]},{id:"washer",group:"appliance",w:60,h:60,g:[["r",0,0,1,1],["l",.08,.17,.92,.17],["e",.5,.57,.3,.3],["e",.5,.57,.14,.14]]},{id:"dryer",group:"appliance",w:60,h:60,g:[["r",0,0,1,1],["l",.08,.17,.92,.17],["e",.5,.57,.3,.3],["p",.36,.5,.5,.64,.64,.5]]},{id:"tv",group:"appliance",w:120,h:30,g:[["r",0,0,1,.42],["l",.5,.42,.5,.72],["l",.3,.72,.7,.72]]},{id:"ac",group:"appliance",w:90,h:25,g:[["r",0,0,1,1],["l",.05,.55,.95,.55],["l",.05,.79,.95,.79]]},{id:"water_heater",group:"appliance",w:45,h:45,g:[["e",.5,.5,.5,.5],["e",.5,.5,.31,.31]]},{id:"toilet",group:"sanitary",w:40,h:70,g:[["r",.06,0,.88,.2],["e",.5,.58,.37,.35],["e",.5,.58,.22,.2]]},{id:"bathtub",group:"sanitary",w:170,h:75,g:[["r",0,0,1,1],["r",.05,.11,.77,.78],["e",.89,.5,.045,.1]]},{id:"shower",group:"sanitary",w:90,h:90,g:[["r",0,0,1,1],["l",0,0,1,1],["l",1,0,0,1],["e",.5,.5,.08,.08]]},{id:"sink",group:"sanitary",w:60,h:45,g:[["r",0,0,1,1],["e",.5,.6,.34,.3],["e",.5,.15,.07,.07]]},{id:"kitchen_sink",group:"sanitary",w:80,h:60,g:[["r",0,0,1,1],["r",.06,.24,.44,.64],["r",.54,.24,.4,.64],["e",.5,.12,.06,.06]]},{id:"bidet",group:"sanitary",w:40,h:55,g:[["e",.5,.5,.44,.5],["e",.5,.5,.26,.3]]},{id:"stairs",group:"other",w:100,h:280,g:[["r",0,0,1,1],["l",0,.111,1,.111],["l",0,.222,1,.222],["l",0,.333,1,.333],["l",0,.444,1,.444],["l",0,.556,1,.556],["l",0,.667,1,.667],["l",0,.778,1,.778],["l",0,.889,1,.889],["l",.5,.93,.5,.06],["p",.38,.16,.5,.06,.62,.16]]},{id:"fireplace",group:"other",w:120,h:40,g:[["r",0,0,1,1],["p",.22,1,.22,.42,.78,.42,.78,1]]},{id:"plant",group:"other",w:40,h:40,g:[["e",.5,.5,.22,.22],["l",.5,.28,.5,.02],["l",.5,.72,.5,.98],["l",.28,.5,.02,.5],["l",.72,.5,.98,.5],["l",.34,.34,.13,.13],["l",.66,.66,.87,.87],["l",.66,.34,.87,.13],["l",.34,.66,.13,.87]]},{id:"rug",group:"other",w:200,h:140,g:[["r",0,0,1,1],["r",.06,.09,.88,.82]]}],wc=new Map(bc.map(t=>[t.id,t]));function kc(t){return t&&wc.get(t)||null}function xc(t){return bc.filter(e=>e.group===t)}function $c(t,e,i=Jl,s=1e3){const n=Number(e)>0?Number(e):5;return(Number(t)||0)/n*i/s}const Sc=5e-4,Mc=Kl;function Cc(t){return Number.isFinite(t)?Math.max(Sc,Math.min(Mc,t)):Sc}const Dc=t=>{const e=Math.round(1e3*t)/1e3;return Object.is(e,-0)?"0":String(e)};function Tc(t,e,i){const s=kc(t);if(!(s&&e>0&&i>0))return"";const n=t=>Dc(t*e),o=t=>Dc(t*i),a=[];for(const t of s.g)if("r"===t[0]){const[,e,i,s,r]=t;a.push(`M${n(e)} ${o(i)}H${n(e+s)}V${o(i+r)}H${n(e)}Z`)}else if("l"===t[0]){const[,e,i,s,r]=t;a.push(`M${n(e)} ${o(i)}L${n(s)} ${o(r)}`)}else if("e"===t[0]){const[,s,r,l,c]=t;a.push(`M${n(s-l)} ${o(r)}A${Dc(l*e)} ${Dc(c*i)} 0 0 1 ${n(s+l)} ${o(r)}A${Dc(l*e)} ${Dc(c*i)} 0 0 1 ${n(s-l)} ${o(r)}Z`)}else{const e=t.slice(1);if(e.length<4)continue;let i=`M${n(e[0])} ${o(e[1])}`;for(let t=2;t+1{let e=(t%360+360)%360;return e>180&&(e-=360),e};function Rc(t,e,i,s,n,o=0){let a=null,r=n;for(const n of s){const[s,l,c,h]=n,d=c-s,u=h-l,p=d*d+u*u;if(!p)continue;const _=Math.sqrt(p);let g=((t-s)*d+(e-l)*u)/p;g=Math.max(0,Math.min(1,g));let m=s+g*d,f=l+g*u;const v=Math.hypot(t-m,e-f);if(!(v0){const t=Math.round(g*_/o)*o;m=s+t/_*d,f=l+t/_*u}a={cx:m+y*(i/2),cy:f+b*(i/2),angle:Pc(180*Math.atan2(-y,b)/Math.PI),dist:v}}return a}function Ac(t,e,i){const s=i;return{a:[t[0]/s,t[1]/s],b:[e[0]/s,e[1]/s]}}function Ic(t,e){const i=e;return[t.a[0]*i,t.a[1]*i,t.b[0]*i,t.b[1]*i]}function Ec(t){return Array.isArray(t)&&t.length>=2&&Number.isFinite(Number(t[0]))&&Number.isFinite(Number(t[1]))}function Fc(t){if(!Array.isArray(t))return[];const e=[];for(const i of t){if(!i||"object"!=typeof i)continue;const t=i;if(!Ec(t.a)||!Ec(t.b))continue;const s=[Number(t.a[0]),Number(t.a[1])],n=[Number(t.b[0]),Number(t.b[1])];Math.hypot(n[0]-s[0],n[1]-s[1])<.001||e.push({a:s,b:n})}return e}function zc(t,e){const i=e[0],s=e[1],n=e[2]-i,o=e[3]-s,a=n*n+o*o;if(a<1e-18){return{q:[i,s],t:0,d:Math.hypot(t[0]-i,t[1]-s)}}let r=((t[0]-i)*n+(t[1]-s)*o)/a;r=Math.max(0,Math.min(1,r));const l=[i+r*n,s+r*o];return{q:l,t:r,d:Math.hypot(t[0]-l[0],t[1]-l[1])}}function Oc(t,e){return zc(t,e).q}function Hc(t,e,i,s,n){const o=zc(t,e).q;let a=o,r=1/0;for(const t of i){const e=Math.hypot(o[0]-t[0],o[1]-t[1]);e<=n&&e0?s:1,g=Math.round(p/_)*_,m=Math.max(0,Math.min(u,g))/u;return[l+h*m,c+d*m]}function Nc(t,e){const i=[],s=(t||[]).filter(t=>t?.id);for(let t=0;tt?.id),a=Fc(e);if(a.length)return Kc(a,t,i,s).map(t=>Ic(t,i));if(!n)return[];const r=[],l=(t,e)=>(t.open_to||[]).includes(e.id)||(e.open_to||[]).includes(t.id);for(let t=0;tAc([t[0],t[1]],[t[2],t[3]],e))}function qc(t,e,i,s){for(const e of t||[])e.open_to&&delete e.open_to;if(!i.length)return;const n=(e||[]).filter(t=>t?.id);new Map(n.map(t=>[t.id,t]));const o=new Map((t||[]).filter(t=>t?.id).map(t=>[t.id,t])),a=(t,e)=>{const i=o.get(t),s=o.get(e);i&&s&&((i.open_to||[]).includes(e)||(i.open_to=[...i.open_to||[],e]),(s.open_to||[]).includes(t)||(s.open_to=[...s.open_to||[],t]))};for(let t=0;tNs(i,t)<4*s)){a(n[t].id,n[e].id);break}}}for(const e of t||[])e.open_to&&!e.open_to.length&&delete e.open_to}function jc(t,e,i,s=0){const n=e[2]-e[0],o=e[3]-e[1],a=Math.hypot(n,o);if(!(a>1e-9))return null;const r=n/a,l=o/a,c=(t[0]-e[0])*r+(t[1]-e[1])*l;if(c<-s||c>a+s)return null;return Math.abs((t[0]-e[0])*l-(t[1]-e[1])*r)>i?null:Ns(t,e)}function Wc(t,e,i){const s=t[2]-t[0],n=t[3]-t[1],o=e[2]-e[0],a=e[3]-e[1],r=Math.hypot(s,n),l=Math.hypot(o,a);return r>1e-9&&l>1e-9&&(!(Math.abs(s/r*(a/l)-n/r*(o/l))>1e-6)&&(Ns([e[0],e[1]],t)<=4*i||Ns([t[0],t[1]],e)<=4*i))}function Uc(t,e,i){if(!t.length)return null;t.sort((t,e)=>t.distance-e.distance);const s=t[0];for(let n=1;ne)break;if(o.semantic!==s.semantic||!Wc(s.seg,o.seg,i))return"ambiguous"}return s}function Gc(t,e,i,s,n=1,o=15){const a=function(t,e,i,s,n=1,o=15){const[a,r]=yr([e[0],e[1]],[e[2],e[3]]);let l=0,c=1/0;const h=[(e[0]+e[2])/2,(e[1]+e[3])/2];for(const e of i){const[i,o]=yr([e[0],e[1]],[e[2],e[3]]);if(Math.abs(a*o-r*i)>.05)continue;const d=Dr(t,[e[0],e[1]],[e[2],e[3]],s,n);if(!(d>0))continue;const u=[(e[0]+e[2])/2,(e[1]+e[3])/2],p=Math.hypot(u[0]-h[0],u[1]-h[1]);p0?l:o}(t,e,i,s,n,o);return Ar(t,[e[0],e[1]],[e[2],e[3]],a,s,n)}function Vc(t,e,i){const s=[[t[0],t[1]],[t[2],t[3]]],n=[(t[0]+t[2])/2,(t[1]+t[3])/2];for(const o of e)if(!(Ns(n,o)>Math.hypot(t[2]-t[0],t[3]-t[1])&&Ns([o[0],o[1]],t)>i))for(const e of[[o[0],o[1]],[o[2],o[3]]])Ns(e,t)<=2*i&&s.push(e);return s}function Kc(t,e,i,s){const n=Fc(t);if(!n.length)return[];const o=Nc(e,s);if(!o.length)return[];const a=[],r=Math.max(4*s,1e-6);for(const t of n){const e=Ic(t,i),n=e[0],l=e[1],c=e[2]-n,h=e[3]-l,d=Math.hypot(c,h);if(d4*s||o>4*s)continue;const a=(t[0]-n)*u+(t[1]-l)*p,c=(t[2]-n)*u+(t[3]-l)*p,h=Math.max(0,Math.min(a,c)),g=Math.min(d,Math.max(a,c));if(g-ht.lo-e.lo||t.hi-e.hi);const i=[];for(const t of e){const e=i[i.length-1];e&&t.lo<=e.hi+r?e.hi=Math.max(e.hi,t.hi):i.push({...t})}for(const e of i){const i=[n+u*e.lo,l+p*e.lo],s=[n+u*e.hi,l+p*e.hi];Math.hypot(s[0]-i[0],s[1]-i[1])i.pair===t&&Math.abs(i.ux*a-i.uy*o)<=1e-6&&Math.abs((e[0]-i.origin[0])*i.uy-(e[1]-i.origin[1])*i.ux)<=c&&Math.abs((e[2]-i.origin[0])*i.uy-(e[3]-i.origin[1])*i.ux)<=c);h||(h={pair:t,origin:[e[0],e[1]],ux:o,uy:a,ranges:[]},l.push(h));const d=(e[0]-h.origin[0])*h.ux+(e[1]-h.origin[1])*h.uy,u=(e[2]-h.origin[0])*h.ux+(e[3]-h.origin[1])*h.uy;h.ranges.push({lo:Math.min(d,u),hi:Math.max(d,u)})}const h=[];for(const t of l){t.ranges.sort((t,e)=>t.lo-e.lo||t.hi-e.hi);const e=[];for(const i of t.ranges){const t=e[e.length-1];t&&i.lo<=t.hi+r?t.hi=Math.max(t.hi,i.hi):e.push({...i})}for(const s of e){const e=[t.origin[0]+t.ux*s.lo,t.origin[1]+t.uy*s.lo],n=[t.origin[0]+t.ux*s.hi,t.origin[1]+t.uy*s.hi];Math.hypot(n[0]-e[0],n[1]-e[1])>=r&&h.push(Ac(e,n,i))}}return h}function Yc(t,e,i,s){const n=Fc(t);if(!n.length)return[];if(e.length!==i.length)return n;const o=[];for(const t of n){const n=Ic(t,s),a=[n[0],n[1]],r=[n[2],n[3]];let l=a,c=r;for(let t=0;t{const e=zc(t,[s[0],s[1],n[0],n[1]]);if(e.d>.001)return t;const i=h[0]-o[0],a=h[1]-o[1];return[o[0]+i*e.t,o[1]+a*e.t]};if(zc([(a[0]+r[0])/2,(a[1]+r[1])/2],[s[0],s[1],n[0],n[1]]).d<.01){l=d(a),c=d(r);break}}o.push(Ac(l,c,s))}return o}const Xc=15e3,Jc=2e3,Zc=new WeakMap;function Qc(t,e){let i=Zc.get(t);if(!i){const e=new Set;i={hiddenAt:"hidden"===t.visibilityState?Date.now():0,token:0,subscribers:e,onVisibility:()=>{const e=Zc.get(t);if(!e)return;const i=Date.now();if("hidden"===t.visibilityState){e.hiddenAt||(e.hiddenAt=i);const t={kind:"hidden",token:e.token,at:i,hiddenFor:0,long:!1};for(const i of[...e.subscribers])i(t);return}const s=e.hiddenAt?Math.max(0,i-e.hiddenAt):0;e.hiddenAt=0,e.token++;const n={kind:"visible",token:e.token,at:i,hiddenFor:s,long:s>=Xc};for(const t of[...e.subscribers])t(n)},onPageShow:e=>{const i=Zc.get(t);if(!i)return;const s=Date.now();i.token++;const n={kind:"pageshow",token:i.token,at:s,hiddenFor:0,long:!!e.persisted,persisted:!!e.persisted};for(const t of[...i.subscribers])t(n)}},Zc.set(t,i),t.addEventListener("visibilitychange",i.onVisibility),t.defaultView?.addEventListener("pageshow",i.onPageShow)}return i.subscribers.add(e),()=>{const i=Zc.get(t);i&&(i.subscribers.delete(e),i.subscribers.size||(t.removeEventListener("visibilitychange",i.onVisibility),t.defaultView?.removeEventListener("pageshow",i.onPageShow),Zc.delete(t)))}}const th={now:()=>Date.now(),setTimeout:(t,e)=>window.setTimeout(t,e),clearTimeout:t=>window.clearTimeout(t),requestAnimationFrame:t=>window.requestAnimationFrame(t),cancelAnimationFrame:t=>window.cancelAnimationFrame(t)};class eh{constructor(t,e=th){this.onChange=t,this.clock=e,this._state="steady",this._token=0,this._frameFingerprint="",this._hasCompleteFrame=!1,this._overlayPhase="none",this._recoveryReason=null,this._overlayTimer=0,this._overlayRaf=0,this._overlayOpaqueAt=0,this._barrierRafs=new Set,this._trace=[],this._disposed=!1}get state(){return this._state}get token(){return this._token}get frameFingerprint(){return this._frameFingerprint}get hasCompleteFrame(){return this._hasCompleteFrame}get overlayPhase(){return this._overlayPhase}get overlayVisible(){return"none"!==this._overlayPhase}get overlayBlocksInteraction(){return this.overlayVisible}get recoveryReason(){return this._recoveryReason}get trace(){return this._trace.map(t=>({...t,...t.stage?{stage:[...t.stage]}:{}}))}note(t,e={}){this.record(t,void 0,e)}record(t,e,i={}){this._trace.push({at:this.clock.now(),token:this._token,event:t,state:this._state,...e?{reason:e}:{},...i}),this._trace.length>80&&this._trace.splice(0,this._trace.length-80)}changed(){this._disposed||this.onChange()}adoptCompleteFrame(t){t&&(this._hasCompleteFrame=!0,this._frameFingerprint=t,this._state="steady",this._recoveryReason=null,this.clearOverlay(),this.record("frame-adopted"),this.changed())}markCompleteFrame(t){t&&(this._hasCompleteFrame=!0,this._frameFingerprint=t,this._state="steady",this._recoveryReason=null,this.clearOverlay(),this.record("frame-complete"),this.changed())}refreshCompleteFrame(t){!this._disposed&&this._hasCompleteFrame&&"steady"===this._state&&t&&t!==this._frameFingerprint&&(this._frameFingerprint=t,this.record("frame-refreshed"))}visibility(t){return"hidden"===t.kind?(this.record("visibility-hidden"),this._token):t.long||"visible"!==t.kind&&"pageshow"!==t.kind?this.beginCandidate("pageshow"===t.kind?"pageshow":"long-resume"):(this.record("pageshow"===t.kind?"pageshow-noop":"visibility-visible-quick"),this._token)}beginCandidate(t,e="plan"){return this._token++,this._recoveryReason=e,this._hasCompleteFrame?(this._state="connection"===e?"offline-stale":"holding",this.clearOverlay()):this.overlayVisible?this._state="overlay-visible":(this._state="overlay-pending",this.scheduleOverlay(e)),this.record("candidate-start",t),this.changed(),this._token}connectionLost(){return this.beginCandidate("connection-lost","connection")}candidateReady(t){return!this._disposed&&t===this._token&&(this._state="candidate-ready",this.record("candidate-ready"),this.changed(),!0)}async commitAfterPaint(t,e){if(this._disposed||t!==this._token)return!1;let i=!0;const s=(async()=>{for(await e.updateComplete();i&&!this._disposed&&t===this._token;)if(e.stageValid()&&e.assetsReady()){if(await this.nextFrame(),t!==this._token||!e.stageValid()||!e.assetsReady())continue;if(await this.nextFrame(),t===this._token&&e.stageValid()&&e.assetsReady())return!0}else await this.nextFrame();return!1})();let n=0;const o=new Promise(t=>{n=this.clock.setTimeout(()=>t({ready:!1,timedOut:!0}),Jc)}),a=await Promise.race([s.then(t=>({ready:t,timedOut:!1})),o]);return i=!1,this.clock.clearTimeout(n),!this._disposed&&t===this._token&&(!(!a.ready&&!a.timedOut)&&(a.ready?(this._hasCompleteFrame=!0,this._frameFingerprint=e.frameFingerprint(),this.record("paint-barrier"),this.finishOverlayAfterCommit(),!0):(this.record("paint-barrier-timeout"),this._hasCompleteFrame?(this._state="connection"===this._recoveryReason?"offline-stale":"steady",this.clearOverlay()):(this._state="recovery-error","opaque"!==this._overlayPhase&&this.showOverlayNow()),this.changed(),!1)))}retry(t=this._recoveryReason||"plan"){return this.beginCandidate("retry",t)}nextFrame(){return new Promise(t=>{const e=this.clock.requestAnimationFrame(()=>{this._barrierRafs.delete(e),t()});this._barrierRafs.add(e)})}scheduleOverlay(t){this.clearOverlayTimer(),this._recoveryReason=t,this._overlayTimer=this.clock.setTimeout(()=>{this._overlayTimer=0,this._hasCompleteFrame||"overlay-pending"!==this._state&&"candidate-ready"!==this._state||(this._state="overlay-visible",this._overlayPhase="entering",this.record("overlay-enter"),this.changed(),this._overlayRaf=this.clock.requestAnimationFrame(()=>{this._overlayRaf=0,"entering"===this._overlayPhase&&(this._overlayPhase="fading-in",this.changed(),this._overlayTimer=this.clock.setTimeout(()=>{this._overlayTimer=0,"fading-in"===this._overlayPhase&&(this._overlayPhase="opaque",this._overlayOpaqueAt=this.clock.now(),this.record("overlay-opaque"),this.changed())},150))}))},150)}showOverlayNow(){this.clearOverlayTimer(),this._overlayPhase="opaque",this._overlayOpaqueAt=this.clock.now(),this.record("overlay-error")}finishOverlayAfterCommit(){if(this.clearOverlayTimer(),"none"===this._overlayPhase||"entering"===this._overlayPhase||"fading-in"===this._overlayPhase)return this.clearOverlay(),this._state="steady",this._recoveryReason=null,this.record("candidate-committed"),void this.changed();const t=Math.max(0,this._overlayOpaqueAt+250-this.clock.now());this._overlayTimer=this.clock.setTimeout(()=>{this._overlayTimer=0,this._overlayPhase="leaving",this.record("overlay-leave"),this.changed(),this._overlayTimer=this.clock.setTimeout(()=>{this._overlayTimer=0,this._overlayPhase="none",this._state="steady",this._recoveryReason=null,this.record("candidate-committed"),this.changed()},180)},t)}clearOverlayTimer(){this._overlayTimer&&this.clock.clearTimeout(this._overlayTimer),this._overlayTimer=0}clearOverlay(){this.clearOverlayTimer(),this._overlayRaf&&this.clock.cancelAnimationFrame(this._overlayRaf),this._overlayRaf=0,this._overlayPhase="none",this._overlayOpaqueAt=0}dispose(){this._disposed=!0,this._token++,this.clearOverlay();for(const t of this._barrierRafs)this.clock.cancelAnimationFrame(t);this._barrierRafs.clear()}}function ih(t){let e=2166136261,i=2654435769;const s=new WeakSet,n=t=>{for(let s=0;s>>0)+(i>>>2)}},o=t=>{if(null===t)return void n("n");const e=typeof t;if("string"===e)return void n(`s${t.length}:${t}`);if("number"===e)return void n(`d${Number.isNaN(t)?"NaN":String(t)}`);if("boolean"===e)return void n(t?"t":"f");if("undefined"===e)return void n("u");if("object"!==e)return void n(`${e}:${String(t)}`);const i=t;if(s.has(i))n("[cycle]");else{if(s.add(i),Array.isArray(t)){n("[");for(const e of t)o(e);return n("]"),void s.delete(i)}n("{");for(const e of Object.keys(t).sort())n(e),o(t[e]);n("}"),s.delete(i)}};return o(t),`${(e>>>0).toString(16).padStart(8,"0")}${(i>>>0).toString(16).padStart(8,"0")}`}function sh(t){return ih(t)}const nh=new WeakMap;class oh{constructor(t,e=()=>Date.now()){this.onUpdate=t,this.now=e,this.fallbackAuthority={},this.referenceOwner={},this.referenced=new Set,this.queued=new Set,this.disposed=!1,this.sharedUpdate=()=>{this.disposed||this.onUpdate()}}bind(t){const e=((t,e)=>{const i=t?.connection||t?.callWS||e;return!i||"object"!=typeof i&&"function"!=typeof i?e:i})(t,this.fallbackAuthority);return this.shared&&this.authority===e||(this.shared&&(this.shared.listeners.delete(this.sharedUpdate),this.shared.references.delete(this.referenceOwner)),this.authority=e,this.shared=(t=>{let e=nh.get(t);return e||(e={signed:{},queued:new Set,inFlight:new Map,retry:new Map,listeners:new Set,settlers:new Set,references:new Map},nh.set(t,e)),e})(e),this.disposed||(this.shared.listeners.add(this.sharedUpdate),this.shared.references.set(this.referenceOwner,new Set(this.referenced)))),this.shared}start(t,e){this.disposed=!1,this.referenced=new Set(e());const i=this.bind(t());i.listeners.add(this.sharedUpdate),i.references.set(this.referenceOwner,new Set(this.referenced)),this.stopTimer(),this.resignTimer=setInterval(()=>this.resign(t(),e()),288e5)}dispose(){if(this.disposed=!0,this.stopTimer(),clearTimeout(this.batchTimer),this.shared){this.shared.listeners.delete(this.sharedUpdate),this.shared.references.delete(this.referenceOwner);for(const t of this.queued)this.shared.queued.delete(t)}this.queued.clear()}invalidate(t){const e=this.bind(t);clearTimeout(this.batchTimer),this.queued.clear(),e.queued.clear(),e.inFlight.clear(),e.retry.clear(),e.signed={}}stopTimer(){void 0!==this.resignTimer&&clearInterval(this.resignTimer),this.resignTimer=void 0}display(t,e){const i=Is(e);if(!i.startsWith("/api/houseplan/content/"))return i;const s=this.bind(t);this.referenced.add(i),s.references.set(this.referenceOwner,new Set(this.referenced));const n=s.signed[i],o=n?this.now()-n.at:1/0;return o{const e=[...this.queued];this.queued.clear();for(const t of e)i.queued.delete(t);this.sign(t,e)},30))}sign(t,e){if(!e.length||!t?.callWS)return;const i=this.bind(t);for(const s of function(t,e){const i=Math.max(1,Math.floor(e)),s=[];for(let e=0;e{const s=i.inFlight.get(t);return!(void 0!==s&&e-s<15e3)&&(i.inFlight.set(t,e),!0)});n.length&&t.callWS({type:"houseplan/content/sign",paths:n}).then(t=>{const e=this.now();let s=0,o=!1;for(const a of n){const n=t?.urls?.[a];if("string"==typeof n&&n){const t=i.signed[a];t?.loaded&&t.url!==n?(t.pending={url:n,at:e},this.preloadReplacement(i,a,n,e)):(i.signed[a]={url:n,at:e,loaded:t?.url===n&&!!t.loaded},o=!0),i.retry.delete(a),s++}else this.backOff(i,a)}if(s&&(this.trimShared(i),o))for(const t of[...i.listeners])t()}).catch(()=>{for(const t of n)this.backOff(i,t)}).finally(()=>{for(const t of n)i.inFlight.get(t)===e&&i.inFlight.delete(t);for(const t of[...i.settlers])t()})}}preloadReplacement(t,e,i,s){const n=()=>{const n=t.signed[e];if(n?.pending?.url===i){t.signed[e]={url:i,at:s,loaded:!0},t.retry.delete(e),this.trimShared(t);for(const e of[...t.listeners])e()}},o=()=>{const s=t.signed[e];s?.pending?.url===i&&(delete s.pending,this.backOff(t,e))};if("undefined"==typeof Image)return void n();const a=new Image;a.onload=()=>{("function"==typeof a.decode?a.decode():Promise.resolve()).then(n).catch(o)},a.onerror=o,a.src=i}preloadCurrentImage(t,e,i){if(i.loaded)return Promise.resolve(!0);if(i.preload)return i.preload;if("undefined"==typeof Image)return i.loaded=!0,Promise.resolve(!0);const s=i.url;return i.preload=new Promise(n=>{const o=new Image;let a=!1;const r=o=>{if(a)return;a=!0,clearTimeout(l);const r=t.signed[e];if(r===i&&delete r.preload,o&&r===i&&r.url===s){r.loaded=!0;for(const e of[...t.listeners])e();n(!0)}else o||r!==i||this.backOff(t,e),n(!1)};o.onload=()=>{("function"==typeof o.decode?o.decode():Promise.resolve()).then(()=>r(!0)).catch(()=>r(!1))},o.onerror=()=>r(!1);const l=setTimeout(()=>r(!1),Jc);o.src=s}),i.preload}prepareImage(t,e){const i=Is(e);if(!i.startsWith("/api/houseplan/content/"))return Promise.resolve(!0);const s=this.bind(t),n=()=>{const e=s.signed[i];if(e&&this.now()-e.atthis.now()&&!s.inFlight.has(i)&&!s.queued.has(i)?Promise.resolve(!1):null},o=n();return o?(a=o,new Promise(t=>{let e=!1;const i=i=>{e||(e=!0,clearTimeout(s),t(i))},s=setTimeout(()=>i(!1),Jc);a.then(i).catch(()=>i(!1))})):new Promise(t=>{let e=!1,i=null;const o=i=>{e||(e=!0,clearTimeout(r),s.settlers.delete(a),t(i))},a=()=>{e||i||(i=n(),i&&i.then(o).catch(()=>o(!1)))},r=setTimeout(()=>o(!1),Jc);s.settlers.add(a),a()});var a}backOff(t,e){const i=t.retry.get(e)?.delay||0,s=Math.min(6e4,i?2*i:2e3);t.retry.set(e,{notBefore:this.now()+s,delay:s})}trimShared(t){const e=Object.entries(t.signed);if(e.length<=512)return;const i=new Set(t.inFlight.keys());for(const e of t.references.values())for(const t of e)i.add(t);for(const[t,s]of e)(s.pending||s.preload)&&i.add(t);e.sort((t,e)=>e[1].at-t[1].at);const s=e.filter(([t])=>i.has(t));for(const t of e){if(s.length>=512)break;i.has(t[0])||s.push(t)}t.signed=Object.fromEntries(s)}resign(t,e){const i=this.bind(t);this.referenced=new Set(e),i.references.set(this.referenceOwner,new Set(this.referenced));const s=this.now(),n=new Set;for(const t of i.references.values())for(const e of t)n.add(e);const o={};for(const[t,e]of Object.entries(i.signed))n.has(t)&&s-e.at!!o[t]&&!o[t].pending))}markLoaded(t,e,i){const s=Is(e);if(!s.startsWith("/api/houseplan/content/"))return;const n=this.bind(t).signed[s];if(n&&(!i||n.url===i)&&!n.loaded){n.loaded=!0;for(const e of[...this.bind(t).listeners])e()}}isReady(t,e){const i=Is(e);if(!i.startsWith("/api/houseplan/content/"))return!0;const s=this.bind(t).signed[i];return!!s&&this.now()-s.at{if(null==t||""===t)return null;const e=Number(t);return Number.isFinite(e)?e:null},ch=t=>{const e=t,i=lh(Array.isArray(e)?e[0]:e?.x),s=lh(Array.isArray(e)?e[1]:e?.y);return null==i||null==s?null:[i,s]};function hh(t){if(!Array.isArray(t))return null;const e=[];for(const i of t){const t=ch(i);if(!t)return null;e.push(t)}if(e.length>1){const t=e[0],i=e[e.length-1];t[0]===i[0]&&t[1]===i[1]&&e.pop()}if(e.length<3)return null;let i=0,s=0,n=0;for(let t=0;tt+e[0],0)/e.length,e.reduce((t,e)=>t+e[1],0)/e.length]:[s/(3*i),n/(3*i)]}function dh(t){if(!Array.isArray(t))return null;const e=[];for(const i of t){const t=ch(i);if(!t)return null;e.push(t)}if(e.length>1){const t=e[0],i=e[e.length-1];t[0]===i[0]&&t[1]===i[1]&&e.pop()}const i=hh(e);if(!i)return null;const s=e.map(t=>t[0]),n=e.map(t=>t[1]);return{centroid:i,bbox:[Math.min(...s),Math.min(...n),Math.max(...s),Math.max(...n)]}}function uh(t){let e=t;if(e&&"object"==typeof e&&!Array.isArray(e)){const t=e;e=t.path??t.points??e}if(!Array.isArray(e)||!e.length)return[];let i=(e.some(t=>(t=>Array.isArray(t)?t.length>=2&&!Array.isArray(t[0])&&("object"!=typeof t[0]||null==t[0]):!!t&&"object"==typeof t&&("x"in t||"y"in t))(t))?[e]:e.filter(Array.isArray)).map(t=>t.map(ch).filter(t=>null!=t)).filter(t=>t.length>=2);i.length>64&&(i=i.slice(-64));if(i.reduce((t,e)=>t+e.length,0)<=4e3)return i.map(t=>t.slice());const s=4e3-2*i.length,n=i.map(t=>t.length-2),o=n.reduce((t,e)=>t+e,0),a=n.map(t=>s*t/o),r=a.map(Math.floor);let l=s-r.reduce((t,e)=>t+e,0);const c=a.map((t,e)=>({index:e,fraction:t-Math.floor(t)})).sort((t,e)=>e.fraction-t.fraction||t.index-e.index);for(let t=0;tfunction(t,e){if(e>=t.length)return t.slice();if(e<=2)return[t[0],t[t.length-1]];const i=[];for(let s=0;st.slice()),i=e[e.length-1];return i?(i.length>2?i.pop():e.pop(),e):[]}function gh(t){if(!t)return null;const e=t.vacuum_position||t.robot_position||null,i=e&&null!=lh(e.x)&&null!=lh(e.y)?{x:lh(e.x),y:lh(e.y),a:lh(e.a??e.angle??e.theta)}:null,s=uh(t.path?.path??t.path?.points??t.path),n=[],o=t.rooms,a=Array.isArray(o)?o.map((t,e)=>[String(t?.id??e),t]):o&&"object"==typeof o?Object.entries(o):[];for(const[t,e]of a){if(!e||"object"!=typeof e)continue;const i=String(e.name??e.label??"").trim(),s=[[lh(e.cx),lh(e.cy)],[lh(e.center?.x),lh(e.center?.y)],[lh(e.x),lh(e.y)]].find(([t,e])=>null!=t&&null!=e);let o=s?.[0]??null,a=s?.[1]??null;const r=dh(e.outline),l=lh(e.x0),c=lh(e.y0),h=lh(e.x1),d=lh(e.y1),u=(null!=l&&null!=c&&null!=h&&null!=d?[Math.min(l,h),Math.min(c,d),Math.max(l,h),Math.max(c,d)]:null)||r?.bbox||null;if(null!=o&&null!=a||!r||([o,a]=r.centroid),null!=o&&null!=a||!u||(o=(u[0]+u[2])/2,a=(u[1]+u[3])/2),i&&null!=o&&null!=a){const e={id:t,name:i,cx:o,cy:a};u&&([e.x0,e.y0,e.x1,e.y1]=u),n.push(e)}}const r=function(t){return String(t.map_name??t.current_map??t.map_index??t.selected_map??"default")}(t);return i||n.length||s.length?{pos:i,path:s,rooms:n,mapId:r}:null}function mh(t,e,i){if(!t||!e)return null;const s=e.attributes||{},n=t.split(".")[0]||"",o=null!=i?.platform?String(i.platform):null,a=!!ch(s.vacuum_position??s.robot_position),r=!(!s.rooms||"object"!=typeof s.rooms),l=uh(s.path?.path??s.path?.points??s.path).length>0,c=[s.map_name,s.current_map,s.map_index,s.selected_map].some(t=>null!=t),h="xiaomi_cloud_map_extractor"===o,d=r||l||c;let u=null;if(a?u="compatible":h?u="known_xcme_incomplete":d?u="partial":"camera"===n&&(u="camera"),!u)return null;const p=a?"camera"===n?300:200:h?100:d?50:0;return{entityId:t,name:String(s.friendly_name||t),platform:o,category:u,hasPosition:a,hasRooms:r,hasPath:l,hasMapId:c,score:p}}const fh=t=>t.toLowerCase().replace(/[\s_\-.,]+/g,"");function vh(t,e){const i=new Map(e.map(t=>[fh(t.name),t])),s=[],n=[];for(const e of t){const t=i.get(fh(e.name));t&&(s.push([[e.cx,e.cy],[t.cx,t.cy]]),n.push(e.name))}if(s.length<3)return null;const o=function(t){if(t.length<3)return null;let e=0,i=0,s=0,n=0,o=0,a=0,r=0,l=0,c=0,h=0,d=0,u=0;for(const[[p,_],[g,m]]of t){if(![p,_,g,m].every(Number.isFinite))return null;e+=p*p,i+=p*_,s+=p,n+=_*_,o+=_,a+=1,r+=p*g,l+=_*g,c+=g,h+=p*m,d+=_*m,u+=m}const p=[e,i,s,i,n,o,s,o,a],_=t=>{const[e,i,s,n,o,a,r,l,c]=p,h=e*(o*c-a*l)-i*(n*c-a*r)+s*(n*l-o*r);if(!Number.isFinite(h)||Math.abs(h)<1e-9)return null;const d=[(o*c-a*l)/h,(s*l-i*c)/h,(i*a-s*o)/h,(a*r-n*c)/h,(e*c-s*r)/h,(s*n-e*a)/h,(n*l-o*r)/h,(i*r-e*l)/h,(e*o-i*n)/h];return[d[0]*t[0]+d[1]*t[1]+d[2]*t[2],d[3]*t[0]+d[4]*t[1]+d[5]*t[2],d[6]*t[0]+d[7]*t[1]+d[8]*t[2]]},g=_([r,l,c]),m=_([h,d,u]);if(!g||!m)return null;const f=[g[0],g[1],g[2],m[0],m[1],m[2]];return f.every(Number.isFinite)?f:null}(s);return o?{matrix:o,matched:n,residual:rh(o,s)}:null}function yh(t,e,i){const s=t[t.length-1];if(s&&s[0]===e[0]&&s[1]===e[1])return t;if(t.push(e),t.length<=600)return t;let n=function(t,e){if(t.length<3)return t.slice();const i=new Uint8Array(t.length);i[0]=i[t.length-1]=1;const s=[[0,t.length-1]];for(;s.length;){const[n,o]=s.pop(),[a,r]=t[n],[l,c]=t[o],h=l-a,d=c-r,u=Math.hypot(h,d)||1e-9;let p=0,_=-1;for(let e=n+1;ep&&(p=i,_=e)}_>0&&p>e&&(i[_]=1,s.push([n,_],[_,o]))}const n=[];for(let e=0;e600&&(n=n.filter((t,e)=>e%2==0||e===n.length-1)),n}function bh(t){return"cleaning"===t||"returning"===t||"on"===t}const wh={0:[1,0],90:[0,1],180:[-1,0],270:[0,-1]};function kh(t){const[e,i]=wh[t.rot]||[1,0],s=t.mir?-1:1;return[t.s*e*s,-t.s*i,t.ox,t.s*i*s,t.s*e,t.oy]}function xh(t){const e=t[0]*t[4]-t[1]*t[3];if(!Number.isFinite(e)||Math.abs(e)<1e-12)return null;const i=e<0,s=Math.sqrt(Math.abs(e));let n=180*Math.atan2(-t[1],t[4])/Math.PI;return n=(90*Math.round(n/90)%360+360)%360,{ox:t[2],oy:t[5],s:s,rot:n,mir:i}}function $h(t,e,i,s){const[n,o]=ah(kh(e),i,s),a=kh({...t,ox:0,oy:0}),[r,l]=ah(a,i,s);return{...t,ox:n-r,oy:o-l}}function Sh(t){const e=t?.trail_mode;return"never"===e||"cleaning"===e||"always"===e?e:!1===t?.trail?"never":"cleaning"}const Mh={offStates:["off"],unknownUsesToggle:!0},Ch={light:Mh,switch:Mh,fan:Mh,humidifier:Mh,input_boolean:Mh,automation:Mh,remote:Mh,group:Mh,climate:{...Mh,featureMasks:{turn_on:256,turn_off:128,toggle:384}},media_player:{...Mh,featureMasks:{turn_on:128,turn_off:256,toggle:384}},siren:{...Mh,featureMasks:{turn_on:1,turn_off:2,toggle:3}},vacuum:{...Mh,featureMasks:{turn_on:1,turn_off:2,toggle:3}},water_heater:{...Mh,featureMasks:{turn_on:8,turn_off:8,toggle:8}},camera:{...Mh,featureMasks:{turn_on:1,turn_off:1,toggle:1}}};function Dh(t){return t.slice(0,t.indexOf("."))}function Th(t,e,i){if(!t?.services||"object"!=typeof t.services)return!1;const s=t.services?.[e];return!!s&&Object.prototype.hasOwnProperty.call(s,i)}function Ph(t,e,i){return Th(t,e,i)?{domain:e,service:i}:Th(t,"homeassistant",i)?{domain:"homeassistant",service:i}:null}function Rh(t,e){return t?.entities?.[e]||null}function Ah(t,e,i){const s=t?.states?.[i],n=Rh(e,i);return s?.attributes?.friendly_name||n?.name||n?.original_name||i}function Ih(t,e){const i=Rh(t,e);if(null!=i?.disabled_by)return!0;const s=i?.device_id?t?.devices?.[i.device_id]:null;return null!=s?.disabled_by}function Eh(t,e){const i=t?.attributes?.supported_features;if(null==i||""===i)return!1;const s=Number(i);return Number.isFinite(s)&&(s&e)===e}function Fh(t,e,i){const s=Dh(i);if("lock"===s||"alarm_control_panel"===s)return!0;if("cover"!==s)return!1;const n=t?.states?.[i],o=Rh(e,i),a=String(n?.attributes?.device_class||o?.device_class||o?.original_device_class||"");return Ui.has(a)}function zh(t,e,i,s,n){return{ref:i,entityId:s,name:s?Ah(t,e,s):null,reason:n}}function Oh(t,e,i,s,n,o=null){return{target:null,skipped:zh(t,e,i,s,n),semantics:o,nextEffect:null,command:null}}function Hh(t,e,i,s,n=i){const o=Dh(i);if("cover"!==o&&"valve"!==o)return function(t,e,i,s,n=i){const o=Dh(i),a=t?.states?.[i];if(Ih(e,i))return Oh(t,e,n,i,"ha-disabled","power");if(Fh(t,e,i))return Oh(t,e,n,i,"secure");if(!a)return Oh(t,e,n,i,"missing","power");if("unavailable"===a.state)return Oh(t,e,n,i,"unavailable","power");const r=Ch[o];if(!r)return Oh(t,e,n,i,"unsupported");let l,c;if("unknown"===a.state||""===a.state){if(!r.unknownUsesToggle)return Oh(t,e,n,i,"unsupported","power");l="toggle",c="toggle"}else r.offStates.includes(String(a.state))?(l="turn-on",c="turn_on"):(l="turn-off",c="turn_off");const h=r.featureMasks?.[c];if(h&&!Eh(a,h))return Oh(t,e,n,i,"unsupported","power");const d=Ph(t,o,c);return d?{target:{entityId:i,name:Ah(t,e,i),state:String(a.state||""),via:s},skipped:null,semantics:"power",nextEffect:l,command:{...d,data:{entity_id:i}}}:Oh(t,e,n,i,"unsupported","power")}(t,e,i,s,n);if(Ih(e,i))return Oh(t,e,n,i,"ha-disabled",o);if(Fh(t,e,i))return Oh(t,e,n,i,"secure",o);const a=t?.states?.[i];if(!a)return Oh(t,e,n,i,"missing",o);if("unavailable"===a.state)return Oh(t,e,n,i,"unavailable",o);const r=function(t,e,i){const s=String(i?.state||""),n="closed"===s?{service:`open_${e}`,effect:"open",feature:1}:"open"===s?{service:`close_${e}`,effect:"close",feature:2}:"opening"===s||"closing"===s?{service:`stop_${e}`,effect:"stop",feature:8}:null;return n&&Eh(i,n.feature)&&Th(t,e,n.service)?n:Eh(i,3)&&Th(t,e,"toggle")?{service:"toggle",effect:"toggle"}:null}(t,o,a);if(!r)return Oh(t,e,n,i,"unsupported",o);return{target:{entityId:i,name:Ah(t,e,i),state:String(a.state||""),via:s},skipped:null,semantics:o,nextEffect:r.effect,command:{domain:o,service:r.service,data:{entity_id:i}}}}function Nh(t){return"entity"===t.bindingKind?t.bindingRef&&Ms(t.bindingRef)?[t.bindingRef]:[]:"virtual"===t.bindingKind?[]:Zn(t)}function Lh(t){const e=t.marker?.toggle_entity;return e&&Nh(t).includes(e)?e:null}function Bh(t,e,i){const s=function(t,e){if("entity"===t.bindingKind&&t.bindingRef){const e=t.marker?.light_entity?Qn(t):null;return[...new Set([e,t.bindingRef].filter(t=>!!t))]}const i=t.entities.length?t.entities:t.allEntities||[],s=t.marker?.light_entity||t.primary&&Ms(t.primary)?Qn(t):null;return[...new Set([s,...Vn(e,i)].filter(t=>!!t))]}(i,e);if(!s.length)return null;const n="entity"===i.bindingKind?"binding":"device-role";if("binding"===n)return Hh(t,e,s[0],n);let o=null,a=null;for(const i of s){const s=Hh(t,e,i,n);if(s.command)return s;const r=s.skipped?.reason;if("missing"===r||"unavailable"===r||"secure"===r)return s;"ha-disabled"!==r?o||=s:a||=s}return o||a}function qh(t){const e=t.skipped?.reason;return"missing"===e?"unavailable":e||"unsupported"}function jh(t,e){return{origin:t,kind:"none",semantics:null,targets:[],skippedTargets:[],noneReason:e,nextEffect:null,command:null}}function Wh(t,e){return"cover"===t||"toggle"===t?"toggle":"more-info"===t||"run"===t||"info"===t?t:(null==t||""===t)&&"light"===e?"toggle":"info"}function Uh(t,e){return{origin:t,kind:"single",semantics:e.semantics,targets:e.target?[e.target]:[],skippedTargets:e.skipped?[e.skipped]:[],noneReason:e.command?null:qh(e),nextEffect:e.nextEffect,command:e.command}}function Gh(t,e,i,s=[]){const n=new Map,o=[],a=new Set,r=t=>{const e=`${t.ref}\n${t.entityId||""}\n${t.reason}`;a.has(e)||(a.add(e),o.push(t))};for(const t of s)r(t);for(const s of i){const i=Hh(t,e,s.entityId,s.via,s.ref);i.target?n.set(s.entityId,n.get(s.entityId)||i.target):i.skipped&&r(i.skipped)}const l=[...n.values()];if(!l.length)return{origin:"explicit-toggle",kind:"group",semantics:"group-power",targets:l,skippedTargets:o,noneReason:o.length&&o.every(t=>"secure"===t.reason)?"secure":"configured-targets-missing",nextEffect:null,command:null};const c=l.some(t=>"on"===t.state)?"turn_off":"turn_on",h=Ph(t,"homeassistant",c);return h?{origin:"explicit-toggle",kind:"group",semantics:"group-power",targets:l,skippedTargets:o,noneReason:null,nextEffect:"turn_on"===c?"turn-on":"turn-off",command:{...h,data:{entity_id:l.map(t=>t.entityId)}}}:{origin:"explicit-toggle",kind:"group",semantics:"group-power",targets:[],skippedTargets:[...o,...l.map(i=>zh(t,e,i.entityId,i.entityId,"unsupported"))],noneReason:"unsupported",nextEffect:null,command:null}}function Vh(t){return String(t.marker?.id||t.id||"")}function Kh(t){const{hass:e,device:i}=t,s=t.registryHass||e,n=function(t){return"toggle"===t.tapAction?"explicit-toggle":"cover"===t.tapAction?"legacy-cover":!t.tapAction&&t.primary?.startsWith("light.")?"default-light":null}(i);if(!n)return null;const o=i.marker;if("explicit-toggle"===n&&yn(o)){const e=String(o?.id||i.id||""),s=oo(t.devices).get(e);if(s)return function(t,e){const i=t.registryHass||t.hass;return Gh(t.hass,i,e.driverEids.map(t=>({entityId:t,via:"control-marker-driver",ref:`marker:${e.markerId}`})))}(t,s);const a=bn(o,t.virtualLights);return{origin:n,kind:"single",semantics:"power",targets:[{entityId:"",name:i.name,state:a?"on":"off",via:"virtual-light"}],skippedTargets:[],noneReason:null,nextEffect:a?"turn-off":"turn-on",command:null,operation:{kind:"virtual-light",markerId:o.id}}}if("explicit-toggle"===n){if(Xn(i.marker?.binding,i.marker?.controls??i.controls,i.entities).length)return function(t,e=null){const{hass:i,device:s,devices:n}=t,o=t.registryHass||i,a=Xn(s.marker?.binding,s.marker?.controls??s.controls,s.entities),r=t.lightSources||lo(i,n,null,t.virtualLights),l=new Map;for(const t of r){if(!t.key.startsWith("marker:"))continue;const e=l.get(t.key)||[];e.push(t),l.set(t.key,e)}const c=oo(n),h=new Map;for(const t of n){const e=String(t.marker?.id||t.id||"");e&&h.set(e,t)}const d=[],u=[];e&&d.push({entityId:e,via:"entity"===s.bindingKind?"binding":"device-role",ref:e});for(const t of a){if(!t.startsWith("marker:")){Ms(t)?d.push({entityId:t,via:"control-entity",ref:t}):u.push(zh(i,o,t,t.includes(".")?t:null,"unsupported"));continue}const e=l.get(t)||[];if(!e.length){const e=h.get(t.slice(7));if("ha_disabled"===e?.bindingStatus?.kind){const s=e.bindingStatus.allEntityIds[0]||null;u.push({ref:t,entityId:s,name:e.name||(s?Ah(i,o,s):null),reason:"ha-disabled"})}else u.push(zh(i,o,t,null,"missing"));continue}const n=[...new Set(e.flatMap(t=>t.serviceEids))];if(n.length){for(const e of n)d.push({entityId:e,via:"control-entity",ref:t});continue}const a=e.some(t=>t.passive),r=t.slice(7),p=Vh(s),_=c.get(r)?.controllers.find(t=>Vh(t.device)===p);if(a&&_?.driverEids.length)for(const e of _.driverEids)d.push({entityId:e,via:"control-marker-driver",ref:t});else u.push(zh(i,o,t,null,a?"missing":"unsupported"))}return Gh(i,o,d,u)}(t,Lh(i))}if("legacy-cover"===n){const t=i.entities.find(t=>t.startsWith("cover."))||i.allEntities?.find(t=>t.startsWith("cover."));return t?Uh(n,Hh(e,s,t,"device-role")):jh(n,"no-actionable-entity")}const a=Lh(i),r=a?Hh(e,s,a,"entity"===i.bindingKind?"binding":"device-role"):Bh(e,s,i);return r?Uh(n,r):jh(n,i.virtual||"virtual"===i.bindingKind?"no-actionable-entity":"no-binding")}function Yh(t){if(!t)return[];const e=Array.isArray(t.data.entity_id)?t.data.entity_id:[t.data.entity_id];return[...new Set(e)].sort()}function Xh(t){return t?t.operation?t.operation:t.command?{kind:"ha-service",command:t.command}:null:null}function Jh(t,e){const i=Xh(t),s=Xh(e);return!(!i||!s||i.kind!==s.kind)&&("virtual-light"===i.kind&&"virtual-light"===s.kind?i.markerId===s.markerId:"ha-service"===i.kind&&"ha-service"===s.kind&&function(t,e){const i=Yh(t),s=Yh(e);return i.length===s.length&&i.every((t,e)=>t===s[e])}(i.command,s.command))}const Zh=t=>!!t&&t.length>=2&&Number.isFinite(t[0])&&Number.isFinite(t[1]);function Qh(t,e=5,i=5){return fr(t.cm,e,i)/2}function td(t,e,i=1,s=5,n=5,o=0){const a=t.host;if(!a||"partition"!==a.kind||"string"!=typeof a.id||!a.id)return{resolved:null,reason:"invalid-host"};const r=e.find(t=>t.id===a.id);if(!r)return{resolved:null,reason:"missing-partition"};if(!Zh(r.a)||!Zh(r.b)||!Number.isFinite(a.t)||a.t<0||a.t>1)return{resolved:null,reason:"invalid-position"};const l=r.b[0]-r.a[0],c=r.b[1]-r.a[1],h=Math.hypot(l,c),d=Number(t.length)*i;if(!(h>1e-9&&d>0&&Number.isFinite(d)))return{resolved:null,reason:"invalid-length"};const u=a.t*h;if(u-d/2h-o+1e-9)return{resolved:null,reason:"does-not-fit"};const p=l/h,_=c/h;let g=180*Math.atan2(c,l)/Math.PI;return g>=90?g-=180:g<-90&&(g+=180),{reason:null,resolved:{opening:t,host:a,partition:r,center:[r.a[0]+l*a.t,r.a[1]+c*a.t],angle:g,length:d,depth:fr(r.cm,s,n),t:a.t,axis:{a:[r.a[0],r.a[1]],b:[r.b[0],r.b[1]],ux:p,uy:_,length:h}}}}function ed(t,e,i=1,s=5,n=5){return td(t,e,i,s,n,0)}function id(t,e,i=1,s=5,n=5){const o=t.host,a="partition"===o?.kind?e.find(t=>t.id===o.id):void 0;if(!a)return ed(t,e,i,s,n);const r=td(t,e,i,s,n,Qh(a,s,n));return"does-not-fit"===r.reason?{resolved:null,reason:"does-not-fit-jamb"}:r}function sd(t,e){return!t||(t.length!==e.length||t.host?.kind!==e.host?.kind||t.host?.id!==e.host?.id||t.host?.t!==e.host?.t)}function nd(t){const{center:e,length:i,axis:s,host:n}=t,o=i/2;return{hostId:n.id,a:[e[0]-s.ux*o,e[1]-s.uy*o],b:[e[0]+s.ux*o,e[1]+s.uy*o],depth:t.depth}}function od(t,e=!1){const i=e?1:-1,s=t.depth/2;return{ox:-t.axis.uy*i*s,oy:t.axis.ux*i*s,cm:t.partition.cm,side:i}}function ad(t,e,i){const{center:s,length:n,axis:o}=t,a=n/2,r=e.flatMap(t=>{if(!t.kind||t.open)return[];const e=t.b[0]-t.a[0],n=t.b[1]-t.a[1],r=Math.hypot(e,n);if(!(r>i))return[];const l=e/r,c=n/r;if(Math.abs(o.ux*c-o.uy*l)>1e-6)return[];if(Math.abs((s[0]-t.a[0])*c-(s[1]-t.a[1])*l)>i)return[];const h=t=>(t[0]-s[0])*o.ux+(t[1]-s[1])*o.uy,d=h(t.a),u=h(t.b),p=Math.max(-a,Math.min(d,u)),_=Math.min(a,Math.max(d,u));return _>=p-i?[[p,_]]:[]});if(!r.length)return!1;r.sort((t,e)=>t[0]-e[0]||t[1]-e[1]);let l=-a;for(const[t,e]of r){if(t>l+i)return!1;if(l=Math.max(l,e),l>=a-i)return!0}return!1}function rd(t,e,i){return{...t,x:e.center[0]/i,y:e.center[1]/i,angle:e.angle}}function ld(t){return!!t&&t.length>=2&&Number.isFinite(t[0])&&Number.isFinite(t[1])}function cd(t){return`${t[0].toFixed(6)},${t[1].toFixed(6)}`}function hd(t,e,i){return Math.abs(t[0]-e[0])_d(s,t,e)))continue;const t=cd(s);a.has(t)||a.set(t,{point:[s[0],s[1]],key:t})}}}return{segments:[...o.values()].sort((t,e)=>t.key.localeCompare(e.key)),endpoints:[...a.values()].sort((t,e)=>t.key.localeCompare(e.key))}}function md(t,e,i){return e.some(e=>ld(e)&&hd(t,e,i))}function fd(t,e,i){if(!i)return!0;const s=t-i.distance;return s<-1e-9||Math.abs(s)<=1e-9&&e.localeCompare(i.key)<0}function vd(t,e,i){const s=t.b[0]-t.a[0],n=t.b[1]-t.a[1],o=Math.hypot(s,n);if(!(o>0))return[...t.a];const a=s/o,r=n/o,l=Math.max(0,Math.min(o,(e[0]-t.a[0])*a+(e[1]-t.a[1])*r)),c=i>0?Math.max(0,Math.min(o,Math.round(l/i)*i)):l;return[t.a[0]+a*c,t.a[1]+r*c]}const yd=.001;function bd(t,e,i){const s=[];for(let n=0;n+1=0?e[n]:i;s.push({a:[o[0],o[1]],b:[a[0],a[1]],cm:r})}return s}function wd(t){return!!t&&t.length>=2&&Number.isFinite(t[0])&&Number.isFinite(t[1])}function kd(t,e,i,s){return t*s-e*i}function xd(t){let e=0;for(let i=0;it.localeCompare(e)),e[0]}function Dd(t,e,i){const s=[...t];for(let t=!0;t&&s.length>=3;){t=!1;for(let n=0;n=0){s.splice(n,1),t=!0;break}}}return s}function Td(t,e){const i=t.map(t=>Math.max(0,Math.min(1,t))).sort((t,e)=>t-e),s=[];for(const t of i)(!s.length||Math.abs(t-s[s.length-1])>e)&&s.push(t);return s}function Pd(t,e){return[t.a[0]+(t.b[0]-t.a[0])*e,t.a[1]+(t.b[1]-t.a[1])*e]}function Rd(t,e,i){const s=function(t,e){const i=e.b[0]-e.a[0],s=e.b[1]-e.a[1],n=i*i+s*s;return n>0?((t[0]-e.a[0])*i+(t[1]-e.a[1])*s)/n:0}(t,e);if(s<-i||s>1+i)return null;const n=Pd(e,s);return Math.hypot(n[0]-t[0],n[1]-t[1])<=i?Math.max(0,Math.min(1,s)):null}function Ad(t,e,i,s,n){const o=t.b[0]-t.a[0],a=t.b[1]-t.a[1],r=e.b[0]-e.a[0],l=e.b[1]-e.a[1],c=e.a[0]-t.a[0],h=e.a[1]-t.a[1],d=kd(o,a,r,l),u=Math.max(Math.hypot(o,a),Math.hypot(r,l),1);if(Math.abs(d)>n*u){const t=kd(c,h,r,l)/d,e=kd(c,h,o,a)/d;return void(t>=-n&&t<=1+n&&e>=-n&&e<=1+n&&(i.push(Math.max(0,Math.min(1,t))),s.push(Math.max(0,Math.min(1,e)))))}if(!(Math.abs(kd(c,h,o,a))>n*u)){for(const s of[e.a,e.b]){const e=Rd(s,t,n);null!=e&&i.push(e)}for(const i of[t.a,t.b]){const t=Rd(i,e,n);null!=t&&s.push(t)}}}function Id(t){let e=t+1|0;return e^=e<<13,e^=e>>>17,e^=e<<5,e>>>0}function Ed(t,e){return t.minY-e.minY||t.index-e.index}function Fd(t){return t.subtreeMaxY=Math.max(t.item.maxY,t.left?.subtreeMaxY??-1/0,t.right?.subtreeMaxY??-1/0),t}function zd(t){const e=t.right;return t.right=e.left,e.left=Fd(t),Fd(e)}function Od(t){const e=t.left;return t.left=e.right,e.right=Fd(t),Fd(e)}function Hd(t,e){return t?(Ed(e,t.item)<0?(t.left=Hd(t.left,e),t.left.priority0)t.right=Nd(t.right,e);else{if(!t.left)return t.right;if(!t.right)return t.left;t.left.priority=e&&Ld(t.left,e,i,s),t.item.minY<=i&&t.item.maxY>=e&&s.push(t.item),t.item.minY<=i&&Ld(t.right,e,i,s))}function Bd(t,e=.001){const i=Number.isFinite(e)&&e>0?e:yd,s=t.filter(t=>wd(t.a)&&wd(t.b)&&"string"==typeof t.key&&t.key.length>0&&Math.hypot(t.b[0]-t.a[0],t.b[1]-t.a[1])>i),n=s.map(()=>[0,1]);!function(t,e,i){const s=t.map((t,e)=>({index:e,minX:Math.min(t.a[0],t.b[0])-i,maxX:Math.max(t.a[0],t.b[0])+i,minY:Math.min(t.a[1],t.b[1])-i,maxY:Math.max(t.a[1],t.b[1])+i})),n=[...s].sort((t,e)=>t.minX-e.minX||t.minY-e.minY||t.index-e.index),o=[...s].sort((t,e)=>t.maxX-e.maxX||t.index-e.index),a=new Set;let r=null,l=0;for(const s of n){for(;lt.index-e.index);for(const o of n)Ad(t[o.index],t[s.index],e[o.index],e[s.index],i);a.add(s.index),r=Hd(r,s)}}(s,n,i);const o=new Map;for(let t=0;t({key:t,a:e.a,b:e.b,sourceKeys:[...e.sourceKeys].sort((t,e)=>t.localeCompare(e))})).sort((t,e)=>t.key.localeCompare(e.key))}const qd=1e-5;function jd(t){const e=t.map(()=>[]);for(let i=0;i=1-1e-9||u<=1e-9||u>=1-1e-9||(e[i].push(d),e[a].push(u))}}const i=[];for(let s=0;st-e),1];for(let t=1;t{const i=e[2]-e[0],s=e[3]-e[1],n=i*i+s*s;if(!(n>0))return Math.hypot(t[0]-e[0],t[1]-e[1]);const o=Math.max(0,Math.min(1,((t[0]-e[0])*i+(t[1]-e[1])*s)/n));return Math.hypot(t[0]-(e[0]+o*i),t[1]-(e[1]+o*s))},Gd=(t,e,i,s)=>{const n=s[2]-s[0],o=s[3]-s[1],a=e*o-i*n;if(Math.abs(a)<1e-12)return 1/0;const r=s[0]-t[0],l=s[1]-t[1],c=(r*o-l*n)/a;if(!(c>1e-9))return 1/0;const h=(r*i-l*e)/a;return h<-1e-9||h>1+1e-9?1/0:c};function Vd(t,e,i,s=96){if(!(e>0&&Number.isFinite(t[0])&&Number.isFinite(t[1])))return[];const n=[];for(const s of i){if(!s||s.length<4)continue;if(![s[0],s[1],s[2],s[3]].every(Number.isFinite))continue;const i=Ud(t,s);if(i<1e-7)return[];i>e||n.push(s)}const o=[],a=Math.max(12,Math.round(s));for(let t=0;tt-e);const l=[];let c=Number.NEGATIVE_INFINITY;for(const i of o){if(i-c<1e-9)continue;c=i;const s=Math.cos(i),o=Math.sin(i);let a=e;for(const e of n){const i=Gd(t,s,o,e);i=3?l:[]}class Kd extends ht{constructor(){super(...arguments),this._spaces=null,this._spacesLoading=!1}setConfig(t){this._config=t}async _loadSpaces(){if(!this._spaces&&!this._spacesLoading&&this.hass){this._spacesLoading=!0;try{const t=await this.hass.callWS({type:"houseplan/config/get"});this._spaces=(t?.config?.spaces||[]).map(t=>({value:t.id,label:t.title||t.id}))}catch{this._spaces=[]}finally{this._spacesLoading=!1}}}get _lang(){return sa(this.hass,this._config?.language)}get _schema(){const t=this._spaces||[],e=this._lang;return[{name:"title",selector:{text:{}}},t.length?{name:"default_floor",selector:{select:{mode:"dropdown",options:t}}}:{name:"default_floor",selector:{text:{}}},{name:"language",selector:{select:{mode:"dropdown",options:[{value:"",label:na(e,"editor.lang_auto")},{value:"en",label:na(e,"editor.lang_en")},{value:"ru",label:na(e,"editor.lang_ru")}]}}},{name:"icon_size",selector:{number:{min:1,max:6,step:.1,mode:"box"}}},{name:"show_temperature",selector:{boolean:{}}},{name:"live_states",selector:{boolean:{}}},{name:"show_signal",selector:{boolean:{}}},{name:"kiosk",selector:{boolean:{}}},{name:"cycle",selector:{number:{min:0,max:3600,step:5,mode:"box"}}}]}render(){if(!this.hass||!this._config)return G;this._loadSpaces();const t=this._lang,e={title:na(t,"editor.title"),default_floor:na(t,"editor.default_floor"),language:na(t,"editor.language"),icon_size:na(t,"editor.icon_size"),show_temperature:na(t,"editor.show_temperature"),live_states:na(t,"editor.live_states"),show_signal:na(t,"editor.show_signal"),kiosk:na(t,"editor.kiosk"),cycle:na(t,"editor.cycle")};return j``}const er={color:"#607d8b",opacity:1,widthCm:3.6,fill:!1,fillColor:"#607d8b",fillOpacity:.25},ir=(t,e=1)=>{const i=Number(t);return Number.isFinite(i)?Math.min(1,Math.max(0,i)):e},sr=t=>{let e=Number(t);return Number.isFinite(e)?(e=(e%360+360)%360,e>180?e-360:e):0};function nr(t,e,i){return sr(e)?[t.x,t.y]:i([t.x,t.y])}const or=(t,e,i)=>{const s=Number(t),n=Number.isFinite(e)&&e>0?e:5;return Number.isFinite(s)&&s>0?s/n*i:0},ar=(t,e,i)=>{const s=Number(t),n=Number.isFinite(e)&&e>0?e:5;return Number.isFinite(s)&&i>0?s/i*n:0},rr=(t,e,i,s=er.widthCm)=>{const n=Number(t?.width_cm);if(Number.isFinite(n)&&n>0)return n;const o=Number(t?.width);return Number.isFinite(o)&&o>0?ar(o,e,i):s};function lr(t,e){return{color:t.color,opacity:ir(t.opacity),width_cm:Math.max(.1,Math.min(100,Number(t.widthCm)||.1)),...e?{fill:t.fill,fill_color:t.fillColor,fill_opacity:ir(t.fillOpacity,.25)}:{}}}function cr(t){const e=t.x+t.w/2,i=t.y+t.h/2,s=sr(t.angle)*Math.PI/180,n=Math.cos(s),o=Math.sin(s),a=(t,s)=>{const a=t-e,r=s-i;return[e+a*n-r*o,i+a*o+r*n]};return[a(t.x,t.y),a(t.x+t.w,t.y),a(t.x+t.w,t.y+t.h),a(t.x,t.y+t.h)]}function hr(t){const e=cr(t),i=(t,e)=>[(t[0]+e[0])/2,(t[1]+e[1])/2],s=[(e[0][0]+e[2][0])/2,(e[0][1]+e[2][1])/2];return{points:[...e,i(e[0],e[1]),i(e[1],e[2]),i(e[2],e[3]),i(e[3],e[0]),s],segments:e.map((t,i)=>({a:t,b:e[(i+1)%4]}))}}function dr(t,e,i,s,n,o,a,r){const l=sr(t.angle)*Math.PI/180,c=Math.cos(l),h=Math.sin(l),d=-Math.sin(l),u=Math.cos(l),p=t.x+t.w/2,_=t.y+t.h/2,g=e>0?-t.w/2:t.w/2,m=i>0?-t.h/2:t.h/2,f=p+g*c+m*d,v=_+g*h+m*u,y=s-f,b=n-v;let w=(y*c+b*h)*(e>0?1:-1),k=(y*d+b*u)*(i>0?1:-1),x=null;if(o){const e=w/Math.max(t.w,r),i=k/Math.max(t.h,r);x=Math.max(r/Math.max(t.w,r),r/Math.max(t.h,r),e,i),w=t.w*x,k=t.h*x}if(a>0)if(o){const e=Math.max(1,Math.round(t.w/a)),i=Math.max(1,Math.round(t.h/a));if(Math.abs(t.w-e*a)<1e-6&&Math.abs(t.h-i*a)<1e-6){const s=(t,e)=>{let i=Math.abs(t),s=Math.abs(e);for(;s;)[i,s]=[s,i%s];return Math.max(1,i)},n=1/s(e,i),o=Math.max(r/t.w,r/t.h),a=Math.max(o,Math.round((x??1)/n)*n);w=t.w*a,k=t.h*a}else{t.w>=t.h?(w=Math.round(w/a)*a,k=w*(t.h/Math.max(t.w,r))):(k=Math.round(k/a)*a,w=k*(t.w/Math.max(t.h,r)))}}else w=Math.round(w/a)*a,k=Math.round(k/a)*a;w=Math.max(r,w),k=Math.max(r,k);return{x:f+(e>0?w/2:-w/2)*c+(i>0?k/2:-k/2)*d-w/2,y:v+(e>0?w/2:-w/2)*h+(i>0?k/2:-k/2)*u-k/2,w:w,h:k,angle:sr(t.angle)||void 0}}const ur=(t,e,i)=>{const s=i[0]-e[0],n=i[1]-e[1],o=s*s+n*n;if(o<1e-12)return[...e];const a=Math.max(0,Math.min(1,((t[0]-e[0])*s+(t[1]-e[1])*n)/o));return[e[0]+s*a,e[1]+n*a]};const pr=15;function _r(t,e){return Number.isFinite(t)&&t>0&&Number.isFinite(e)&&e>0&&t*e<3}function gr(t){return Number.isFinite(t)?Math.max(1,Math.min(100,t)):1}function mr(t,e){return!Number.isFinite(t)||t<=0?"":String(e?Math.round(t/2.54*100)/100:Math.round(100*t)/100)}function fr(t,e,i){const s=Number(e)>0?Number(e):5;return gr(t)/s*i}function vr(t,e){return e>0&&Number.isFinite(t)?Math.round(t/e)*e:t}function yr(t,e){let i=e[0]-t[0],s=e[1]-t[1];const n=Math.hypot(i,s);return n<1e-12?[1,0]:(i/=n,s/=n,(i<-1e-12||Math.abs(i)<=1e-12&&s<0)&&(i=-i,s=-s),[i,s])}function br(t,e,i){const s=vr((t[0]+e[0])/2,i),n=vr((t[1]+e[1])/2,i),[o,a]=yr(t,e);let r=Math.atan2(a,o);r<0&&(r+=Math.PI);const l=Math.round(1800*r)/1800,c=i>0&&i<.01?6:i<1?4:2;return`${s.toFixed(c)},${n.toFixed(c)}@${l.toFixed(4)}`}function wr(t,e,i,s){return 1===s?br(t,e,i):br([t[0]/s,t[1]/s],[e[0]/s,e[1]/s],i)}function kr(t,e){if(!Array.isArray(t.a)||!Array.isArray(t.b)||t.a.length<2||t.b.length<2)return null;const i=[Number(t.a[0]),Number(t.a[1]),Number(t.b[0]),Number(t.b[1])];if(!i.every(Number.isFinite))return null;const s=e>0?e:1;return[[i[0]*s,i[1]*s],[i[2]*s,i[3]*s]]}function xr(t,e,i,s,n){const o=n>0?n:1;return{key:wr(t,e,s,o),cm:gr(i),a:[t[0]/o,t[1]/o],b:[e[0]/o,e[1]/o]}}function $r(t,e){const i=e>0?e:1,s=[];for(const e of t){const t=e.key.lastIndexOf("@");if(t<0)continue;const[n,o]=e.key.slice(0,t).split(",").map(Number),a=Number(e.key.slice(t+1));[n,o,a].every(Number.isFinite)&&s.push({w:e,x:n*i,y:o*i,ang:a})}return s}function Sr(t,e){const[i,s]=yr(t,e);let n=Math.atan2(s,i);return n<0&&(n+=Math.PI),n}function Mr(t,e){let i=Math.abs(t-e);return i>Math.PI/2&&(i=Math.PI-i),i<.02}function Cr(t,e,i,s,n=1){if(!t?.length)return null;const o=wr(e,i,s,n),a=t.find(t=>t.key===o);if(a)return a;const r=n>0?n:1,l=(e[0]+i[0])/2,c=(e[1]+i[1])/2,h=Sr(e,i),d=Math.max(.5*s,1e-9)*r;for(const e of $r(t,r))if(Mr(e.ang,h)&&Math.hypot(e.x-l,e.y-c)<=d)return e.w;return null}function Dr(t,e,i,s,n=1){const o=Cr(t,e,i,s,n);if(o&&o.cm>0)return gr(o.cm);const a=function(t,e,i,s,n){if(!t?.length)return null;const o=n>0?n:1,a=Math.hypot(i[0]-e[0],i[1]-e[1]);if(a<1e-12)return null;const r=Sr(e,i),l=Math.max(.5*s,1e-9)*o;let c=null;for(const s of t){if(!(s.cm>0))continue;const t=kr(s,o);if(!t)continue;const n=Math.hypot(t[1][0]-t[0][0],t[1][1]-t[0][1]);if(n<1e-12||!Mr(Sr(t[0],t[1]),r))continue;if(sl(e[0],e[1],t[0][0],t[0][1],t[1][0],t[1][1])>l||sl(i[0],i[1],t[0][0],t[0][1],t[1][0],t[1][1])>l)continue;if(n+l(o.has(t.key)||(t=>{const e=kr(t,s);if(!e)return!1;const[i,o]=e,r=o[0]-i[0],c=o[1]-i[1],h=Math.hypot(r,c);if(h<=l)return!1;if(!a.some(t=>{const e=[t[0],t[1]],s=[t[2],t[3]];return Mr(Sr(i,o),Sr(e,s))&&sl(i[0],i[1],e[0],e[1],s[0],s[1])<=l&&sl(o[0],o[1],e[0],e[1],s[0],s[1])<=l}))return!1;const d=(n||[]).some(t=>{const e=[t[0],t[1]],s=[t[2],t[3]];if(!Mr(Sr(i,o),Sr(e,s)))return!1;const n=t=>Math.abs((t[0]-i[0])*c-(t[1]-i[1])*r)/h;if(n(e)>l||n(s)>l)return!1;const a=h*h,d=((e[0]-i[0])*r+(e[1]-i[1])*c)/a,u=((s[0]-i[0])*r+(s[1]-i[1])*c)/a;return Math.min(1,Math.max(d,u))-Math.max(0,Math.min(d,u))>l/h});return!d})(t))&&t.cm>=1&&t.cm<=100)}function Pr(t,e,i,s=8){const[n,o]=yr(t,e);let a=Math.atan2(o,n);a<0&&(a+=Math.PI);let r=i*Math.PI/180%Math.PI;r<0&&(r+=Math.PI);let l=Math.abs(a-r);return l>Math.PI/2&&(l=Math.PI-l),l<=s*Math.PI/180}function Rr(t,e,i,s,n=1){if(!t?.length)return[];if(e.length!==i.length)return t.slice();const o=new Map;for(let t=0;t0?n:1,r=Math.max(.5*s,1e-9)*a,l=new Set,c=[];for(const n of t){let t="",h=null;const d=kr(n,a);if(d)for(let n=0;nr||sl(d[1][0],d[1][1],o[0],o[1],l[0],l[1])>r)continue;const p=l[0]-o[0],_=l[1]-o[1],g=p*p+_*_;if(g<1e-18)continue;const m=t=>{const e=Math.max(0,Math.min(1,((t[0]-o[0])*p+(t[1]-o[1])*_)/g));return[c[0]+(u[0]-c[0])*e,c[1]+(u[1]-c[1])*e]};h=[m(d[0]),m(d[1])],t=wr(h[0],h[1],s,a);break}if(d||(t=o.get(n.key)||""),!t){const o=$r([n],a)[0];if(o)for(let n=0;n1.000001)continue;if(sl(o.x,o.y,l[0],l[1],c[0],c[1])>r)continue;const m=h[0]+(d[0]-h[0])*Math.max(0,Math.min(1,g)),f=h[1]+(d[1]-h[1])*Math.max(0,Math.min(1,g)),[v,y]=yr(h,d),b=Math.max(s*a,1e-6);t=wr([m-v*b,f-y*b],[m+v*b,f+y*b],s,a);break}}t||(t=n.key),l.has(t)||(l.add(t),c.push(h?xr(h[0],h[1],n.cm,s,a):{...n,key:t,cm:gr(n.cm)}))}return c}function Ar(t,e,i,s,n,o=1){const a=wr(e,i,n,o),r=(t||[]).filter(t=>t.key!==a);return null==s||s<1?r:[...r,xr(e,i,s,n,o)]}function Ir(t,e,i,s,n,o=[],a=1){let r=t?t.slice():[];for(const t of function(t,e,i,s,n=1,o=[]){const a=Xr(t,e,i,s,n,o);if(!a)return[];const r=[];for(let t=0;t0||(c=Ar(c,e,i,s,n,a)))}return c}function Fr(t){const{a:e,b:i,halfDepth:s}=t;if(!Array.isArray(e)||!Array.isArray(i)||e.length<2||i.length<2||![e[0],e[1],i[0],i[1]].every(Number.isFinite))return null;const n=i[0]-e[0],o=i[1]-e[1],a=Math.hypot(n,o);if(!(a>1e-9&&s>0&&Number.isFinite(s)))return null;const r=-o/a*s,l=n/a*s;return[[e[0]+r,e[1]+l],[i[0]+r,i[1]+l],[i[0]-r,i[1]-l],[e[0]-r,e[1]-l]]}function zr(t,e,i){return Math.hypot(t[0]-e[0],t[1]-e[1])<=i}function Or(t,e,i){const s=e.b[0]-e.a[0],n=e.b[1]-e.a[1],o=s*s+n*n;if(!(o>i*i))return!1;const a=((t[0]-e.a[0])*s+(t[1]-e.a[1])*n)/o;if(!(a>0&&a<1))return!1;const r=[e.a[0]+s*a,e.a[1]+n*a];return Math.hypot(t[0]-r[0],t[1]-r[1])<=i}function Hr(t,e,i,s){const n=Math.hypot(e,i);if(!(n>1e-9&&s>0))return;const o=[e/n,i/n],a=t.find(t=>Math.abs(t.u[0]*o[1]-t.u[1]*o[0])<1e-9&&t.u[0]*o[0]+t.u[1]*o[1]>1-1e-9);a?a.halfDepth=Math.max(a.halfDepth,s):t.push({u:o,halfDepth:s})}function Nr(t,e=1e-6){const i=(t||[]).filter(t=>t&&Array.isArray(t.a)&&Array.isArray(t.b)&&t.a.length>=2&&t.b.length>=2&&t.a.every(Number.isFinite)&&t.b.every(Number.isFinite)&&Number.isFinite(t.halfDepth)&&t.halfDepth>0&&Math.hypot(t.b[0]-t.a[0],t.b[1]-t.a[1])>1e-9);if(i.length<2)return[];const s=Math.max(Number.isFinite(e)?e:0,1e-9),n=i.flatMap(t=>[t.a,t.b]).map(t=>[t[0],t[1]]).sort((t,e)=>t[0]-e[0]||t[1]-e[1]),o=[];for(const t of n)o.some(e=>zr(e,t,s))||o.push(t);const a=[];for(const t of o){const e=[];for(const n of i)zr(t,n.a,s)?Hr(e,n.b[0]-n.a[0],n.b[1]-n.a[1],n.halfDepth):zr(t,n.b,s)?Hr(e,n.a[0]-n.b[0],n.a[1]-n.b[1],n.halfDepth):Or(t,n,s)&&(Hr(e,n.a[0]-t[0],n.a[1]-t[1],n.halfDepth),Hr(e,n.b[0]-t[0],n.b[1]-t[1],n.halfDepth));if(!(e.length<2)){e.sort((t,e)=>Math.atan2(t.u[1],t.u[0])-Math.atan2(e.u[1],e.u[0])||t.halfDepth-e.halfDepth);for(let i=0;is*s&&a.push(m)}}}return a}function Lr(t,e,i,s){if(!(e>0)||!t||t.length<2)return"";if(i&&t.length>=3){let i=t;const n=t[t.length-1];if(t.length>=4&&Math.hypot(t[0][0]-n[0],t[0][1]-n[1])<1e-9&&(i=t.slice(0,-1)),i.length>=3){const t=i.map((t,i)=>s?.[i]||e),n=_l(i,t),o=Vr(i,t);if(n&&o)return`${Kr(n)} ${Kr(Yr(o))}`}}const n=[];for(let i=0;i=1e-9&&r>0&&n.push({a:o,b:a,halfDepth:r})}const o=[...n.map(Fr).filter(t=>!!t),...Nr(n)],a=function(t){let e=null;try{for(const i of t){if(i.length<3)continue;const t=ol(i);e=e?si(e,t):[t]}return e}catch{return null}}(o);return a?hl(a):o.map(t=>Kr(t)).join(" ")}function Br(t,e,i,s,n=1){if(!i.length)return!1;const o=qr(s,n),a=(t[0]+e[0])/2,r=(t[1]+e[1])/2,[l,c]=yr(t,e);for(const t of i){const[e,i]=yr([t[0],t[1]],[t[2],t[3]]);if(!(Math.abs(l*i-c*e)>.05)&&sl(a,r,t[0],t[1],t[2],t[3])<=o)return!0}return!1}function qr(t,e){return Math.max(t*(e>0?e:1)*.04,1e-9)}function jr(t){let e=0;for(let i=0;it[1]!=l>t[1]&&t[0]<(r-o)*(t[1]-a)/(l-a+0)+o&&(i=!i)}return i}([c[0]+.001*r,c[1]+.001*l],t)||(r=-r,l=-l),[r,l]}function Ur(t,e){const i=t[0]*e[1]-t[1]*e[0],s=t[0]*e[0]+t[1]*e[1];return Math.abs(i)<1e-9&&s>0}function Gr(t,e,i,s){const n=e[0]*s[1]-e[1]*s[0];if(Math.abs(n)<1e-12)return null;const o=[i[0]-t[0],i[1]-t[1]],a=(o[0]*s[1]-o[1]*s[0])/n;return[t[0]+a*e[0],t[1]+a*e[1]]}function Vr(t,e){const i=t?.length||0;if(i<3||e.length!==i)return null;if(e.every(t=>!(t>0)))return t.map(t=>[t[0],t[1]]);const s=[];for(let n=0;n0||d>0)){s.push([t[n][0],t[n][1]]);continue}if(h>0!=d>0){const e=t[n],i=h>0?[e[0]+u*h,e[1]+p*h]:[e[0],e[1]],o=d>0?[e[0]+_*d,e[1]+g*d]:[e[0],e[1]];s.push(i),Math.hypot(o[0]-i[0],o[1]-i[1])>1e-9&&s.push(o);continue}if(Ur(b,w)){const e=t[n],i=[e[0]+u*h,e[1]+p*h],o=[e[0]+_*d,e[1]+g*d];s.push(i),Math.hypot(o[0]-i[0],o[1]-i[1])>1e-9&&s.push(o);continue}const $=Gr(k,b,x,w),S=Math.max(h,d,1e-9);if($){if(Math.hypot($[0]-t[n][0],$[1]-t[n][1])<=4*S){s.push($);continue}}h>0&&s.push([t[n][0]+u*h,t[n][1]+p*h]),d>0&&s.push([t[n][0]+_*d,t[n][1]+g*d]),h>0||d>0||s.push([t[n][0],t[n][1]])}return s.length>=3?s:null}function Kr(t,e=!0){if(!t.length)return"";let i=`M ${t[0][0]} ${t[0][1]}`;for(let e=1;et?.id===e),r=hi(a);if(!r||r.length<3)return null;const l=qr(s,n),c=[];for(const i of t||[]){if(!i||i.id===e)continue;const t=hi(i);if(t)for(const e of Cs(r,t,l))c.push([e[0],e[1]],[e[2],e[3]])}for(const t of i||[])c.push([t[0],t[1]],[t[2],t[3]]);for(const t of o||[]){const e=kr(t,n);e&&c.push(e[0],e[1])}const h=[],d=[];for(let t=0;tl)continue;const a=((t[0]-e[0])*(i[0]-e[0])+(t[1]-e[1])*(i[1]-e[1]))/(s*s);a<=n||a>=1-n||(o.some(t=>Math.abs(t-a)*s<=2*l)||o.push(a))}o.sort((t,e)=>t-e);for(const s of o)h.push([e[0]+(i[0]-e[0])*s,e[1]+(i[1]-e[1])*s]),d.push(t)}return{poly:h,parent:d,orig:r}}function Jr(t,e,i,s){const n=e.poly.length,o=new Array(n).fill(0);if(!t?.length)return o;const a=new Set,r=[];for(let l=0;l0?(o[l]=gr(c.cm),a.add(c.key)):r.push(l)}if(!r.length)return o;const l=s>0?s:1,c=Math.max(.5*i,1e-9)*l,h=$r(t,l).filter(t=>t.w.cm>0);for(let t=r.length-1;t>=0;t--){const i=r[t],s=e.poly[i],a=e.poly[(i+1)%n],d=Sr(s,a);let u=null;for(const t of h){const e=kr(t.w,l);if(!e||!Mr(Sr(e[0],e[1]),d))continue;if(sl(s[0],s[1],e[0][0],e[0][1],e[1][0],e[1][1])>c||sl(a[0],a[1],e[0][0],e[0][1],e[1][0],e[1][1])>c)continue;const i=Math.hypot(a[0]-s[0],a[1]-s[1]),n=Math.hypot(e[1][0]-e[0][0],e[1][1]-e[0][1]),o=Math.max(0,n-i);(!u||oc||sl(n[0],n[1],e[0][0],e[0][1],e[1][0],e[1][1])>c)continue;i=!0,o=Math.max(0,Math.hypot(e[1][0]-e[0][0],e[1][1]-e[0][1])-_)}else{if(sl(t.x,t.y,s[0],s[1],n[0],n[1])>c)continue;o=Math.hypot(t.x-d,t.y-u)}(!p||i&&!p.exact||i===p.exact&&ot?.id===e),n=hi(s);if(!n)return[];const o=[];for(const s of t||[]){if(!s||s.id===e)continue;const t=hi(s);if(t)for(const e of Cs(n,t,i))o.push(e)}return o}(t,e,qr(n,r)),h=function(t,e,i,s,n){const o=qr(s,n),a=[];for(let r=0;rsl(h,d,t[0],t[1],t[2],t[3])<=o);a.push(u?"shared":"outer")}return a}(l.poly,c,s,n,r),d=Jr(i,l,n,r),u=d.map((t,e)=>h[e]&&t>0?fr(t,o,a)/2:0);return{...l,kinds:h,cms:d,offsets:u}}function Qr(t,e,i,s,n,o,a=1){const r=[];for(const l of t||[]){if(!l?.id)continue;const c=Zr(t,l.id,e,i,s,n,o,a);if(c)for(let t=0;t0&&(r=Ar(r,t.a,t.b,t.cm,s,a));return r}function el(t,e,i,s,n,o,a=1){if(!e?.length)return[];const r=[],l=new Set;for(const c of Qr(t,e,i,s,n,o,a))!c.open&&c.cm>0&&!l.has(c.key)&&(l.add(c.key),r.push(c));const c=[];for(const r of t||[]){if(!r?.id)continue;const l=Zr(t,r.id,e,i,s,n,o,a);if(l)for(let t=0;t0)||null===l.kinds[i]){t++;continue}let o=t;for(;o+10&&c.push({a:[h[0],h[1]],b:[d[0],d[1]],key:wr(h,d,s,a),cm:n,len:u}),t=o+1}}}c.sort((t,e)=>e.len-t.len||t.key.localeCompare(e.key));const h=[],d=new Set,u=new Set,p=4*qr(s,a);for(const t of c){const e=r.filter(e=>!u.has(e.key)&&e.cm===t.cm&&Mr(Sr(e.a,e.b),Sr(t.a,t.b))&&sl(e.a[0],e.a[1],t.a[0],t.a[1],t.b[0],t.b[1])<=p&&sl(e.b[0],e.b[1],t.a[0],t.a[1],t.b[0],t.b[1])<=p);if(e.length){for(const t of e)u.add(t.key);d.has(t.key)||(d.add(t.key),h.push(xr(t.a,t.b,t.cm,s,a)))}}for(const t of r)u.has(t.key)||d.has(t.key)||(d.add(t.key),h.push(xr(t.a,t.b,t.cm,s,a)));return h}function il(t,e,i,s,n,o,a,r=1){const l=qr(n,r),c=(s[0]+s[2])/2,h=(s[1]+s[3])/2,d=Sr([s[0],s[1]],[s[2],s[3]]);let u=null;for(const s of Qr(t,e,i,n,o,a,r)){if(!Mr(Sr(s.a,s.b),d))continue;const t=sl(c,h,s.a[0],s.a[1],s.b[0],s.b[1]);t>4*l||(!u||tt?.id===e),c=hi(l);if(!c||c.length<3)return null;if(!i?.length)return c.map(t=>[t[0],t[1]]);const h=Zr(t,e,i,s,n,o,a,r);return h&&h.offsets.some(t=>t>0)&&Vr(h.poly,h.offsets)||c.map(t=>[t[0],t[1]])}function ol(t){const e=t.map(t=>[t[0],t[1]]);return e.push([t[0][0],t[0][1]]),[e]}function al(t,e=1){if(!Array.isArray(t)||t.length<3)return null;const i=Number.isFinite(e)&&e>0?e:1,s=1e-12*Math.max(1,i),n=[];for(const e of t){if(!Array.isArray(e)||e.length<2)return null;const t=Number(e[0]),i=Number(e[1]);if(!Number.isFinite(t)||!Number.isFinite(i))return null;const o=Math.round(t/s)*s,a=Math.round(i/s)*s;if(!Number.isFinite(o)||!Number.isFinite(a))return null;n.push([Object.is(o,-0)?0:o,Object.is(a,-0)?0:a])}return Math.abs(jr(n))>s*s?n:null}function rl(t,e,i,s){if(sl(t[0],t[1],e[0],e[1],i[0],i[1])>s)return!1;const n=i[0]-e[0],o=i[1]-e[1],a=(t[0]-e[0])*n+(t[1]-e[1])*o,r=n*n+o*o,l=s*Math.sqrt(r);return a>=-l&&a<=r+l}function ll(t,e,i){const s=[],n=[];for(let o=0;oi*i))continue;const d=i/Math.sqrt(h),u=[0,1];for(const t of e)for(const e of[t.a,t.b]){if(!rl(e,a,r,i))continue;const t=((e[0]-a[0])*l+(e[1]-a[1])*c)/h;t>d&&t<1-d&&u.push(t)}u.sort((t,e)=>t-e);const p=u.filter((t,e)=>0===e||Math.abs(t-u[e-1])>d);for(let t=0;t=3&&n.length===s.length?{poly:s,offsets:n}:null}function cl(t,e,i,s,n,o,a){const r=(t||[]).map(hi).filter(t=>!!t&&t.length>=3);if(!r.length)return null;let l=si(ol(r[0]));for(let t=1;t"outer"===t.kind&&t.half>0),h=4*qr(s,a);let d=null;for(const t of function(t){const e=[];for(const i of Array.isArray(t)?t:[])if(Array.isArray(i))for(const t of i){if(!Array.isArray(t)||t.length<4)continue;const i=t.slice(0,-1).map(t=>[t[0],t[1]]);i.length>=3&&e.push(i)}return e}(l)){const e=ll(t,c,h);if(!e||!e.offsets.some(t=>t>0))continue;const i=_l(e.poly,e.offsets),s=Vr(e.poly,e.offsets);if(!i||!s)continue;const n=oi(ol(i),ol(s));d=d?si(d,n):n}return{centre:l,shell:d||[]}}function hl(t){if(!t)return"";let e="";for(const i of t)if(Array.isArray(i))for(const t of i){if(!Array.isArray(t)||t.length<4)continue;const i=t.slice(0,t.length-1);i.length<3||(e+=(e?" ":"")+Kr(i.map(t=>[t[0],t[1]])))}return e}function dl(t,e,i,s=[],n,o,a,r=1,l=[]){if(!e?.length&&!l.length)return null;const c=[];let h=0;for(const s of t||[]){if(!s?.id)continue;const l=Zr(t,s.id,e,i,n,o,a,r);if(!l||l.poly.length<3||!l.offsets.some(t=>t>0))continue;for(const t of l.offsets)t>0&&(h=Math.max(h,2*t));const d=_l(l.poly,l.offsets),u=Vr(l.poly,l.offsets);d&&c.push({outset:d,inset:u})}for(const t of l){const e=t.map(t=>t[0]),i=t.map(t=>t[1]);if(e.length){const s=Math.min(Math.max(...e)-Math.min(...e),Math.max(...i)-Math.min(...i)),n=Math.min(...t.map((e,i)=>{const s=t[(i+1)%t.length];return Math.hypot(s[0]-e[0],s[1]-e[1])}));h=Math.max(h,t.length>16?s:n)}}const d=function(t,e,i,s,n,o,a){if(!e?.length||!i?.length)return[];const r=4*qr(s,a),l=new Map;for(const r of Qr(t,e,i,s,n,o,a))!r.open&&r.half>0&&!l.has(r.key)&&l.set(r.key,r);const c=[...l.values()];if(c.length<2)return[];const h=[];for(const t of i)for(const e of[[t[0],t[1]],[t[2],t[3]]])h.some(t=>Math.hypot(t[0]-e[0],t[1]-e[1])<=r)||h.push(e);const d=[],u=(t,e)=>{let i=0,s=0;if(Math.hypot(t.a[0]-e[0],t.a[1]-e[1])<=r)i=t.b[0]-t.a[0],s=t.b[1]-t.a[1];else{if(!(Math.hypot(t.b[0]-e[0],t.b[1]-e[1])<=r))return null;i=t.a[0]-t.b[0],s=t.a[1]-t.b[1]}const n=Math.hypot(i,s);return n>r?[i/n,s/n]:null};for(const t of h){const e=c.map(e=>({iv:e,u:u(e,t)})).filter(t=>!!t.u);for(let i=0;i4*_||d.push(a>0?[t.slice(),h,p,u]:[t.slice(),u,p,h])}}return d}(t,e,i,n,o,a,r),u=s.length?gl(t,e,i,n,o,a,r):null;try{const p=cl(t,e,i,n,o,a,r),_=p?p.shell?.length?si(p.centre,p.shell):p.centre:[],g=t=>{const e=ol(t.outset);return t.inset?oi(e,ol(t.inset)):e};let m=null;for(const t of c)try{const e=g(t);m=m?si(m,e):e}catch{}if(p)for(const s of pl(t,e,i,n,o,a,r))try{const t=ni(ol(s.quad),p.centre);m=m?si(m,t):t}catch{}m=function(t,e,i=1,s=si){let n=t;for(const t of e||[]){const e=al(t,i);if(e)try{const t=ol(e);n=n?s(n,t):t}catch{}}return n}(m,d,r),m&&p&&(m=ni(m,p.centre)),p?.shell?.length&&(m=m?si(m,p.shell):p.shell);for(const t of s){if(!(t.length>0))continue;const e=vl(u,t,!0);if(!e.negative&&!e.positive)continue;const i=t.angle*Math.PI/180,s=Math.cos(i),o=Math.sin(i),a=-o,l=s,c=t.length/2,d=1.25*Math.max(h,n*r),p=[[t.x-s*c-a*d,t.y-o*c-l*d],[t.x+s*c-a*d,t.y+o*c-l*d],[t.x+s*c+a*d,t.y+o*c+l*d],[t.x-s*c+a*d,t.y-o*c+l*d]];m&&(m=oi(m,ol(p)))}for(const t of l)t.length<3||(m=m?si(m,ol(t)):[ol(t)]);return{geom:m||[],paperGeom:_,depthUnits:h,openingIndex:u}}catch{return null}}function ul(t,e,i,s=[],n,o,a,r=1,l=[]){if(!e?.length&&!l.length)return null;const c=dl(t,e,i,s,n,o,a,r,l),h=c?hl(c.geom):"",d=c?hl(c.paperGeom):"";return c&&h?{d:h,paperD:d,depthUnits:c.depthUnits,fillRule:"evenodd"}:null}function pl(t,e,i,s,n,o,a=1){if(!e?.length)return[];const r=new Set,l=[];for(const c of t||[]){if(!c?.id)continue;const h=Zr(t,c.id,e,i,s,n,o,a);if(!h)continue;const d=h.poly;for(let t=0;t0))continue;const p=wr(e,i,s,a);if(r.has(p))continue;r.add(p);const _=fr(u,n,o),[g,m]=Wr(d,t),f=-g,v=-m,y=_/2,b=[[e[0]+f*y,e[1]+v*y],[i[0]+f*y,i[1]+v*y],[i[0]+g*y,i[1]+m*y],[e[0]+g*y,e[1]+m*y]];l.push({key:p,kind:c,cm:u,quad:b,a:[e[0],e[1]],b:[i[0],i[1]],depthUnits:_})}}return l}function _l(t,e){const i=t?.length||0;if(i<3||e.length!==i)return null;if(e.every(t=>!(t>0)))return t.map(t=>[t[0],t[1]]);Yr(t),e.slice().reverse();const s=[];for(let n=0;n0||r>0)){s.push([t[n][0],t[n][1]]);continue}if(a>0!=r>0){const e=t[n],i=a>0?[e[0]-l*a,e[1]-c*a]:[e[0],e[1]],o=r>0?[e[0]-h*r,e[1]-d*r]:[e[0],e[1]];s.push(i),Math.hypot(o[0]-i[0],o[1]-i[1])>1e-9&&s.push(o);continue}if(Ur(b,w)){const e=t[n],i=[e[0]-l*a,e[1]-c*a],o=[e[0]-h*r,e[1]-d*r];s.push(i),Math.hypot(o[0]-i[0],o[1]-i[1])>1e-9&&s.push(o);continue}const $=Gr(k,b,x,w),S=Math.max(a,r,1e-9);if($){if(Math.hypot($[0]-t[n][0],$[1]-t[n][1])<=4*S){s.push($);continue}}a>0&&s.push([t[n][0]-l*a,t[n][1]-c*a]),r>0&&s.push([t[n][0]-h*r,t[n][1]-d*r])}return s.length>=3?s:null}function gl(t,e,i,s,n,o,a=1){const r=[];for(const l of t||[]){if(!l?.id)continue;const c=Zr(t,l.id,e,i,s,n,o,a);if(!c)continue;const h=Math.abs(Pi(c.poly));for(let t=0;t[Math.max(e,t.x0),Math.min(i,t.x1)]).filter(t=>t[1]-t[0]>s).sort((t,e)=>t[0]-e[0]||t[1]-e[1]);if(!n.length)return{coverage:0,full:!1};let o=n[0][0],a=n[0][1],r=0,l=o<=e+s;for(let t=1;t=i-s,{coverage:r,full:l}}function fl(t,e){return Number(e.full)-Number(t.full)||t.faceDistance-e.faceDistance||t.area-e.area||t.roomId.localeCompare(e.roomId)}function vl(t,e,i=!1){const s=Number(e?.x),n=Number(e?.y),o=Number(e?.angle),a=Number(e?.length);if(!([s,n,o,a].every(Number.isFinite)&&a>0))return{negative:null,positive:null};const r=o*Math.PI/180,l=Math.cos(r),c=Math.sin(r),h=-c,d=l,u=a/2,p=Math.max(1e-9,t.adjacencyEps),_=new Map;let g=0;for(const e of t.edges){if(i&&!(e.half>0))continue;if(!Pr(e.a,e.b,o))continue;const[t,a]=yr(e.a,e.b);if(Math.abs((s-e.a[0])*a-(n-e.a[1])*t)>p)continue;const r=(e.a[0]-s)*l+(e.a[1]-n)*c,m=(e.b[0]-s)*l+(e.b[1]-n)*c,f=Math.max(-u,Math.min(r,m)),v=Math.min(u,Math.max(r,m));if(v-f<=p)continue;const y=e.inward[0]*h+e.inward[1]*d>=0?1:-1,b=((e.a[0]+e.b[0])/2-s)*h+((e.a[1]+e.b[1])/2-n)*d,w=Math.abs(b+y*e.half),k=`${y}|${e.roomId}`,x={x0:f,x1:v,half:e.half,cm:e.cm,key:e.key,axis:[t,a]},$=_.get(k);$?($.pieces.push(x),$.faceDistance=Math.min($.faceDistance,w)):_.set(k,{roomId:e.roomId,side:y,order:g++,pieces:[x],faceDistance:w,area:e.area,coverage:0,full:!1})}for(const t of _.values()){const e=ml(t.pieces,-u,u,p);t.coverage=e.coverage,t.full=e.full}const m=t=>{const e=[..._.values()].filter(e=>e.side===t&&e.coverage>p);return e.sort(fl),e[0]||null};return{negative:m(-1),positive:m(1)}}function yl(t,e){const i=vl(t,e),s=[i.negative,i.positive].filter(t=>!!t).sort((t,e)=>t.order-e.order);if(!s.length)return{ox:0,oy:0,cm:0,side:-1};const n=s[0],o=e.flip_v?-n.side:n.side,a=(-1===o?i.negative:i.positive)||n,r=[...a.pieces].sort((t,e)=>(t.x0<=0&&t.x1>=0?0:Math.min(Math.abs(t.x0),Math.abs(t.x1)))-(e.x0<=0&&e.x1>=0?0:Math.min(Math.abs(e.x0),Math.abs(e.x1)))||e.x1-e.x0-(t.x1-t.x0)||t.key.localeCompare(e.key))[0];if(!(r.half>0&&r.cm>0))return{ox:0,oy:0,cm:0,side:o};const l=e.angle*Math.PI/180,c=-Math.sin(l),h=Math.cos(l);return{ox:c*o*r.half,oy:h*o*r.half,cm:r.cm,side:o}}function bl(t,e){const i=1e-9,s=e.filter(t=>Number.isFinite(t.x0)&&Number.isFinite(t.x1)&&Number.isFinite(t.half)&&t.x1>t.x0&&t.half>0);if(!s.length)return"";const n=s.flatMap(t=>[t.x0,t.x1]).sort((t,e)=>t-e),o=[];for(const t of n){const e=o[o.length-1];(void 0===e||t>e+i)&&o.push(t)}const a=[];for(let t=0;t+1e+i))continue;const r=(e+n)/2,l=s.reduce((t,e)=>r>=e.x0-i&&r<=e.x1+i?Math.max(t,e.half):t,0);if(!(l>0))continue;const c=a[a.length-1];c&&e<=c.x1+i&&Math.abs(l-c.half)<=i?c.x1=n:a.push({x0:e,x1:n,half:l})}const r=[];for(const t of a){const e=r[r.length-1],s=e?.[e.length-1];s&&t.x0<=s.x1+i?(t.x0=s.x1,e.push(t)):r.push([t])}return r.map(e=>{const i=e[0],s=e[e.length-1],n=Math.min(.25*Math.min(...e.map(t=>t.half)),.75),o=-t*n,a=[];if(1===t){a.push(`M ${i.x0} ${o} L ${s.x1} ${o}`);for(let t=e.length-1;t>=0;t--){const i=e[t];a.push(`L ${i.x1} ${i.half} L ${i.x0} ${i.half}`)}}else{a.push(`M ${s.x1} ${o} L ${i.x0} ${o}`);for(const t of e)a.push(`L ${t.x0} ${-t.half} L ${t.x1} ${-t.half}`)}return a.push("Z"),a.join(" ")}).join(" ")}function wl(t,e,i,s){if(!s)return i;const n=t.angle*Math.PI/180,o=Math.cos(n),a=Math.sin(n),r=[],l=1e-9;for(const n of i){const[i,c]=n.axis,h=o*i+a*c;if(Math.abs(h)<=l)continue;const d=t.x*i+t.y*c,u=d+h*n.x0,p=d+h*n.x1,_=Math.min(u,p),g=Math.max(u,p),m=`${n.key}|${e}`,f=s.get(m)||[];let v=[[_,g]];for(const[t,e]of f){const i=[];for(const[s,n]of v)e<=s+l||t>=n-l?i.push([s,n]):(t>s+l&&i.push([s,Math.min(n,t)]),et[0]-e[0]||t[1]-e[1]),b=[];for(const t of y){const e=b[b.length-1];e&&t[0]<=e[1]+l?e[1]=Math.max(e[1],t[1]):b.push([t[0],t[1]])}s.set(m,b)}return r}function kl(t,e){const i=new Map;return e.map(e=>function(t,e,i){const s=vl(t,e,!0),n=s.negative,o=s.positive;if(!n&&!o)return null;let a;if(n&&o)a=[{candidate:n,side:-1},{candidate:o,side:1}];else{const t=n||o;a=[{candidate:t,side:-1},{candidate:t,side:1}]}const r=a.map(({candidate:t,side:s})=>({candidate:t,side:s,pieces:wl(e,s,t.pieces,i)})),l=r.map(({candidate:t,side:e,pieces:i})=>({side:e,roomId:t.roomId,d:bl(e,i)})),c=r.flatMap(({pieces:t})=>t);if(!c.length)return null;const h=Math.max(...c.map(t=>t.half));return{faces:l,minY:-h,maxY:h,wallKey:[...new Set(c.map(t=>t.key))].sort().join("|")}}(t,e,i))}const xl=150;function $l(t){return Number.isFinite(t)?Math.max(1,Math.min(xl,t)):1}function Sl(t){return((Number.isFinite(Number(t))?Number(t):0)%90+90)%90}const Ml=t=>{const e=t.map(t=>[t[0],t[1]]);return!e.length||e[0][0]===e[e.length-1][0]&&e[0][1]===e[e.length-1][1]||e.push([...e[0]]),[e]};function Cl(t){const e=[];for(const i of t||[])for(const t of i||[]){const i=(t||[]).filter(t=>Array.isArray(t)&&t.length>=2);i.length<4||e.push(`M ${i.slice(0,-1).map(t=>`${t[0]} ${t[1]}`).join(" L ")} Z`)}return e.join(" ")}function Dl(t,e,i,s,n){return Fr({a:t,b:e,halfDepth:fr(i,s,n)/2})}function Tl(t,e,i){const s=Number(e)>0?Number(e):5,n=$l(t.cm)/s*i,o=t.center[0],a=t.center[1];if("circle"===t.shape){const t=n/2;return Array.from({length:96},(e,i)=>{const s=i/96*Math.PI*2;return[o+Math.cos(s)*t,a+Math.sin(s)*t]})}const r=n/2,l=Sl(t.angle)*Math.PI/180,c=Math.cos(l),h=Math.sin(l);return[[-r,-r],[r,-r],[r,r],[-r,r]].map(([t,e])=>[o+t*c-e*h,a+t*h+e*c])}function Pl(t,e,i=1e-9){if(!e.length)return[t];let s=[Ml(t)];try{for(const t of e){const e=t.b[0]-t.a[0],n=t.b[1]-t.a[1],o=Math.hypot(e,n);if(!(o>i))continue;const a=e/o,r=n/o,l=-r,c=a,h=1.25*Math.max(Number(t.depth)||0,4*i),d=Math.max(2*i,1e-9*o),u=[[t.a[0]-a*d-l*h,t.a[1]-r*d-c*h],[t.b[0]+a*d-l*h,t.b[1]+r*d-c*h],[t.b[0]+a*d+l*h,t.b[1]+r*d+c*h],[t.a[0]-a*d+l*h,t.a[1]-r*d+c*h]];s=oi(s,Ml(u))}return Ol(s)}catch{return[t]}}function Rl(t,e,i,s=Math.max(2e-4*i,1e-9),n=[]){const o=[],a=[],r=new Map;for(const t of n){const e=r.get(t.hostId)||[];e.push(t),r.set(t.hostId,e)}const l=[],c=[],h=[];for(const s of t.room_drafts||[])for(let t=0;t+1Tl(t,e,i)),u=Nr([...o,...a],s).flatMap(t=>Pl(t,n,s));return{drafts:l,partitions:c,columns:d,patches:u,all:[...l,...h,...u,...d]}}function Al(t){try{const e=t.filter(t=>t.length>=3).map(t=>Ml(t));return e.length?si(e[0],...e.slice(1)):null}catch{return null}}const Il=t=>`M ${t.map(t=>`${t[0]} ${t[1]}`).join(" L ")} Z`;function El(t,e){const i=Al(t.filter(t=>t.length>=3)),s=Al(e.filter(t=>t.length>=3));if(!i)return[];if(!s)return[];try{return function(t){const e=[];for(const i of t||[]){if(zl([i])<=1e-6)continue;const t=[];for(const e of i||[]){const i=(e||[]).filter(t=>Array.isArray(t)&&t.length>=2);i.length<4||t.push(Il(i.slice(0,-1)))}t.length&&e.push(t.join(" "))}return e}(ni(i,s))}catch{return[]}}function Fl(t,e){if(!e.length)return[Ml(t)];try{const i=Al(e);if(i)return oi(Ml(t),i)}catch{}let i=[Ml(t)];for(const t of e)if(!(t.length<3))try{i=oi(i,Ml(t))}catch{}return i}function zl(t){let e=0;for(const i of t||[])if(i?.length){e+=Pi(i[0]||[]);for(let t=1;t=4&&e.push(t.slice(0,-1).map(t=>[t[0],t[1]]))}return e}function Hl(t,e){let i=!1;for(let s=0,n=e.length-1;st[1]!=l>t[1]&&t[0]<(r-o)*(t[1]-a)/(l-a||1e-12)+o&&(i=!i)}return i}function Nl(t,e,i){return function(t,e){for(const i of e||[]){const e=i?.[0];if(!e?.length||!Hl(t,e))continue;let s=!1;for(let e=1;eHl(t,e))}function Ll(t,e,i){if(Math.hypot(t.center[0]-e.center[0],t.center[1]-e.center[1])>i)return!1;if(Math.abs($l(t.cm)-$l(e.cm))>1e-6)return!1;if(t.shape!==e.shape)return!0;if("circle"===t.shape||"circle"===e.shape)return!0;const s=Math.abs(Sl(t.angle)-Sl(e.angle));return Math.min(s,90-s)<=1e-6}const Bl=1e3;function ql(t,e){const i=Number(t),s=Number.isFinite(i)&&i>0?i:1,n=s>=1?e:e*s,o=s>=1?e/s:e;return{x:(e-n)/2,y:(e-o)/2,w:n,h:o}}const jl=.01,Wl=100;function Ul(t,e=1e3){const i=ql(t?.plan_aspect,e),s=Number(t?.plan_scale),n=Number.isFinite(s)&&s>0?Math.min(Wl,Math.max(jl,s)):1,o=Number(t?.plan_scale_x),a=Number(t?.plan_scale_y),r=Number.isFinite(o)&&o>0?Math.min(Wl,Math.max(jl,o)):n,l=Number.isFinite(a)&&a>0?Math.min(Wl,Math.max(jl,a)):n,c=Number(t?.plan_x),h=Number(t?.plan_y),d=sr(t?.plan_angle);return{x:i.x+(Number.isFinite(c)?ic(c):0)*e,y:i.y+(Number.isFinite(h)?ic(h):0)*e,w:i.w*r,h:i.h*l,...d?{angle:d}:{}}}function Gl(t){if(null==t.x||null==t.y)return{x:t.x,y:t.y,w:t.w,h:t.h};const e=Number(t.w)||0,i=Number(t.h)||0;return{x:e<0?t.x+e:t.x,y:i<0?t.y+i:t.y,w:Math.abs(e),h:Math.abs(i)}}function Vl(t){return t&&Array.isArray(t.spaces)?t.spaces.map(t=>{const e=Bl,i=function(t){return Array.isArray(t)&&4===t.length&&t.every(t=>Number.isFinite(t))&&t[2]>1e-6&&t[3]>1e-6?t:[0,0,1,1]}(t.view_box);return{id:t.id,title:t.title,vb:[i[0]*Bl,i[1]*e,i[2]*Bl,i[3]*e],bg:t.plan_url?{href:Is(t.plan_url),...Ul(t,Bl)}:null,rooms:(t.rooms||[]).map(t=>{const i={...t,...Gl(t)};return{id:i.id,name:i.name,area:i.area??null,open_to:i.open_to||void 0,settings:i.settings||void 0,x:null!=i.x?i.x*Bl:void 0,y:null!=i.y?i.y*e:void 0,w:null!=i.w?i.w*Bl:void 0,h:null!=i.h?i.h*e:void 0,poly:i.poly?i.poly.map(t=>[t[0]*Bl,t[1]*e]):void 0}}),room_drafts:(t.room_drafts||[]).map(t=>({id:t.id,points:(t.points||[]).map(t=>[t[0]*Bl,t[1]*e]),segments:(t.segments||[]).map(t=>({cm:Number(t.cm)}))})),partitions:(t.partitions||[]).map(t=>({id:t.id,a:[t.a[0]*Bl,t.a[1]*e],b:[t.b[0]*Bl,t.b[1]*e],cm:Number(t.cm)})),wall_columns:(t.wall_columns||[]).map(t=>({id:t.id,shape:"circle"===t.shape?"circle":"square",center:[t.center[0]*Bl,t.center[1]*e],cm:Number(t.cm),..."circle"===t.shape?{}:{angle:Sl(t.angle)}}))}}):[]}const Kl=5e3,Yl=Kl*Bl,Xl=240,Jl=Bl/Xl,Zl=1/Xl;function Ql(t){if(!Number.isFinite(t))return t;const e=Math.round(t*Xl/Bl)*Bl/Xl;return Math.abs(e-t)<=1e-9*Jl?t:e}function tc(t){return{x:Ql(t.x),y:Ql(t.y)}}function ec(t){return Number.isFinite(t)?Math.min(Yl,Math.max(-Yl,t)):0}function ic(t){return Number.isFinite(t)?Math.min(Kl,Math.max(-Kl,t)):0}const sc=1/3,nc=200;function oc(t){let e=1/0,i=1/0,s=-1/0,n=-1/0;for(const o of t){const t=Number(o[0]),a=Number(o[1]);Number.isFinite(t)&&Number.isFinite(a)&&(ts&&(s=t),a>n&&(n=a))}return e>s?null:{minX:e,minY:i,maxX:s,maxY:n}}function ac(t){return t.poly&&t.poly.length?oc(t.poly):null==t.x||null==t.y?null:oc([[t.x,t.y],[t.x+(t.w||0),t.y+(t.h||0)]])}function rc(t,e){const i=[];for(const e of t.rooms||[]){const t=ac(e);t&&i.push(t)}if(t.bg){const e=oc(cr(t.bg));e&&i.push(e)}for(const t of e||[])if(Array.isArray(t)){const e=oc([t]);e&&i.push(e)}else i.push(t);return i}const lc=t=>{if(!t.length)return 0;const e=[...t].sort((t,e)=>t-e),i=e.length>>1;return e.length%2?e[i]:(e[i-1]+e[i])/2},cc=t=>{let e=1/0,i=1/0,s=-1/0,n=-1/0;for(const o of t)o.minXs&&(s=o.maxX),o.maxY>n&&(n=o.maxY);return e>s||i>n?null:{x:e,y:i,w:s-e,h:n-i}};function hc(t,e){let{x:i,y:s,w:n,h:o}=t;n<30&&(i=i+n/2-100,n=nc),o<30&&(s=s+o/2-100,o=nc);const a=Math.max(n,o)*e;return{x:i-a,y:s-a,w:n+2*a,h:o+2*a}}function dc(t,e={}){const i=e.pad??.05,s=e.k??10,n=e.minSpread??50,o=t.filter(t=>Number.isFinite(t.minX)&&Number.isFinite(t.minY)&&Number.isFinite(t.maxX)&&Number.isFinite(t.maxY)&&Math.abs(t.minX)<=Yl&&Math.abs(t.maxX)<=Yl&&Math.abs(t.minY)<=Yl&&Math.abs(t.maxY)<=Yl);if(!o.length)return{core:null,all:null,outliers:0};const a=cc(o);if(o.length<4){const t=hc(a,i);return{core:t,all:t,outliers:0}}const r=o.map(t=>(t.minX+t.maxX)/2),l=o.map(t=>(t.minY+t.maxY)/2),c=lc(r),h=lc(l),d=o.map((t,e)=>Math.max(Math.abs(r[e]-c),Math.abs(l[e]-h))),u=Math.max(((t,e)=>t.length?t[Math.min(t.length-1,Math.max(0,Math.round(e*(t.length-1))))]:0)([...d].sort((t,e)=>t-e),.75),n),p=d.map(t=>t>s*u),_=p.filter(Boolean).length,g=_&&_<=o.length*sc?o.filter((t,e)=>!p[e]):o;return{core:hc(cc(g)||a,i),all:hc(a,i),outliers:g===o?0:_}}function uc(t,e,i=.05){const s=dc(rc(t,e),{pad:i});if(s.core)return s.core;const n=t.vb&&4===t.vb.length&&t.vb[2]>0&&t.vb[3]>0?t.vb:[0,0,Bl,Bl];return{x:n[0],y:n[1],w:n[2],h:n[3]}}function pc(t){const e=uc(t);return{x:e.x+e.w/2,y:e.y+e.h/2}}function _c(t){const e=[];for(const i of t.rooms||[]){const t=ac(i);t&&e.push(t)}const i=dc(e,{pad:0}).core;return i?Math.max(Bl,Math.min(Yl,Math.max(i.w,i.h))):Bl}function gc(t,e,i,s=1){const n=Number(i),o=Number.isFinite(s)&&s>0?s:1;return!Number.isFinite(n)||n<=0?t*o:t*_c(e)*o/n}const mc=[1,2,5,10,20,50,100,200,500,1e3];function fc(t){if(t.poly&&t.poly.length){const e=t.poly.map(t=>t[0]),i=t.poly.map(t=>t[1]),s=Math.min(...e),n=Math.min(...i);return{x:s,y:n,w:Math.max(...e)-s,h:Math.max(...i)-n}}return{x:t.x??0,y:t.y??0,w:t.w??0,h:t.h??0}}function vc(t,e,i,s){const n=i["rl_"+(t.id||"")];if(n&&n.s===e)return{x:n.x*Bl,y:n.y*Bl};const o=function(t){if(t.poly){const e=t.poly.length;return[t.poly.reduce((t,e)=>t+e[0],0)/e,t.poly.reduce((t,e)=>t+e[1],0)/e]}return[t.x+t.w/2,t.y+.1*Math.min(t.w,t.h)]}(t);return tc({x:o[0],y:o[1]})}const yc=["furniture","appliance","sanitary","other"],bc=[{id:"sofa",group:"furniture",w:220,h:90,g:[["r",0,0,1,1],["l",.09,.26,.91,.26],["l",.09,.26,.09,1],["l",.91,.26,.91,1],["l",.5,.26,.5,1]]},{id:"armchair",group:"furniture",w:90,h:85,g:[["r",0,0,1,1],["l",.14,.28,.86,.28],["l",.14,.28,.14,1],["l",.86,.28,.86,1]]},{id:"coffee_table",group:"furniture",w:110,h:60,g:[["r",0,0,1,1],["r",.08,.14,.84,.72]]},{id:"table_dining",group:"furniture",w:140,h:80,g:[["r",0,0,1,1],["r",.06,.11,.88,.78]]},{id:"table_round",group:"furniture",w:120,h:120,g:[["e",.5,.5,.5,.5],["e",.5,.5,.41,.41]]},{id:"chair",group:"furniture",w:45,h:45,g:[["r",0,0,1,.18],["r",.06,.18,.88,.8]]},{id:"desk",group:"furniture",w:120,h:60,g:[["r",0,0,1,1],["r",.63,.07,.31,.86],["l",.63,.5,.94,.5]]},{id:"bed_double",group:"furniture",w:160,h:200,g:[["r",0,0,1,1],["r",0,0,1,.07],["r",.06,.1,.4,.15],["r",.54,.1,.4,.15],["l",0,.33,1,.33]]},{id:"bed_single",group:"furniture",w:90,h:200,g:[["r",0,0,1,1],["r",0,0,1,.07],["r",.15,.1,.7,.15],["l",0,.33,1,.33]]},{id:"nightstand",group:"furniture",w:45,h:40,g:[["r",0,0,1,1],["r",.12,.14,.76,.33],["r",.12,.53,.76,.33]]},{id:"wardrobe",group:"furniture",w:100,h:60,g:[["r",0,0,1,1],["l",0,.72,1,.72],["l",.5,.72,.5,1]]},{id:"bookshelf",group:"furniture",w:80,h:30,g:[["r",0,0,1,1],["l",.34,0,.34,1],["l",.67,0,.67,1]]},{id:"fridge",group:"appliance",w:60,h:65,g:[["r",0,0,1,1],["l",0,.36,1,.36],["l",.83,.44,.83,.64]]},{id:"stove",group:"appliance",w:60,h:60,g:[["r",0,0,1,1],["e",.29,.31,.15,.15],["e",.71,.31,.15,.15],["e",.29,.71,.15,.15],["e",.71,.71,.15,.15]]},{id:"dishwasher",group:"appliance",w:60,h:60,g:[["r",0,0,1,1],["r",.1,.12,.8,.76],["e",.5,.5,.27,.27],["e",.5,.5,.13,.13]]},{id:"washer",group:"appliance",w:60,h:60,g:[["r",0,0,1,1],["l",.08,.17,.92,.17],["e",.5,.57,.3,.3],["e",.5,.57,.14,.14]]},{id:"dryer",group:"appliance",w:60,h:60,g:[["r",0,0,1,1],["l",.08,.17,.92,.17],["e",.5,.57,.3,.3],["p",.36,.5,.5,.64,.64,.5]]},{id:"tv",group:"appliance",w:120,h:30,g:[["r",0,0,1,.42],["l",.5,.42,.5,.72],["l",.3,.72,.7,.72]]},{id:"ac",group:"appliance",w:90,h:25,g:[["r",0,0,1,1],["l",.05,.55,.95,.55],["l",.05,.79,.95,.79]]},{id:"water_heater",group:"appliance",w:45,h:45,g:[["e",.5,.5,.5,.5],["e",.5,.5,.31,.31]]},{id:"toilet",group:"sanitary",w:40,h:70,g:[["r",.06,0,.88,.2],["e",.5,.58,.37,.35],["e",.5,.58,.22,.2]]},{id:"bathtub",group:"sanitary",w:170,h:75,g:[["r",0,0,1,1],["r",.05,.11,.77,.78],["e",.89,.5,.045,.1]]},{id:"shower",group:"sanitary",w:90,h:90,g:[["r",0,0,1,1],["l",0,0,1,1],["l",1,0,0,1],["e",.5,.5,.08,.08]]},{id:"sink",group:"sanitary",w:60,h:45,g:[["r",0,0,1,1],["e",.5,.6,.34,.3],["e",.5,.15,.07,.07]]},{id:"kitchen_sink",group:"sanitary",w:80,h:60,g:[["r",0,0,1,1],["r",.06,.24,.44,.64],["r",.54,.24,.4,.64],["e",.5,.12,.06,.06]]},{id:"bidet",group:"sanitary",w:40,h:55,g:[["e",.5,.5,.44,.5],["e",.5,.5,.26,.3]]},{id:"stairs",group:"other",w:100,h:280,g:[["r",0,0,1,1],["l",0,.111,1,.111],["l",0,.222,1,.222],["l",0,.333,1,.333],["l",0,.444,1,.444],["l",0,.556,1,.556],["l",0,.667,1,.667],["l",0,.778,1,.778],["l",0,.889,1,.889],["l",.5,.93,.5,.06],["p",.38,.16,.5,.06,.62,.16]]},{id:"fireplace",group:"other",w:120,h:40,g:[["r",0,0,1,1],["p",.22,1,.22,.42,.78,.42,.78,1]]},{id:"plant",group:"other",w:40,h:40,g:[["e",.5,.5,.22,.22],["l",.5,.28,.5,.02],["l",.5,.72,.5,.98],["l",.28,.5,.02,.5],["l",.72,.5,.98,.5],["l",.34,.34,.13,.13],["l",.66,.66,.87,.87],["l",.66,.34,.87,.13],["l",.34,.66,.13,.87]]},{id:"rug",group:"other",w:200,h:140,g:[["r",0,0,1,1],["r",.06,.09,.88,.82]]}],wc=new Map(bc.map(t=>[t.id,t]));function kc(t){return t&&wc.get(t)||null}function xc(t){return bc.filter(e=>e.group===t)}function $c(t,e,i=Jl,s=1e3){const n=Number(e)>0?Number(e):5;return(Number(t)||0)/n*i/s}const Sc=5e-4,Mc=Kl;function Cc(t){return Number.isFinite(t)?Math.max(Sc,Math.min(Mc,t)):Sc}const Dc=t=>{const e=Math.round(1e3*t)/1e3;return Object.is(e,-0)?"0":String(e)};function Tc(t,e,i){const s=kc(t);if(!(s&&e>0&&i>0))return"";const n=t=>Dc(t*e),o=t=>Dc(t*i),a=[];for(const t of s.g)if("r"===t[0]){const[,e,i,s,r]=t;a.push(`M${n(e)} ${o(i)}H${n(e+s)}V${o(i+r)}H${n(e)}Z`)}else if("l"===t[0]){const[,e,i,s,r]=t;a.push(`M${n(e)} ${o(i)}L${n(s)} ${o(r)}`)}else if("e"===t[0]){const[,s,r,l,c]=t;a.push(`M${n(s-l)} ${o(r)}A${Dc(l*e)} ${Dc(c*i)} 0 0 1 ${n(s+l)} ${o(r)}A${Dc(l*e)} ${Dc(c*i)} 0 0 1 ${n(s-l)} ${o(r)}Z`)}else{const e=t.slice(1);if(e.length<4)continue;let i=`M${n(e[0])} ${o(e[1])}`;for(let t=2;t+1{let e=(t%360+360)%360;return e>180&&(e-=360),e};function Rc(t,e,i,s,n,o=0){let a=null,r=n;for(const n of s){const[s,l,c,h]=n,d=c-s,u=h-l,p=d*d+u*u;if(!p)continue;const _=Math.sqrt(p);let g=((t-s)*d+(e-l)*u)/p;g=Math.max(0,Math.min(1,g));let m=s+g*d,f=l+g*u;const v=Math.hypot(t-m,e-f);if(!(v0){const t=Math.round(g*_/o)*o;m=s+t/_*d,f=l+t/_*u}a={cx:m+y*(i/2),cy:f+b*(i/2),angle:Pc(180*Math.atan2(-y,b)/Math.PI),dist:v}}return a}function Ac(t,e,i){const s=i;return{a:[t[0]/s,t[1]/s],b:[e[0]/s,e[1]/s]}}function Ic(t,e){const i=e;return[t.a[0]*i,t.a[1]*i,t.b[0]*i,t.b[1]*i]}function Ec(t){return Array.isArray(t)&&t.length>=2&&Number.isFinite(Number(t[0]))&&Number.isFinite(Number(t[1]))}function Fc(t){if(!Array.isArray(t))return[];const e=[];for(const i of t){if(!i||"object"!=typeof i)continue;const t=i;if(!Ec(t.a)||!Ec(t.b))continue;const s=[Number(t.a[0]),Number(t.a[1])],n=[Number(t.b[0]),Number(t.b[1])];Math.hypot(n[0]-s[0],n[1]-s[1])<.001||e.push({a:s,b:n})}return e}function zc(t,e){const i=e[0],s=e[1],n=e[2]-i,o=e[3]-s,a=n*n+o*o;if(a<1e-18){return{q:[i,s],t:0,d:Math.hypot(t[0]-i,t[1]-s)}}let r=((t[0]-i)*n+(t[1]-s)*o)/a;r=Math.max(0,Math.min(1,r));const l=[i+r*n,s+r*o];return{q:l,t:r,d:Math.hypot(t[0]-l[0],t[1]-l[1])}}function Oc(t,e){return zc(t,e).q}function Hc(t,e,i,s,n){const o=zc(t,e).q;let a=o,r=1/0;for(const t of i){const e=Math.hypot(o[0]-t[0],o[1]-t[1]);e<=n&&e0?s:1,g=Math.round(p/_)*_,m=Math.max(0,Math.min(u,g))/u;return[l+h*m,c+d*m]}function Nc(t,e){const i=[],s=(t||[]).filter(t=>t?.id);for(let t=0;tt?.id),a=Fc(e);if(a.length)return Kc(a,t,i,s).map(t=>Ic(t,i));if(!n)return[];const r=[],l=(t,e)=>(t.open_to||[]).includes(e.id)||(e.open_to||[]).includes(t.id);for(let t=0;tAc([t[0],t[1]],[t[2],t[3]],e))}function qc(t,e,i,s){for(const e of t||[])e.open_to&&delete e.open_to;if(!i.length)return;const n=(e||[]).filter(t=>t?.id);new Map(n.map(t=>[t.id,t]));const o=new Map((t||[]).filter(t=>t?.id).map(t=>[t.id,t])),a=(t,e)=>{const i=o.get(t),s=o.get(e);i&&s&&((i.open_to||[]).includes(e)||(i.open_to=[...i.open_to||[],e]),(s.open_to||[]).includes(t)||(s.open_to=[...s.open_to||[],t]))};for(let t=0;tNs(i,t)<4*s)){a(n[t].id,n[e].id);break}}}for(const e of t||[])e.open_to&&!e.open_to.length&&delete e.open_to}function jc(t,e,i,s=0){const n=e[2]-e[0],o=e[3]-e[1],a=Math.hypot(n,o);if(!(a>1e-9))return null;const r=n/a,l=o/a,c=(t[0]-e[0])*r+(t[1]-e[1])*l;if(c<-s||c>a+s)return null;return Math.abs((t[0]-e[0])*l-(t[1]-e[1])*r)>i?null:Ns(t,e)}function Wc(t,e,i){const s=t[2]-t[0],n=t[3]-t[1],o=e[2]-e[0],a=e[3]-e[1],r=Math.hypot(s,n),l=Math.hypot(o,a);return r>1e-9&&l>1e-9&&(!(Math.abs(s/r*(a/l)-n/r*(o/l))>1e-6)&&(Ns([e[0],e[1]],t)<=4*i||Ns([t[0],t[1]],e)<=4*i))}function Uc(t,e,i){if(!t.length)return null;t.sort((t,e)=>t.distance-e.distance);const s=t[0];for(let n=1;ne)break;if(o.semantic!==s.semantic||!Wc(s.seg,o.seg,i))return"ambiguous"}return s}function Gc(t,e,i,s,n=1,o=15){const a=function(t,e,i,s,n=1,o=15){const[a,r]=yr([e[0],e[1]],[e[2],e[3]]);let l=0,c=1/0;const h=[(e[0]+e[2])/2,(e[1]+e[3])/2];for(const e of i){const[i,o]=yr([e[0],e[1]],[e[2],e[3]]);if(Math.abs(a*o-r*i)>.05)continue;const d=Dr(t,[e[0],e[1]],[e[2],e[3]],s,n);if(!(d>0))continue;const u=[(e[0]+e[2])/2,(e[1]+e[3])/2],p=Math.hypot(u[0]-h[0],u[1]-h[1]);p0?l:o}(t,e,i,s,n,o);return Ar(t,[e[0],e[1]],[e[2],e[3]],a,s,n)}function Vc(t,e,i){const s=[[t[0],t[1]],[t[2],t[3]]],n=[(t[0]+t[2])/2,(t[1]+t[3])/2];for(const o of e)if(!(Ns(n,o)>Math.hypot(t[2]-t[0],t[3]-t[1])&&Ns([o[0],o[1]],t)>i))for(const e of[[o[0],o[1]],[o[2],o[3]]])Ns(e,t)<=2*i&&s.push(e);return s}function Kc(t,e,i,s){const n=Fc(t);if(!n.length)return[];const o=Nc(e,s);if(!o.length)return[];const a=[],r=Math.max(4*s,1e-6);for(const t of n){const e=Ic(t,i),n=e[0],l=e[1],c=e[2]-n,h=e[3]-l,d=Math.hypot(c,h);if(d4*s||o>4*s)continue;const a=(t[0]-n)*u+(t[1]-l)*p,c=(t[2]-n)*u+(t[3]-l)*p,h=Math.max(0,Math.min(a,c)),g=Math.min(d,Math.max(a,c));if(g-ht.lo-e.lo||t.hi-e.hi);const i=[];for(const t of e){const e=i[i.length-1];e&&t.lo<=e.hi+r?e.hi=Math.max(e.hi,t.hi):i.push({...t})}for(const e of i){const i=[n+u*e.lo,l+p*e.lo],s=[n+u*e.hi,l+p*e.hi];Math.hypot(s[0]-i[0],s[1]-i[1])i.pair===t&&Math.abs(i.ux*a-i.uy*o)<=1e-6&&Math.abs((e[0]-i.origin[0])*i.uy-(e[1]-i.origin[1])*i.ux)<=c&&Math.abs((e[2]-i.origin[0])*i.uy-(e[3]-i.origin[1])*i.ux)<=c);h||(h={pair:t,origin:[e[0],e[1]],ux:o,uy:a,ranges:[]},l.push(h));const d=(e[0]-h.origin[0])*h.ux+(e[1]-h.origin[1])*h.uy,u=(e[2]-h.origin[0])*h.ux+(e[3]-h.origin[1])*h.uy;h.ranges.push({lo:Math.min(d,u),hi:Math.max(d,u)})}const h=[];for(const t of l){t.ranges.sort((t,e)=>t.lo-e.lo||t.hi-e.hi);const e=[];for(const i of t.ranges){const t=e[e.length-1];t&&i.lo<=t.hi+r?t.hi=Math.max(t.hi,i.hi):e.push({...i})}for(const s of e){const e=[t.origin[0]+t.ux*s.lo,t.origin[1]+t.uy*s.lo],n=[t.origin[0]+t.ux*s.hi,t.origin[1]+t.uy*s.hi];Math.hypot(n[0]-e[0],n[1]-e[1])>=r&&h.push(Ac(e,n,i))}}return h}function Yc(t,e,i,s){const n=Fc(t);if(!n.length)return[];if(e.length!==i.length)return n;const o=[];for(const t of n){const n=Ic(t,s),a=[n[0],n[1]],r=[n[2],n[3]];let l=a,c=r;for(let t=0;t{const e=zc(t,[s[0],s[1],n[0],n[1]]);if(e.d>.001)return t;const i=h[0]-o[0],a=h[1]-o[1];return[o[0]+i*e.t,o[1]+a*e.t]};if(zc([(a[0]+r[0])/2,(a[1]+r[1])/2],[s[0],s[1],n[0],n[1]]).d<.01){l=d(a),c=d(r);break}}o.push(Ac(l,c,s))}return o}const Xc=15e3,Jc=2e3,Zc=new WeakMap;function Qc(t,e){let i=Zc.get(t);if(!i){const e=new Set;i={hiddenAt:"hidden"===t.visibilityState?Date.now():0,token:0,subscribers:e,onVisibility:()=>{const e=Zc.get(t);if(!e)return;const i=Date.now();if("hidden"===t.visibilityState){e.hiddenAt||(e.hiddenAt=i);const t={kind:"hidden",token:e.token,at:i,hiddenFor:0,long:!1};for(const i of[...e.subscribers])i(t);return}const s=e.hiddenAt?Math.max(0,i-e.hiddenAt):0;e.hiddenAt=0,e.token++;const n={kind:"visible",token:e.token,at:i,hiddenFor:s,long:s>=Xc};for(const t of[...e.subscribers])t(n)},onPageShow:e=>{const i=Zc.get(t);if(!i)return;const s=Date.now();i.token++;const n={kind:"pageshow",token:i.token,at:s,hiddenFor:0,long:!!e.persisted,persisted:!!e.persisted};for(const t of[...i.subscribers])t(n)}},Zc.set(t,i),t.addEventListener("visibilitychange",i.onVisibility),t.defaultView?.addEventListener("pageshow",i.onPageShow)}return i.subscribers.add(e),()=>{const i=Zc.get(t);i&&(i.subscribers.delete(e),i.subscribers.size||(t.removeEventListener("visibilitychange",i.onVisibility),t.defaultView?.removeEventListener("pageshow",i.onPageShow),Zc.delete(t)))}}const th={now:()=>Date.now(),setTimeout:(t,e)=>window.setTimeout(t,e),clearTimeout:t=>window.clearTimeout(t),requestAnimationFrame:t=>window.requestAnimationFrame(t),cancelAnimationFrame:t=>window.cancelAnimationFrame(t)};class eh{constructor(t,e=th){this.onChange=t,this.clock=e,this._state="steady",this._token=0,this._frameFingerprint="",this._hasCompleteFrame=!1,this._overlayPhase="none",this._recoveryReason=null,this._overlayTimer=0,this._overlayRaf=0,this._overlayOpaqueAt=0,this._barrierRafs=new Set,this._trace=[],this._disposed=!1}get state(){return this._state}get token(){return this._token}get frameFingerprint(){return this._frameFingerprint}get hasCompleteFrame(){return this._hasCompleteFrame}get overlayPhase(){return this._overlayPhase}get overlayVisible(){return"none"!==this._overlayPhase}get overlayBlocksInteraction(){return this.overlayVisible}get recoveryReason(){return this._recoveryReason}get trace(){return this._trace.map(t=>({...t,...t.stage?{stage:[...t.stage]}:{}}))}note(t,e={}){this.record(t,void 0,e)}record(t,e,i={}){this._trace.push({at:this.clock.now(),token:this._token,event:t,state:this._state,...e?{reason:e}:{},...i}),this._trace.length>80&&this._trace.splice(0,this._trace.length-80)}changed(){this._disposed||this.onChange()}adoptCompleteFrame(t){t&&(this._hasCompleteFrame=!0,this._frameFingerprint=t,this._state="steady",this._recoveryReason=null,this.clearOverlay(),this.record("frame-adopted"),this.changed())}markCompleteFrame(t){t&&(this._hasCompleteFrame=!0,this._frameFingerprint=t,this._state="steady",this._recoveryReason=null,this.clearOverlay(),this.record("frame-complete"),this.changed())}refreshCompleteFrame(t){!this._disposed&&this._hasCompleteFrame&&"steady"===this._state&&t&&t!==this._frameFingerprint&&(this._frameFingerprint=t,this.record("frame-refreshed"))}visibility(t){return"hidden"===t.kind?(this.record("visibility-hidden"),this._token):t.long||"visible"!==t.kind&&"pageshow"!==t.kind?this.beginCandidate("pageshow"===t.kind?"pageshow":"long-resume"):(this.record("pageshow"===t.kind?"pageshow-noop":"visibility-visible-quick"),this._token)}beginCandidate(t,e="plan"){return this._token++,this._recoveryReason=e,this._hasCompleteFrame?(this._state="connection"===e?"offline-stale":"holding",this.clearOverlay()):this.overlayVisible?this._state="overlay-visible":(this._state="overlay-pending",this.scheduleOverlay(e)),this.record("candidate-start",t),this.changed(),this._token}connectionLost(){return this.beginCandidate("connection-lost","connection")}candidateReady(t){return!this._disposed&&t===this._token&&(this._state="candidate-ready",this.record("candidate-ready"),this.changed(),!0)}async commitAfterPaint(t,e){if(this._disposed||t!==this._token)return!1;let i=!0;const s=(async()=>{for(await e.updateComplete();i&&!this._disposed&&t===this._token;)if(e.stageValid()&&e.assetsReady()){if(await this.nextFrame(),t!==this._token||!e.stageValid()||!e.assetsReady())continue;if(await this.nextFrame(),t===this._token&&e.stageValid()&&e.assetsReady())return!0}else await this.nextFrame();return!1})();let n=0;const o=new Promise(t=>{n=this.clock.setTimeout(()=>t({ready:!1,timedOut:!0}),Jc)}),a=await Promise.race([s.then(t=>({ready:t,timedOut:!1})),o]);return i=!1,this.clock.clearTimeout(n),!this._disposed&&t===this._token&&(!(!a.ready&&!a.timedOut)&&(a.ready?(this._hasCompleteFrame=!0,this._frameFingerprint=e.frameFingerprint(),this.record("paint-barrier"),this.finishOverlayAfterCommit(),!0):(this.record("paint-barrier-timeout"),this._hasCompleteFrame?(this._state="connection"===this._recoveryReason?"offline-stale":"steady",this.clearOverlay()):(this._state="recovery-error","opaque"!==this._overlayPhase&&this.showOverlayNow()),this.changed(),!1)))}retry(t=this._recoveryReason||"plan"){return this.beginCandidate("retry",t)}nextFrame(){return new Promise(t=>{const e=this.clock.requestAnimationFrame(()=>{this._barrierRafs.delete(e),t()});this._barrierRafs.add(e)})}scheduleOverlay(t){this.clearOverlayTimer(),this._recoveryReason=t,this._overlayTimer=this.clock.setTimeout(()=>{this._overlayTimer=0,this._hasCompleteFrame||"overlay-pending"!==this._state&&"candidate-ready"!==this._state||(this._state="overlay-visible",this._overlayPhase="entering",this.record("overlay-enter"),this.changed(),this._overlayRaf=this.clock.requestAnimationFrame(()=>{this._overlayRaf=0,"entering"===this._overlayPhase&&(this._overlayPhase="fading-in",this.changed(),this._overlayTimer=this.clock.setTimeout(()=>{this._overlayTimer=0,"fading-in"===this._overlayPhase&&(this._overlayPhase="opaque",this._overlayOpaqueAt=this.clock.now(),this.record("overlay-opaque"),this.changed())},150))}))},150)}showOverlayNow(){this.clearOverlayTimer(),this._overlayPhase="opaque",this._overlayOpaqueAt=this.clock.now(),this.record("overlay-error")}finishOverlayAfterCommit(){if(this.clearOverlayTimer(),"none"===this._overlayPhase||"entering"===this._overlayPhase||"fading-in"===this._overlayPhase)return this.clearOverlay(),this._state="steady",this._recoveryReason=null,this.record("candidate-committed"),void this.changed();const t=Math.max(0,this._overlayOpaqueAt+250-this.clock.now());this._overlayTimer=this.clock.setTimeout(()=>{this._overlayTimer=0,this._overlayPhase="leaving",this.record("overlay-leave"),this.changed(),this._overlayTimer=this.clock.setTimeout(()=>{this._overlayTimer=0,this._overlayPhase="none",this._state="steady",this._recoveryReason=null,this.record("candidate-committed"),this.changed()},180)},t)}clearOverlayTimer(){this._overlayTimer&&this.clock.clearTimeout(this._overlayTimer),this._overlayTimer=0}clearOverlay(){this.clearOverlayTimer(),this._overlayRaf&&this.clock.cancelAnimationFrame(this._overlayRaf),this._overlayRaf=0,this._overlayPhase="none",this._overlayOpaqueAt=0}dispose(){this._disposed=!0,this._token++,this.clearOverlay();for(const t of this._barrierRafs)this.clock.cancelAnimationFrame(t);this._barrierRafs.clear()}}function ih(t){let e=2166136261,i=2654435769;const s=new WeakSet,n=t=>{for(let s=0;s>>0)+(i>>>2)}},o=t=>{if(null===t)return void n("n");const e=typeof t;if("string"===e)return void n(`s${t.length}:${t}`);if("number"===e)return void n(`d${Number.isNaN(t)?"NaN":String(t)}`);if("boolean"===e)return void n(t?"t":"f");if("undefined"===e)return void n("u");if("object"!==e)return void n(`${e}:${String(t)}`);const i=t;if(s.has(i))n("[cycle]");else{if(s.add(i),Array.isArray(t)){n("[");for(const e of t)o(e);return n("]"),void s.delete(i)}n("{");for(const e of Object.keys(t).sort())n(e),o(t[e]);n("}"),s.delete(i)}};return o(t),`${(e>>>0).toString(16).padStart(8,"0")}${(i>>>0).toString(16).padStart(8,"0")}`}function sh(t){return ih(t)}const nh=new WeakMap;class oh{constructor(t,e=()=>Date.now()){this.onUpdate=t,this.now=e,this.fallbackAuthority={},this.referenceOwner={},this.referenced=new Set,this.queued=new Set,this.disposed=!1,this.sharedUpdate=()=>{this.disposed||this.onUpdate()}}bind(t){const e=((t,e)=>{const i=t?.connection||t?.callWS||e;return!i||"object"!=typeof i&&"function"!=typeof i?e:i})(t,this.fallbackAuthority);return this.shared&&this.authority===e||(this.shared&&(this.shared.listeners.delete(this.sharedUpdate),this.shared.references.delete(this.referenceOwner)),this.authority=e,this.shared=(t=>{let e=nh.get(t);return e||(e={signed:{},queued:new Set,inFlight:new Map,retry:new Map,listeners:new Set,settlers:new Set,references:new Map},nh.set(t,e)),e})(e),this.disposed||(this.shared.listeners.add(this.sharedUpdate),this.shared.references.set(this.referenceOwner,new Set(this.referenced)))),this.shared}start(t,e){this.disposed=!1,this.referenced=new Set(e());const i=this.bind(t());i.listeners.add(this.sharedUpdate),i.references.set(this.referenceOwner,new Set(this.referenced)),this.stopTimer(),this.resignTimer=setInterval(()=>this.resign(t(),e()),288e5)}dispose(){if(this.disposed=!0,this.stopTimer(),clearTimeout(this.batchTimer),this.shared){this.shared.listeners.delete(this.sharedUpdate),this.shared.references.delete(this.referenceOwner);for(const t of this.queued)this.shared.queued.delete(t)}this.queued.clear()}invalidate(t){const e=this.bind(t);clearTimeout(this.batchTimer),this.queued.clear(),e.queued.clear(),e.inFlight.clear(),e.retry.clear(),e.signed={}}stopTimer(){void 0!==this.resignTimer&&clearInterval(this.resignTimer),this.resignTimer=void 0}display(t,e){const i=Is(e);if(!i.startsWith("/api/houseplan/content/"))return i;const s=this.bind(t);this.referenced.add(i),s.references.set(this.referenceOwner,new Set(this.referenced));const n=s.signed[i],o=n?this.now()-n.at:1/0;return o{const e=[...this.queued];this.queued.clear();for(const t of e)i.queued.delete(t);this.sign(t,e)},30))}sign(t,e){if(!e.length||!t?.callWS)return;const i=this.bind(t);for(const s of function(t,e){const i=Math.max(1,Math.floor(e)),s=[];for(let e=0;e{const s=i.inFlight.get(t);return!(void 0!==s&&e-s<15e3)&&(i.inFlight.set(t,e),!0)});n.length&&t.callWS({type:"houseplan/content/sign",paths:n}).then(t=>{const e=this.now();let s=0,o=!1;for(const a of n){const n=t?.urls?.[a];if("string"==typeof n&&n){const t=i.signed[a];t?.loaded&&t.url!==n?(t.pending={url:n,at:e},this.preloadReplacement(i,a,n,e)):(i.signed[a]={url:n,at:e,loaded:t?.url===n&&!!t.loaded},o=!0),i.retry.delete(a),s++}else this.backOff(i,a)}if(s&&(this.trimShared(i),o))for(const t of[...i.listeners])t()}).catch(()=>{for(const t of n)this.backOff(i,t)}).finally(()=>{for(const t of n)i.inFlight.get(t)===e&&i.inFlight.delete(t);for(const t of[...i.settlers])t()})}}preloadReplacement(t,e,i,s){const n=()=>{const n=t.signed[e];if(n?.pending?.url===i){t.signed[e]={url:i,at:s,loaded:!0},t.retry.delete(e),this.trimShared(t);for(const e of[...t.listeners])e()}},o=()=>{const s=t.signed[e];s?.pending?.url===i&&(delete s.pending,this.backOff(t,e))};if("undefined"==typeof Image)return void n();const a=new Image;a.onload=()=>{("function"==typeof a.decode?a.decode():Promise.resolve()).then(n).catch(o)},a.onerror=o,a.src=i}preloadCurrentImage(t,e,i){if(i.loaded)return Promise.resolve(!0);if(i.preload)return i.preload;if("undefined"==typeof Image)return i.loaded=!0,Promise.resolve(!0);const s=i.url;return i.preload=new Promise(n=>{const o=new Image;let a=!1;const r=o=>{if(a)return;a=!0,clearTimeout(l);const r=t.signed[e];if(r===i&&delete r.preload,o&&r===i&&r.url===s){r.loaded=!0;for(const e of[...t.listeners])e();n(!0)}else o||r!==i||this.backOff(t,e),n(!1)};o.onload=()=>{("function"==typeof o.decode?o.decode():Promise.resolve()).then(()=>r(!0)).catch(()=>r(!1))},o.onerror=()=>r(!1);const l=setTimeout(()=>r(!1),Jc);o.src=s}),i.preload}prepareImage(t,e){const i=Is(e);if(!i.startsWith("/api/houseplan/content/"))return Promise.resolve(!0);const s=this.bind(t),n=()=>{const e=s.signed[i];if(e&&this.now()-e.atthis.now()&&!s.inFlight.has(i)&&!s.queued.has(i)?Promise.resolve(!1):null},o=n();return o?(a=o,new Promise(t=>{let e=!1;const i=i=>{e||(e=!0,clearTimeout(s),t(i))},s=setTimeout(()=>i(!1),Jc);a.then(i).catch(()=>i(!1))})):new Promise(t=>{let e=!1,i=null;const o=i=>{e||(e=!0,clearTimeout(r),s.settlers.delete(a),t(i))},a=()=>{e||i||(i=n(),i&&i.then(o).catch(()=>o(!1)))},r=setTimeout(()=>o(!1),Jc);s.settlers.add(a),a()});var a}backOff(t,e){const i=t.retry.get(e)?.delay||0,s=Math.min(6e4,i?2*i:2e3);t.retry.set(e,{notBefore:this.now()+s,delay:s})}trimShared(t){const e=Object.entries(t.signed);if(e.length<=512)return;const i=new Set(t.inFlight.keys());for(const e of t.references.values())for(const t of e)i.add(t);for(const[t,s]of e)(s.pending||s.preload)&&i.add(t);e.sort((t,e)=>e[1].at-t[1].at);const s=e.filter(([t])=>i.has(t));for(const t of e){if(s.length>=512)break;i.has(t[0])||s.push(t)}t.signed=Object.fromEntries(s)}resign(t,e){const i=this.bind(t);this.referenced=new Set(e),i.references.set(this.referenceOwner,new Set(this.referenced));const s=this.now(),n=new Set;for(const t of i.references.values())for(const e of t)n.add(e);const o={};for(const[t,e]of Object.entries(i.signed))n.has(t)&&s-e.at!!o[t]&&!o[t].pending))}markLoaded(t,e,i){const s=Is(e);if(!s.startsWith("/api/houseplan/content/"))return;const n=this.bind(t).signed[s];if(n&&(!i||n.url===i)&&!n.loaded){n.loaded=!0;for(const e of[...this.bind(t).listeners])e()}}isReady(t,e){const i=Is(e);if(!i.startsWith("/api/houseplan/content/"))return!0;const s=this.bind(t).signed[i];return!!s&&this.now()-s.at{if(null==t||""===t)return null;const e=Number(t);return Number.isFinite(e)?e:null},ch=t=>{const e=t,i=lh(Array.isArray(e)?e[0]:e?.x),s=lh(Array.isArray(e)?e[1]:e?.y);return null==i||null==s?null:[i,s]};function hh(t){if(!Array.isArray(t))return null;const e=[];for(const i of t){const t=ch(i);if(!t)return null;e.push(t)}if(e.length>1){const t=e[0],i=e[e.length-1];t[0]===i[0]&&t[1]===i[1]&&e.pop()}if(e.length<3)return null;let i=0,s=0,n=0;for(let t=0;tt+e[0],0)/e.length,e.reduce((t,e)=>t+e[1],0)/e.length]:[s/(3*i),n/(3*i)]}function dh(t){if(!Array.isArray(t))return null;const e=[];for(const i of t){const t=ch(i);if(!t)return null;e.push(t)}if(e.length>1){const t=e[0],i=e[e.length-1];t[0]===i[0]&&t[1]===i[1]&&e.pop()}const i=hh(e);if(!i)return null;const s=e.map(t=>t[0]),n=e.map(t=>t[1]);return{centroid:i,bbox:[Math.min(...s),Math.min(...n),Math.max(...s),Math.max(...n)]}}function uh(t){let e=t;if(e&&"object"==typeof e&&!Array.isArray(e)){const t=e;e=t.path??t.points??e}if(!Array.isArray(e)||!e.length)return[];let i=(e.some(t=>(t=>Array.isArray(t)?t.length>=2&&!Array.isArray(t[0])&&("object"!=typeof t[0]||null==t[0]):!!t&&"object"==typeof t&&("x"in t||"y"in t))(t))?[e]:e.filter(Array.isArray)).map(t=>t.map(ch).filter(t=>null!=t)).filter(t=>t.length>=2);i.length>64&&(i=i.slice(-64));if(i.reduce((t,e)=>t+e.length,0)<=4e3)return i.map(t=>t.slice());const s=4e3-2*i.length,n=i.map(t=>t.length-2),o=n.reduce((t,e)=>t+e,0),a=n.map(t=>s*t/o),r=a.map(Math.floor);let l=s-r.reduce((t,e)=>t+e,0);const c=a.map((t,e)=>({index:e,fraction:t-Math.floor(t)})).sort((t,e)=>e.fraction-t.fraction||t.index-e.index);for(let t=0;tfunction(t,e){if(e>=t.length)return t.slice();if(e<=2)return[t[0],t[t.length-1]];const i=[];for(let s=0;st.slice()),i=e[e.length-1];return i?(i.length>2?i.pop():e.pop(),e):[]}function gh(t){if(!t)return null;const e=t.vacuum_position||t.robot_position||null,i=e&&null!=lh(e.x)&&null!=lh(e.y)?{x:lh(e.x),y:lh(e.y),a:lh(e.a??e.angle??e.theta)}:null,s=uh(t.path?.path??t.path?.points??t.path),n=[],o=t.rooms,a=Array.isArray(o)?o.map((t,e)=>[String(t?.id??e),t]):o&&"object"==typeof o?Object.entries(o):[];for(const[t,e]of a){if(!e||"object"!=typeof e)continue;const i=String(e.name??e.label??"").trim(),s=[[lh(e.cx),lh(e.cy)],[lh(e.center?.x),lh(e.center?.y)],[lh(e.x),lh(e.y)]].find(([t,e])=>null!=t&&null!=e);let o=s?.[0]??null,a=s?.[1]??null;const r=dh(e.outline),l=lh(e.x0),c=lh(e.y0),h=lh(e.x1),d=lh(e.y1),u=(null!=l&&null!=c&&null!=h&&null!=d?[Math.min(l,h),Math.min(c,d),Math.max(l,h),Math.max(c,d)]:null)||r?.bbox||null;if(null!=o&&null!=a||!r||([o,a]=r.centroid),null!=o&&null!=a||!u||(o=(u[0]+u[2])/2,a=(u[1]+u[3])/2),i&&null!=o&&null!=a){const e={id:t,name:i,cx:o,cy:a};u&&([e.x0,e.y0,e.x1,e.y1]=u),n.push(e)}}const r=function(t){return String(t.map_name??t.current_map??t.map_index??t.selected_map??"default")}(t);return i||n.length||s.length?{pos:i,path:s,rooms:n,mapId:r}:null}function mh(t,e,i){if(!t||!e)return null;const s=e.attributes||{},n=t.split(".")[0]||"",o=null!=i?.platform?String(i.platform):null,a=!!ch(s.vacuum_position??s.robot_position),r=!(!s.rooms||"object"!=typeof s.rooms),l=uh(s.path?.path??s.path?.points??s.path).length>0,c=[s.map_name,s.current_map,s.map_index,s.selected_map].some(t=>null!=t),h="xiaomi_cloud_map_extractor"===o,d=r||l||c;let u=null;if(a?u="compatible":h?u="known_xcme_incomplete":d?u="partial":"camera"===n&&(u="camera"),!u)return null;const p=a?"camera"===n?300:200:h?100:d?50:0;return{entityId:t,name:String(s.friendly_name||t),platform:o,category:u,hasPosition:a,hasRooms:r,hasPath:l,hasMapId:c,score:p}}const fh=t=>t.toLowerCase().replace(/[\s_\-.,]+/g,"");function vh(t,e){const i=new Map(e.map(t=>[fh(t.name),t])),s=[],n=[];for(const e of t){const t=i.get(fh(e.name));t&&(s.push([[e.cx,e.cy],[t.cx,t.cy]]),n.push(e.name))}if(s.length<3)return null;const o=function(t){if(t.length<3)return null;let e=0,i=0,s=0,n=0,o=0,a=0,r=0,l=0,c=0,h=0,d=0,u=0;for(const[[p,_],[g,m]]of t){if(![p,_,g,m].every(Number.isFinite))return null;e+=p*p,i+=p*_,s+=p,n+=_*_,o+=_,a+=1,r+=p*g,l+=_*g,c+=g,h+=p*m,d+=_*m,u+=m}const p=[e,i,s,i,n,o,s,o,a],_=t=>{const[e,i,s,n,o,a,r,l,c]=p,h=e*(o*c-a*l)-i*(n*c-a*r)+s*(n*l-o*r);if(!Number.isFinite(h)||Math.abs(h)<1e-9)return null;const d=[(o*c-a*l)/h,(s*l-i*c)/h,(i*a-s*o)/h,(a*r-n*c)/h,(e*c-s*r)/h,(s*n-e*a)/h,(n*l-o*r)/h,(i*r-e*l)/h,(e*o-i*n)/h];return[d[0]*t[0]+d[1]*t[1]+d[2]*t[2],d[3]*t[0]+d[4]*t[1]+d[5]*t[2],d[6]*t[0]+d[7]*t[1]+d[8]*t[2]]},g=_([r,l,c]),m=_([h,d,u]);if(!g||!m)return null;const f=[g[0],g[1],g[2],m[0],m[1],m[2]];return f.every(Number.isFinite)?f:null}(s);return o?{matrix:o,matched:n,residual:rh(o,s)}:null}function yh(t,e,i){const s=t[t.length-1];if(s&&s[0]===e[0]&&s[1]===e[1])return t;if(t.push(e),t.length<=600)return t;let n=function(t,e){if(t.length<3)return t.slice();const i=new Uint8Array(t.length);i[0]=i[t.length-1]=1;const s=[[0,t.length-1]];for(;s.length;){const[n,o]=s.pop(),[a,r]=t[n],[l,c]=t[o],h=l-a,d=c-r,u=Math.hypot(h,d)||1e-9;let p=0,_=-1;for(let e=n+1;ep&&(p=i,_=e)}_>0&&p>e&&(i[_]=1,s.push([n,_],[_,o]))}const n=[];for(let e=0;e600&&(n=n.filter((t,e)=>e%2==0||e===n.length-1)),n}function bh(t){return"cleaning"===t||"returning"===t||"on"===t}const wh={0:[1,0],90:[0,1],180:[-1,0],270:[0,-1]};function kh(t){const[e,i]=wh[t.rot]||[1,0],s=t.mir?-1:1;return[t.s*e*s,-t.s*i,t.ox,t.s*i*s,t.s*e,t.oy]}function xh(t){const e=t[0]*t[4]-t[1]*t[3];if(!Number.isFinite(e)||Math.abs(e)<1e-12)return null;const i=e<0,s=Math.sqrt(Math.abs(e));let n=180*Math.atan2(-t[1],t[4])/Math.PI;return n=(90*Math.round(n/90)%360+360)%360,{ox:t[2],oy:t[5],s:s,rot:n,mir:i}}function $h(t,e,i,s){const[n,o]=ah(kh(e),i,s),a=kh({...t,ox:0,oy:0}),[r,l]=ah(a,i,s);return{...t,ox:n-r,oy:o-l}}function Sh(t){const e=t?.trail_mode;return"never"===e||"cleaning"===e||"always"===e?e:!1===t?.trail?"never":"cleaning"}const Mh={offStates:["off"],unknownUsesToggle:!0},Ch={light:Mh,switch:Mh,fan:Mh,humidifier:Mh,input_boolean:Mh,automation:Mh,remote:Mh,group:Mh,climate:{...Mh,featureMasks:{turn_on:256,turn_off:128,toggle:384}},media_player:{...Mh,featureMasks:{turn_on:128,turn_off:256,toggle:384}},siren:{...Mh,featureMasks:{turn_on:1,turn_off:2,toggle:3}},vacuum:{...Mh,featureMasks:{turn_on:1,turn_off:2,toggle:3}},water_heater:{...Mh,featureMasks:{turn_on:8,turn_off:8,toggle:8}},camera:{...Mh,featureMasks:{turn_on:1,turn_off:1,toggle:1}}};function Dh(t){return t.slice(0,t.indexOf("."))}function Th(t,e,i){if(!t?.services||"object"!=typeof t.services)return!1;const s=t.services?.[e];return!!s&&Object.prototype.hasOwnProperty.call(s,i)}function Ph(t,e,i){return Th(t,e,i)?{domain:e,service:i}:Th(t,"homeassistant",i)?{domain:"homeassistant",service:i}:null}function Rh(t,e){return t?.entities?.[e]||null}function Ah(t,e,i){const s=t?.states?.[i],n=Rh(e,i);return s?.attributes?.friendly_name||n?.name||n?.original_name||i}function Ih(t,e){const i=Rh(t,e);if(null!=i?.disabled_by)return!0;const s=i?.device_id?t?.devices?.[i.device_id]:null;return null!=s?.disabled_by}function Eh(t,e){const i=t?.attributes?.supported_features;if(null==i||""===i)return!1;const s=Number(i);return Number.isFinite(s)&&(s&e)===e}function Fh(t,e,i){const s=Dh(i);if("lock"===s||"alarm_control_panel"===s)return!0;if("cover"!==s)return!1;const n=t?.states?.[i],o=Rh(e,i),a=String(n?.attributes?.device_class||o?.device_class||o?.original_device_class||"");return Ui.has(a)}function zh(t,e,i,s,n){return{ref:i,entityId:s,name:s?Ah(t,e,s):null,reason:n}}function Oh(t,e,i,s,n,o=null){return{target:null,skipped:zh(t,e,i,s,n),semantics:o,nextEffect:null,command:null}}function Hh(t,e,i,s,n=i){const o=Dh(i);if("cover"!==o&&"valve"!==o)return function(t,e,i,s,n=i){const o=Dh(i),a=t?.states?.[i];if(Ih(e,i))return Oh(t,e,n,i,"ha-disabled","power");if(Fh(t,e,i))return Oh(t,e,n,i,"secure");if(!a)return Oh(t,e,n,i,"missing","power");if("unavailable"===a.state)return Oh(t,e,n,i,"unavailable","power");const r=Ch[o];if(!r)return Oh(t,e,n,i,"unsupported");let l,c;if("unknown"===a.state||""===a.state){if(!r.unknownUsesToggle)return Oh(t,e,n,i,"unsupported","power");l="toggle",c="toggle"}else r.offStates.includes(String(a.state))?(l="turn-on",c="turn_on"):(l="turn-off",c="turn_off");const h=r.featureMasks?.[c];if(h&&!Eh(a,h))return Oh(t,e,n,i,"unsupported","power");const d=Ph(t,o,c);return d?{target:{entityId:i,name:Ah(t,e,i),state:String(a.state||""),via:s},skipped:null,semantics:"power",nextEffect:l,command:{...d,data:{entity_id:i}}}:Oh(t,e,n,i,"unsupported","power")}(t,e,i,s,n);if(Ih(e,i))return Oh(t,e,n,i,"ha-disabled",o);if(Fh(t,e,i))return Oh(t,e,n,i,"secure",o);const a=t?.states?.[i];if(!a)return Oh(t,e,n,i,"missing",o);if("unavailable"===a.state)return Oh(t,e,n,i,"unavailable",o);const r=function(t,e,i){const s=String(i?.state||""),n="closed"===s?{service:`open_${e}`,effect:"open",feature:1}:"open"===s?{service:`close_${e}`,effect:"close",feature:2}:"opening"===s||"closing"===s?{service:`stop_${e}`,effect:"stop",feature:8}:null;return n&&Eh(i,n.feature)&&Th(t,e,n.service)?n:Eh(i,3)&&Th(t,e,"toggle")?{service:"toggle",effect:"toggle"}:null}(t,o,a);if(!r)return Oh(t,e,n,i,"unsupported",o);return{target:{entityId:i,name:Ah(t,e,i),state:String(a.state||""),via:s},skipped:null,semantics:o,nextEffect:r.effect,command:{domain:o,service:r.service,data:{entity_id:i}}}}function Nh(t){return"entity"===t.bindingKind?t.bindingRef&&Ms(t.bindingRef)?[t.bindingRef]:[]:"virtual"===t.bindingKind?[]:Zn(t)}function Lh(t){const e=t.marker?.toggle_entity;return e&&Nh(t).includes(e)?e:null}function Bh(t,e,i){const s=function(t,e){if("entity"===t.bindingKind&&t.bindingRef){const e=t.marker?.light_entity?Qn(t):null;return[...new Set([e,t.bindingRef].filter(t=>!!t))]}const i=t.entities.length?t.entities:t.allEntities||[],s=t.marker?.light_entity||t.primary&&Ms(t.primary)?Qn(t):null;return[...new Set([s,...Vn(e,i)].filter(t=>!!t))]}(i,e);if(!s.length)return null;const n="entity"===i.bindingKind?"binding":"device-role";if("binding"===n)return Hh(t,e,s[0],n);let o=null,a=null;for(const i of s){const s=Hh(t,e,i,n);if(s.command)return s;const r=s.skipped?.reason;if("missing"===r||"unavailable"===r||"secure"===r)return s;"ha-disabled"!==r?o||=s:a||=s}return o||a}function qh(t){const e=t.skipped?.reason;return"missing"===e?"unavailable":e||"unsupported"}function jh(t,e){return{origin:t,kind:"none",semantics:null,targets:[],skippedTargets:[],noneReason:e,nextEffect:null,command:null}}function Wh(t,e){return"cover"===t||"toggle"===t?"toggle":"more-info"===t||"run"===t||"info"===t?t:(null==t||""===t)&&"light"===e?"toggle":"info"}function Uh(t,e){return{origin:t,kind:"single",semantics:e.semantics,targets:e.target?[e.target]:[],skippedTargets:e.skipped?[e.skipped]:[],noneReason:e.command?null:qh(e),nextEffect:e.nextEffect,command:e.command}}function Gh(t,e,i,s=[]){const n=new Map,o=[],a=new Set,r=t=>{const e=`${t.ref}\n${t.entityId||""}\n${t.reason}`;a.has(e)||(a.add(e),o.push(t))};for(const t of s)r(t);for(const s of i){const i=Hh(t,e,s.entityId,s.via,s.ref);i.target?n.set(s.entityId,n.get(s.entityId)||i.target):i.skipped&&r(i.skipped)}const l=[...n.values()];if(!l.length)return{origin:"explicit-toggle",kind:"group",semantics:"group-power",targets:l,skippedTargets:o,noneReason:o.length&&o.every(t=>"secure"===t.reason)?"secure":"configured-targets-missing",nextEffect:null,command:null};const c=l.some(t=>"on"===t.state)?"turn_off":"turn_on",h=Ph(t,"homeassistant",c);return h?{origin:"explicit-toggle",kind:"group",semantics:"group-power",targets:l,skippedTargets:o,noneReason:null,nextEffect:"turn_on"===c?"turn-on":"turn-off",command:{...h,data:{entity_id:l.map(t=>t.entityId)}}}:{origin:"explicit-toggle",kind:"group",semantics:"group-power",targets:[],skippedTargets:[...o,...l.map(i=>zh(t,e,i.entityId,i.entityId,"unsupported"))],noneReason:"unsupported",nextEffect:null,command:null}}function Vh(t){return String(t.marker?.id||t.id||"")}function Kh(t){const{hass:e,device:i}=t,s=t.registryHass||e,n=function(t){return"toggle"===t.tapAction?"explicit-toggle":"cover"===t.tapAction?"legacy-cover":!t.tapAction&&t.primary?.startsWith("light.")?"default-light":null}(i);if(!n)return null;const o=i.marker;if("explicit-toggle"===n&&yn(o)){const e=String(o?.id||i.id||""),s=oo(t.devices).get(e);if(s)return function(t,e){const i=t.registryHass||t.hass;return Gh(t.hass,i,e.driverEids.map(t=>({entityId:t,via:"control-marker-driver",ref:`marker:${e.markerId}`})))}(t,s);const a=bn(o,t.virtualLights);return{origin:n,kind:"single",semantics:"power",targets:[{entityId:"",name:i.name,state:a?"on":"off",via:"virtual-light"}],skippedTargets:[],noneReason:null,nextEffect:a?"turn-off":"turn-on",command:null,operation:{kind:"virtual-light",markerId:o.id}}}if("explicit-toggle"===n){if(Xn(i.marker?.binding,i.marker?.controls??i.controls,i.entities).length)return function(t,e=null){const{hass:i,device:s,devices:n}=t,o=t.registryHass||i,a=Xn(s.marker?.binding,s.marker?.controls??s.controls,s.entities),r=t.lightSources||lo(i,n,null,t.virtualLights),l=new Map;for(const t of r){if(!t.key.startsWith("marker:"))continue;const e=l.get(t.key)||[];e.push(t),l.set(t.key,e)}const c=oo(n),h=new Map;for(const t of n){const e=String(t.marker?.id||t.id||"");e&&h.set(e,t)}const d=[],u=[];e&&d.push({entityId:e,via:"entity"===s.bindingKind?"binding":"device-role",ref:e});for(const t of a){if(!t.startsWith("marker:")){Ms(t)?d.push({entityId:t,via:"control-entity",ref:t}):u.push(zh(i,o,t,t.includes(".")?t:null,"unsupported"));continue}const e=l.get(t)||[];if(!e.length){const e=h.get(t.slice(7));if("ha_disabled"===e?.bindingStatus?.kind){const s=e.bindingStatus.allEntityIds[0]||null;u.push({ref:t,entityId:s,name:e.name||(s?Ah(i,o,s):null),reason:"ha-disabled"})}else u.push(zh(i,o,t,null,"missing"));continue}const n=[...new Set(e.flatMap(t=>t.serviceEids))];if(n.length){for(const e of n)d.push({entityId:e,via:"control-entity",ref:t});continue}const a=e.some(t=>t.passive),r=t.slice(7),p=Vh(s),_=c.get(r)?.controllers.find(t=>Vh(t.device)===p);if(a&&_?.driverEids.length)for(const e of _.driverEids)d.push({entityId:e,via:"control-marker-driver",ref:t});else u.push(zh(i,o,t,null,a?"missing":"unsupported"))}return Gh(i,o,d,u)}(t,Lh(i))}if("legacy-cover"===n){const t=i.entities.find(t=>t.startsWith("cover."))||i.allEntities?.find(t=>t.startsWith("cover."));return t?Uh(n,Hh(e,s,t,"device-role")):jh(n,"no-actionable-entity")}const a=Lh(i),r=a?Hh(e,s,a,"entity"===i.bindingKind?"binding":"device-role"):Bh(e,s,i);return r?Uh(n,r):jh(n,i.virtual||"virtual"===i.bindingKind?"no-actionable-entity":"no-binding")}function Yh(t){if(!t)return[];const e=Array.isArray(t.data.entity_id)?t.data.entity_id:[t.data.entity_id];return[...new Set(e)].sort()}function Xh(t){return t?t.operation?t.operation:t.command?{kind:"ha-service",command:t.command}:null:null}function Jh(t,e){const i=Xh(t),s=Xh(e);return!(!i||!s||i.kind!==s.kind)&&("virtual-light"===i.kind&&"virtual-light"===s.kind?i.markerId===s.markerId:"ha-service"===i.kind&&"ha-service"===s.kind&&function(t,e){const i=Yh(t),s=Yh(e);return i.length===s.length&&i.every((t,e)=>t===s[e])}(i.command,s.command))}const Zh=t=>!!t&&t.length>=2&&Number.isFinite(t[0])&&Number.isFinite(t[1]);function Qh(t,e=5,i=5){return fr(t.cm,e,i)/2}function td(t,e,i=1,s=5,n=5,o=0){const a=t.host;if(!a||"partition"!==a.kind||"string"!=typeof a.id||!a.id)return{resolved:null,reason:"invalid-host"};const r=e.find(t=>t.id===a.id);if(!r)return{resolved:null,reason:"missing-partition"};if(!Zh(r.a)||!Zh(r.b)||!Number.isFinite(a.t)||a.t<0||a.t>1)return{resolved:null,reason:"invalid-position"};const l=r.b[0]-r.a[0],c=r.b[1]-r.a[1],h=Math.hypot(l,c),d=Number(t.length)*i;if(!(h>1e-9&&d>0&&Number.isFinite(d)))return{resolved:null,reason:"invalid-length"};const u=a.t*h;if(u-d/2h-o+1e-9)return{resolved:null,reason:"does-not-fit"};const p=l/h,_=c/h;let g=180*Math.atan2(c,l)/Math.PI;return g>=90?g-=180:g<-90&&(g+=180),{reason:null,resolved:{opening:t,host:a,partition:r,center:[r.a[0]+l*a.t,r.a[1]+c*a.t],angle:g,length:d,depth:fr(r.cm,s,n),t:a.t,axis:{a:[r.a[0],r.a[1]],b:[r.b[0],r.b[1]],ux:p,uy:_,length:h}}}}function ed(t,e,i=1,s=5,n=5){return td(t,e,i,s,n,0)}function id(t,e,i=1,s=5,n=5){const o=t.host,a="partition"===o?.kind?e.find(t=>t.id===o.id):void 0;if(!a)return ed(t,e,i,s,n);const r=td(t,e,i,s,n,Qh(a,s,n));return"does-not-fit"===r.reason?{resolved:null,reason:"does-not-fit-jamb"}:r}function sd(t,e){return!t||(t.length!==e.length||t.host?.kind!==e.host?.kind||t.host?.id!==e.host?.id||t.host?.t!==e.host?.t)}function nd(t){const{center:e,length:i,axis:s,host:n}=t,o=i/2;return{hostId:n.id,a:[e[0]-s.ux*o,e[1]-s.uy*o],b:[e[0]+s.ux*o,e[1]+s.uy*o],depth:t.depth}}function od(t,e=!1){const i=e?1:-1,s=t.depth/2;return{ox:-t.axis.uy*i*s,oy:t.axis.ux*i*s,cm:t.partition.cm,side:i}}function ad(t,e,i){const{center:s,length:n,axis:o}=t,a=n/2,r=e.flatMap(t=>{if(!t.kind||t.open)return[];const e=t.b[0]-t.a[0],n=t.b[1]-t.a[1],r=Math.hypot(e,n);if(!(r>i))return[];const l=e/r,c=n/r;if(Math.abs(o.ux*c-o.uy*l)>1e-6)return[];if(Math.abs((s[0]-t.a[0])*c-(s[1]-t.a[1])*l)>i)return[];const h=t=>(t[0]-s[0])*o.ux+(t[1]-s[1])*o.uy,d=h(t.a),u=h(t.b),p=Math.max(-a,Math.min(d,u)),_=Math.min(a,Math.max(d,u));return _>=p-i?[[p,_]]:[]});if(!r.length)return!1;r.sort((t,e)=>t[0]-e[0]||t[1]-e[1]);let l=-a;for(const[t,e]of r){if(t>l+i)return!1;if(l=Math.max(l,e),l>=a-i)return!0}return!1}function rd(t,e,i){return{...t,x:e.center[0]/i,y:e.center[1]/i,angle:e.angle}}function ld(t){return!!t&&t.length>=2&&Number.isFinite(t[0])&&Number.isFinite(t[1])}function cd(t){return`${t[0].toFixed(6)},${t[1].toFixed(6)}`}function hd(t,e,i){return Math.abs(t[0]-e[0])_d(s,t,e)))continue;const t=cd(s);a.has(t)||a.set(t,{point:[s[0],s[1]],key:t})}}}return{segments:[...o.values()].sort((t,e)=>t.key.localeCompare(e.key)),endpoints:[...a.values()].sort((t,e)=>t.key.localeCompare(e.key))}}function md(t,e,i){return e.some(e=>ld(e)&&hd(t,e,i))}function fd(t,e,i){if(!i)return!0;const s=t-i.distance;return s<-1e-9||Math.abs(s)<=1e-9&&e.localeCompare(i.key)<0}function vd(t,e,i){const s=t.b[0]-t.a[0],n=t.b[1]-t.a[1],o=Math.hypot(s,n);if(!(o>0))return[...t.a];const a=s/o,r=n/o,l=Math.max(0,Math.min(o,(e[0]-t.a[0])*a+(e[1]-t.a[1])*r)),c=i>0?Math.max(0,Math.min(o,Math.round(l/i)*i)):l;return[t.a[0]+a*c,t.a[1]+r*c]}const yd=.001;function bd(t,e,i){const s=[];for(let n=0;n+1=0?e[n]:i;s.push({a:[o[0],o[1]],b:[a[0],a[1]],cm:r})}return s}function wd(t){return!!t&&t.length>=2&&Number.isFinite(t[0])&&Number.isFinite(t[1])}function kd(t,e,i,s){return t*s-e*i}function xd(t){let e=0;for(let i=0;it.localeCompare(e)),e[0]}function Dd(t,e,i){const s=[...t];for(let t=!0;t&&s.length>=3;){t=!1;for(let n=0;n=0){s.splice(n,1),t=!0;break}}}return s}function Td(t,e){const i=t.map(t=>Math.max(0,Math.min(1,t))).sort((t,e)=>t-e),s=[];for(const t of i)(!s.length||Math.abs(t-s[s.length-1])>e)&&s.push(t);return s}function Pd(t,e){return[t.a[0]+(t.b[0]-t.a[0])*e,t.a[1]+(t.b[1]-t.a[1])*e]}function Rd(t,e,i){const s=function(t,e){const i=e.b[0]-e.a[0],s=e.b[1]-e.a[1],n=i*i+s*s;return n>0?((t[0]-e.a[0])*i+(t[1]-e.a[1])*s)/n:0}(t,e);if(s<-i||s>1+i)return null;const n=Pd(e,s);return Math.hypot(n[0]-t[0],n[1]-t[1])<=i?Math.max(0,Math.min(1,s)):null}function Ad(t,e,i,s,n){const o=t.b[0]-t.a[0],a=t.b[1]-t.a[1],r=e.b[0]-e.a[0],l=e.b[1]-e.a[1],c=e.a[0]-t.a[0],h=e.a[1]-t.a[1],d=kd(o,a,r,l),u=Math.max(Math.hypot(o,a),Math.hypot(r,l),1);if(Math.abs(d)>n*u){const t=kd(c,h,r,l)/d,e=kd(c,h,o,a)/d;return void(t>=-n&&t<=1+n&&e>=-n&&e<=1+n&&(i.push(Math.max(0,Math.min(1,t))),s.push(Math.max(0,Math.min(1,e)))))}if(!(Math.abs(kd(c,h,o,a))>n*u)){for(const s of[e.a,e.b]){const e=Rd(s,t,n);null!=e&&i.push(e)}for(const i of[t.a,t.b]){const t=Rd(i,e,n);null!=t&&s.push(t)}}}function Id(t){let e=t+1|0;return e^=e<<13,e^=e>>>17,e^=e<<5,e>>>0}function Ed(t,e){return t.minY-e.minY||t.index-e.index}function Fd(t){return t.subtreeMaxY=Math.max(t.item.maxY,t.left?.subtreeMaxY??-1/0,t.right?.subtreeMaxY??-1/0),t}function zd(t){const e=t.right;return t.right=e.left,e.left=Fd(t),Fd(e)}function Od(t){const e=t.left;return t.left=e.right,e.right=Fd(t),Fd(e)}function Hd(t,e){return t?(Ed(e,t.item)<0?(t.left=Hd(t.left,e),t.left.priority0)t.right=Nd(t.right,e);else{if(!t.left)return t.right;if(!t.right)return t.left;t.left.priority=e&&Ld(t.left,e,i,s),t.item.minY<=i&&t.item.maxY>=e&&s.push(t.item),t.item.minY<=i&&Ld(t.right,e,i,s))}function Bd(t,e=.001){const i=Number.isFinite(e)&&e>0?e:yd,s=t.filter(t=>wd(t.a)&&wd(t.b)&&"string"==typeof t.key&&t.key.length>0&&Math.hypot(t.b[0]-t.a[0],t.b[1]-t.a[1])>i),n=s.map(()=>[0,1]);!function(t,e,i){const s=t.map((t,e)=>({index:e,minX:Math.min(t.a[0],t.b[0])-i,maxX:Math.max(t.a[0],t.b[0])+i,minY:Math.min(t.a[1],t.b[1])-i,maxY:Math.max(t.a[1],t.b[1])+i})),n=[...s].sort((t,e)=>t.minX-e.minX||t.minY-e.minY||t.index-e.index),o=[...s].sort((t,e)=>t.maxX-e.maxX||t.index-e.index),a=new Set;let r=null,l=0;for(const s of n){for(;lt.index-e.index);for(const o of n)Ad(t[o.index],t[s.index],e[o.index],e[s.index],i);a.add(s.index),r=Hd(r,s)}}(s,n,i);const o=new Map;for(let t=0;t({key:t,a:e.a,b:e.b,sourceKeys:[...e.sourceKeys].sort((t,e)=>t.localeCompare(e))})).sort((t,e)=>t.key.localeCompare(e.key))}const qd=1e-5;function jd(t){const e=t.map(()=>[]);for(let i=0;i=1-1e-9||u<=1e-9||u>=1-1e-9||(e[i].push(d),e[a].push(u))}}const i=[];for(let s=0;st-e),1];for(let t=1;t{const i=e[2]-e[0],s=e[3]-e[1],n=i*i+s*s;if(!(n>0))return Math.hypot(t[0]-e[0],t[1]-e[1]);const o=Math.max(0,Math.min(1,((t[0]-e[0])*i+(t[1]-e[1])*s)/n));return Math.hypot(t[0]-(e[0]+o*i),t[1]-(e[1]+o*s))},Gd=(t,e,i,s)=>{const n=s[2]-s[0],o=s[3]-s[1],a=e*o-i*n;if(Math.abs(a)<1e-12)return 1/0;const r=s[0]-t[0],l=s[1]-t[1],c=(r*o-l*n)/a;if(!(c>1e-9))return 1/0;const h=(r*i-l*e)/a;return h<-1e-9||h>1+1e-9?1/0:c};function Vd(t,e,i,s=96){if(!(e>0&&Number.isFinite(t[0])&&Number.isFinite(t[1])))return[];const n=[];for(const s of i){if(!s||s.length<4)continue;if(![s[0],s[1],s[2],s[3]].every(Number.isFinite))continue;const i=Ud(t,s);if(i<1e-7)return[];i>e||n.push(s)}const o=[],a=Math.max(12,Math.round(s));for(let t=0;tt-e);const l=[];let c=Number.NEGATIVE_INFINITY;for(const i of o){if(i-c<1e-9)continue;c=i;const s=Math.cos(i),o=Math.sin(i);let a=e;for(const e of n){const i=Gd(t,s,o,e);i=3?l:[]}class Kd extends ht{constructor(){super(...arguments),this._spaces=null,this._spacesLoading=!1}setConfig(t){this._config=t}async _loadSpaces(){if(!this._spaces&&!this._spacesLoading&&this.hass){this._spacesLoading=!0;try{const t=await this.hass.callWS({type:"houseplan/config/get"});this._spaces=(t?.config?.spaces||[]).map(t=>({value:t.id,label:t.title||t.id}))}catch{this._spaces=[]}finally{this._spacesLoading=!1}}}get _lang(){return sa(this.hass,this._config?.language)}get _schema(){const t=this._spaces||[],e=this._lang;return[{name:"title",selector:{text:{}}},t.length?{name:"default_floor",selector:{select:{mode:"dropdown",options:t}}}:{name:"default_floor",selector:{text:{}}},{name:"language",selector:{select:{mode:"dropdown",options:[{value:"",label:na(e,"editor.lang_auto")},{value:"en",label:na(e,"editor.lang_en")},{value:"ru",label:na(e,"editor.lang_ru")}]}}},{name:"icon_size",selector:{number:{min:1,max:6,step:.1,mode:"box"}}},{name:"show_temperature",selector:{boolean:{}}},{name:"live_states",selector:{boolean:{}}},{name:"show_signal",selector:{boolean:{}}},{name:"kiosk",selector:{boolean:{}}},{name:"cycle",selector:{number:{min:0,max:3600,step:5,mode:"box"}}}]}render(){if(!this.hass||!this._config)return G;this._loadSpaces();const t=this._lang,e={title:na(t,"editor.title"),default_floor:na(t,"editor.default_floor"),language:na(t,"editor.language"),icon_size:na(t,"editor.icon_size"),show_temperature:na(t,"editor.show_temperature"),live_states:na(t,"editor.live_states"),show_signal:na(t,"editor.show_signal"),kiosk:na(t,"editor.kiosk"),cycle:na(t,"editor.cycle")};return j`{const e=vc(t);return W`${t.name}`}),T=lo(a,c,null,t.virtualLights),P=c.map(s=>{const n=function(t,e,i,s,n){const o=e[t.id];return o&&o.s===t.space?{x:o.x*Bl,y:o.y*Bl}:s[t.id]?s[t.id]:tc(pc(n))}(s,t.layout,t.cfg,h,e),o=(n.x-y[0])/y[2]*100,l=(n.y-y[1])/y[3]*100,d=i.showLqi??!1!==t.showSignal,u=t.presentations?.get(hu(s.id,d))||au(a,s,{liveStates:!1!==t.liveStates,showTemperature:!1!==t.showTemperature,showSignal:d,activityRuntime:t.activityRuntime?.get(s.id),sourceDetails:!1,lightDevices:c,lightSources:T,registryHass:r,reducedMotion:t.reducedMotion}),p=[`left:${o}%`,`top:${l}%`,...jo(u)],_=[s.name,"none"!==u.pulse.kind?na(t.lang,`marker.pulse_a11y_${u.pulse.reason}`):"",To(u.valueBadge)].filter(Boolean).join(", ");return j`
`),C=new Map;for(const t of e.rooms)if(t.id){const e=b.get(t)||null;C.set(t.id,Fs(i.glow,t)&&(!e||e.opacity<=0)?{color:s.glow_base.c,opacity:s.glow_base.a,mode:"glow"}:null)}const D=lo(a,c,null,t.virtualLights),T=c.map(s=>{const n=function(t,e,i,s,n){const o=e[t.id];return o&&o.s===t.space?{x:o.x*Bl,y:o.y*Bl}:s[t.id]?s[t.id]:tc(pc(n))}(s,t.layout,t.cfg,h,e),o=(n.x-y[0])/y[2]*100,l=(n.y-y[1])/y[3]*100,d=i.showLqi??!1!==t.showSignal,u=t.presentations?.get(hu(s.id,d))||au(a,s,{liveStates:!1!==t.liveStates,showTemperature:!1!==t.showTemperature,showSignal:d,activityRuntime:t.activityRuntime?.get(s.id),sourceDetails:!1,lightDevices:c,lightSources:D,registryHass:r,reducedMotion:t.reducedMotion}),p=[`left:${o}%`,`top:${l}%`,...jo(u)],_=[s.name,"none"!==u.pulse.kind?na(t.lang,`marker.pulse_a11y_${u.pulse.reason}`):"",To(u.valueBadge)].filter(Boolean).join(", ");return j`
${Wo(u,{})} -
`}),R=i.showNames?e.rooms.filter(t=>t.name).map(s=>{const n=function(t,e,i){const s=i["rl_"+(t.id||"")];if(s&&s.s===e)return{x:s.x*Bl,y:s.y*Bl};const n=vc(t);return tc({x:n[0],y:n[1]})}(s,e.id,t.layout,t.cfg),o=(n.x-y[0])/y[2]*100,a=(n.y-y[1])/y[3]*100,r=Math.min(1,i.opacity+.25);return j`
`}),P=i.showNames?e.rooms.filter(t=>t.name).map(s=>{const n=vc(s,e.id,t.layout,t.cfg),o=(n.x-y[0])/y[2]*100,a=(n.y-y[1])/y[3]*100,r=Math.min(1,i.opacity+.25);return j`
${s.name}
`}):[],A=e.bg?t.displayUrl?t.displayUrl(e.bg.href):e.bg.href:"",I=t.cfg.spaces.find(e=>e.id===t.spaceId)?.settings||{},E="daynight"===Ya(t.cfg?.settings,I)?Ha(a,t.dayCycleNow??new Date):null,F=hs(t.cfg?.settings,i),z=!!(p.length||f.length&&i.showBorders),O=z?ih(k.length?{rooms:e.rooms,walls:p,extras:f,cellCm:_,passages:k.map(t=>({x:t.rx,y:t.ry,angle:t.angle,length:t.rlen})),hostedCompositeOpenings:$}:{rooms:e.rooms,walls:p,extras:f,cellCm:_}):"",H=z?function(t,e,i,s){let n=uu.get(t);n||(n=new Map,uu.set(t,n));const o=n.get(e);if(o?.fingerprint===i)return o.value;const a=s();return n.set(e,{fingerprint:i,value:a}),a}(t.cfg,e.id,O,()=>ul(e.rooms,p,[],[...k.filter(t=>!t.host).map(t=>({x:t.rx,y:t.ry,angle:t.angle,length:t.rlen})),...$],Zl,_,Jl,Bl,f)):null,N=k.length&&p.length?function(t,e,i,s,n,o,a,r=1){return[n,o,a,r].every(Number.isFinite)&&o>0&&r>0&&i?.length?kl(gl(t,i,s,n,o,a,r),e):e.map(()=>null)}(e.rooms,k.map(t=>({x:t.rx,y:t.ry,angle:t.angle,length:t.rlen})),p,[],Zl,_,Jl,Bl):k.map(()=>null),L=k.length?du({openings:k,geometries:N,fillsByRoomId:w,idPrefix:`${e.id}-static-data`,groupClass:"opening-tunnels static-opening-tunnels",dataLayer:"data"}):G,B=k.length?du({openings:k,geometries:N,fillsByRoomId:C,idPrefix:`${e.id}-static-glow`,groupClass:"opening-tunnels glow-base-tunnels static-opening-tunnels",dataLayer:"glow-base"}):G,q=p.length&&H?.paperD?[{path:H.paperD}]:di(e.rooms),U=i.showBorders?H:null,V=t.stageWidth&&y[2]?t.stageWidth/y[2]:1,K=!!U&&_r(U.depthUnits,V),Y=i.color||"#607d8b",X=i.hideOpenings?[]:g.map(t=>{const e=t.opening,i="passage"!==e.type&&e.contact?a.states?.[e.contact]?.state:null,s=gi(e.type,i,!!e.invert),n=s>0&&!!e.contact,o="gate"===e.type?!e.flip_v:!!e.flip_v,r={type:e.type,length:t.length,angle:t.angle,amount:s,flipH:!!e.flip_h,flipV:!!e.flip_v,base:Y,tone:n?"var(--hp-open)":Y,cellCm:_,gridPitch:Jl,face:od(t,o)};return W`${s.name}
`}):[],R=e.bg?t.displayUrl?t.displayUrl(e.bg.href):e.bg.href:"",A=t.cfg.spaces.find(e=>e.id===t.spaceId)?.settings||{},I="daynight"===Ya(t.cfg?.settings,A)?Ha(a,t.dayCycleNow??new Date):null,E=hs(t.cfg?.settings,i),F=!!(p.length||f.length&&i.showBorders),z=F?ih(k.length?{rooms:e.rooms,walls:p,extras:f,cellCm:_,passages:k.map(t=>({x:t.rx,y:t.ry,angle:t.angle,length:t.rlen})),hostedCompositeOpenings:$}:{rooms:e.rooms,walls:p,extras:f,cellCm:_}):"",O=F?function(t,e,i,s){let n=uu.get(t);n||(n=new Map,uu.set(t,n));const o=n.get(e);if(o?.fingerprint===i)return o.value;const a=s();return n.set(e,{fingerprint:i,value:a}),a}(t.cfg,e.id,z,()=>ul(e.rooms,p,[],[...k.filter(t=>!t.host).map(t=>({x:t.rx,y:t.ry,angle:t.angle,length:t.rlen})),...$],Zl,_,Jl,Bl,f)):null,H=k.length&&p.length?function(t,e,i,s,n,o,a,r=1){return[n,o,a,r].every(Number.isFinite)&&o>0&&r>0&&i?.length?kl(gl(t,i,s,n,o,a,r),e):e.map(()=>null)}(e.rooms,k.map(t=>({x:t.rx,y:t.ry,angle:t.angle,length:t.rlen})),p,[],Zl,_,Jl,Bl):k.map(()=>null),N=k.length?du({openings:k,geometries:H,fillsByRoomId:w,idPrefix:`${e.id}-static-data`,groupClass:"opening-tunnels static-opening-tunnels",dataLayer:"data"}):G,L=k.length?du({openings:k,geometries:H,fillsByRoomId:C,idPrefix:`${e.id}-static-glow`,groupClass:"opening-tunnels glow-base-tunnels static-opening-tunnels",dataLayer:"glow-base"}):G,B=p.length&&O?.paperD?[{path:O.paperD}]:di(e.rooms),q=i.showBorders?O:null,U=t.stageWidth&&y[2]?t.stageWidth/y[2]:1,V=!!q&&_r(q.depthUnits,U),K=i.color||"#607d8b",Y=i.hideOpenings?[]:g.map(t=>{const e=t.opening,i="passage"!==e.type&&e.contact?a.states?.[e.contact]?.state:null,s=gi(e.type,i,!!e.invert),n=s>0&&!!e.contact,o="gate"===e.type?!e.flip_v:!!e.flip_v,r={type:e.type,length:t.length,angle:t.angle,amount:s,flipH:!!e.flip_h,flipV:!!e.flip_v,base:K,tone:n?"var(--hp-open)":K,cellCm:_,gridPitch:Jl,face:od(t,o)};return W` ${Xd(r)} `});return j` -
- ${tr(E)} + style="aspect-ratio:${y[2]}/${y[3]}${E?";background:"+E:""};--wall-fill:${s.wall_fill.c};--wall-fill-op:${s.wall_fill.a}${I?`;${Qa(I)}`:""}"> + ${tr(I)} - ${U?W` + ${q?W` - + `:G} - ${q.map(t=>"path"in t?W``:"poly"in t?W``:W``)} - ${A?W`t.assetLoaded?.(e.bg.href,A)} + ${B.map(t=>"path"in t?W``:"poly"in t?W``:W``)} + ${R?W`t.assetLoaded?.(e.bg.href,R)} transform=${e.bg.angle?`rotate(${e.bg.angle} ${e.bg.x+e.bg.w/2} ${e.bg.y+e.bg.h/2})`:G} preserveAspectRatio="none" />`:G} ${S} - ${L} + ${N} ${M.length?W``:G} - ${B} - ${D} - ${U?W` - + - + `:G} - ${X} + ${Y} ${""} -
${P}${R}
+
${T}${P}
`}let mu=null,fu=null,vu=0,yu=-1,bu=null,wu=[];const ku=new Set,xu=(t,e)=>{"function"==typeof t&&e.push(t)};function $u(){if(mu)return mu;try{const t=JSON.parse(localStorage.getItem("houseplan_card_cfg_v1")||"null");if(t&&t.config&&Array.isArray(t.config.spaces)){const e=t.layout||{};return{config:t.config,rev:t.rev||0,configFingerprint:t.config_fingerprint||ih(t.config),layout:e,layoutRev:t.layout_rev||0,layoutFingerprint:t.layout_fingerprint||ih(e),virtualLights:gn(t.virtual_lights,t.rev||0)}}}catch{}return null}function Su(t,e=!1){if(e&&(mu=null,vu++,fu))return fu.catch(()=>null).then(()=>Su(t,!1));if(mu)return Promise.resolve(mu);if(fu)return yu!==vu?fu.catch(()=>null).then(()=>Su(t,!1)):fu;return yu=vu,fu=async function(t,e){const[i,s]=await Promise.all([t.callWS({type:"houseplan/config/get"}),t.callWS({type:"houseplan/layout/get"})]),n=i?.rev??0,o=mu?mn(mu.virtualLights,i?.virtual_lights,n,!!i&&"virtual_lights"in i):gn(i?.virtual_lights,n),a={config:i?.config??null,rev:n,configFingerprint:ih(i?.config??null),layout:s?.layout??{},layoutRev:s?.rev??0,layoutFingerprint:ih(s?.layout??{}),virtualLights:o};e===vu&&(mu=a);const r=t.connection;if(r?.subscribeEvents&&bu!==r){for(const t of wu)t();wu=[],bu=r;const t=()=>{mu=null,vu++,ku.forEach(t=>t())},e=[];try{if(xu(await r.subscribeEvents(t,"houseplan_config_updated"),e),xu(await r.subscribeEvents(t,"houseplan_layout_updated"),e),xu(await r.subscribeEvents(t=>{if(mu){const e=wn(mu.virtualLights,t?.data);if(e===mu.virtualLights)return;mu={...mu,virtualLights:e}}else vu++;ku.forEach(t=>t())},"houseplan_virtual_light_updated"),e),bu===r)wu=e;else for(const t of e)t()}catch{for(const t of e)t();bu===r&&(bu=null)}}return a}(t,vu).finally(()=>{fu=null,yu=-1}),fu}const Mu=3300;function Cu(t,e){return{sources:t,last:Object.fromEntries(e.map(t=>[t.eid,t.state])),flashTs:0,flashKind:null,timer:0,gen:0,expiresAt:0,alarmActive:"alarm"===dn(e).status}}function Du(t,e,i,s){s(t.timer);const n=Cu(e,i);Object.assign(t,n)}function Tu(t,e,i,s,n){t.flashTs&&i-t.flashTs"transition"===t.activity)&&(i(t.timer),t.flashTs=0,t.flashKind=null,t.expiresAt=0);if("alarm"===dn(e).status){t.alarmActive||(i(t.timer),t.flashTs=0,t.flashKind=null,t.expiresAt=0);for(const i of e)t.last[i.eid]=i.state;return t.alarmActive=!0,null}if(t.alarmActive){for(const i of e)t.last[i.eid]=i.state;return t.alarmActive=!1,null}let s=null;for(const i of e){const e=un(t.last[i.eid],i);("event"===e||!s&&e)&&(s=e),t.last[i.eid]=i.state}return s}class Ru extends ht{constructor(){super(...arguments),this._spaces=null,this._spacesLoading=!1}setConfig(t){this._config=t}async _loadSpaces(){if(!this._spaces&&!this._spacesLoading&&this.hass){this._spacesLoading=!0;try{const t=await this.hass.callWS({type:"houseplan/config/get"});this._spaces=(t?.config?.spaces||[]).map(t=>({value:t.id,label:t.title||t.id}))}catch{this._spaces=[]}finally{this._spacesLoading=!1}}}get _lang(){return sa(this.hass,this._config?.language)}get _schema(){const t=this._spaces||[];return[t.length?{name:"space",selector:{select:{mode:"dropdown",options:t}}}:{name:"space",selector:{text:{}}},{name:"title",selector:{text:{}}},{name:"show_button",selector:{boolean:{}}},{name:"button_label",selector:{text:{}}},{name:"button_target",selector:{text:{}}},{name:"icon_size",selector:{number:{min:1,max:6,step:.1,mode:"box"}}},{name:"show_temperature",selector:{boolean:{}}},{name:"live_states",selector:{boolean:{}}},{name:"show_signal",selector:{boolean:{}}}]}render(){if(!this.hass||!this._config)return G;this._loadSpaces();const t=this._lang,e={space:na(t,"editor.space"),title:na(t,"editor.title"),show_button:na(t,"editor.show_button"),button_label:na(t,"editor.button_label"),button_target:na(t,"editor.button_target"),icon_size:na(t,"editor.icon_size"),show_temperature:na(t,"editor.show_temperature"),live_states:na(t,"editor.live_states"),show_signal:na(t,"editor.show_signal")};return j``:W``});return W``}_renderSvgRoomLabels(t,e){return"iso"===this._renderProjection||t.bg||e.showNames||this._markup?W``:W`${t.rooms.map(t=>{const e=this._roomCenter(t);return W`${t.name}`})}`}_renderWallBodies(t){if("iso"===this._renderProjection)return W``;if(t&&!t.showBorders&&("view"===this._mode||"devices"===this._mode))return W``;const e=this._wallUnionGeometry();if(!e)return W``;const i=this._stageEl,s=this._viewOr(this._baseVb()),n=i&&i.clientWidth&&s.w?i.clientWidth/s.w:1,o=t?.color||"#607d8b",a=_r(e.depthUnits,n),r=this._fillColors.wall_fill;return W` + fill=${a.color} fill-opacity=${a.opacity} pointer-events="none">`});return W``}_renderWallBodies(t){if("iso"===this._renderProjection)return W``;if(t&&!t.showBorders&&("view"===this._mode||"devices"===this._mode))return W``;const e=this._wallUnionGeometry();if(!e)return W``;const i=this._stageEl,s=this._viewOr(this._baseVb()),n=i&&i.clientWidth&&s.w?i.clientWidth/s.w:1,o=t?.color||"#607d8b",a=_r(e.depthUnits,n),r=this._fillColors.wall_fill;return W` @@ -5560,7 +5547,6 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="51c4bdb005b2539779085578bcce5ee1b4b3 ${this._renderOpeningTunnelFills(i,u)} ${this._renderGlowBaseRooms(i,p)} ${this._renderOpeningTunnelFills(i,p,"glow-base")} - ${this._renderSvgRoomLabels(i,c)} ${A?this._renderGlowLayer(i,c):G} ${this._renderSunRays(i)} ${this._editing?W`${this._renderMeasureLabel(f)}
`:G} diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 81b0f256..fca42336 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -2,6 +2,13 @@ ## v1.65.0-beta.4 — 2026-08-19 +- Turning off **Show names** now removes room names completely in View, kiosk, + the static card and hidden isometric mode, while Plan still exposes the + existing draggable card for positioning. Re-enabling names restores its + saved layout. **Breaking styling-hook change:** the fallback SVG + `text.rlabel` / `.rlabel` public hook has been removed; enabled room names + use `[data-hp="room-label"].roomlabel` + ([#203](https://github.com/Matysh/houseplan-card/issues/203)). - Closing a virtual room boundary now inherits the real thickness of an adjacent wall even when another room splits that saved wall into smaller atomic stretches. A 20/22 cm wall therefore no longer receives an accidental diff --git a/docs/CHANGELOG.ru.md b/docs/CHANGELOG.ru.md index 279e32fe..ec3cfb7e 100755 --- a/docs/CHANGELOG.ru.md +++ b/docs/CHANGELOG.ru.md @@ -8,6 +8,14 @@ ## v1.65.0-beta.4 — 2026-08-19 +- Выключение **«Показывать названия»** теперь полностью убирает названия комнат + из Просмотра, киоска, статической карточки и скрытой изометрии, а редактор + Плана по-прежнему временно показывает существующую карточку для настройки + позиции. Повторное включение восстанавливает сохранённую компоновку. + **Несовместимое изменение styling-hook:** публичный резервный SVG-хук + `text.rlabel` / `.rlabel` удалён; включённые названия используют + `[data-hp="room-label"].roomlabel` + ([#203](https://github.com/Matysh/houseplan-card/issues/203)). - При закрытии виртуальной границы теперь наследуется реальная толщина соседней стены, даже если другая комната разделила сохранённую стену на несколько атомарных участков. Поэтому на стене 20/22 см больше не появляется случайная diff --git a/docs/STYLING-HOOKS.md b/docs/STYLING-HOOKS.md index 0d134b3f..c0e467d3 100644 --- a/docs/STYLING-HOOKS.md +++ b/docs/STYLING-HOOKS.md @@ -92,7 +92,6 @@ Everything in this table is **public API**. | --- | --- | --- | --- | --- | | Device marker | `div` (HTML, marker layer) | `device` | `data-id` = marker/device id, `data-entity` = primary entity id, `data-area` = area id, `data-binding-status` = `active` \| `ha-disabled` \| `orphaned` \| `unverified`, `data-disabled-reason` = `device` \| `entity` \| `all-entities` when applicable | `.dev` | | Room shape | `polygon` / `rect` / `path` (SVG) | `room` | `data-id` = room id, `data-area` = area id | `.room` | -| Room name (no metrics) | `text` (SVG) | `room-label` | `data-id` = room id, `data-area` | `.rlabel` | | Room card (name + metrics) | `div` (HTML, marker layer) | `room-label` | `data-id` = room id, `data-area` | `.roomlabel` | | Door / window / gate | `g` (SVG) | `opening` | `data-id` = opening id, `data-kind` = `door` \| `window` \| `gate` | `.opening` | | Coloured tunnel inside a thick opening | `path` / `g` (SVG) | `opening-tunnel` | `data-id` = opening id, `data-kind` = `door` \| `window` \| `gate` | `.opening-tunnel` | @@ -132,6 +131,13 @@ usually wants: Inside a room card: `.rlname` (the name) and `.rlmetrics` / `.rlm` (the metric row and one metric in it). +**Breaking hook change in #203.** The former SVG fallback +`text.rlabel[data-hp="room-label"]` has been removed. A space with +`show_names: false` now emits no permanent room-label element at all, as the +setting promises. Target the HTML room-card hook +`[data-hp="room-label"].roomlabel` when room names are enabled. Plan editor +temporarily renders the same HTML card so it can still be positioned. + ### 3.2 Public state classes These are set on `.dev` and describe **live state**, so a rule may key off diff --git a/docs/TESTING.md b/docs/TESTING.md index 595346c1..4798fde2 100644 --- a/docs/TESTING.md +++ b/docs/TESTING.md @@ -2081,7 +2081,7 @@ require hands on real hardware — they remain for the human pass. carries `data-hp="device"`, `data-id`, `data-entity` and `data-area`; a room `data-hp="room"` + `data-id` + `data-area`; a door/window/gate `data-hp="opening"` + `data-kind`; a decor shape `data-hp="decor"` + - `data-kind`; a room caption `data-hp="room-label"`; a floor tab + `data-kind`; a visible room card `data-hp="room-label"`; a floor tab `data-hp="space-tab"`. The ids are the ones in your config, not DOM positions — they survive a reload [auto: smoke_styling_hooks] - [ ] **Absent is absent**: a virtual marker has NO `data-entity` at all, and a @@ -2092,7 +2092,7 @@ require hands on real hardware — they remain for the human pass. signal badges disappear and nothing else moves. Then target one marker by `[data-entity="…"]` and confirm it is the only one affected [manual] - [ ] **The static card carries the same hooks**: a `houseplan-space-card` - has `data-hp` on its rooms, room labels and markers (it draws no openings + has `data-hp` on its rooms, visible room labels and markers (it draws no openings and no decor, so those are simply absent), and it needs its OWN card-mod block — it is a different card with its own shadow root [auto: smoke_styling_hooks] @@ -2359,6 +2359,20 @@ require hands on real hardware — they remain for the human pass. ## Hiding layers: decor, openings, virtual walls (docs/UX-MODES.md, dev, unreleased) +- [ ] **Room names have one literal off state (#203)**: disable «Показывать + названия» in the live space dialog, save and reopen it. Full View, kiosk, + hidden isometric and `houseplan-space-card` contain no + `[data-hp="room-label"]` and no legacy `text.rlabel`. Plan temporarily + shows the same draggable HTML card and gear; returning to View hides it. + Cancel restores the previous setting, while re-enabling names restores + the saved card position and area icon + [auto: `smoke_hide_room_names`, `smoke_styling_hooks`]. +- [ ] **Each renderer can fail independently**: restoring the old full-card SVG + fallback, compact-card SVG fallback or hidden-isometric override makes + the dedicated smoke red + [mutation: `hidden-room-names-full-svg-fallback`, + `hidden-room-names-compact-svg-fallback`, + `hidden-room-names-iso-override`]. - [ ] **«Скрыть декоративный слой»** (owner 2026-08-05): a space with lines, labels or furniture on it → space settings → Display → tick the box, save. The plan loses all of it, in View, in the Plan editor and in the Device diff --git a/docs/USER-GUIDE.ru.md b/docs/USER-GUIDE.ru.md index 626ed35d..dee43f01 100644 --- a/docs/USER-GUIDE.ru.md +++ b/docs/USER-GUIDE.ru.md @@ -268,7 +268,7 @@ desktop: для точного рисования, Resize, модификато |---|---|---| | Масштаб | Сантиметров на клетку | Переводит сетку в реальные размеры и площади; начальное значение 5 см | | Отображение | Всегда показывать границы | Рисует контуры комнат в просмотре | -| Отображение | Показывать названия | Рисует карточки/названия комнат; их можно двигать в редакторе плана | +| Отображение | Показывать названия | Рисует карточки комнат в Просмотре, киоске и статической карточке; при выключении не оставляет упрощённых подписей | | Отображение | Показывать LQI | Переопределяет базовую настройку карточки для этого пространства | | Отображение | Скрыть декоративный слой | Не рисует линии, фигуры, текст и мебель в просмотре; в редакторе подложки они остаются видимыми | | Отображение | Скрыть проёмы | Скрывает только символы дверей, окон и ворот; свет, солнечные лучи и датчики проёмов продолжают работать | @@ -277,6 +277,10 @@ desktop: для точного рисования, Resize, модификато Карточка комнаты остаётся частью плана: её можно перемещать и масштабировать в редакторе, а в просмотре она собирает только включённые метрики. +Если «Показывать названия» выключено, редактор Плана временно показывает +карточку только для настройки её позиции. После возврата в Просмотр она снова +исчезает; сохранённая позиция не теряется и используется при повторном +включении названий. ![Карточка комнаты с температурой, LQI и состоянием света](images/08-room-card.png) | Стиль | Цвет и прозрачность | Общий цвет границ и названий | diff --git a/docs/UX-MODES.md b/docs/UX-MODES.md index 32a08321..6413c728 100644 --- a/docs/UX-MODES.md +++ b/docs/UX-MODES.md @@ -111,7 +111,7 @@ Header in View: space tabs, device count, zoom cluster. Nothing else. ### What a space may choose not to draw (2026-08-05) -Three switches in the space's Display section decide how much of the plan is +Four switches in the space's Display section decide how much of the plan is inked. All of them are **display only** — nothing is deleted, nothing changes meaning, and each layer stays visible in the editor that owns it, because a layer you cannot see is a layer you cannot edit. @@ -119,6 +119,7 @@ layer you cannot see is a layer you cannot edit. | Setting | Off (default) | On | Always drawn in | |---|---|---|---| | `show_borders` — «Всегда отображать границы комнат» | in View, borders and dashed **virtual walls** are hidden | both are drawn | room borders: Plan; virtual walls: all editors | +| `show_names` — «Показывать названия» | no room name/card is drawn in View, kiosk or the static card | the HTML room card is drawn | Plan, for positioning only | | `hide_decor` — «Скрыть декоративный слой» | decor is drawn | lines, shapes, labels and furniture are hidden | the Background editor | | `hide_openings` — «Скрыть проёмы» | doors, windows and gates are drawn | their symbols are hidden | the Plan editor | @@ -127,6 +128,11 @@ layer you cannot see is a layer you cannot edit. only walls were a few floating dashed stretches. Every editor deliberately shows them regardless of the switch: hiding geometry while editing a plan, device placement or its underlay makes those modes visually ambiguous. +- **`show_names: false` means no permanent fallback label.** View, kiosk, + hidden isometric and `houseplan-space-card` all omit the room name. Plan may + show the same HTML card temporarily so its saved position remains editable; + returning to View hides it again. Re-enabling names restores the saved + layout rather than creating a new one. - **Their geometry and their presentation are separate.** Every virtual span still ends on the real wall centreline. In View the thick wall body is painted over the dash ends, so they visually stop at its faces; editors paint @@ -135,9 +141,10 @@ layer you cannot see is a layer you cannot edit. through it, the sun still enters at a window, a contact sensor still opens it, and the resize tool still anchors to it. Anything else would be a second meaning for one setting. -- Both new switches store **nothing when off** (the key is omitted, as +- Both hide switches store **nothing when off** (the key is omitted, as `bg_color` is), so a plan written before this reads back byte-for-byte. - Backend: `hide_decor` / `hide_openings`, strictly `bool`, both optional. + Backend: `show_names`, `hide_decor` and `hide_openings` are strictly `bool` + and optional. ## Devices — placement and marker configuration diff --git a/docs/images/screenshots.json b/docs/images/screenshots.json index ff5b402e..fdf35033 100644 --- a/docs/images/screenshots.json +++ b/docs/images/screenshots.json @@ -1,7 +1,7 @@ { "version": 1, "fixture": "synthetic-only", - "sourceFingerprint": "51c4bdb005b2539779085578bcce5ee1b4b3e3137542ef1aeb440232344c3105", + "sourceFingerprint": "49963a7758df03d7aaaa3af3b9f198d629f4ca44af5c8ef9834c7afce5fda8ba", "captureScriptSha256": "34f2219790d46efd8250e7a1bd829cb8fc0b0547e1260635fefa52407551b41b", "command": "npm run build && node demo/docs/capture.mjs", "scenarios": { @@ -13,7 +13,7 @@ }, "theme": "dark", "language": "en", - "sourceSha256": "51c4bdb005b2539779085578bcce5ee1b4b3e3137542ef1aeb440232344c3105", + "sourceSha256": "49963a7758df03d7aaaa3af3b9f198d629f4ca44af5c8ef9834c7afce5fda8ba", "imageSha256": "d36b6f9f8139f31ef73a780c6511a640a26055efd9d7a24c24fd48b1d8379bf0" }, "view-touch": { @@ -24,7 +24,7 @@ }, "theme": "dark", "language": "en", - "sourceSha256": "51c4bdb005b2539779085578bcce5ee1b4b3e3137542ef1aeb440232344c3105", + "sourceSha256": "49963a7758df03d7aaaa3af3b9f198d629f4ca44af5c8ef9834c7afce5fda8ba", "imageSha256": "358e25ff9984d0fb0c03cfbb848df40c425fdfe64cd5f4f613b1e754ca9d4249" }, "space-create": { @@ -35,7 +35,7 @@ }, "theme": "dark", "language": "en", - "sourceSha256": "51c4bdb005b2539779085578bcce5ee1b4b3e3137542ef1aeb440232344c3105", + "sourceSha256": "49963a7758df03d7aaaa3af3b9f198d629f4ca44af5c8ef9834c7afce5fda8ba", "imageSha256": "c53db2e5c642a5549c13f3c93a5b359fed69bdb2621bf71a243a877ffcb95e6b" }, "room-contour-close": { @@ -46,7 +46,7 @@ }, "theme": "dark", "language": "en", - "sourceSha256": "51c4bdb005b2539779085578bcce5ee1b4b3e3137542ef1aeb440232344c3105", + "sourceSha256": "49963a7758df03d7aaaa3af3b9f198d629f4ca44af5c8ef9834c7afce5fda8ba", "imageSha256": "2f13ea645af306eee9cc7c52699c928377b72f412b08c1a3db6beb848ace1b51" }, "plan-context-tray": { @@ -57,7 +57,7 @@ }, "theme": "dark", "language": "en", - "sourceSha256": "51c4bdb005b2539779085578bcce5ee1b4b3e3137542ef1aeb440232344c3105", + "sourceSha256": "49963a7758df03d7aaaa3af3b9f198d629f4ca44af5c8ef9834c7afce5fda8ba", "imageSha256": "a6c526fede11bc3503fd2384bd4a3f6afa008f481c5c47578f06cae6c81c6f9b" }, "device-editor": { @@ -68,7 +68,7 @@ }, "theme": "dark", "language": "en", - "sourceSha256": "51c4bdb005b2539779085578bcce5ee1b4b3e3137542ef1aeb440232344c3105", + "sourceSha256": "49963a7758df03d7aaaa3af3b9f198d629f4ca44af5c8ef9834c7afce5fda8ba", "imageSha256": "7c3e25534fc819c45431907616c3d523961505859ee68af27cce2daec9f04fb0" }, "device-display-preview": { @@ -79,7 +79,7 @@ }, "theme": "dark", "language": "en", - "sourceSha256": "51c4bdb005b2539779085578bcce5ee1b4b3e3137542ef1aeb440232344c3105", + "sourceSha256": "49963a7758df03d7aaaa3af3b9f198d629f4ca44af5c8ef9834c7afce5fda8ba", "imageSha256": "df3a54395c83bffd7a161f1fb3de0143e12e76567535aedf9883873ead74df91" }, "background-editor": { @@ -90,7 +90,7 @@ }, "theme": "dark", "language": "en", - "sourceSha256": "51c4bdb005b2539779085578bcce5ee1b4b3e3137542ef1aeb440232344c3105", + "sourceSha256": "49963a7758df03d7aaaa3af3b9f198d629f4ca44af5c8ef9834c7afce5fda8ba", "imageSha256": "d7cfe70551d9260169df8efd832e32ed7df99c7f60b55d1fd4a8322bd4c47175" }, "room-card": { @@ -101,7 +101,7 @@ }, "theme": "dark", "language": "en", - "sourceSha256": "51c4bdb005b2539779085578bcce5ee1b4b3e3137542ef1aeb440232344c3105", + "sourceSha256": "49963a7758df03d7aaaa3af3b9f198d629f4ca44af5c8ef9834c7afce5fda8ba", "imageSha256": "176abba71d41cfb045a33f82a794d9fbb2a5d3c48e6df66e6ec3a8e448311b11" }, "device-info": { @@ -112,7 +112,7 @@ }, "theme": "dark", "language": "en", - "sourceSha256": "51c4bdb005b2539779085578bcce5ee1b4b3e3137542ef1aeb440232344c3105", + "sourceSha256": "49963a7758df03d7aaaa3af3b9f198d629f4ca44af5c8ef9834c7afce5fda8ba", "imageSha256": "2199ed88b215bf2bff63bf665028f78b2aa6a92c3032b803931790f2ef071893" } } diff --git a/scripts/mutation-gate.mjs b/scripts/mutation-gate.mjs index f5499f78..14464159 100644 --- a/scripts/mutation-gate.mjs +++ b/scripts/mutation-gate.mjs @@ -404,6 +404,56 @@ export const MUTANTS = [ replace: ' if (!replacingRemoved && prevPos && prevPos.s === targetSpaceId && !roomChanged) {', }], }, + { + id: 'hidden-room-names-full-svg-fallback', + guard: 'node demo/smoke_hide_room_names.mjs', + because: 'show_names:false must remove every permanent label from the full flat renderer; ' + + 'the smoke must reject the legacy centred SVG substitute independently of compact and iso', + patches: [{ + file: 'src/houseplan-card.ts', + find: " ${this._renderOpeningTunnelFills(space, glowBase, 'glow-base')}\n" + + ' ${glowLayerVisible ? this._renderGlowLayer(space, disp) : nothing}', + replace: " ${this._renderOpeningTunnelFills(space, glowBase, 'glow-base')}\n" + + ' ${!space.bg && !disp.showNames && !this._markup ? svg`${space.rooms.map((room) => {\n' + + ' const center = this._roomCenter(room);\n' + + ' return svg`${room.name}`;\n' + + ' })}` : nothing}\n' + + ' ${glowLayerVisible ? this._renderGlowLayer(space, disp) : nothing}', + }], + }, + { + id: 'hidden-room-names-compact-svg-fallback', + guard: 'node demo/smoke_hide_room_names.mjs', + because: 'the compact card is an independent renderer and must not replace a disabled HTML ' + + 'room card with the old SVG name even when the full card is correct', + patches: [{ + file: 'src/space-render.ts', + find: ' spaceModels, defaultPositions, markerPos, labelPos, spaceFrame, iconCqw, NORM_W,', + replace: ' spaceModels, roomCenter, defaultPositions, markerPos, labelPos, spaceFrame, iconCqw, NORM_W,', + }, { + file: 'src/space-render.ts', + find: ' ${passageGlowTunnels}\n ${wallUnion', + replace: ' ${passageGlowTunnels}\n' + + ' ${!space.bg && !disp.showNames ? svg`${space.rooms.map((room) => {\n' + + ' const center = roomCenter(room);\n' + + ' return svg`${room.name}`;\n' + + ' })}` : nothing}\n' + + ' ${wallUnion', + }], + }, + { + id: 'hidden-room-names-iso-override', + guard: 'node demo/smoke_hide_room_names.mjs', + because: 'hidden isometric View must obey the same show_names:false contract instead of ' + + 'forcing an HTML room card solely because the space has no backdrop', + patches: [{ + file: 'src/houseplan-card.ts', + find: ' ${disp.showNames || this._markup\n', + replace: ' ${disp.showNames || (iso && !space.bg) || this._markup\n', + }], + }, { id: 'plan-room-area-icon-hidden', guard: 'node demo/smoke_room_link.mjs', diff --git a/src/houseplan-card.ts b/src/houseplan-card.ts index d27baed6..1cb1307c 100755 --- a/src/houseplan-card.ts +++ b/src/houseplan-card.ts @@ -10907,17 +10907,6 @@ class HouseplanCard extends LitElement { return svg`` as unknown as TemplateResult; } - private _renderSvgRoomLabels(space: SpaceModel, disp: SpaceDisplay): TemplateResult { - if (this._renderProjection === 'iso' || space.bg || disp.showNames || this._markup) - return svg`` as unknown as TemplateResult; - return svg`${space.rooms.map((room) => { - const center = this._roomCenter(room); - return svg`${room.name}`; - })}` as unknown as TemplateResult; - } - private _renderWallBodies(disp: SpaceDisplay): TemplateResult { if (this._renderProjection === 'iso') return svg`` as unknown as TemplateResult; if (disp && !disp.showBorders && (this._mode === 'view' || this._mode === 'devices')) @@ -15754,7 +15743,6 @@ class HouseplanCard extends LitElement { ${this._renderOpeningTunnelFills(space, roomFills)} ${this._renderGlowBaseRooms(space, glowBase)} ${this._renderOpeningTunnelFills(space, glowBase, 'glow-base')} - ${this._renderSvgRoomLabels(space, disp)} ${glowLayerVisible ? this._renderGlowLayer(space, disp) : nothing} ${this._renderSunRays(space)} ${this._editing ? svg` this._renderRoomLabel(r, space, view, disp)) : nothing} ${this._markup ? space.rooms.map((r) => this._renderRoomGear(r, space, view)) : nothing} diff --git a/src/space-render.ts b/src/space-render.ts index 03928757..f5f37a74 100644 --- a/src/space-render.ts +++ b/src/space-render.ts @@ -42,7 +42,7 @@ import { contentFingerprint } from './visual-continuity'; import type { VirtualLightSnapshot } from './virtual-light-state'; import { renderOpeningTunnelFills } from './render/opening-tunnels'; import { - spaceModels, roomCenter, defaultPositions, markerPos, labelPos, spaceFrame, iconCqw, NORM_W, + spaceModels, defaultPositions, markerPos, labelPos, spaceFrame, iconCqw, NORM_W, GRID_STEP_N, GRID_PITCH, staticPassageOpenings, type Layout, type ContentItem, } from './space-geometry'; @@ -342,15 +342,6 @@ export function renderSpaceStatic(o: StaticRenderOpts): TemplateResult | null { ? { color: colors.glow_base.c, opacity: colors.glow_base.a, mode: 'glow' } : null); } - const staticSvgLabels = !space.bg && !disp.showNames - ? space.rooms.map((room) => { - const center = roomCenter(room); - return svg`${room.name}`; - }) - : []; - const planLightSources = resolvedLightSources(planHass, devs, null, o.virtualLights); const markers = devs.map((d) => { const p = markerPos(d, o.layout, o.cfg, defPos, space); @@ -529,7 +520,6 @@ export function renderSpaceStatic(o: StaticRenderOpts): TemplateResult | null { ? svg`` : nothing} ${passageGlowTunnels} - ${staticSvgLabels} ${wallUnion ? svg`