From ca383febef67d8a64870b3e79c7eabf087e88b0b Mon Sep 17 00:00:00 2001 From: Matysh Date: Thu, 27 Aug 2026 17:17:05 +0300 Subject: [PATCH] chore: release v1.68.1 Owner-approved emergency stable hotfix; the release commit changes only version fields, generated bundles and release metadata. Issue: #324 User-Visible: yes --- custom_components/houseplan/const.py | 2 +- .../houseplan/frontend/houseplan-card.js | 4 ++-- custom_components/houseplan/manifest.json | 2 +- dist/houseplan-card.js | 4 ++-- docs/CHANGELOG.md | 2 ++ docs/CHANGELOG.ru.md | 2 ++ docs/RELEASE-NOTES.md | 14 +++++--------- docs/STATUS.md | 4 ++-- package-lock.json | 4 ++-- package.json | 2 +- src/houseplan-card.ts | 2 +- 11 files changed, 21 insertions(+), 21 deletions(-) diff --git a/custom_components/houseplan/const.py b/custom_components/houseplan/const.py index 5f2b1e05..4636b5c9 100755 --- a/custom_components/houseplan/const.py +++ b/custom_components/houseplan/const.py @@ -46,7 +46,7 @@ PLAN_ORPHAN_TTL_S = 3600 SCHEDULED_GRACE_S = 30 * 24 * 3600 FILES_DIR = "houseplan/files" CONF_ADMIN_ONLY = "admin_only" -VERSION = "1.68.0" +VERSION = "1.68.1" # Portable backup format. This is deliberately independent from the Home # Assistant Store version above: storage migrations and files exported by a diff --git a/custom_components/houseplan/frontend/houseplan-card.js b/custom_components/houseplan/frontend/houseplan-card.js index bc35b11d..8901591b 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__="bf3bb218d73d1895f6f7e87b49dc82893e856d6621324930a6ef6fe7f80f232d";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:p}=Object,u=globalThis,_=u.trustedTypes,m=_?_.emptyScript:"",g=u.reactiveElementPolyfillSupport,f=(t,e)=>t,v={toAttribute(t,e){switch(e){case Boolean:t=t?m: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"),u.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=p(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,g?.({ReactiveElement:w}),(u.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,P=`<${D}>`,T=document,R=()=>T.createComment(""),I=t=>null===t||"object"!=typeof t&&"function"!=typeof t,A=Array.isArray,z="[ \t\n\f\r]",F=/<(?:(!--|\/[^a-zA-Z])|(\/?[a-zA-Z][^>\s]*)|(\/?$))/g,E=/-->/g,N=/>/g,O=RegExp(`>|${z}(?:([^\\s"'>=/]+)(${z}*=${z}*(?:[^ \t\n\f\r"'\`<>=]|("|')|))|$)`,"g"),L=/'/g,H=/"/g,B=/^(?:script|style|textarea|title)$/i,q=t=>(e,...i)=>({_$litType$:t,strings:e,values:i}),W=q(1),j=q(2),U=Symbol.for("lit-noChange"),G=Symbol.for("lit-nothing"),V=new WeakMap,K=T.createTreeWalker(T,129);function Y(t,e){if(!A(t)||!t.hasOwnProperty("raw"))throw Error("invalid template strings array");return void 0!==S?S.createHTML(e):e}const J=(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]?O:'"'===l[3]?H:L):a===H||a===L?a=O:a===E||a===N?a=F:(a=O,n=void 0);const d=a===O&&t[e+1].startsWith("/>")?" ":"";o+=a===F?i+P: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 X{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]=J(t,e);if(this.el=X.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;iA(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&&I(this._$AH)?this._$AA.nextSibling.data=t:this.T(T.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=X.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 X(t)),e}k(t){A(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=!I(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 pt=2,ut=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 mt={},gt=ut(class extends _t{constructor(){super(...arguments),this.ot=mt}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=ut(class extends _t{constructor(t){if(super(t),t.type!==pt)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,p=n.length-1,u=0,_=o.length-1;for(;d<=p&&u<=_;)if(null===n[d])d++;else if(null===n[p])p--;else if(r[d]===a[u])l[u]=wt(n[d],o[u]),d++,u++;else if(r[p]===a[_])l[_]=wt(n[p],o[_]),p--,_--;else if(r[d]===a[_])l[_]=wt(n[d],o[_]),bt(t,l[_+1],n[d]),d++,_--;else if(r[p]===a[u])l[u]=wt(n[p],o[u]),bt(t,n[d],n[p]),p--,u++;else if(void 0===c&&(c=St(a,u,_),h=St(r,d,p)),c.has(r[d]))if(c.has(r[p])){const e=h.get(a[u]),i=void 0!==e?n[e]:null;if(null===i){const e=bt(t,n[d]);wt(e,o[u]),l[u]=e}else l[u]=wt(i,o[u]),bt(t,n[d],i),n[e]=null;u++}else $t(n[p]),p--;else $t(n[d]),d++;for(;u<=_;){const e=bt(t,l[_+1]);wt(e,o[u]),l[u++]=e}for(;d<=p;){const t=n[d++];null!==t&&$t(t)}return this.ut=a,xt(t,l),U}}),Ct=new WeakMap;let Dt=0;class Pt 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=W` +globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="f7fe0cda471359472c0fbec24cff665db6e165d00ccae0a32823a686c5f53f1f";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:p}=Object,u=globalThis,_=u.trustedTypes,m=_?_.emptyScript:"",g=u.reactiveElementPolyfillSupport,f=(t,e)=>t,v={toAttribute(t,e){switch(e){case Boolean:t=t?m: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"),u.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=p(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,g?.({ReactiveElement:w}),(u.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,P=`<${D}>`,T=document,R=()=>T.createComment(""),I=t=>null===t||"object"!=typeof t&&"function"!=typeof t,A=Array.isArray,z="[ \t\n\f\r]",F=/<(?:(!--|\/[^a-zA-Z])|(\/?[a-zA-Z][^>\s]*)|(\/?$))/g,E=/-->/g,N=/>/g,O=RegExp(`>|${z}(?:([^\\s"'>=/]+)(${z}*=${z}*(?:[^ \t\n\f\r"'\`<>=]|("|')|))|$)`,"g"),L=/'/g,H=/"/g,B=/^(?:script|style|textarea|title)$/i,q=t=>(e,...i)=>({_$litType$:t,strings:e,values:i}),W=q(1),j=q(2),U=Symbol.for("lit-noChange"),G=Symbol.for("lit-nothing"),V=new WeakMap,K=T.createTreeWalker(T,129);function Y(t,e){if(!A(t)||!t.hasOwnProperty("raw"))throw Error("invalid template strings array");return void 0!==S?S.createHTML(e):e}const J=(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]?O:'"'===l[3]?H:L):a===H||a===L?a=O:a===E||a===N?a=F:(a=O,n=void 0);const d=a===O&&t[e+1].startsWith("/>")?" ":"";o+=a===F?i+P: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 X{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]=J(t,e);if(this.el=X.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;iA(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&&I(this._$AH)?this._$AA.nextSibling.data=t:this.T(T.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=X.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 X(t)),e}k(t){A(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=!I(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 pt=2,ut=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 mt={},gt=ut(class extends _t{constructor(){super(...arguments),this.ot=mt}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=ut(class extends _t{constructor(t){if(super(t),t.type!==pt)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,p=n.length-1,u=0,_=o.length-1;for(;d<=p&&u<=_;)if(null===n[d])d++;else if(null===n[p])p--;else if(r[d]===a[u])l[u]=wt(n[d],o[u]),d++,u++;else if(r[p]===a[_])l[_]=wt(n[p],o[_]),p--,_--;else if(r[d]===a[_])l[_]=wt(n[d],o[_]),bt(t,l[_+1],n[d]),d++,_--;else if(r[p]===a[u])l[u]=wt(n[p],o[u]),bt(t,n[d],n[p]),p--,u++;else if(void 0===c&&(c=St(a,u,_),h=St(r,d,p)),c.has(r[d]))if(c.has(r[p])){const e=h.get(a[u]),i=void 0!==e?n[e]:null;if(null===i){const e=bt(t,n[d]);wt(e,o[u]),l[u]=e}else l[u]=wt(i,o[u]),bt(t,n[d],i),n[e]=null;u++}else $t(n[p]),p--;else $t(n[d]),d++;for(;u<=_;){const e=bt(t,l[_+1]);wt(e,o[u]),l[u++]=e}for(;d<=p;){const t=n[d++];null!==t&&$t(t)}return this.ut=a,xt(t,l),U}}),Ct=new WeakMap;let Dt=0;class Pt 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=W` ${this.icon?W``:G} ${this.title} `;return this._useHaDialog?W`${t.visibleLabel}`:G}
${t?.content||G}
- `}afterRender(){const t=this.host.root();this._blocked&&(this._openGroupId?this.closeGroup(!1):"palette"===this._currentModel?.kind&&this._currentModel.dismiss?.()),this._syncGlobalDismissListener();const e=t.querySelector(".editor-secondary"),i=this._renderedContext,s=e?.dataset.contextId||"";if(s&&i&&s!==i&&!window.matchMedia?.("(prefers-reduced-motion: reduce)")?.matches&&(this._contentAnimation?.cancel(),this._contentAnimation=e?.querySelector(".editor-secondary-content")?.animate([{opacity:.35,transform:"translateY(-4px)"},{opacity:1,transform:"translateY(0)"}],{duration:100,easing:"ease-out"})),this._renderedContext=s,i&&s!==i&&this._focusOwned){const i=s?e?.querySelector('[tabindex="0"], button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled])'):t.querySelector(".editbar-tools");i?.focus?.(),this._focusOwned=!!s}if("palette"===this._currentModel?.kind&&this._currentModel.launcherId){const e=[...t.querySelectorAll("[data-editor-palette]")].find(t=>t.dataset.editorPalette===this._currentModel?.launcherId);e&&null!==e.offsetParent||this._currentModel.dismiss?.()}if(!this._openGroupId)return;const n=[...t.querySelectorAll("[data-editor-group]")].find(t=>t.dataset.editorGroup===this._openGroupId);n&&null!==n.offsetParent||this.closeGroup(!0)}handleOutsideDismiss(t){if(q_(t,t=>t.hasAttribute("data-editor-navigation")))return"pointerdown"===t.type?this.closeForNavigation():"click"===t.type&&this._dismissPointerTarget&&this._clearDismissClick(),!1;if("click"===t.type&&this._dismissPointerTarget){return!!(t.composedPath?.()||[t.target]).includes(this._dismissPointerTarget)&&(this._clearDismissClick(),t.preventDefault(),t.stopImmediatePropagation(),!0)}const e=this._openGroupId||this._blocked||"palette"!==this._currentModel?.kind?null:this._currentModel;if("pointerdown"===t.type&&(this._openGroupId||e)){const i=q_(t,t=>t.classList.contains("editor-secondary")),s=q_(t,t=>!!t.dataset.editorGroup),n=q_(t,t=>!!t.dataset.editorPalette),o=q_(t,t=>t.classList.contains("stage"));if(!(i||s||n||"stay-open-on-canvas"===e?.dismissPolicy&&o))return t.preventDefault(),t.stopImmediatePropagation(),this._dismissPointerTarget=t.target,clearTimeout(this._dismissTimer),this._dismissTimer=window.setTimeout(()=>{this._clearDismissClick()},800),this._openGroupId?this.closeGroup(!1):e?.dismiss?.(),this._syncGlobalDismissListener(),!0}return!1}_activateGroupItem(t,e,i){if(t.id!==this._openGroupId)return;const s=t.items.find(t=>t.id===e);if(!s||s.disabled)return;const n="toggle"===s.role&&"stay-open"===s.closePolicy,o=0===i.detail;n||(this._openGroupId=null,this.host.requestUpdate(),this._syncGlobalDismissListener()),s.invoke(),!n&&o&&this.host.updateComplete().then(()=>{const e=[...this.host.root().querySelectorAll("[data-editor-group]")].find(e=>e.dataset.editorGroup===t.id&&null!==e.offsetParent);e?.focus()})}_groupKeydown(t){if(!["ArrowLeft","ArrowRight","Home","End"].includes(t.key))return;const e=[...t.currentTarget.querySelectorAll(".editor-group-item:not([disabled])")];if(!e.length)return;t.preventDefault();const i=e.indexOf(this.host.root().activeElement),s="Home"===t.key?0:"End"===t.key?e.length-1:"ArrowLeft"===t.key?i<=0?e.length-1:i-1:(i+1)%e.length;e[s]?.focus()}_clearDismissClick(){this._dismissPointerTarget=null,clearTimeout(this._dismissTimer),this._dismissTimer=void 0,this._syncGlobalDismissListener()}_syncGlobalDismissListener(){const t=!this._blocked&&"palette"===this._currentModel?.kind,e=!!this._openGroupId||t||!!this._dismissPointerTarget;e!==this._globalDismissListening&&(this._globalDismissListening=e,e?(window.addEventListener("pointerdown",this._globalDismissGuard,!0),window.addEventListener("click",this._globalDismissGuard,!0)):(window.removeEventListener("pointerdown",this._globalDismissGuard,!0),window.removeEventListener("click",this._globalDismissGuard,!0)))}}const j_=t=>t.stopPropagation(),U_=4.166666666666667e-9;function G_(t){return Number.isFinite(t)?Math.round(t/Th)*Th:t}const V_=(t,e,i,s)=>Math.hypot(i-t,s-e),K_=(t,e,i,s,n,o,a,r)=>Math.hypot(Math.max(Math.abs(n-t),Math.abs(n+a-(t+i))),Math.max(Math.abs(o-e),Math.abs(o+r-(e+s)))),Y_=(t,e,i,s,n,o,a)=>{const r=Math.max(Number(s)||0,0)/2,l=Math.PI/180,c=Math.cos(i*l)*r,h=Math.sin(i*l)*r,d=Math.cos(a*l)*r,p=Math.sin(a*l)*r,u=Math.max(V_(t+c,e+h,n+d,o+p),V_(t-c,e-h,n-d,o-p)),_=Math.max(V_(t+c,e+h,n-d,o-p),V_(t-c,e-h,n+d,o+p));return Math.min(u,_)},J_=t=>{const e=Number(t?.cell_cm);return e>0?e:5};function X_(t,e){const i=JSON.parse(JSON.stringify(t||[])),s=JSON.parse(JSON.stringify(e||{}));let n=0,o=0,a=0,r=0,l="",c=0,h=0,d=0;const p=(t,e)=>{Number.isFinite(t)&&Number.isFinite(e)&&t!==e&&Math.abs(e-t)<=U_&&h++},u=(t,e)=>{p(t[0],e[0]),p(t[1],e[1])},_={};let m=5;for(const t of i){const e=J_(t);null!=t?.id&&(_[String(t.id)]=e),e>m&&(m=e)}const g=(t,e,i,s=!1)=>{if(!(t>U_||s))return;n++,t>a&&(a=t);const o=t*Dh*e;o>r&&(r=o,l=i)};for(const t of i){const e=J_(t),i=null!=t?.id?String(t.id):"";for(const s of t.rooms||[]){o++;let t=0;if(s.poly?.length)s.poly=s.poly.map(e=>{const i=[G_(e[0]),G_(e[1])];return t=Math.max(t,V_(e[0],e[1],i[0],i[1])),u(e,i),i});else if(null!=s.x&&null!=s.y){const e=s.x,i=s.y,n=s.w||0,o=s.h||0,a=G_(e+n),r=G_(i+o),l=G_(e),c=G_(i),h=Math.max(Th,a-l),d=Math.max(Th,r-c);t=K_(e,i,n,o,l,c,h,d),s.x=l,s.y=c,s.w=h,s.h=d,p(e,l),p(i,c),p(e+n,l+h),p(i+o,c+d)}g(t,e,i)}for(const s of t.room_drafts||[]){o++;let t=0;const n=s.points||[],a=n.map(e=>{const i=[G_(e[0]),G_(e[1])];return t=Math.max(t,V_(e[0],e[1],i[0],i[1])),i}),r=a.length?[a[0]]:[],l=a.length?[[n[0],a[0]]]:[],c=[];for(let t=0;t+1=2)for(const[t,e]of l)u(t,e);g(t,e,i)}if(Array.isArray(t.room_drafts)){const e=t.room_drafts.length;t.room_drafts=t.room_drafts.filter(t=>t.points?.length>=2),d+=e-t.room_drafts.length,t.room_drafts.length||delete t.room_drafts}for(const s of t.partitions||[]){o++;const n=[s.a[0],s.a[1]],a=[s.b[0],s.b[1]],r=[G_(n[0]),G_(n[1])],l=[G_(a[0]),G_(a[1])];let c=Math.max(V_(n[0],n[1],r[0],r[1]),V_(a[0],a[1],l[0],l[1]));const h=V_(r[0],r[1],l[0],l[1]),d=(t.openings||[]).filter(t=>"partition"===t.host?.kind&&t.host.id===s.id).every(t=>{const e=Number(t.length),i=Number(t.host.t),s=i*h;return Number.isFinite(e)&&e>0&&Number.isFinite(i)&&i>=0&&i<=1&&s-e/2>=-U_&&s+e/2<=h+U_});h>U_&&d?(s.a=r,s.b=l,u(n,r),u(a,l)):c=0,g(c,e,i)}for(const s of t.wall_columns||[]){o++;const t=[s.center[0],s.center[1]],n=[G_(t[0]),G_(t[1])],a=V_(t[0],t[1],n[0],n[1]);s.center=n,u(t,n),g(a,e,i)}for(const s of t.decor||[]){o++;let t=0;if("line"===s.kind){const e=[s.x1,s.y1],i=[s.x2,s.y2],n=[G_(e[0]),G_(e[1])],o=[G_(i[0]),G_(i[1])];t=Math.max(V_(e[0],e[1],n[0],n[1]),V_(i[0],i[1],o[0],o[1])),s.x1=n[0],s.y1=n[1],s.x2=o[0],s.y2=o[1],u(e,n),u(i,o)}else{const e=s.x,i=s.y,n=s.w,o=s.h,a=G_(e),r=G_(i);if(null!=s.w&&null!=s.h){const l=G_(e+n),c=G_(i+o),h=Math.max(Th,l-a),d=Math.max(Th,c-r);t=K_(e,i,n,o,a,r,h,d),s.w=h,s.h=d,p(e+n,a+h),p(i+o,r+d)}else t=V_(e,i,a,r);s.x=a,s.y=r,p(e,a),p(i,r)}g(t,e,i)}for(const s of t.openings||[]){if(o++,"partition"===s.host?.kind){const n=(t.partitions||[]).find(t=>t.id===s.host.id),o=Number(s.host.t);if(!n||!Number.isFinite(o)||o<0||o>1)continue;const a=n.b[0]-n.a[0],r=n.b[1]-n.a[1];if(Math.hypot(a,r)<=U_)continue;const l=n.a[0]+a*o,h=n.a[1]+r*o;let d=180*Math.atan2(r,a)/Math.PI;d>=90?d-=180:d<-90&&(d+=180);const p=Number(s.angle),u=!(Number.isFinite(p)&&p===d),_=Y_(s.x,s.y,Number.isFinite(p)?p:d,Number(s.length)||0,l,h,d);s.x=l,s.y=h,s.angle=d,u&&c++,g(_,e,i,u);continue}const n=ui([s.x,s.y],t.rooms||[],.025,{step:Th,length:Number(s.length)||0});if(!n)continue;const a=Number(s.angle),r=!(Number.isFinite(a)&&a===n.angle),l=Y_(s.x,s.y,Number.isFinite(a)?a:n.angle,Number(s.length)||0,n.x,n.y,n.angle);s.x=n.x,s.y=n.y,s.angle=n.angle,r&&c++,g(l,e,i,r)}}for(const[t,e]of Object.entries(s)){if(!e||"object"!=typeof e)continue;const i=e;if("number"!=typeof i.x||"number"!=typeof i.y)continue;o++;const n=G_(i.x),a=G_(i.y),r=V_(i.x,i.y,n,a);s[t]={...i,x:n,y:a},p(i.x,n),p(i.y,a);const l="string"==typeof i.s?i.s:"";g(r,_[l]??m,l)}return{spaces:i,layout:s,report:{moved:n,coordsCanonicalized:h,total:o,maxShift:a,maxShiftCm:r,maxSpace:l,rotated:c,removedDrafts:d},changed:n>0||h>0}}function Z_(t,e){const i=e.base+t*e.span;return Math.min(1,Math.max(0,i))}const Q_=t=>Array.isArray(t)&&t.length>=2&&Number.isFinite(t[0])&&Number.isFinite(t[1]),tm=(t,e)=>Math.hypot(t[0]-e[0],t[1]-e[1]);function em(t,e,i){const s=i[0]-e[0],n=i[1]-e[1],o=s*s+n*n;if(o<=0)return tm(t,e);let a=((t[0]-e[0])*s+(t[1]-e[1])*n)/o;return a=Math.max(0,Math.min(1,a)),Math.hypot(t[0]-(e[0]+s*a),t[1]-(e[1]+n*a))}function im(t,e,i,s,n){for(const s of e)if(s&&!i.has(s.id)&&Q_(s.a)&&Q_(s.b)&&(tm(t,s.a)<=n||tm(t,s.b)<=n))return!0;for(const e of s?.roomPolygons||[])for(let i=0;i0&&r>0))return null;if(Math.abs(n[0]/a*(o[1]/r)-n[1]/a*(o[0]/r))>i)return null;for(const[i,n]of[[t.a,e.a],[t.a,e.b],[t.b,e.a],[t.b,e.b]])if(tm(i,n)<=s)return[(i[0]+n[0])/2,(i[1]+n[1])/2];return null}function nm(t,e){const i=.05*(Number(e.pitch)>0?Number(e.pitch):1),s=new Map;let n=(t||[]).filter(t=>!!t&&"string"==typeof t.id&&Q_(t.a)&&Q_(t.b));if(n.length<2)return{partitions:[...t||[]],merged:0,openingMoves:[]};const o=e.seedIds&&e.seedIds.length?new Set(e.seedIds):null;let a=0;for(let t=0;ttm(e,t.at)>i);let h=c[0]??r.a,d=c[c.length-1]??l.b;if(c.length<2&&(h=r.a,d=l.b),d[0]0?(d[0]-h[0])/u:0,m=u>0?(d[1]-h[1])/u:0,g=t=>u>0?((t[0]-h[0])*_+(t[1]-h[1])*m)/u:0;for(const t of[r,l]){const e=g(t.a),i=g(t.b)-e;for(const[n,o]of s)o.toId===t.id&&s.set(n,{fromId:o.fromId,toId:p.id,base:e+o.base*i,span:o.span*i});s.set(t.id,{fromId:t.id,toId:p.id,base:e,span:i})}o&&o.add(p.id),n=n.filter((e,i)=>i!==t.i&&i!==t.j),n.splice(t.i,0,p),a++}return{partitions:n,merged:a,openingMoves:[...s.values()]}}function om(t,e,i,s){if(!t?.length||!i.length)return 0;const n=new Map(i.map(t=>[t.fromId,t]));let o=0;for(const i of t){const t=i?.host;if(!t||"partition"!==t.kind)continue;const a=n.get(t.id);if(!a)continue;i.host={...t,id:a.toId,t:Z_(t.t,a)},o++;const r=Sp(i,e,s.coordScale,s.cellCm,s.gridPitch).resolved;r&&Object.assign(i,Ip(i,r,s.coordScale))}return o}function am(t,e){const i=e?.excludeDraftId||null;return{roomPolygons:(t?.rooms||[]).map(t=>hi(t)).filter(t=>!!t),columns:t?.wall_columns||[],draftEnds:(t?.room_drafts||[]).flatMap(t=>{if(i&&t?.id===i)return[];const e=t?.points||[];return e.length?[e[0],e[e.length-1]]:[]})}}const rm=t=>!!t&&t.length>=2&&Number.isFinite(t[0])&&Number.isFinite(t[1]),lm=(t,e)=>t[0]-e[0]||t[1]-e[1],cm=(t,e,i,s)=>[t[0]+e*s,t[1]+i*s],hm=(t,e,i,s)=>(t[0]-e[0])*i+(t[1]-e[1])*s,dm=(t,e,i,s,n)=>{const o=e[0]-t[0],a=e[1]-t[1],r=Math.hypot(o,a);if(!(r>n))return null;const l=o/r,c=a/r,h=e=>Math.abs((e[0]-t[0])*c-(e[1]-t[1])*l);if(h(i)>n||h(s)>n)return null;const d=hm(i,t,l,c),p=hm(s,t,l,c),u=Math.max(0,Math.min(d,p)),_=Math.min(r,Math.max(d,p));return _-u>n?{lo:u,hi:_}:null},pm=(t,e,i)=>Math.min(t.hi,e.hi)-Math.max(t.lo,e.lo)>i,um=t=>{const e=new Set(["id","a","b","cm"]);return Object.keys(t||{}).every(t=>e.has(t))},_m=(t,e,i,s)=>{const n=t.b[0]-t.a[0],o=t.b[1]-t.a[1],a=Math.hypot(n,o);if(!(a>s))return!0;const r=n/a,l=o/a,c=gl(t.cm,i.cellCm,i.gridPitch)/2;return e.some(e=>{const n=e?.center;if(!rm(n))return!0;const o=hm(n,t.a,r,l),h=Math.abs((n[0]-t.a[0])*l-(n[1]-t.a[1])*r),d=gl(Number(e.cm),i.cellCm,i.gridPitch)*("square"===e.shape?Math.SQRT1_2:.5);return!(Number.isFinite(d)&&d>0)||o>=-d-s&&o<=a+d+s&&h<=c+d+s})},mm=(t,e,i)=>{if(t.host){const s=Sp(t,e,i.coordScale,i.cellCm,i.gridPitch).resolved;return s?{center:s.center,angle:s.angle,length:s.length}:null}const s=Number(t.x)*i.coordScale,n=Number(t.y)*i.coordScale,o=Number(t.angle),a=Number(t.length)*i.coordScale;return[s,n,o,a].every(Number.isFinite)&&a>0?{center:[s,n],angle:o,length:a}:null},gm=(t,e,i)=>{const s=t.angle*Math.PI/180,n=Math.cos(s),o=Math.sin(s),a=e.angle*Math.PI/180,r=Math.cos(a),l=Math.sin(a);if(Math.abs(n*l-o*r)>1e-6)return!1;const c=e.center[0]-t.center[0],h=e.center[1]-t.center[1];if(Math.abs(c*o-h*n)>i)return!1;const d=c*n+h*o;return Math.max(-t.length/2,d-e.length/2)({...t,a:[t.a[0]*e,t.a[1]*e],b:[t.b[0]*e,t.b[1]*e]}),vm=(t,e,i,s)=>{const n=`~r-${(t=>{let e=2166136261;for(let i=0;i>>0;return e.toString(36)})(`${t}|${e[0].toFixed(9)},${e[1].toFixed(9)}|${i[0].toFixed(9)},${i[1].toFixed(9)}`)}`,o=`${t.slice(0,Math.max(1,64-n.length))}${n}`;let a=o;for(let t=2;s.has(a);t++){const e=`-${t}`;a=`${o.slice(0,64-e.length)}${e}`}return s.add(a),a},ym=(t,e)=>{const i=[];for(const s of t){const t=i[i.length-1];!(t&&Math.abs(t.hi-s.lo)<=e&&t.safe===s.safe)||s.safe&&t.signature!==s.signature?i.push({lo:s.lo,hi:s.hi,a:s.a,b:s.b,safe:s.safe,signature:s.signature,roomIds:s.roomIds,finalCm:s.finalCm}):(t.hi=s.hi,t.b=s.b)}return i};function bm(t,e,i,s,n){const o=i||[],a=Array.isArray(t?.partitions)?t.partitions:[],r=Array.isArray(t?.openings)?t.openings:[],l=Array.isArray(t?.room_drafts)?t.room_drafts:[],c={walls:o,partitions:a,openings:r,roomDrafts:l,partitionsReconciled:0,openingsRehosted:0,removedDrafts:0};if(!a.length&&!l.length)return c;const h=Math.max(2e-4*n.gridPitch,1e-9);let d=o,p=a,u=r;const _=dc(e.rooms,d,s,n.pitch,n.cellCm,n.gridPitch,n.coordScale),m=((t,e,i,s)=>{const n=new Map(t.map(t=>[t.id,t])),o=new Set;for(const t of e){if(!n.get(t.id)||!Array.isArray(t.points)||t.points.length<2||t.segments.length!==t.points.length-1)continue;let e=!0;for(let n=0;n+10)){e=!1;break}const l=Math.hypot(a[0]-o[0],a[1]-o[1]);if(!(l>s)){e=!1;break}const c=i.flatMap(t=>{const e=t.cm>0?t.cm:ll;if(t.open||"outer"!==t.kind&&"shared"!==t.kind||e+st.lo-e.lo||t.hi-e.hi);let h=0;for(const t of c){if(t.lo>h+s)break;if(h=Math.max(h,t.hi),h>=l-s)break}h!m.has(t.id));let f=0,v=0;const y=new Map(e.partitions.map(t=>[t.id,t]));for(const t of[...a].sort((t,e)=>t.id.localeCompare(e.id))){if(!p.some(e=>e.id===t.id))continue;if(!um(t))continue;const i=y.get(t.id);if(!(i&&rm(i.a)&&rm(i.b)&&Number.isFinite(i.cm)&&i.cm>0))continue;const[o,a]=lm(i.a,i.b)<=0?[[i.a[0],i.a[1]],[i.b[0],i.b[1]]]:[[i.b[0],i.b[1]],[i.a[0],i.a[1]]],r=a[0]-o[0],l=a[1]-o[1],c=Math.hypot(r,l);if(!(c>h))continue;const _=r/c,g=l/c,b=dc(e.rooms,d,s,n.pitch,n.cellCm,n.gridPitch,n.coordScale),w=b.flatMap(t=>{if(t.open||"outer"!==t.kind&&"shared"!==t.kind)return[];const e=dm(o,a,t.a,t.b,h);return e?[{interval:t,range:e}]:[]});if(!w.length)continue;const k=u.filter(t=>"partition"===t.host?.kind&&t.host.id===i.id).map(t=>({opening:t,resolved:Sp(t,e.partitions,n.coordScale,n.cellCm,n.gridPitch).resolved}));if(k.some(t=>!t.resolved))continue;const x=[0,c];for(const{range:t}of w)x.push(t.lo,t.hi);const $=x.slice(),S=new Map;for(const{opening:t,resolved:e}of k){const i=hm(e.center,o,_,g),s={lo:i-e.length/2,hi:i+e.length/2};S.set(t.id,s),$.push(Math.max(0,s.lo),Math.min(c,s.hi))}const M=[...new Set($.filter(t=>Number.isFinite(t)&&t>=-h&&t<=c+h).map(t=>Math.max(0,Math.min(c,t)).toFixed(9)))].map(Number).sort((t,e)=>t-e),C=p.map(t=>fm(t,n.coordScale)).filter(t=>t.id!==i.id),D=e.room_drafts.filter(t=>!m.has(t.id)),P=[];for(let t=0;t+1h))continue;const r=cm(o,_,g,s),l=cm(o,_,g,a),c=w.filter(({range:t})=>t.lo<=s+h&&t.hi>=a-h).map(({interval:t})=>t),d=new Map;for(const t of c)d.set(t.roomId,t);const p=[...d.values()],u=new Set(p.map(t=>t.kind)),m=new Set(p.map(t=>t.cm>0?t.cm:ll)),f=p[0]?.kind,v=[...d.keys()].sort(),y=1===u.size&&1===m.size&&("outer"===f&&1===v.length||"shared"===f&&2===v.length),b={id:i.id,a:r,b:l,cm:i.cm},k=C.some(t=>!!dm(r,l,t.a,t.b,h)),x=D.some(t=>t.points.some((e,i)=>i+10?p[0].cm:ll:0,T=y?Math.max(S,i.cm):i.cm;P.push({lo:s,hi:a,a:r,b:l,safe:$,signature:$?`${f}|${v.join(",")}|${T}`:"",roomIds:v,roomCm:S,finalCm:T})}if(!P.some(t=>t.safe))continue;const T=new Map;for(const{opening:t,resolved:e}of k){const s=S.get(t.id),o=x.some(t=>t>s.lo+h&&tpm(t,s,h)),r=new Set(a.filter(t=>t.safe).map(t=>t.signature));if(!o&&a.length>0&&a.every(t=>t.safe)&&1===r.size&&Rp(e,b,h)){T.set(t.id,{resolved:e,signature:[...r][0]});continue}const l=xp(i,n.cellCm,n.gridPitch),c={lo:s.lo-l,hi:s.hi+l};for(const t of P)pm(t,c,h)&&(t.safe=!1,t.signature="")}let R=!0;for(;R;){R=!1;for(const[t,e]of[...T.entries()]){const s=S.get(t),o=P.filter(t=>pm(t,s,h));if(o.length>0&&o.every(t=>t.safe)&&o.every(t=>t.signature===e.signature))continue;T.delete(t);const a=xp(i,n.cellCm,n.gridPitch),r={lo:s.lo-a,hi:s.hi+a};for(const t of P)pm(t,r,h)&&(t.safe=!1,t.signature="");R=!0}}const I=ym(P,h),A=I.filter(t=>t.safe),z=I.filter(t=>!t.safe);if(!A.length)continue;if(p.length-1+z.length>2e3)continue;let F=d;for(const t of A){const[e,s]=lm(i.a,i.b)<=0?[t.a,t.b]:[t.b,t.a];F=Fl(F,e,s,t.finalCm,n.pitch,n.coordScale)}if(F=uc(e.rooms,F,s,n.pitch,n.cellCm,n.gridPitch,n.coordScale),F.length>500)continue;const E=new Set(p.map(t=>t.id));E.delete(i.id);const N=z.map((t,e)=>{const s=[t.a[0]/n.coordScale,t.a[1]/n.coordScale],o=[t.b[0]/n.coordScale,t.b[1]/n.coordScale],a=0===e?i.id:vm(i.id,s,o,E);return E.add(a),{id:a,a:s,b:o,cm:i.cm}}),O=p.findIndex(t=>t.id===i.id),L=p.slice();L.splice(O,1,...N);const H=L.map(t=>fm(t,n.coordScale)),B=new Map;let q=!0;for(const{opening:t,resolved:e}of k){const i=T.get(t.id);if(i){const e=Ip(t,i.resolved,n.coordScale),{host:s,...o}=e;B.set(t.id,o);continue}const s=S.get(t.id),o=N[z.findIndex(t=>t.lo<=s.lo+h&&t.hi>=s.hi-h)],a=o&&H.find(t=>t.id===o.id);if(!o||!a){q=!1;break}const r=a.b[0]-a.a[0],l=a.b[1]-a.a[1],c=Math.hypot(r,l),d=hm(e.center,a.a,r/c,l/c),p={...Ip(t,e,n.coordScale),host:{kind:"partition",id:o.id,t:d/c}};if(!Mp(p,H,n.coordScale,n.cellCm,n.gridPitch).resolved){q=!1;break}B.set(t.id,p)}if(!q)continue;const W=u.map(t=>B.get(t.id)||t),j=[...T.keys()].map(t=>B.get(t)),U=j.map(t=>mm(t,H,n));if(U.some(t=>!t))continue;let G=!1;for(let t=0;tt.id));for(const t of W){if(V.has(t.id))continue;const e=mm(t,H,n);e&&U.some(t=>gm(t,e,h))&&(G=!0)}if(G)continue;const K=Ec(e.rooms,F,s,n.pitch,n.cellCm,n.gridPitch,n.coordScale);[...T.entries()].every(([t,e])=>{const i=B.get(t),s=Lc(K,{x:i.x*n.coordScale,y:i.y*n.coordScale,angle:i.angle,length:i.length*n.coordScale},!0),o=[s.negative,s.positive].filter(t=>!!t?.full),a=e.signature.split("|")[1].split(","),r=new Set(o.map(t=>t.roomId));return o.length===a.length&&r.size===a.length&&a.every(t=>r.has(t))})&&(d=F,p=L,u=W,f+=A.length,v+=T.size)}return{walls:d,partitions:p,openings:u,roomDrafts:g,partitionsReconciled:f,openingsRehosted:v,removedDrafts:m.size}}const wm=t=>JSON.parse(JSON.stringify(t)),km=(t,e)=>Object.prototype.hasOwnProperty.call(t,e),xm=(t,e)=>e.length>0&&e.length<=35&&("space"===t?/^[a-z0-9_-]+$/.test(e):/^[A-Za-z0-9_-]+$/.test(e));function $m(t,e){let i=String(e??"");const s=t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),n=new RegExp(`^${s}_(.+)_([0-9a-f]{8})$`);let o=0;for(;o<16;o++){const t=n.exec(i);if(!t)return{root:i,layers:o,bounded:!1};i=t[1]}return{root:i,layers:o,bounded:n.test(i)}}const Sm=(t,e,i)=>{const s=t.get(e)||[];s.push(i),t.set(e,s)};const Mm=1e-9;class Cm extends Error{constructor(t,e=""){super(e?`${t}: ${e}`:t),this.reason=t,this.name="WallSegmentModelError"}}const Dm=t=>JSON.parse(JSON.stringify(t)),Pm=t=>Array.isArray(t)&&t.length>=2&&Number.isFinite(Number(t[0]))&&Number.isFinite(Number(t[1])),Tm=t=>[Number(t[0]),Number(t[1])],Rm=t=>`${Number(t[0]).toFixed(12)},${Number(t[1]).toFixed(12)}`,Im=(t,e)=>{const i=Rm(t),s=Rm(e);return iRm(t)<=Rm(e)?[Tm(t),Tm(e)]:[Tm(e),Tm(t)],zm=(t,e)=>Math.hypot(e[0]-t[0],e[1]-t[1]),Fm=t=>{const e=[[Number(t.points[0][0]),Number(t.points[0][1])]],i=[];for(let s=1;s{const i=new Set,s=t=>{const e=Number(t);if(!Number.isFinite(e))return;const s=e/Th;Math.abs(s-Math.round(s))>=Ur&&i.add(e.toFixed(12))};for(const e of Array.isArray(t?.rooms)?t.rooms:[])for(const t of hi(e)||[])s(t[0]),s(t[1]);for(const e of[t?.wall_segments,t?.walls])for(const t of Array.isArray(e)?e:[])s(t?.a?.[0]),s(t?.a?.[1]),s(t?.b?.[0]),s(t?.b?.[1]);for(const t of e)s(t?.[0]),s(t?.[1]);return i.size},Nm=(t,e,i)=>{const s=i[0]-e[0],n=i[1]-e[1],o=s*s+n*n;return o>1e-18?((t[0]-e[0])*s+(t[1]-e[1])*n)/o:0},Om=(t,e,i)=>{const s=Math.max(0,Math.min(1,Nm(t,e,i)));return Math.hypot(t[0]-(e[0]+(i[0]-e[0])*s),t[1]-(e[1]+(i[1]-e[1])*s))},Lm=(t,e,i,s,n=Mm)=>{const o=e[0]-t[0],a=e[1]-t[1],r=Math.hypot(o,a);if(r<=n)return 0;const l=e=>Math.abs((e[0]-t[0])*a-(e[1]-t[1])*o)/r;if(l(i)>n||l(s)>n)return 0;const c=Nm(i,t,e),h=Nm(s,t,e);return Math.max(0,Math.min(1,Math.max(c,h))-Math.max(0,Math.min(c,h)))*r},Hm=t=>{const e=(new TextEncoder).encode(t),i=8*e.length,s=64*Math.ceil((e.length+9)/64),n=new Uint8Array(s);n.set(e),n[e.length]=128;const o=new DataView(n.buffer);o.setUint32(s-8,Math.floor(i/4294967296),!1),o.setUint32(s-4,i>>>0,!1);const a=new Uint32Array([1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298]),r=new Uint32Array([1779033703,3144134277,1013904242,2773480762,1359893119,2600822924,528734635,1541459225]),l=new Uint32Array(64),c=(t,e)=>t>>>e|t<<32-e;for(let t=0;t>>3,n=c(i,17)^c(i,19)^i>>>10;l[t]=l[t-16]+s+l[t-7]+n>>>0}let[e,i,s,n,h,d,p,u]=r;for(let t=0;t<64;t++){const o=u+(c(h,6)^c(h,11)^c(h,25))+(h&d^~h&p)+a[t]+l[t]>>>0,r=e&i^e&s^i&s;u=p,p=d,d=h,h=n+o>>>0,n=s,s=i,i=e,e=o+((c(e,2)^c(e,13)^c(e,22))+r>>>0)>>>0}r[0]=r[0]+e>>>0,r[1]=r[1]+i>>>0,r[2]=r[2]+s>>>0,r[3]=r[3]+n>>>0,r[4]=r[4]+h>>>0,r[5]=r[5]+d>>>0,r[6]=r[6]+p>>>0,r[7]=r[7]+u>>>0}const h=new Uint8Array(32),d=new DataView(h.buffer);for(let t=0;t{const e="abcdefghijklmnopqrstuvwxyz234567";let i=0,s=0,n="";for(const o of t)for(s=s<<8|o,i+=8;i>=5;)n+=e[s>>>i-5&31],i-=5;return i&&(n+=e[s<<5-i&31]),n},qm=(t,e,i,s,n="")=>{const[o,a]=Am(e,i),r=`${t}|${Rm(o)}|${Rm(a)}|${[...s].sort().join(",")}${n}`;return`wall-${Bm(Hm(r)).slice(0,20)}`};let Wm=0;const jm=t=>{for(let e=0;e<1e3;e++){const e=globalThis.crypto?.randomUUID?.(),i=`wall-${e||Bm(Hm(`${Date.now()}|${Wm++}|${Math.random()}`)).slice(0,26)}`;if(!t.has(i))return i}throw new Cm("duplicate-id","id factory exhausted")},Um=t=>{const e=new Map;for(const i of Array.isArray(t?.wall_segments)?t.wall_segments:[])if(i&&"string"==typeof i.id&&Pm(i.a)&&Pm(i.b)){if(e.has(i.id))throw new Cm("duplicate-id",i.id);e.set(i.id,i)}return e},Gm=(t,e,i)=>{const s=(i,s)=>{const n=t[0]-i[0],o=t[1]-i[1];return Math.abs(e[0]-s[0]-n)<=Mm&&Math.abs(e[1]-s[1]-o)<=Mm?[n,o]:null};return s(i.a,i.b)||s(i.b,i.a)},Vm=(t,e)=>{const i=Array.isArray(t.rooms)?t.rooms:[],s=ud(t.open_spans).map(t=>[t.a[0],t.a[1],t.b[0],t.b[1]]),n=s.length?s:_d(i,null,1,.04*Th,!0),o=[];for(const t of i){const i=hi(t),s=Array.isArray(t?.wall_ids)?t.wall_ids:[];if(i&&s.length===i.length)for(let t=0;t"partition"!==t.host?.kind&&[Number(t.x),Number(t.y)].every(Number.isFinite)&&Number.isFinite(Number(t.angle))&&Number(t.length)>0&&n.some(e=>Om([Number(t.x),Number(t.y)],[e[0],e[1]],[e[2],e[3]])<=.04*Th)):[],l=r.map(t=>{const e=Number(t.angle)*Math.PI/180,i=[Math.cos(e),Math.sin(e)],s=Number(t.length)/2,n=[Number(t.x),Number(t.y)];return{a:[n[0]-i[0]*s,n[1]-i[1]*s],b:[n[0]+i[0]*s,n[1]+i[1]*s]}}),c=(t,e)=>r.some(i=>{const s=[Number(i.x),Number(i.y)];if(!Rl(t,e,Number(i.angle)))return!1;if(Om(s,t,e)>.02*Th)return!1;const n=zm(t,e),o=Nm(s,t,e)*n,a=Number(i.length)/2;return o+a>=-Mm&&o-a<=n+Mm}),h=new Map,d=[];for(const s of i){const r=String(s?.id||""),p=hi(s);if(!r||!p||p.length<3)throw new Cm("invalid-room",r);const u=ec(i,r,a,Th,1,[...t.walls||[],...l]);if(!u||u.poly.length<3)throw new Cm("invalid-room",r);const _=Array.isArray(s.wall_ids)?s.wall_ids:[],m=_.length===p.length;let g=null,f=m;if(f)for(let t=0;tMm||Math.abs(s[1]-g[1])>Mm)){f=!1;break}g=s}const v=[];for(let t=0;t2)throw new Cm("third-owner",a);const d=m?_[u.parent[t]]:void 0;if("string"==typeof d&&d){const n=e.get(d);f||!n||Lm(i,s,n.a,n.b)>Mm?l.preferredIds.add(d):l.positionalIds.add(d),l.preferredCarriers.set(d,{a:Tm(p[u.parent[t]]),b:Tm(p[(u.parent[t]+1)%p.length])})}const g=u.parent[t];l.parentKeys.add(wl(p[g],p[(g+1)%p.length],Th));const y=[(i[0]+s[0])/2,(i[1]+s[1])/2],b=t=>t.some(t=>Om(y,[t[0],t[1]],[t[2],t[3]])<=.04*Th);l.zeroWall||=b(o)||b(n)&&!c(i,s),v.push(a)}const y={...s};delete y.wall_ids,d.push({...y,poly:u.poly.map(t=>[t[0],t[1]]),wall_ids:v})}return{atoms:[...h.values()].sort((t,e)=>t.key.localeCompare(e.key)),rooms:d}},Km=(t,e,i,s,n)=>{const o=new Map([...i.values()].map(t=>[Im(t.a,t.b),t])),a=(t=>{const e=new Map;for(const i of t)"wall"===i.host?.kind&&e.set(i.host.id,(e.get(i.host.id)||0)+1);return e})(t.openings||[]),r=new Map;for(const t of e){const e=n?.get(t.key);if(e){const s=i.get(e);if(!s)throw new Cm("duplicate-id",e);r.set(t,s);continue}if(t.preferredIds.size>1)throw new Cm("duplicate-id",[...t.preferredIds].sort().join(","));const s=[...t.preferredIds][0],l=s?i.get(s):void 0;if(l){r.set(t,l);continue}const c=s?t.preferredCarriers.get(s):void 0;if(s&&c){r.set(t,{id:s,a:c.a,b:c.b,cm:0});continue}const h=o.get(t.key);if(h){r.set(t,h);continue}const d=[...i.values()].filter(e=>Lm(t.a,t.b,e.a,e.b)>Mm),p=[...new Map(d.map(t=>[t.id,t])).values()];if(p.sort((t,e)=>(a.get(e.id)||0)-(a.get(t.id)||0)||zm(e.a,e.b)-zm(t.a,t.b)||t.id.localeCompare(e.id)),p[0])r.set(t,p[0]);else if(1===t.positionalIds.size){const e=i.get([...t.positionalIds][0]);e&&r.set(t,e)}}const l=new Map;for(const[t,e]of r){const i=l.get(e.id)||[];i.push(t),l.set(e.id,i)}for(const[t,e]of l){const s=i.get(t)||r.get(e[0]);if(!s)throw new Cm("duplicate-id",t);const n=[(s.a[0]+s.b[0])/2,(s.a[1]+s.b[1])/2];e.sort((t,e)=>{const i=Om(n,t.a,t.b)<=Mm?0:1,o=Om(n,e.a,e.b)<=Mm?0:1;if(i!==o)return i-o;return(Om(s.a,t.a,t.b)<=Mm?0:1)-(Om(s.a,e.a,e.b)<=Mm?0:1)||t.key.localeCompare(e.key)}),e[0].id=t}const c=(t=>{const e=new Set;for(const i of[t.rooms,t.openings,t.decor,t.room_drafts,t.partitions,t.wall_columns])for(const t of Array.isArray(i)?i:[])"string"==typeof t?.id&&t.id&&e.add(t.id);for(const i of Array.isArray(t.room_drafts)?t.room_drafts:[])for(const t of Array.isArray(i?.segments)?i.segments:[])"string"==typeof t?.id&&t.id&&e.add(t.id);return e})(t);for(const t of e)if(t.id){if(c.has(t.id))throw new Cm("duplicate-id",t.id);c.add(t.id)}const h=e.filter(t=>!t.id);if(s){const e=h.map(e=>{const[i,s]=Am(e.a,e.b),n=`${String(t.id||"")}|${Rm(i)}|${Rm(s)}|${[...e.owners].sort().join(",")}`,o=Bm(Hm(n));return{atom:e,seed:n,digest:o,base:`wall-${o.slice(0,20)}`}}).sort((t,e)=>t.digest.localeCompare(e.digest)||t.atom.key.localeCompare(e.atom.key)),i=new Map;for(const t of e){const e=i.get(t.digest);if(e&&e!==t.seed)throw new Cm("duplicate-id",t.digest);i.set(t.digest,t.seed);let s=1,n=t.base;for(;c.has(n);)n=`${t.base}-${++s}`;t.atom.id=n,c.add(n)}}else for(const t of h)t.id=jm(c),c.add(t.id)},Ym=(t,e)=>{if("partition"===t.host?.kind)return null;const i=[Number(t.x),Number(t.y)];if(!i.every(Number.isFinite))return null;const s=e=>{if(!(Number(e.cm)>0))return!1;const s=Nm(i,e.a,e.b),n=zm(e.a,e.b),o=Number(t.length)/2;return s>=-Mm&&s<=1+Mm&&Om(i,e.a,e.b)<=.02*Th&&Rl(e.a,e.b,Number(t.angle))&&Number.isFinite(o)&&o>=0&&s*n-o>=-Mm&&s*n+o<=n+Mm},n="wall"===t.host?.kind?e.find(e=>e.id===t.host.id):null,o=n&&s(n)?[n]:e.filter(s);if(1!==o.length)return null;const a=o[0];return{kind:"wall",id:a.id,t:Math.max(0,Math.min(1,Nm(i,a.a,a.b)))}},Jm=(t,e)=>{const i=[Number(t.x),Number(t.y)];if(!i.every(Number.isFinite))return null;const s=Number(t.length)/2,n=e.filter(e=>{if(!(Number(e.cm)>0))return!1;const n=Nm(i,e.a,e.b),o=zm(e.a,e.b);return n>=-Mm&&n<=1+Mm&&Om(i,e.a,e.b)<=.02*Th&&Rl(e.a,e.b,Number(t.angle))&&Number.isFinite(s)&&s>=0&&n*o-s>=-Mm&&n*o+s<=o+Mm}),o=(e=>{if(!e.length)return null;const s="wall"===t.host?.kind?e.find(e=>e.id===t.host.id):null;return s||[...e].sort((t,e)=>Om(i,t.a,t.b)-Om(i,e.a,e.b)||Number(e.cm)-Number(t.cm)||(t.ide.id?1:0))[0]})(n);return o?{kind:"wall",id:o.id,t:Math.max(0,Math.min(1,Nm(i,o.a,o.b)))}:null},Xm=(t,e,i)=>{const s=Um(t),{atoms:n,rooms:o}=Vm(t,s);Km(t,n,s,e,i);const a=n.map(e=>{const i=e.id?s.get(e.id):void 0,n=((t,e,i)=>{if(e.zeroWall)return 0;const s=Array.isArray(t.walls)?t.walls:[],n=wl(e.a,e.b,Th),o=s.filter(t=>Number(t.cm)>0&&(!(t.key!==n&&!e.parentKeys.has(t.key))||!(!Pm(t.a)||!Pm(t.b))&&Lm(e.a,e.b,t.a,t.b)>=zm(e.a,e.b)-Mm)).map(t=>Math.max(1,Math.min(100,Number(t.cm))));if(new Set(o.map(t=>t.toFixed(9))).size>1)throw new Cm("thickness-conflict",e.key);if(o.length)return o[0];const a=Pl(s,e.a,e.b,Th,1);return a>0?a:Number(i?.cm)>0?Number(i.cm):0})(t,e,i);return{...i||{},id:e.id,a:[...e.a],b:[...e.b],cm:n}}),r=new Map(n.map(t=>[t.key,t.id]));for(const t of o)t.wall_ids=t.wall_ids.map(t=>r.get(t));t.rooms=o,t.wall_segments=a,t.walls=a.filter(t=>t.cm>0).map(t=>({key:wl(t.a,t.b,Th),cm:t.cm,a:[...t.a],b:[...t.b]})),t.walls.length||delete t.walls,delete t.open_spans;for(const e of t.rooms)delete e.open_to;return((t,e)=>{const i=new Set;for(const e of[t.rooms,t.openings,t.decor,t.room_drafts,t.partitions,t.wall_columns,t.wall_segments])for(const t of Array.isArray(e)?e:[])"string"==typeof t?.id&&t.id&&i.add(t.id);for(const s of Array.isArray(t.room_drafts)?t.room_drafts:[]){const n=Array.isArray(s.segments)?s.segments:[];for(let o=0;o{const s=Array.isArray(t.openings)?t.openings:[];for(const t of s){if("partition"===t.host?.kind)continue;if(!t.host&&!i){const i=Ym(t,e);i&&(t.host=i);continue}const s=Ym(t,e)??(i?Jm(t,e):null);if(s)t.host=s;else{if(!i)throw new Cm("opening-host",t.id);delete t.host}}})(t,a,e),a.reduce((t,e)=>t+(s.has(e.id)?0:1),0)};function Zm(t,e={}){const i=JSON.stringify(t),s=Dm(t);rl(s);let n=0;const o=Number(s?.model_version||0)<9;for(const t of Array.isArray(s?.spaces)?s.spaces:[]){const i=e.lineageSpaceId===String(t?.id||"")?e.lineageHints:void 0;n+=Xm(t,o,i)}return s.model_version=9,rl(s),{config:s,changed:i!==JSON.stringify(s),migratedSegments:n}}const Qm=t=>!!t&&"object"==typeof t&&!Array.isArray(t);function tg(t,e){const i=(t,e)=>{if(Array.isArray(t)&&Array.isArray(e)){const s=new Map;for(const e of t)Qm(e)&&"string"==typeof e.id&&e.id&&s.set(e.id,e);const n=e.map((e,n)=>{if(Qm(e)&&"string"==typeof e.id&&e.id){const t=s.get(e.id);return t?i(t,e):Dm(e)}return n[e,e in t?i(t[e],s):Dm(s)]);for(const e of Object.keys(t))delete t[e];for(const[e,i]of s)t[e]=i;return t}return Dm(e)};return i(t,e)}const eg=(t,e)=>Object.prototype.hasOwnProperty.call(t,e),ig=(t,e,i)=>Math.min(i,Math.max(e,t)),sg=t=>Sh({spaces:[t]})[0],ng=(t,e,i)=>{const s=i>0?i:1,n=t=>`${(t[0]/s).toFixed(12)},${(t[1]/s).toFixed(12)}`,o=n(t),a=n(e);return o0?a:1,l=Math.max(s*r*.02,1e-9),c=[];for(const e of t||[])for(const t of hi(e)||[])c.push([t[0],t[1]]);const h=[];for(const t of i||[])Array.isArray(t)&&t.length>=4&&t.slice(0,4).every(Number.isFinite)&&h.push([t[0],t[1]],[t[2],t[3]]);const d=(t,e)=>e.some(e=>Math.hypot(t[0]-e[0],t[1]-e[1])<=2*l),p=new Map;for(const a of t||[]){if(!a?.id)continue;const u=hc(t,a.id,e,i,s,n,o,r);if(u)for(let t=0;t0&&_>0&&a===m&&_!==a))continue;const g=u.poly[s],f=u.poly[(s+1)%u.poly.length],v=Math.hypot(f[0]-g[0],f[1]-g[1]);if(!(v>l&&v<.5*o-1e-9*o))continue;if(d(g,h)||d(f,h))continue;if(d(g,c)&&d(f,c))continue;const y=ng(g,f,r),b=p.get(y);b?b.targets.add(a):p.set(y,{a:[g[0],g[1]],b:[f[0],f[1]],targets:new Set([a])})}}}let u=e.slice();const _=(t,e)=>Math.hypot(t[0]-e[0],t[1]-e[1])<=2*l,m=(t,e)=>{if(!Array.isArray(t.a)||!Array.isArray(t.b)||t.a.length<2||t.b.length<2)return!1;const i=[Number(t.a[0])*r,Number(t.a[1])*r],s=[Number(t.b[0])*r,Number(t.b[1])*r];return!![...i,...s].every(Number.isFinite)&&(_(i,e.a)&&_(s,e.b)||_(i,e.b)&&_(s,e.a))};for(const t of[...p.values()].filter(t=>1===t.targets.size).sort((t,e)=>ng(t.a,t.b,r).localeCompare(ng(e.a,e.b,r)))){const e=[...t.targets][0],i=u.filter(e=>m(e,t));if(new Set(i.map(t=>t.cm)).size>1)continue;let n=!1;u=u.map(i=>m(i,t)?(n=!0,i.cm===e?i:{...i,cm:e}):i),n||(u=Fl(u,t.a,t.b,e,s,r))}return u}const ag=t=>{const e=[];for(const i of t||[]){const t=hi(i);if(t?.length)for(let i=0;i"string"==typeof t?.id?t.id:"").filter(Boolean),h=new Set(c),d=new Map;for(const t of c){const e=$m("space",t);e.layers>0&&xm("space",e.root)&&Sm(d,e.root,t)}const p=new Map,u=new Map,_=new Map,m=new Map;for(const t of r){const e="string"==typeof t?.id?t.id:"";if(!e)continue;const i=new Map;for(const s of Array.isArray(t.rooms)?t.rooms:[]){const t="string"==typeof s?.id?s.id:"";if(!t)continue;const n=$m("room",t);n.layers>0&&xm("room",n.root)&&Sm(i,n.root,t),u.has(t)||u.set(t,e),_.has(t)||_.set(t,String(s.name||""));const o="string"==typeof s.area?s.area:"";if(o){const i=m.get(o)||[];i.push({spaceId:e,roomId:t}),m.set(o,i)}}p.set(e,i)}const g=new Set(u.keys()),f=new Map,v=new Map;for(const t of l)"string"==typeof t?.id&&t.id&&(!0===t.removed?v.set(t.id,t):f.set(t.id,t));const y={spaceRefsRemapped:0,roomRefsRemapped:0,positionsRemapped:0,markersDetached:0,positionsUnresolved:0,nestedRefsUnresolved:0,deadSpaceIds:[],orphanRoomLabelsRemoved:0,orphanDevicePositionsRemoved:0,orphanGroupPositionsRemoved:0,liveMissingPositionsRemoved:0,removedPositions:[],liveMissingPositions:[],unverifiedPositions:[]},b=new Set,w=t=>h.has(t)?null:(()=>{const e=$m("space",t).root;if(!xm("space",e))return null;const i=d.get(e)||[];return 1===i.length?i[0]:null})(),k=(t,e)=>{const i=$m("room",t).root;if(!xm("room",i))return null;const s=p.get(e)?.get(i)||[];return 1===s.length?s[0]:null},x=t=>{const e=i.effectiveAreaByMarker?.[t]||"",s=e&&m.get(e)||[];return 1===s.length?s[0]:null},$=(t,e,i)=>{if("string"==typeof t.room_id&&t.room_id&&!g.has(t.room_id)){const s=e?k(t.room_id,e):null;s?(t.room_id=s,y.roomRefsRemapped++):i?(t.room_id=i.roomId,y.roomRefsRemapped++):!0!==t.removed&&delete t.room_id}const s=t.vacuum?.segment_map;if(s&&"object"==typeof s&&!Array.isArray(s))for(const t of Object.keys(s)){const i=s[t];if("string"!=typeof i||!i||g.has(i))continue;const n=e?k(i,e):null;n?(s[t]=n,y.roomRefsRemapped++):y.nestedRefsUnresolved++}};for(const t of l){const e="string"==typeof t?.id?t.id:"";if(!e)continue;const i="string"==typeof t.space?t.space:"",s=i&&!h.has(i),o=n[e],a="string"==typeof o?.s?o.s:"",r=a&&!h.has(a),l=!0===t.removed;let c=i&&h.has(i)?i:null,d=null,p=!1;if(s){const s=w(i);s?(t.space=s,c=s,p=!0,y.spaceRefsRemapped++):l||"virtual"===t.binding?l||(delete t.space,c=null,y.markersDetached++):(d=x(e),d?(t.space=d.spaceId,c=d.spaceId,y.spaceRefsRemapped++):(delete t.space,c=null,y.markersDetached++))}l&&!p||$(t,c,d),r&&p&&a===i&&c&&(n[e]={...o,s:c},y.positionsRemapped++,b.add(e))}for(const t of Object.keys(n)){if(b.has(t))continue;const e=n[t],i="string"==typeof e?.s?e.s:"";if(!i||h.has(i))continue;const s=w(i);if(s){if(t.startsWith("rl_")){const i=t.slice(3),o=k(i,s);if(o){const i=`rl_${o}`;km(n,i)||(n[i]={...e,s:s}),delete n[t],y.roomRefsRemapped++,y.positionsRemapped++;continue}}n[t]={...e,s:s},y.positionsRemapped++}}const S=i.ownerRoster,M=!0===S?.authoritative,C=new Set(S?.deviceIds||[]),D=new Set(S?.entityIds||[]),P=new Set(Array.isArray(s.settings?.known_devices)?s.settings.known_devices.filter(t=>"string"==typeof t):[]),T=(t,e="")=>{const i=String(S?.names?.[t]||e||"").trim();return i&&i!==t?i:""},R=(t,e,i,s="",n)=>({id:t,spaceId:e,kind:i,name:T(t,s),...n?{reason:n}:{}}),I=t=>{"room_label"===t?y.orphanRoomLabelsRemoved++:"group"===t?y.orphanGroupPositionsRemoved++:y.orphanDevicePositionsRemoved++},A=new Set;for(const[t,e]of Object.entries(n)){const s="string"==typeof e?.s?e.s:"";if(!s||h.has(s))continue;let o,a;const r=f.get(t),l=v.get(t);if(r)o=R(t,s,"device",String(r.name||"")),a="live";else if(l)o=R(t,s,"device",String(l.name||"")),a="absent";else if(t.startsWith("rl_")){const e=t.slice(3);o=R(t,s,"room_label",_.get(e)||""),a=g.has(e)?"live":"absent"}else if(t.startsWith("lg_")){const e=t.slice(3);o=R(t,s,"group"),a=D.has(e)?"live":M?"absent":"unverified","unverified"===a&&(o.reason="registry_unavailable")}else C.has(t)?(o=R(t,s,"device"),a="live"):P.has(t)?(o=R(t,s,"device"),a=M?"absent":"unverified","unverified"===a&&(o.reason="registry_unavailable")):(o=R(t,s,"unknown","","unknown_owner"),a="unverified");if("absent"!==a){if("live"===a){if(y.liveMissingPositions.push(o),!0===i.removeLiveMissingPositions){delete n[t],y.liveMissingPositionsRemoved++,I(o.kind),y.removedPositions.push(o);continue}}else y.unverifiedPositions.push(o);y.positionsUnresolved++,A.add(s)}else delete n[t],I(o.kind),y.removedPositions.push(o)}return y.deadSpaceIds=[...A].sort((t,e)=>t.localeCompare(e)),{config:s,layout:n,report:y,changed:JSON.stringify(s)!==o||JSON.stringify(n)!==a}}(t,e,i),a=o.config,r=nl(a,o.layout);rl(a),al(o.layout);const l=JSON.stringify(t||{}),c=JSON.stringify(e||{}),h=Number.isInteger(Number(a.model_version))?Number(a.model_version):0,d=(t=>{let e=0,i=0,s=0;for(const i of t.markers||[]){if("ripple"===i.display&&(i.display="icon_ripple",e++),Array.isArray(i.controls)){const t="string"==typeof i.binding&&i.binding.startsWith("entity:")?i.binding.slice(7):"",s=t?i.controls.filter(e=>e!==t):i.controls;JSON.stringify(s)!==JSON.stringify(i.controls)&&(i.controls=s.length?s:null,e++)}const t=i.vacuum;t&&eg(t,"trail")&&(["never","cleaning","always"].includes(t.trail_mode)||(t.trail_mode=!1===t.trail?"never":"cleaning"),delete t.trail,e++)}for(const n of t.spaces||[]){const t=n.settings;"glow"===t?.fill_mode&&("boolean"!=typeof t.glow_enabled&&(t.glow_enabled=!0),t.fill_mode="none",e++,i++);for(const t of n.rooms||[]){const i=t.settings;"glow"===i?.fill_mode&&("boolean"!=typeof i.glow&&(i.glow=!0),delete i.fill_mode,e++,s++)}if(eg(n,"segments")&&(delete n.segments,e++),eg(n,"plan_scale")){const t=Number(n.plan_scale);Number.isFinite(t)&&t>=wh&&t<=kh&&(eg(n,"plan_scale_x")||(n.plan_scale_x=t),eg(n,"plan_scale_y")||(n.plan_scale_y=t),delete n.plan_scale,e++)}const o=Number(n.cell_cm);eg(n,"cell_cm")&&(!Number.isFinite(o)||o<.1||o>1e3)&&(n.cell_cm=Number.isFinite(o)&&o>0?ig(o,.1,1e3):5,e++);const a=Number(n.cell_cm),r=Number.isFinite(a)&&a>0?a:5;for(const t of n.wall_columns||[])if("circle"===t.shape)eg(t,"angle")&&(delete t.angle,e++);else if("square"===t.shape&&eg(t,"angle")){const i=((Number(t.angle)||0)%90+90)%90;t.angle!==i&&(t.angle=i,e++)}for(const t of n.decor||[]){if(eg(t,"width")){const i=Number(t.width);(eg(t,"width_cm")||Number.isFinite(i))&&(eg(t,"width_cm")||(t.width_cm=Number(ig(i/Ph*r,.1,100).toFixed(6))),delete t.width,e++)}if("rect"!==t?.kind&&"ellipse"!==t?.kind||!0!==t.fill||(eg(t,"fill_color")||(t.fill_color=t.color||"#607d8b",e++),eg(t,"fill_opacity")||(t.fill_opacity=.25,e++)),"text"!==t?.kind)continue;void 0===t.size_cm?(t.size_cm=Number(ig(es*is(t)/Ph*r,.1,2e3).toFixed(6)),delete t.scale,delete t.size,e++):(eg(t,"scale")||eg(t,"size"))&&(delete t.scale,delete t.size,e++);let i=String(t.text??"");const s=[...i.matchAll(/\{([^{}\r\n]+)\}/g)].some(t=>!!Yi(t[1]));if(!(eg(t,"entity")||eg(t,"attr")||eg(t,"unit")))continue;const n=String(t.unit??"").trim(),o="state"===String(t.attr??"").trim().toLowerCase()?null:t.attr,a=s||n?"":Ji(t.entity,o);if(s||a){if(a){const e=i.indexOf("{}");i=e>=0?i.slice(0,e)+a+i.slice(e+2):`${i}${i?" ":""}${a}`,t.text=i}delete t.entity,delete t.attr,delete t.unit,e++}}}return{total:e,glowSpaces:i,glowRooms:s}})(a);let p=d.total;const u=(_=a.spaces||[],JSON.parse(JSON.stringify(_)));var _;const m=X_(a.spaces||[],o.layout);let g=0,f=0,v=0,y="";const b=m.spaces.map(t=>{const e=function(t){const e=JSON.parse(JSON.stringify(t||{}));let i=Array.isArray(e.rooms)?e.rooms:[];const s=new Map;for(const t of i){const e=hi(t);if(e)for(let t=0;tt.key.localeCompare(e.key))){let e=null;for(const s of $a(t,i)){const t=r.get(_a(s.from));if(t&&t!==_a(s.to))continue;const n=wa(i,s);if(ka(i,n,s)){e=s,i=n;break}}e?(r.set(_a(e.from),_a(e.to)),n++,a=Math.max(a,Math.hypot(e.to[0]-e.from[0],e.to[1]-e.from[1]))):o++}e.rooms=i;for(const t of e.room_drafts||[]){if(!Array.isArray(t?.points)||t.points.length<2)continue;const e=t.points.map(t=>[...t]),i=e.slice(0,-1).flatMap((i,s)=>{const n=e[s+1],o=pa(i,n);return o?[{key:`${String(t.id||"")}:${s}`,a:[...i],b:[...n],axis:o.axis}]:[]});let s=e;for(const t of i){let e=null;for(const i of $a(t,[{poly:s}])){const t=s.map(t=>ba(t,i)),n=t.length>=4&&ma(t[0],t[t.length-1]),o=n?t.slice(0,-1):t;if(n?va(o):ya(o)){e=i,s=t;break}}e?(n++,a=Math.max(a,Math.hypot(e.to[0]-e.from[0],e.to[1]-e.from[1]))):o++}t.points=s}for(const t of e.partitions||[]){if(!Array.isArray(t?.a)||!Array.isArray(t?.b))continue;const i=pa(t.a,t.b);if(!i)continue;const s={key:String(t.id||ga(t.a,t.b)),a:[...t.a],b:[...t.b],axis:i.axis};let r=null;for(const i of $a(s,[{poly:[t.a,t.b]}])){const s=ba(t.a,i),n=ba(t.b,i),o=Math.hypot(n[0]-s[0],n[1]-s[1]);if(!(o>0))continue;const a=(e.openings||[]).filter(e=>"partition"===e?.host?.kind&&e.host.id===t.id).every(t=>{const e=Number(t.host.t),i=Number(t.length);return Number.isFinite(e)&&e>=0&&e<=1&&Number.isFinite(i)&&i>0&&e*o-i/2>=-1e-12&&e*o+i/2<=o+1e-12});if(a){r=i,t.a=s,t.b=n;break}}r?(n++,a=Math.max(a,Math.hypot(r.to[0]-r.from[0],r.to[1]-r.from[1]))):o++}return{space:e,report:{wallsStraightened:n,wallsStraightenSkipped:o,maxStraightenShift:a},changed:n>0}}(t);g+=e.report.wallsStraightened,f+=e.report.wallsStraightenSkipped;const i=Number(t?.cell_cm)>0?Number(t.cell_cm):5,s=e.report.maxStraightenShift/Th*i;return s>v&&(v=s,y=String(t?.id||"")),e.space}),w=g?X_(b,m.layout):{...m,spaces:b};a.spaces=w.spaces;const k=g?{...m.report,moved:m.report.moved+w.report.moved,coordsCanonicalized:m.report.coordsCanonicalized+w.report.coordsCanonicalized,maxShift:Math.max(m.report.maxShift,w.report.maxShift),maxShiftCm:Math.max(m.report.maxShiftCm,w.report.maxShiftCm),maxSpace:w.report.maxShiftCm>m.report.maxShiftCm?w.report.maxSpace:m.report.maxSpace,rotated:m.report.rotated+w.report.rotated,removedDrafts:m.report.removedDrafts+w.report.removedDrafts}:{...m.report};let x=0,$=0,S=0,M=0,C=0,D=0,P=0,T=0;for(let t=0;t0===Number(t.cm)),walls:e.walls||[]}),o=sg(e),r=sg(i);if(!o||!r)continue;const l=ag(o.rooms),c=ag(r.rooms),h=.02*Ph,d=(e.wall_segments||[]).filter(t=>0===Number(t.cm)).map(t=>({...t,key:wl(t.a,t.b,Th),cm:0})),p=new Set(d.map(t=>t.key)),_=m_(e,o.rooms,yh,h);$+=_.length;for(const t of _){const e=[t[0]/yh,t[1]/yh],i=[t[2]/yh,t[3]/yh],s=wl(e,i,Th);p.has(s)||(p.add(s),d.push({key:s,a:e,b:i,cm:0}))}const m=d.length,g=Al(d,l,c,Th,yh),f=(t,e,i)=>{const s=i[0]-e[0],n=i[1]-e[1],o=s*s+n*n;if(!(o>0))return Math.hypot(t[0]-e[0],t[1]-e[1]);const a=Math.max(0,Math.min(1,((t[0]-e[0])*s+(t[1]-e[1])*n)/o));return Math.hypot(t[0]-(e[0]+s*a),t[1]-(e[1]+n*a))},v=g.filter(t=>{if(!Array.isArray(t.a)||!Array.isArray(t.b))return!1;const e=t.a.map(t=>t*yh),i=t.b.map(t=>t*yh);return c.some(([t,s])=>f(e,t,s)<=4*h&&f(i,t,s)<=4*h)});S+=Math.max(0,m-v.length);const y=(i.wall_segments||[]).filter(t=>Number(t.cm)>0);i.wall_segments=[...y,...v.map(({key:t,...e})=>e)];const b=v.map(t=>[t.a[0]*yh,t.a[1]*yh,t.b[0]*yh,t.b[1]*yh]),w=Array.isArray(e.walls)?e.walls.length:0;let k=Al(e.walls,l,c,Th,yh);k=og(r.rooms,k,b,Th,Number(i.cell_cm)>0?Number(i.cell_cm):5,Ph,yh),k=uc(r.rooms,k,b,Th,Number(i.cell_cm)>0?Number(i.cell_cm):5,Ph,yh),k=Tl(k,i.rooms||[],Th,1,b.map(t=>[t[0]/yh,t[1]/yh,t[2]/yh,t[3]/yh])),x+=Math.max(0,w-k.length),k.length?i.walls=k:delete i.walls;const R=nm(i.partitions||[],{pitch:Th,geometry:am(i)});R.merged&&(M+=R.merged,i.partitions=R.partitions,om(i.openings,i.partitions,R.openingMoves,{coordScale:yh,cellCm:Number(i.cell_cm)>0?Number(i.cell_cm):5,gridPitch:Ph}));const I=sg(i);if(I){const t=n(i,I,i.walls||[],b,{pitch:Th,cellCm:Number(i.cell_cm)>0?Number(i.cell_cm):5,gridPitch:Ph,coordScale:yh});t.partitionsReconciled&&(C+=t.partitionsReconciled,D+=t.openingsRehosted,t.partitions.length?i.partitions=t.partitions:delete i.partitions,t.openings.length?i.openings=t.openings:delete i.openings,t.walls.length?i.walls=t.walls:delete i.walls),t.removedDrafts&&(P+=t.removedDrafts,t.roomDrafts.length?i.room_drafts=t.roomDrafts:delete i.room_drafts)}JSON.stringify({zero:(i.wall_segments||[]).filter(t=>0===Number(t.cm)),walls:i.walls||[]})!==s&&T++}let R=0;h<=9&&(R=function(t){const e=Zm(t);return tg(t,e.config),{...e,config:t}}(a).migratedSegments);const I=rl(a),A=al(w.layout),z=JSON.stringify(I)!==l||JSON.stringify(A)!==c;h<9&&z&&(I.model_version=9);const F=JSON.stringify(I)!==l||JSON.stringify(A)!==c,E=Number.isInteger(Number(I.model_version))?Number(I.model_version):h,N=F?k:{...k,moved:0,coordsCanonicalized:0,maxShift:0,maxShiftCm:0,maxSpace:"",rotated:0,removedDrafts:0},O=F?o.report:{...o.report,spaceRefsRemapped:0,roomRefsRemapped:0,positionsRemapped:0,markersDetached:0,orphanRoomLabelsRemoved:0,orphanDevicePositionsRemoved:0,orphanGroupPositionsRemoved:0,liveMissingPositionsRemoved:0};return{config:I,layout:A,report:{...N,modelFrom:h,modelTo:E,migrated:F?p:0,glowSpacesMigrated:F?d.glowSpaces:0,glowRoomsMigrated:F?d.glowRooms:0,canonicalized:F?T:0,wallSegmentsMigrated:F?R:0,legacyZeroWallsMigrated:F?$:0,wallsMerged:F?x:0,spansMerged:F?S:0,partitionsMerged:F?M:0,partitionsReconciled:F?C:0,openingsRehosted:F?D:0,redundantDraftsRemoved:F?P:0,wallsStraightened:F?g:0,wallsStraightenSkipped:f,maxStraightenShiftCm:F?v:0,maxStraightenSpace:F?y:"",latticeCoordinatesCanonicalized:F?r.canonicalized:0,latticeCoordinatesFar:F?r.far:0,latticeMaxShift:F?r.maxShift:0,latticeMaxShiftCm:F?r.maxShiftCm:0,latticeSpaces:F?r.spaces:[],...O},changed:F}}function lg(t,e,i){const s=(t?.spaces||[]).find(t=>t?.id===i),n=new Set((s?.rooms||[]).map(t=>String(t?.id||"")).filter(Boolean)),o=[...new Set((t?.markers||[]).filter(t=>!0!==t?.removed&&"string"==typeof t?.id).filter(t=>t.space===i||"string"==typeof t.room_id&&n.has(t.room_id)||e?.[t.id]?.s===i).map(t=>t.id))].sort((t,e)=>t.localeCompare(e));return{markerIds:o,count:o.length}}function cg(t){return t instanceof Error?t.name||"Error":typeof t}function hg(t){return wd({id:t?.id??"",cell_cm:t?.cell_cm,rooms:t?.rooms||[],walls:t?.walls||[],wall_segments:t?.wall_segments||[],open_spans:t?.open_spans||[],openings:t?.openings||[],partitions:t?.partitions||[],room_drafts:t?.room_drafts||[],wall_columns:t?.wall_columns||[]})}function dg(t,e,i,s=Ph,n=1e3){return(Array.isArray(t?.openings)?t.openings:[]).flatMap(t=>{const o={...t,rx:Number(t.x)*n,ry:Number(t.y)*n,rlen:Number(t.length)*n};if(!t.host||"wall"===t.host.kind)return[o];const a=Sp(t,e.partitions,n,i,s);return a.resolved?[{...t,rx:a.resolved.center[0],ry:a.resolved.center[1],rlen:a.resolved.length,angle:a.resolved.angle,partitionHost:a.resolved}]:[]})}function pg(t,e=()=>!0){return t.flatMap(t=>t.host&&t.partitionHost&&e(t)?[Dp(t.partitionHost)]:[])}function ug(t,e,i,s,n,o,a=Ph,r=1e3){const l=dc(e.rooms,[...i],s,n,o,a,r);return t.flatMap(t=>{const e={x:t.rx,y:t.ry,angle:Number(t.angle)||0,length:t.rlen};return t.host&&"wall"!==t.host.kind?t.partitionHost&&Rp(t.partitionHost,l,2e-4*a)?[e]:[]:[e]})}function _g(t,e){const i=Th,s=Ph,n=yh,o=Number.isFinite(Number(e.cellCm))&&Number(e.cellCm)>0?Number(e.cellCm):5,a=Array.isArray(t?.walls)?t.walls:[],r=function(t,e,i=Ph,s=1e3){return _d(e.rooms,t?.open_spans,s,.02*i)}(t,e,s,n),l=function(t,e,i=Ph){if(!e.length)return[];const s=t.filter(t=>t?.id),n=.02*i,o=[];for(let t=0;t{const e=[(t[0]+t[2])/2,(t[1]+t[3])/2];return h.some(t=>Ls(e,t)<4*n)}).map(t=>[...t]);d.length&&o.push({a:a,b:r,segs:d})}return o}(e.rooms,r,s).flatMap(t=>t.segs),c=dg(t,e,o,s,n),h=pg(c),d=ih(e,o,s,2e-4*s,h).all;return{space:e,walls:a,openCuts:l,openings:c,roomOpenings:ug(c,e,a,l,i,o,s,n),partitionCuts:h,physicalBodies:d,wallKeyPitch:i,cellCm:o,gridPitch:s,coordScale:n}}function mg(t,e,i){const s="string"==typeof t?.title?t.title.trim():"",n=null==t?.id?"":String(t.id).trim();return{spaceId:n,displayName:s||n||i(e+1)}}function gg(t,e={}){const i=(e.fingerprint||wd)(t),s=Array.isArray(t?.spaces)?t.spaces:[],n=e.fallbackSpaceName||(t=>`Space ${t}`),o=e.prepareSpace||_g,a=e.wallPass||Rc,r=e.floorPass||Pc,l=[];for(let i=0;i0||d.physicalBodies.length>0;if(!d.space.rooms.length&&!p){l.push({...h,status:"not-applicable"});continue}let u=null;if(p){try{u=a(d.space.rooms,d.walls,d.openCuts,d.roomOpenings,d.wallKeyPitch,d.cellCm,d.gridPitch,d.coordScale,d.physicalBodies)}catch(t){l.push({...h,status:"failed",reason:"wall-exception",detail:cg(t)});continue}if(null==u){l.push({...h,status:"failed",reason:"wall-null"});continue}if("degraded-extra"===u.status){l.push({...h,status:"failed",reason:"wall-degraded-extra"});continue}if("failed-core"===u.status){l.push({...h,status:"failed",reason:"wall-failed-core"});continue}e.captureWallGeometry?.(d,u)}if(d.space.rooms.length&&null==u?.paperGeom){let t;try{t=r(d.space.rooms,d.walls,d.openCuts,d.wallKeyPitch,d.cellCm,d.gridPitch,d.coordScale)}catch(t){l.push({...h,status:"failed",reason:"floor-exception",detail:cg(t)});continue}if(null==t){l.push({...h,status:"failed",reason:"floor-null"});continue}}l.push({...h,status:"ok"})}const c=l.filter(t=>"failed"===t.status);return{fingerprint:i,spaces:l,failures:c,ok:0===c.length}}class fg{constructor(t=50){this._undo=[],this._redo=[],this._limit=Math.max(30,Math.floor(t))}get canUndo(){return this._undo.length>0}get canRedo(){return this._redo.length>0}get undoName(){return this._undo[this._undo.length-1]?.name??null}get redoName(){return this._redo[this._redo.length-1]?.name??null}get size(){return this._undo.length}push(t){this._undo.push(t),this._undo.length>this._limit&&this._undo.splice(0,this._undo.length-this._limit),this._redo=[]}undo(){const t=this._undo.pop()??null;return t&&this._redo.push(t),t}redo(){const t=this._redo.pop()??null;return t&&this._undo.push(t),t}clear(){this._undo=[],this._redo=[]}}const vg=new WeakMap;const yg=(t,e,i)=>255===t[i+3]&&e.every((e,s)=>Math.abs(t[i+s]-e)<=2);async function bg(t){const e=t.defaultView;if(!e||!e.CSS?.supports?.("mix-blend-mode","screen"))return!1;const i=[128,32,16],s=[16,64,128],n=[9,19,29],o=`\n \n \n \n \n \n `,a=e.URL.createObjectURL(new Blob([o],{type:"image/svg+xml"}));try{const o=await new Promise((t,i)=>{const s=new e.Image,n=e.setTimeout(()=>i(new Error("SVG blend probe timeout")),1e3);s.onload=()=>{e.clearTimeout(n),t(s)},s.onerror=()=>{e.clearTimeout(n),i(new Error("SVG blend probe failed"))},s.src=a}),r=t.createElement("canvas");r.width=4,r.height=1;const l=r.getContext("2d",{willReadFrequently:!0});if(!l)return!1;l.drawImage(o,0,0,4,1);const c=l.getImageData(0,0,4,1).data;return yg(c,i,0)&&yg(c,function(t,e){return[0,1,2].map(i=>Math.round(255-(255-t[i])*(255-e[i])/255))}(i,s),4)&&yg(c,s,8)&&yg(c,n,12)}catch{return!1}finally{e.URL.revokeObjectURL(a)}}const wg={now:()=>performance.now(),requestFrame:t=>requestAnimationFrame(t),cancelFrame:t=>cancelAnimationFrame(t)},kg=t=>Math.max(0,Math.min(1,t)),xg=(t,e,i)=>t+(e-t)*i,$g=(t,e,i)=>{const s=1-t;return 3*s*s*t*e+3*s*t*t*i+t*t*t};function Sg(t,e){return{centerX:t.x+t.w/2,centerY:t.y+t.h/2,pixelsPerUnit:e>0&&t.w>0?e/t.w:1,viewBox:{...t}}}function Mg(t,e,i){const s=Math.max(1e-9,t.pixelsPerUnit),n=Math.max(1e-9,e/s),o=Math.max(1e-9,i/s);return{x:t.centerX-n/2,y:t.centerY-o/2,w:n,h:o}}function Cg(t){const e=t.trim(),i=/^rgba?\(\s*([\d.]+)[, ]+([\d.]+)[, ]+([\d.]+)(?:\s*[,/]\s*([\d.]+))?\s*\)$/i.exec(e);if(i)return[Number(i[1]),Number(i[2]),Number(i[3]),null==i[4]?1:Number(i[4])];const s=/^#([0-9a-f]{6}|[0-9a-f]{8})$/i.exec(e)?.[1];return s?[parseInt(s.slice(0,2),16),parseInt(s.slice(2,4),16),parseInt(s.slice(4,6),16),8===s.length?parseInt(s.slice(6,8),16)/255:1]:null}function Dg(t,e,i){const s=Cg(t),n=Cg(e);if(!s||!n)return i<.5?t:e;const o=kg(i);return`rgba(${Math.round(xg(s[0],n[0],o))}, ${Math.round(xg(s[1],n[1],o))}, ${Math.round(xg(s[2],n[2],o))}, ${xg(s[3],n[3],o).toFixed(3)})`}function Pg(t,e,i){const s=(t=>{const e=kg(t);if(0===e||1===e)return e;let i=0,s=1,n=e;for(let t=0;t<12;t++)n=(i+s)/2,$g(n,.2,.2){const e=this._state;if(!e||e.token!==n)return;const i=kg((t-e.startedAt)/e.duration);e.presented=i>=1?e.to:Pg(e.from,e.to,i),e.phase=i>=1?"settling":"running",this._hooks.frame(e),i<1?this._raf=this._clock.requestFrame(a):(this._raf=0,this._hooks.settled(e),this._state?.token===n&&(this._state=null))};return this._raf=this._clock.requestFrame(a),n}cancel(t=!0){this._raf&&this._clock.cancelFrame(this._raf),this._raf=0;const e=this._state;this._state=null,this._token++,e&&t&&(e.phase="settling",e.presented=e.to,this._hooks.frame(e),this._hooks.settled(e))}dispose(){this.cancel(!1)}}const Rg="houseplan_card_labs_v1",Ig=Object.freeze([Object.freeze({id:"iso",issue:89,since:"1.62.0",expires:"1.65.0",summary:"Volumetric plan renderer"})]);function Ag(t){const e=/^(\d+)\.(\d+)\.(\d+)(?:-[0-9A-Za-z.-]+)?$/.exec(String(t||"").trim());if(!e)return null;const i=e.slice(1).map(Number);return i.every(t=>Number.isSafeInteger(t))?i:null}function zg(t,e){for(let i=0;i<3;i++)if(t[i]!==e[i])return t[i]t.split(",")).map(t=>t.trim()).filter(Boolean)}function Hg(t,e,i,s=Ig){const n=function(t,e=Ig){const i=Ag(t),s=new Map;if(!i||!Eg(e))return s;for(const t of e){const e=Ag(t.since),n=Ag(t.expires);zg(i,e)>=0&&zg(i,n)<0&&s.set(t.id,t)}return s}(i,s),o=new Set(Eg(s)?s.map(t=>t.id):[]),a=new Set(function(t){if(!t)return[];try{const e=JSON.parse(t);return Array.isArray(e)?e.filter(t=>"string"==typeof t):[]}catch{return[]}}(e).filter(t=>n.has(t)));let r=!1;const l=t=>{if("off"===t)return a.clear(),void(r=!0);const e=t.startsWith("-"),i=e?t.slice(1):t;o.has(i)&&(r=!0,e||!n.has(i)?a.delete(i):a.add(i))};for(const e of Lg(new URLSearchParams(String(t.search||"").replace(/^\?/,""))))l(e);for(const e of Lg(Ng(t.hash)))l(e);const c=Object.freeze([...a].sort());return{active:c,space:Og(t.hash),persist:r?JSON.stringify(c):void 0,knownUrlOperation:r}}let Bg={active:Object.freeze([]),space:""},qg="",Wg=!1,jg="";const Ug=new Set;function Gg(){if("undefined"==typeof window)return Bg;const t=Hg(window.location,function(){try{return window.localStorage.getItem(Rg)}catch{return null}}(),qg);void 0!==t.persist&&function(t){try{window.localStorage.setItem(Rg,t)}catch{}}(t.persist),Bg={active:t.active,space:t.space},window.__hpLabs=t.active;for(const t of Ug)t(Bg);return Bg}function Vg(){Gg()}function Kg(t){return qg=t,"undefined"==typeof window?Bg:(Wg||(Wg=!0,window.addEventListener("hashchange",Vg),window.addEventListener("popstate",Vg)),Gg())}const Yg=Object.freeze({rotDeg:0,tiltDeg:20,xyScale:1,zScale:1,origin:Object.freeze([500,500])});function Jg(t){return[t.rotDeg,t.tiltDeg,t.xyScale,t.zScale,t.origin[0],t.origin[1]].every(Number.isFinite)&&Math.abs(t.xyScale)>1e-12&&Math.abs(Math.cos(t.tiltDeg*Math.PI/180))>1e-12}function Xg(t,e,i=Yg){if(!(Jg(i)&&Number.isFinite(t[0])&&Number.isFinite(t[1])&&Number.isFinite(e)))throw new Error("invalid isometric projection input");const s=i.rotDeg*Math.PI/180,n=i.tiltDeg*Math.PI/180,o=t[0]-i.origin[0],a=t[1]-i.origin[1],r=(o*Math.cos(s)-a*Math.sin(s))*i.xyScale,l=(o*Math.sin(s)+a*Math.cos(s))*i.xyScale;return[i.origin[0]+r,i.origin[1]+l*Math.cos(n)-e*i.zScale*Math.sin(n)]}function Zg(t,e=Yg){if(!Jg(e)||!Number.isFinite(t[0])||!Number.isFinite(t[1]))throw new Error("invalid isometric projection input");const i=e.rotDeg*Math.PI/180,s=e.tiltDeg*Math.PI/180,n=(t[0]-e.origin[0])/e.xyScale,o=(t[1]-e.origin[1])/(e.xyScale*Math.cos(s));return[e.origin[0]+n*Math.cos(i)+o*Math.sin(i),e.origin[1]-n*Math.sin(i)+o*Math.cos(i)]}function Qg(t=Yg){return`matrix(${function(t=Yg){if(!Jg(t))throw new Error("invalid isometric camera");const e=t.rotDeg*Math.PI/180,i=t.tiltDeg*Math.PI/180,s=t.xyScale*Math.cos(e),n=-t.xyScale*Math.sin(e),o=t.xyScale*Math.sin(e)*Math.cos(i),a=t.xyScale*Math.cos(e)*Math.cos(i);return[s,o,n,a,t.origin[0]-s*t.origin[0]-n*t.origin[1],t.origin[1]-o*t.origin[0]-a*t.origin[1]]}(t).map(t=>Number(t.toFixed(12))).join(" ")})`}function tf(t,e=Yg){const{rect:i,wallHeight:s}=t,n=t.openingHeight??s,o=t.floorDepth??0;if(!(i.w>=0)||!(i.h>=0)||!Number.isFinite(s)||!Number.isFinite(n)||!Number.isFinite(o)||s<0||n<0||o<0)throw new Error("invalid isometric frame");const a=[[i.x,i.y],[i.x+i.w,i.y],[i.x+i.w,i.y+i.h],[i.x,i.y+i.h]],r=Math.max(s,n),l=a.flatMap(t=>[Xg(t,-o,e),Xg(t,r,e)]),c=l.map(t=>t[0]),h=l.map(t=>t[1]),d=Math.min(...c),p=Math.min(...h);return{x:d,y:p,w:Math.max(...c)-d,h:Math.max(...h)-p}}const ef=t=>`${Number(t[0].toFixed(4))} ${Number(t[1].toFixed(4))}`;function sf(t){let e=0;for(let i=0;iArray.isArray(t)&&Number.isFinite(t[0])&&Number.isFinite(t[1])).map(t=>[Number(t[0]),Number(t[1])]),i=e[e.length-1];return e.length>1&&e[0][0]===i[0]&&e[0][1]===i[1]&&e.pop(),e}(t);if(i.length<3)return[];const s=!e;return sf(i)>0===s?i:[...i].reverse()}function of(t,e,i){return t.length?`M ${t.map(t=>ef(Xg(t,i,e))).join(" L ")} Z`:""}function af(t,e,i){const s=e[1]-t[1],n=-(e[0]-t[0]),o=i.rotDeg*Math.PI/180;return s*Math.sin(o)+n*Math.cos(o)}function rf(t,e,i=Yg){if(!Number.isFinite(e)||e<0)throw new Error("invalid floor edge height");const s=(t||[]).map(t=>(t||[]).map((t,e)=>function(t,e){const i=nf(t,e);if(!i.length)return i;let s=0;for(let t=1;t0)).filter(t=>t.length>=3&&Math.abs(sf(t))>=1e-9)).filter(t=>t.length&&sf(t[0])>0);s.sort((t,e)=>{const i=t[0][0],s=e[0][0];return i[0]-s[0]||i[1]-s[1]||Math.abs(sf(e[0]))-Math.abs(sf(t[0]))});const n=[],o=[];let a=0;for(let t=0;tt.depth-e.depth||t.component-e.component||t.edge-e.edge),{footprintPath:n.join(" "),sides:o,componentCount:s.length,edgeCount:a}}function lf(t,e){return t^=Math.round(64*(Number.isFinite(e)?e:0)),Math.imul(t,16777619)>>>0}const cf=t=>t.every(Number.isFinite);function hf(t,e,i,s){const n=t[0]*i,o=t[1]*s,a=e*Math.PI/180;return[n*Math.cos(a)-o*Math.sin(a),n*Math.sin(a)+o*Math.cos(a)]}function df(t,e,i,s,n,o,a){const r=t.flipH?-1:1,l="gate"===t.type?1:t.flipV?-1:1,c=(t.type,t.flipV,t.angle,t.face,{ox:0,oy:0}),h=function(t,e){return[t[0]+e[0],t[1]+e[1]]}([t.x+c.ox,t.y+c.oy],hf(i,t.angle,r,l));return{leaf:e,hinge:h,closedVector:hf(s,t.angle,r,l),quarterVector:hf([-s[1],s[0]],t.angle,r,l),turnDeg:n,bottom:o,top:a}}const pf=t=>`${Number(t[0].toFixed(4))} ${Number(t[1].toFixed(4))}`;function uf(t,e,i=Yg){const s=Math.max(0,Math.min(1,Number.isFinite(e)?e:0));return t.leaves.map(e=>{const n=function(t,e){const i=t.turnDeg*e*Math.PI/180;return[t.hinge[0]+t.closedVector[0]*Math.cos(i)+t.quarterVector[0]*Math.sin(i),t.hinge[1]+t.closedVector[1]*Math.cos(i)+t.quarterVector[1]*Math.sin(i)]}(e,s),o=Xg(e.hinge,e.bottom,i),a=Xg(n,e.bottom,i),r=Xg(n,e.top,i),l=Xg(e.hinge,e.top,i);return{id:t.id,sourceIndex:t.sourceIndex,type:t.type,leaf:e.leaf,d:`M ${pf(o)} L ${pf(a)} L ${pf(r)} L ${pf(l)} Z`,shadowD:`M ${pf(Xg(e.hinge,0,i))} L ${pf(Xg(n,0,i))}`,depth:Math.max(o[1],a[1])}})}const _f={window:120,door:90,passage:90,gate:300};function mf(t){return _f[t]}function gf(t,e){const i=[t[0],t[1]],s=[e[0],e[1]];return function(t,e){return t[0]-e[0]||t[1]-e[1]}(i,s)<=0?{a:i,b:s}:{a:s,b:i}}function ff(t){const e=new Map;return t.forEach((t,i)=>{if(!t.kind||t.open)return;const s=gf(t.a,t.b);if(Math.hypot(s.b[0]-s.a[0],s.b[1]-s.a[1])<=1e-9)return;const n=function(t,e){const i=t=>(Math.abs(t)<=5e-10?0:Math.round(1e6*t)/1e6).toFixed(6);return`${i(t[0])},${i(t[1])}>${i(e[0])},${i(e[1])}`}(s.a,s.b),o=e.get(n);if(o)return o.physicalHalfWidth=Math.max(o.physicalHalfWidth,t.half||0),o.sourceOrder=Math.min(o.sourceOrder,i),void(t.partitionHost&&(o.partitionHost&&o.partitionHost.id!==t.partitionHost.id?o.ambiguousPartitionHost=!0:o.partitionHost=t.partitionHost));e.set(n,{segmentKey:n,a:s.a,b:s.b,physicalHalfWidth:Math.max(0,t.half||0),sourceOrder:i,...t.partitionHost?{partitionHost:t.partitionHost}:{}})}),[...e.values()]}function vf(t,e){if(Math.abs(t.distance-e.distance)>1e-9)return t.distance-e.distance;if(Math.abs(t.perpendicular-e.perpendicular)>1e-9)return t.perpendicular-e.perpendicular;return(t.target.segmentKeye.target.segmentKey?1:0)||t.target.sourceOrder-e.target.sourceOrder}function yf(t){const e=ff(t.intervals).map(e=>{const i=function(t,e){const i=e.b[0]-e.a[0],s=e.b[1]-e.a[1],n=Math.hypot(i,s),o=i/n,a=s/n,r=(t[0]-e.a[0])*o+(t[1]-e.a[1])*a,l=Math.max(0,Math.min(n,r)),c=e.a[0]+l*o,h=e.a[1]+l*a;return{along:l,length:n,x:c,y:h,distance:Math.hypot(t[0]-c,t[1]-h),perpendicular:Math.abs((t[0]-e.a[0])*a-(t[1]-e.a[1])*o)}}(t.pointer,e);return{target:e,...i,envelope:Math.max(t.baseTolerance,e.physicalHalfWidth+t.bodyPointerPadding)}}).filter(t=>t.distance<=t.envelope+1e-9).filter(e=>!function(t,e,i,s,n){const o=e.b[0]-e.a[0],a=e.b[1]-e.a[1],r=Math.hypot(o,a);if(!(r>1e-9))return!1;const l=o/r,c=a/r;for(const o of i){if(!o.open&&o.kind)continue;const i=gf(o.a,o.b),a=i.b[0]-i.a[0],r=i.b[1]-i.a[1],h=Math.hypot(a,r);if(!(h>1e-9))continue;const d=a/h,p=r/h;if(Math.abs(l*p-c*d)>1e-6)continue;if(Math.abs((i.a[0]-e.a[0])*c-(i.a[1]-e.a[1])*l)>n)continue;const u=(t[0]-i.a[0])*d+(t[1]-i.a[1])*p,_=1e-9;if(!(u<=_||u>=h-_)&&Math.abs((t[0]-i.a[0])*p-(t[1]-i.a[1])*d)<=s+1e-9)return!0}return!1}(t.pointer,e.target,t.intervals,e.envelope,Math.max(1e-9,Math.min(t.baseTolerance,.04*t.gridStep)))),i=e.filter(e=>!!e.target.partitionHost&&t.renderedLength+2*e.target.physicalHalfWidth>e.length+1e-9).sort(vf),s=e.filter(e=>!e.target.partitionHost||t.renderedLength+2*e.target.physicalHalfWidth<=e.length+1e-9).sort(vf);let n=s[0];if(!n)return{candidate:null,jambBlockedTarget:i[0]?.target||null};const o=s.filter(t=>Math.abs(t.distance-n.distance)<=1e-9&&Math.abs(t.perpendicular-n.perpendicular)<=1e-9),a=o.filter(t=>t.target.partitionHost);if(a.length){if(1!==new Set(a.map(t=>t.target.partitionHost.id)).size||a.some(t=>t.target.ambiguousPartitionHost))return{candidate:null,jambBlockedTarget:null};const t=a[0],e=t.target.b[0]-t.target.a[0],i=t.target.b[1]-t.target.a[1],s=Math.hypot(e,i),r=e/s,l=i/s,c=o.every(e=>{const i=e.target.b[0]-e.target.a[0],s=e.target.b[1]-e.target.a[1],n=Math.hypot(i,s),o=i/n,a=s/n,c=Math.abs(r*a-l*o)<=1e-6,h=Math.abs((e.target.a[0]-t.target.a[0])*l-(e.target.a[1]-t.target.a[1])*r);return c&&h<=1e-9});if(!c)return{candidate:null,jambBlockedTarget:null};n=t}if(n.target.ambiguousPartitionHost)return{candidate:null,jambBlockedTarget:null};const{target:r,length:l}=n,c=r.b[0]-r.a[0],h=r.b[1]-r.a[1],d=c/l,p=h/l,u=r.partitionHost?r.physicalHalfWidth:0,_=Math.min(Math.max(0,t.renderedLength)/2+u,l/2);let m=n.along;const g=Math.max(t.gridStep,1e-9),f=l/2;m=Math.abs(m-f)<=g/2?f:Math.round(m/g)*g,m=Math.max(_,Math.min(l-_,m));const v=r.a[0]+d*m,y=r.a[1]+p*m,b=Math.max(0,t.renderedLength)/2,w=m-b,k=m+b,x=Math.max(0,w),$=Math.max(0,l-k),S=[r.a[0]+d*(w-x/2),r.a[1]+p*(w-x/2)],M=[r.a[0]+d*(k+$/2),r.a[1]+p*(k+$/2)];let C=180*Math.atan2(h,c)/Math.PI;C>=90?C-=180:C<-90&&(C+=180);const D=Math.abs(m-f)<=1e-9;return{candidate:{presetRevision:t.preset.revision,geometryRevision:t.geometryRevision,pointer:[t.pointer[0],t.pointer[1]],type:t.preset.type,lengthCm:t.preset.lengthCm,flipH:t.preset.flipH,flipV:t.preset.flipV,x:v,y:y,angle:C,renderedLength:t.renderedLength,target:r,...r.partitionHost?{host:{...r.partitionHost,t:l>0?m/l:0}}:{},measure:{labels:[{distance:x,midpoint:S},{distance:$,midpoint:M}],guide:D?{x:v,y:y,angle:C}:null}},jambBlockedTarget:null}}function bf(t,e,i,s,n=1e-6){return t.presetRevision===i&&t.geometryRevision===s&&Math.hypot(t.pointer[0]-e[0],t.pointer[1]-e[1])<=n}const wf=(t,e)=>t[0]*e[1]-t[1]*e[0],kf=(t,e)=>t[0]*e[0]+t[1]*e[1],xf=(t,e)=>[t[0]-e[0],t[1]-e[1]],$f=(t,e,i)=>[t[0]+e[0]*i,t[1]+e[1]*i];function Sf(t,e,i){return Math.abs(wf(t,e))<=i}function Mf(t,e,i){return Math.abs(wf(xf(t,e),i))}function Cf(t,e,i,s,n){const o=e[0]-t[0],a=e[1]-t[1],r=Math.hypot(o,a);if(!(r>n&&i>0))return[];const l=[o/r,a/r];return function(t,e,i){const s=e.map(([e,i])=>[Math.max(0,Math.min(e,i)),Math.min(t,Math.max(e,i))]).filter(([t,e])=>e>t+i).sort((t,e)=>t[0]-e[0]||t[1]-e[1]),n=[];for(const t of s){const e=n[n.length-1];!e||t[0]>e[1]+i?n.push([...t]):e[1]=Math.max(e[1],t[1])}const o=[];let a=0;for(const[t,e]of n)t>a+i&&o.push([a,t]),a=Math.max(a,e);return t>a+i&&o.push([a,t]),o}(r,s.flatMap(e=>{const s=e.b[0]-e.a[0],o=e.b[1]-e.a[1],a=Math.hypot(s,o);if(!(a>n&&Sf(l,[s/a,o/a],1e-6)))return[];if(Mf(e.a,t,l)>1.1*Math.max(i,n)||Mf(e.b,t,l)>1.1*Math.max(i,n))return[];return[[kf(xf(e.a,t),l),kf(xf(e.b,t),l)]]}),n).flatMap(([e,s])=>{const n=Ol({a:$f(t,l,e),b:$f(t,l,s),halfDepth:i});return n?[n]:[]})}function Df(t){const e=t.coordScale??1,i=Math.max(t.epsilon??2e-4*t.gridPitch,1e-9),s=[];for(const i of t.rooms||[]){if(!i?.id)continue;const n=hc(t.rooms,i.id,t.walls,t.openCuts,t.pitch,t.cellCm,t.gridPitch,e);if(!n||n.poly.length<3)continue;const o=Zl(n.poly,n.offsets);!o||o.length<3||s.push({roomId:i.id,profile:n,inner:o})}s.sort((t,e)=>t.roomId.localeCompare(e.roomId));const n=(t.roomOpenings||[]).map(t=>{const e=t.angle*Math.PI/180,i=[Math.cos(e),Math.sin(e)],s=Math.max(0,t.length)/2;return{a:$f([t.x,t.y],i,-s),b:$f([t.x,t.y],i,s)}}),o=[];for(const s of zc(t.rooms,t.walls,t.openCuts,t.pitch,t.cellCm,t.gridPitch,e))for(const t of Cf(s.a,s.b,s.depthUnits/2,n,i))o.push({body:t});const a=new Map;for(const e of t.partitionCuts||[]){const t=a.get(e.hostId)||[];t.push(e),a.set(e.hostId,t)}for(const e of t.partitions||[]){const s=gl(e.cm,t.cellCm,t.gridPitch)/2;for(const t of Cf(e.a,e.b,s,a.get(e.id)||[],i))o.push({body:t,partitionId:e.id})}return{rooms:s,boundaries:o,epsilon:i}}function Pf(t,e,i,s){const n=t.profile.offsets[e];if(!(n>0))return null;const o=function(t,e){const i=t[e],s=t[(e+1)%t.length],n=s[0]-i[0],o=s[1]-i[1],a=Math.hypot(n,o)||1;return function(t){let e=0;for(let i=0;i=0?[-o/a,n/a]:[o/a,-n/a]}(t.profile.poly,e),a=$f(i.center,o,n),r=[];for(let e=0;es&&Sf(i.axis,[l[0]/c,l[1]/c],1e-6)))continue;if(Mf(n,a,i.axis)>s||Mf(o,a,i.axis)>s)continue;const h=kf(xf(n,a),i.axis),d=kf(xf(o,a),i.axis);r.push([Math.min(h,d),Math.max(h,d)])}const l=function(t,e){t.sort((t,e)=>t[0]-e[0]||t[1]-e[1]);const i=[];for(const s of t){const t=i[i.length-1];!t||s[0]>t[1]+e?i.push([...s]):t[1]=Math.max(t[1],s[1])}return i}(r,s).find(([t,e])=>t<=s&&e>=-s);if(!l)return null;const[c,h]=l,d=$f(a,i.axis,-i.half),p=$f(a,i.axis,i.half),u=Math.max(0,-i.half-c),_=Math.max(0,h-i.half),m=u>0?$f(a,i.axis,c):d,g=_>0?$f(a,i.axis,h):p,f=kf(o,i.normal)>=0?1:-1,v=(e,s,n)=>({from:e,to:s,label:[(e[0]+s[0])/2,(e[1]+s[1])/2],axis:i.axis,labelNormal:o,distance:n,roomId:t.roomId,roomSide:f,source:"room-face"});return{left:v(d,m,u),right:v(p,g,_)}}function Tf(t){const e=$f(t.center,t.axis,-t.half),i=$f(t.center,t.axis,t.half),s=$f(t.center,t.axis,Math.min(-t.half,t.targetLo)),n=$f(t.center,t.axis,Math.max(t.half,t.targetHi)),o=(e,i)=>({from:e,to:i,label:[(e[0]+i[0])/2,(e[1]+i[1])/2],axis:t.axis,labelNormal:t.normal,distance:Math.hypot(i[0]-e[0],i[1]-e[1]),source:"host-end"});return[o(e,s),o(i,n)]}function Rf(t,e,i,s){const n=xf(i,e),o=kf(n,n);if(!(o>s*s))return Math.hypot(...xf(t,e))<=s;const a=kf(xf(t,e),n)/o;if(a<-s||a>1+s)return!1;const r=$f(e,n,Math.max(0,Math.min(1,a)));return Math.hypot(...xf(t,r))<=s}function If(t,e,i){let s=!1;for(let n=0,o=e.length-1;nt[1]!=c>t[1]&&t[0]<(l-a)*(t[1]-r)/(c-r)+a&&(s=!s)}return s}function Af(t,e,i,s,n,o){const a=xf(s,i),r=wf(e,a);if(Math.abs(r)<=o)return null;const l=xf(i,t),c=wf(l,a)/r,h=wf(l,e)/r;return c<-o||c>n+o||h<-o||h>1+o?null:Math.max(0,Math.min(n,c))}function zf(t,e,i){const s=Tf(i),n="partition"===t.host?.kind?t.host.id:void 0;return[{base:s[0],direction:[-i.axis[0],-i.axis[1]]},{base:s[1],direction:i.axis}].map(({base:t,direction:i})=>{const s=t.distance,o=function(t,e,i,s,n,o){let a=null;for(const r of s)if(!n||r.partitionId!==n){if(If(t,r.body,o))return 0;for(let s=0;skf(xf(t,n),i));return{center:n,axis:i,normal:s,half:Math.max(0,t.renderedLength)/2,targetLo:Math.min(...o),targetHi:Math.max(...o)}}(t),s=e.rooms.flatMap(t=>{const s=function(t,e,i){const{profile:s}=t;let n=null;for(let t=0;t0))continue;const o=s.poly[t],a=s.poly[(t+1)%s.poly.length],r=xf(a,o),l=Math.hypot(r[0],r[1]);if(!(l>i&&Sf(e.axis,[r[0]/l,r[1]/l],1e-6)))continue;if(Mf(o,e.center,e.axis)>i||Mf(a,e.center,e.axis)>i)continue;const c=kf(xf(o,e.center),e.axis),h=kf(xf(a,e.center),e.axis),d=Math.min(c,h),p=Math.max(c,h);if(d>-e.half+i||p0?d:p<0?-p:0);(!n||u2)return Tf(i);if(s.length){const t=s.map(({room:t,edge:s})=>Pf(t,s,i,e.epsilon));if(t.some(t=>!t))return Tf(i);const n=t;return[...n.map(t=>t.left),...n.map(t=>t.right)]}return zf(t,e,i)}function Ef(t){return!(!t.canEdit||t.kiosk||t.fixedFloor)&&("view"!==t.mode&&("mouse"===t.pointerType&&t.spaceCount>1))}const Nf="1.68.0",Of={badge:"display.badge",icon_ripple:"display.icon_ripple",value:"display.value",static_icon:"display.static_icon"},Lf={badge:"marker.display_hint_badge",icon_ripple:"marker.display_hint_icon_ripple",value:"marker.display_hint_value",static_icon:"marker.display_hint_static_icon"},Hf=2e3,Bf=1e3,qf=1500,Wf=t=>{const e=String(t??"").trim().replace(",",".");if(!/^[+-]?(?:\d+(?:\.\d*)?|\.\d+)$/.test(e))return null;const i=Number(e);return Number.isFinite(i)?i:null},jf=(t,e)=>{if(!t.has(e))return{hit:!1};const i=t.get(e);return t.delete(e),t.set(e,i),{hit:!0,value:i}},Uf=(t,e,i,s)=>{for(t.delete(e),t.set(e,i);t.size>s;){const e=t.keys().next().value;if(void 0===e)break;t.delete(e)}},Gf=new Map;let Vf=0;const Kf=t=>`${window.innerWidth}x${window.innerHeight}|${location.pathname}|${JSON.stringify(t??{})}`;let Yf=1e4;const Jf="houseplan_card_layout_v1",Xf="houseplan_card_cfg_v1",Zf="houseplan_card_zoom_v1",Qf="houseplan_card_nav_v1",tv="houseplan_card_kiosk_v1",ev="houseplan_card_view_v1",iv="hp-dialog, hp-help, hp-color-opacity, hp-device-preview",sv=1e3,nv=[[0,1],[45,.88],[70,.62],[86,.32],[100,0]],ov=(t,e)=>{const i=Math.min(t.x,e.x),s=Math.min(t.y,e.y);return{x:i,y:s,w:Math.max(t.x+t.w,e.x+e.w)-i,h:Math.max(t.y+t.h,e.y+e.h)-s}},av=new Set(["select","draw","column","merge","split","resize","opening","wallthick","delroom"]),rv=2e3,lv=(t,e,i)=>{const s=new Event(e,{bubbles:!0,composed:!0});s.detail=i??{},t.dispatchEvent(s)},cv=t=>{history.pushState(null,"",t),lv(window,"location-changed",{replace:!1})},hv=(t,e)=>{let i,s=null;const n=(...n)=>{clearTimeout(i),s=n,i=window.setTimeout(()=>{i=void 0;const e=s;s=null,e&&t(...e)},e)};return n.flush=()=>{if(void 0===i)return;clearTimeout(i),i=void 0;const e=s;s=null,e&&t(...e)},n.cancel=()=>{clearTimeout(i),i=void 0,s=null},n.pending=()=>void 0!==i,n},dv=t=>{try{t.target?.setPointerCapture?.(t.pointerId)}catch{}};class pv extends ht{constructor(){super(...arguments),this._space="f1",this._layout={},this._serverStorage=!1,this._loadOk=!1,this._serverCanWrite=null,this._loading=!1,this._loadTries=0,this._serverCfg=null,this._cfgRev=0,this._cfgContentFingerprint="",this._unsubCfg=null,this._unsubLayout=null,this._unsubVirtual=null,this._liveSyncAttempt=null,this._liveSyncGeneration=0,this._liveSyncConnection=null,this._layoutRev=0,this._layoutContentFingerprint="",this._virtualLights=mn(null),this._canOptimizeUndo=!1,this._undoKind=null,this._devices=[],this._regSignature="",this._defPos={},this._newSyncKey="",this._tip=null,this._hoverRoom=null,this._pointerModality=new N_(this,()=>this._syncPointerHoverTargets()),this._devicePressAnimations=new Map,this._selId=null,this._toast="",this._mode="view",this._pendingNavMode=null,this._decorTool="select",this._decorStyle={...Rr},this._decorDraft=null,this._decorMove=null,this._decorSel=null,this._decorEraseConfirm=null,this._decorTextDialog=null,this._decorShapeDialog=null,this._backdropDialog=null,this._decorTextSelection={start:0,end:0},this._furnPalette=null,this._dtBox=null,this._dtDrag=null,this._bdDrag=null,this._slide="",this._reducedMotion=!1,this._onMotionChange=t=>{this._reducedMotion=t.matches,this._cancelDevicePressFeedback(),t.matches&&this._modeTransitionPreparing?this._modeTransitionForceAtomic=!0:t.matches&&this._modeTransition.active&&this._cancelModeTransition(!0),this.requestUpdate()},this._editorChromeMode="plan",this._modeTransitionVisual=null,this._modeTransitionPreparing=!1,this._modeTransitionForceAtomic=!1,this._modeTransitionRequest=0,this._modeTransitionTargetZoom=1,this._modeTransitionEditorCamera=null,this._modeTransition=new Tg({frame:t=>this._applyModeTransitionFrame(t),settled:t=>this._settleModeTransition(t)}),this._editorSecondary=new W_({root:()=>this.renderRoot,requestUpdate:()=>this.requestUpdate(),updateComplete:()=>this.updateComplete,clearTip:()=>{this._tip=null}}),this._editorSecondaryCopy={groupActive:(t,e)=>this._t("editor.group_active",{group:t,item:e}),openGroup:t=>this._t("editor.open_group",{group:t}),disabledAction:(t,e)=>this._t("editor.disabled_action",{action:t,reason:e})},this._tool="draw",this._geometryHistory=new fg(50),this._wallDialog=null,this._drawWallField=null,this._activeDraftId=null,this._resumeDraftBySpace={},this._physicalSel=null,this._physicalDialog=null,this._partitionDeleteDialog=null,this._roomDeleteDialog=null,this._physicalDrag=null,this._physicalRotate=null,this._physicalLastTap=null,this._physicalPickCycle=null,this._wallUnionCacheValue=null,this._wallUnionPool=new Map,this._isoGeometryCache=new Map,this._isoFallback=new Set,this._openingTunnelCache=null,this._openingWallIndexCache=new Map,this._openingPlacementIntervalsCache=null,this._openingDimensionContextCache=null,this._planSnapGeometryCache=null,this._planStructuralGeometryCache=null,this._hiddenWallDiagnosticCache=null,this._physicalBodiesCache=null,this._lightPhysicalBodiesCache=null,this._cleanFloorCache=new Map,this._innerContourCache=new Map,this._glowClipCache=new Map,this._glowGeometryWarnings=new Set,this._lightBarrierCache=null,this._lightBarrierPool=new Map,this._glowFeatherUnits=null,this._glowRenderedSources=new Map,this._glowLastAppearance=new Map,this._glowEnteringSources=new Set,this._glowEnterRafs=new Map,this._glowFadeTimers=new Map,this._glowFeatherSuspendUntil=0,this._glowFeatherResumeTimer=0,this._glowSourceSeq=0,this._glowScreenBlend=!1,this._duplicateColumnId=null,this._duplicateColumnTimer=0,this._rszSel=null,this._rszDrag=null,this._rszEligibilityCache=null,this._rszPreview=null,this._rszLive=null,this._path=[],this._cursorPt=null,this._planSnapHover=null,this._mergeSel=null,this._openingPreset=null,this._openingRebindId=null,this._openingPresetRevision=0,this._openingHoverCandidate=null,this._openingJambBlockCm=null,this._openingDialog=null,this._openingInfo=null,this._opDrag=null,this._opMeasure=null,this._mergeDialog=null,this._splitSel=null,this._pendingSplit=null,this._wallFaceBatch=null,this._wallRepairDiagnostic=null,this._wallFaceGraphCache=[],this._areaSel="",this._nameSel="",this._roomDialog=!1,this._roomEditId=null,this._roomFill="",this._roomCustomFill=null,this._roomTempSrc="",this._roomHumSrc="",this._roomSrcOpen=null,this._roomSrcFilter="",this._roomNameScale=1,this._roomLabelScale=1,this._zoom=1,this._view=null,this._zoomBySpace={},this._viewModeSnap=null,this._pointers=new Map,this._panStart=null,this._panLock=null,this._pinchStart=null,this._suppressClick=!1,this._touchContacts=new Map,this._touchSequenceMultitouch=!1,this._touchClickBlockUntil=0,this._connectedPath="",this._routeDepartureHandled=!1,this._onLocationChanged=()=>{this._connectedPath&&location.pathname!==this._connectedPath?this._leaveCardRoute():location.pathname===this._connectedPath&&(this._routeDepartureHandled=!1)},this._touchGestureGuard={capture:!0,handleEvent:t=>this._guardTouchGesture(t)},this._hdrH=118,this._booting=!0,this._bootFading=!1,this._bootSettling=!1,this._bootSettleRaf=0,this._bootLastH=-1,this._bootStart=0,this._bootLastChange=0,this._bootSoft=!1,this._tapConfirm=null,this._onboardingShown=!1,this._rulesDialog=null,this._preflightClipboardFallback=null,this._haIntegrationVersion=null,this._alignDialog=null,this._settingsDialog=null,this._backupExportDialog=null,this._backupImportDialog=null,this._sunRaysCache=null,this._dayCycleTimer=0,this._dayCycleClockKey="",this._compassDrag=!1,this._importDialog=null,this._importQueue=[],this._importTotal=0,this._rulesCompiledSrc="",this._infoCard=null,this._nativeMoreInfoEntity=null,this._markerDialog=null,this._spaceDialog=null,this._keyHandler=t=>this._onKey(t),this._warmVp=null,this._warmVpArmed=!1,this._warmLongReturn=!1,this._warmRevivePending=!1,this._warmGen=++Vf,this._warmKey=null,this._warmSlot=null,this._hashApplied=!1,this._navApplied=!1,this._labs={active:Object.freeze([]),space:""},this._viewPreference={},this._renderProjection="flat",this._kioskScale={icon:1,font:1},this._kioskDialog=!1,this._activityRt=new Map,this._vacRt=new Map,this._vacViewKey="",this._vacLastView=null,this._vacRaf=0,this._vacSrvTrails={},this._vacJumpOnce=!1,this._continuity=this._newContinuityController(),this._continuityHistory=[],this._continuityEpoch=0,this._continuityDataReady=!0,this._continuityPaintToken=-1,this._continuityDisposed=!1,this._renderSnapshotAt=Date.now(),this._hassSequence=0,this._visibleDeviceSnapshot=null,this._candidateDeviceSnapshot=null,this._stagedDeviceSnapshotToken=-1,this._capturedSnapshotSequence=-1,this._capturedSnapshotDevices=null,this._capturedSnapshotLayout=null,this._capturedSnapshotActivity="",this._capturedSnapshotConfigEpoch=-1,this._capturedSnapshotVirtual="",this._lastValidStageSize=null,this._pendingRefitSize=null,this._refitRaf=0,this._pageVisibility=t=>{if(this._continuity.visibility(t),this._dayCycleVisibility(t),"hidden"===t.kind)return this._clearTransientHover(!0),this._cancelDevicePressFeedback(),void(this._modeTransitionPreparing?this._modeTransitionForceAtomic=!0:this._cancelModeTransition(!0));if(this._vacJumpOnce=!0,!t.long){const t=Date.now();let e=!1;for(const i of this._activityRt.values())!i.flashKind||(i.expiresAt||i.flashTs+I_)>t||(i.flashTs=0,i.flashKind=null,i.expiresAt=0,e=!0);return void(e&&this.requestUpdate())}Date.now()-this._renderSnapshotAt>1e3&&this._continuity.note("device-snapshot-stale"),this._continuityDataReady=!1,this._continuityPaintToken=-1,this._resumeSettling=!0,this._loading?this.requestUpdate():this._loadFromServer()},this._resumeSettling=!1,this._viewportInvalidAt=0,this._vacFit=null,this._vacAllCamerasFor=null,this._vacAllCameraCache=null,this._vacCalConfirm=null,this._kioskDots=!1,this._cyclePausedUntil=0,this._swipeStart=null,this._tabDrag=null,this._tabDragRelease=null,this._tabSuppressClick=!1,this._tabOrderWarned=!1,this._lastTap=0,this._onLabsSnapshot=t=>{const e=this._effectiveProjection();this._labs=t;const i=this._effectiveProjection();this._convertProjectionView(e,i),this.requestUpdate()},this._onHashChange=()=>{if(this._hasFixedFloor)return;const t=this._hashSpace();if(t&&this._model.find(e=>e.id===t)&&t!==this._space){if(this._wallFaceBatch&&this._roomDialogCancel(),"plan"===this._mode&&"draw"===this._tool&&!this._finishWallChain())return;this._activeDraftId&&(this._resumeDraftBySpace[this._space]=this._activeDraftId),this._commitSpace(t),this._selId=null,this._path=[],this._clearPlanSnapHover(),this._clearOpeningPlacement(!0),this._tool="draw",this._activeDraftId=null,this._draftSegmentCms=[],this._closingWallCm=null,"plan"===this._mode&&"draw"===this._tool&&this._resumeLastDraft(),this._restoreZoom(),this.requestUpdate()}},this._drag=null,this._rlResize=null,this._holdFired=!1,this._retryContinuity=()=>{this._continuityDataReady=!1,this._continuityPaintToken=-1,this._continuity.retry(this._continuity.recoveryReason||"plan"),this._loading||this._loadFromServer()},this._cfgEpoch=0,this._modelCache=null,this._emptySpaceStateActive=!1,this._decorSnapCache=null,this._markerPreviewMemo=null,this._markerPreviewDevicesMemo=null,this._showHidden=!1,this._connHooked=null,this._connectionWasLost=!1,this._haRegistryConnection=null,this._haRegistryRev=-1,this._haBindingCacheKey="",this._planHassMemo=null,this._onHaRegistryUpdate=()=>{const t=An(this.hass);t.revision===this._haRegistryRev&&this._devices.length||(this._haRegistryRev=t.revision,this._planHassMemo=null,this._regSignature="",this._maybeRebuildDevices(),this.requestUpdate())},this._onConnReady=()=>{if(this._loadTries=0,clearTimeout(this._loadRetryTimer),this._loadRetryTimer=void 0,function(t){const e=Cn(t);e&&(Tn(t,e),Rn(t,e))}(this.hass),this._saveConfigDebounced.pending()&&this._saveConfigDebounced.flush(),this._cfgWriting)return clearTimeout(this._reloadRetry),void(this._reloadRetry=window.setTimeout(this._onConnReady,400));!this._connectionWasLost&&this._continuity.hasCompleteFrame?this._beginContinuityCandidate("connection-ready",!1,"plan"):(this._continuityDataReady=!1,this._continuityPaintToken=-1),this._loading||this._loadFromServer()},this._onConnLost=()=>{this._booting&&!this._continuity.hasCompleteFrame||(this._connectionWasLost=!0,this._continuityDataReady=!1,this._continuityPaintToken=-1,this._continuity.connectionLost())},this._signer=new $d(()=>this.requestUpdate()),this._dirtyPos=new Set,this._sentPos=new Map,this._persistLayout=hv(()=>{if(this._serverStorage){const t=[...this._dirtyPos];this._dirtyPos.clear();for(const e of t){const t=ol(this._layout[e]);t&&(this._layout={...this._layout,[e]:t},this._sentPos.set(e,t),this.hass.callWS({type:"houseplan/layout/update",device_id:e,pos:t}).then(t=>this._noteLayoutRev(t)).catch(t=>this._showToast(this._t("toast.pos_save_failed",{err:this._errText(t)}))).finally(()=>{this._sentPos.get(e)===t&&this._sentPos.delete(e)}))}this._cacheSnapshot()}else this._layout=al(Gr(this._layout)),localStorage.setItem(Jf,JSON.stringify(this._layout))},600),this._frame=null,this._showFar=!1,this._writesPending=0,this._writeChain=Promise.resolve(),this._pendingPhysicalWrites=new Map,this._undoGeometry=()=>{if(this._physicalDrag||this._physicalRotate)return void this._cancelPhysicalGesture();if(this._decorDraft)return this._decorDraft=null,void this.requestUpdate();if(this._decorMove||this._dtDrag||this._bdDrag)return void this._cancelDecorGesture();if(this._rszDrag)return void this._rszCancelDrag();const t=this._geometryHistory.undo();t&&(this._applyGeometryState(t.before,!0)?this._showToast(this._t("history.undone",{name:t.name})):this._geometryHistory.clear())},this._redoGeometry=()=>{if(this._physicalDrag||this._physicalRotate)return void this._cancelPhysicalGesture();if(this._decorDraft)return this._decorDraft=null,void this.requestUpdate();if(this._decorMove||this._dtDrag||this._bdDrag)return void this._cancelDecorGesture();if(this._rszDrag)return void this._rszCancelDrag();const t=this._geometryHistory.redo();t&&(this._applyGeometryState(t.after,!0)?this._showToast(this._t("history.redone",{name:t.name})):this._geometryHistory.clear())},this._saveConfigDebounced=hv(()=>{this._serverCfg&&this._writeConfig().catch(t=>{const e=!0===t?.physicalGeometryRolledBack;"geometry-unsafe"!==t?.code&&("wall_model_client_outdated"===t?.code?this._showToast(this._t("toast.wall_model_client_outdated")):"conflict"===t?.code?(this._showToast(this._t("toast.conflict")),e||(this._cancelPath(),this._reloadConfigOnly(!0))):this._showToast(this._t("toast.cfg_save_failed",{err:this._errText(t)})),e&&this._reloadRejectedPhysicalWrite())})},500),this._draftSegmentCms=[],this._closingWallCm=null,this._savePhysicalDialog=()=>{const t=this._physicalDialog,e=this._curSpaceCfg,i=this._spaceModel();if(!t||!e||!i)return;const s=Wf(t.cm);if(null==s)return void this._showPhysicalRange("column"===t.kind?jc:100,"column"===t.kind?1:0);const n=this._imperial?2.54*s:s,o="column"===t.kind?jc:100,a="column"===t.kind?1:0;if(!Number.isFinite(n)||no)return void this._showPhysicalRange(o,a);if("column"===t.kind){const e=i.wall_columns.find(e=>e.id===t.id);if(!e)return;const s=Wf(t.angle||"0");if("circle"!==t.shape&&(null==s||s<0||s>=90))return void this._showToast(this._t("toast.physical_angle"));const o="circle"===t.shape?{id:t.id,shape:"circle",center:e.center,cm:n}:{id:t.id,shape:"square",center:e.center,cm:n,angle:s};if(i.wall_columns.some(e=>e.id!==t.id&&uh(e,o,.02*this._gridPitch)))return void this._showToast(this._t("toast.column_duplicate"))}const r=this._geometrySnapshot();if("partition"===t.kind){const i=(e.partitions||[]).find(e=>e.id===t.id);if(i&&0===n&&f_(e.openings,{kind:"partition",id:t.id}))return void this._showToast(this._t("toast.zero_wall_opening_conflict"));i&&(i.cm=n)}else if("column"===t.kind){const i=(e.wall_columns||[]).find(e=>e.id===t.id);i&&(i.cm=Gc(n),i.shape="circle"===t.shape?"circle":"square","square"===i.shape?i.angle=Wf(t.angle||"0"):delete i.angle)}else{const i=(e.room_drafts||[]).find(e=>e.id===t.id);i?.segments?.[t.segment||0]&&(i.segments[t.segment||0].cm=n)}const l=this._commitPhysicalGeometry(this._t("history.physical_edit"),r);this._physicalDialog=null,l||this.requestUpdate()},this._deletePhysicalSelection=()=>{const t=this._physicalSel,e=this._curSpaceCfg;if(!t||!e)return;if("draft"===t.kind)return void this._deleteDraftWhole();const i=this._geometrySnapshot();if("partition"===t.kind){const i=(e.openings||[]).filter(e=>"partition"===e.host?.kind&&e.host.id===t.id).sort((t,e)=>(t.host?.t||0)-(e.host?.t||0));if(i.length)return void(this._partitionDeleteDialog={id:t.id,openings:i.map(t=>JSON.parse(JSON.stringify(t)))})}const s="partition"===t.kind?"partitions":"column"===t.kind?"wall_columns":"room_drafts";e[s]=(e[s]||[]).filter(e=>e.id!==t.id),e[s].length||delete e[s],this._activeDraftId===t.id&&this._cancelPath(),this._physicalSel=null,this._physicalDialog=null,this._commitPhysicalGeometry(this._t("history.physical_delete"),i)},this._confirmPartitionDelete=()=>{const t=this._partitionDeleteDialog,e=this._curSpaceCfg;if(!t||!e)return;const i=this._geometrySnapshot();e.partitions=(e.partitions||[]).filter(e=>e.id!==t.id),e.partitions.length||delete e.partitions,e.openings=(e.openings||[]).filter(e=>"partition"!==e.host?.kind||e.host.id!==t.id),e.openings.length||delete e.openings,this._partitionDeleteDialog=null,this._physicalSel=null,this._physicalDialog=null,this._commitPhysicalGeometry(this._t("history.physical_delete"),i)},this._deleteDraftWhole=()=>{const t="draft"===this._physicalDialog?.kind?this._physicalDialog.id:"draft"===this._physicalSel?.kind?this._physicalSel.id:null,e=this._curSpaceCfg;if(!t||!e||!confirm(this._t("confirm.delete_draft")))return;const i=this._geometrySnapshot();e.room_drafts=(e.room_drafts||[]).filter(e=>e.id!==t),e.room_drafts.length||delete e.room_drafts,this._activeDraftId===t&&this._cancelPath(),this._physicalSel=null,this._physicalDialog=null,this._commitPhysicalGeometry(this._t("history.physical_delete"),i)},this._deleteDraftSegment=()=>{const t=this._physicalDialog,e=this._curSpaceCfg;if(!t||"draft"!==t.kind||!e)return;if(!confirm(this._t("confirm.delete_draft_segment")))return;const i=(e.room_drafts||[]).findIndex(e=>e.id===t.id);if(i<0)return;const s=e.room_drafts[i],n=Math.max(0,Math.min(s.segments.length-1,t.segment||0)),o=[],a=s.points.slice(0,n+1),r=s.points.slice(n+1);if(a.length>=2&&o.push({id:s.id,points:a,segments:s.segments.slice(0,n)}),r.length>=2&&o.push({id:o.length?`${s.id}-${Date.now().toString(36)}`:s.id,points:r,segments:s.segments.slice(n+1)}),2===o.length&&e.room_drafts.length>=200)return void this._showToast(this._t("toast.physical_limit"));const l=this._geometrySnapshot();e.room_drafts.splice(i,1,...o),e.room_drafts.length||delete e.room_drafts,this._activeDraftId===s.id&&this._cancelPath(),this._physicalDialog=null,this._physicalSel=o.length?{kind:"draft",id:o[0].id}:null,this._commitPhysicalGeometry(this._t("history.draft_segment_delete"),l)},this._confirmRoomDelete=t=>{const e=this._roomDeleteDialog,i=this._curSpaceCfg,s=this._spaceModel();if(!e||!i||!s)return;const n=s.rooms.find(t=>t.id===e.roomId);if(!n)return void(this._roomDeleteDialog=null);const o=this._openCuts(),a=$u(dc(s.rooms,this._spaceWalls,o,this._wallKeyPitch,this._cellCm,this._gridPitch,sv).filter(t=>t.roomId===n.id),s.partitions,this._openingsR.map(t=>({...t,x:t.rx,y:t.ry})),.02*this._gridPitch),r=new Set(a.materialize.filter(t=>!t.reusePartitionId).map(t=>t.interval.key)).size;if(t&&(i.partitions||[]).length+r>rv)return void this._showToast(this._t("toast.physical_limit"));const l=this._geometrySnapshot(),c=pc(s.rooms,this._spaceWalls,o,this._wallKeyPitch,this._cellCm,this._gridPitch,sv);if(t){i.partitions||=[];const t=new Map,e=new Map,s=t=>{const e=(i.wall_segments||[]).find(e=>{const i=[Number(e.a?.[0])*sv,Number(e.a?.[1])*sv],s=[Number(e.b?.[0])*sv,Number(e.b?.[1])*sv];return this._samePt(t.a,i)&&this._samePt(t.b,s)||this._samePt(t.a,s)&&this._samePt(t.b,i)});return"string"==typeof e?.id&&e.id?e.id:null},n=Date.now().toString(36);for(const o of a.materialize){let a=o.reusePartitionId?i.partitions.find(t=>t.id===o.reusePartitionId):e.get(o.interval.key);a||(a={id:s(o.interval)||`partition-room-${n}-${e.size}`,a:[o.interval.a[0]/sv,o.interval.a[1]/sv],b:[o.interval.b[0]/sv,o.interval.b[1]/sv],cm:o.interval.cm},i.partitions.push(a),e.set(o.interval.key,a)),t.set(o.interval.key,a)}for(const e of i.openings||[]){const i=a.openingIntervals.get(e.id),s=i?t.get(i):null,n=this._openingsR.find(t=>t.id===e.id);if(!s||!n)continue;const o={a:[s.a[0]*sv,s.a[1]*sv],b:[s.b[0]*sv,s.b[1]*sv]};e.host={kind:"partition",id:s.id,t:Su([n.rx,n.ry],o)}}}else if(a.removeOpeningIds.length){const t=new Set(a.removeOpeningIds);i.openings=(i.openings||[]).filter(e=>!t.has(e.id)),i.openings.length||delete i.openings}i.rooms=i.rooms.filter(t=>t.id!==n.id),this._cfgEpoch++;const h=this._normalizeWalls(c,this._openCuts());h.length?i.walls=h:delete i.walls,this._roomDeleteDialog=null,this._commitPhysicalGeometry(this._t(t?"history.delete_room_keep_walls":"history.delete_room_with_walls"),l),this._regSignature="",this._maybeRebuildDevices(),this.requestUpdate()},this._rebindPartitionOpening=()=>{const t=this._openingDialog;if(!t?.id)return;const e=t.id;this._activateMarkupTool("opening"),"opening"===this._tool&&(this._openingRebindId=e,this._openingPreset={type:t.type,lengthCm:t.lengthCm,flipH:t.flipH,flipV:t.flipV,revision:++this._openingPresetRevision},this._openingDialog=null,this._openingHoverCandidate=null)},this._keepClosedAsPartitions=()=>{if(this._wallFaceBatch)return void this._decideWallFace(!1);if(!this._contourClosed||this._pendingSplit||!this._curSpaceCfg)return;const t=this._curSpaceCfg,e=this._path.slice(0,-1);if((t.partitions||[]).length+e.length>rv)return void this._showToast(this._t("toast.physical_limit"));const i=this._geometrySnapshot(),s=Xp(e.length,[...this._draftSegmentCms,this._closingWallCm??void 0],this._drawWallCm,ll);t.partitions||=[];const n=Date.now().toString(36),o=this._activeDraftId?(t.room_drafts||[]).find(t=>t.id===this._activeDraftId):null,a=this._draftSegmentsForPath(this._path,o,s);for(let i=0;it.id!==this._activeDraftId),t.room_drafts.length||delete t.room_drafts),this._commitPhysicalGeometry(this._t("history.contour_to_partitions"),i),this._roomDialog=!1,this._path=[],delete this._resumeDraftBySpace[this._space],this._activeDraftId=null,this._draftSegmentCms=[],this._closingWallCm=null},this._toggleServerPlans=async()=>{const t=this._spaceDialog;if(t)if(t.pickSaved)this._spaceDialog={...t,pickSaved:!1};else{this._spaceDialog={...t,pickSaved:!0,savedBusy:!0};try{const t=await this.hass.callWS({type:"houseplan/plans/list"}),e=this._spaceDialog;e&&(this._spaceDialog={...e,saved:t?.plans||[],savedBusy:!1})}catch(t){const e=this._spaceDialog;e&&(this._spaceDialog={...e,saved:[],savedBusy:!1}),this._showToast(this._t("toast.plans_list_failed",{err:this._errText(t)}))}}},this._aspectJob=null,this._dayCycleTick=()=>{if(!this.isConnected||"hidden"===this.ownerDocument.visibilityState)return;const t=this._dayCycleState();if(!t)return this._dayCycleTimer&&(clearInterval(this._dayCycleTimer),this._dayCycleTimer=0),void(this._dayCycleClockKey="");const e=mr(t);e!==this._dayCycleClockKey&&(this._dayCycleClockKey=e,this.requestUpdate())},this._sunShown=!1,this._sunOut=!1,this._sunOutTimer=0,this._openSettingsDialog=()=>{if(!this._norm)return;const t=this._glowRadiusCm,e=this._imperial?Math.round(t/30.48*10)/10:Math.round(t)/100;this._settingsDialog={colors:JSON.parse(JSON.stringify(this._fillColors)),glowRadius:e,bgColor:hs(this._settings,{bgColor:null})||null,northDeg:$r(this._settings,{}),bgMode:Sr(this._settings,{}),sunRays:Mr(this._settings,{}),busy:!1}},this._reportedPreflightFingerprint=null,this._openAlignDialog=()=>this._previewAlignDialog(!1),this._toggleOptimizeLivePositions=()=>{const t=this._alignDialog;t&&!t.busy&&t.report.liveMissingPositions.length&&this._previewAlignDialog(!t.removeLiveMissingPositions)},this._optimizeUndoBusy=!1,this._openBackupExport=()=>{this._settingsDialog=null,this._backupExportDialog={kind:"full",planOnly:!1,busy:!1,error:""}},this._openRulesDialog=()=>{if(!this._norm)return;const t=this._settings.icon_rules,e=(t&&t.length?t:Jt).map(t=>({...t}));this._rulesDialog={rules:e,test:"",busy:!1}},this._climateCache=null,this._gearPtCache=new WeakMap}get _canEdit(){return!!this._norm&&(!0===this._serverCanWrite||!1!==this._serverCanWrite&&!0===this.hass?.user?.is_admin)}get _kiosk(){return!!this._config?.kiosk}_showKioskDots(){this._kioskDots=!0,clearTimeout(this._kioskDotsTimer),this._kioskDotsTimer=window.setTimeout(()=>this._kioskDots=!1,2500)}get _modeTransitionBusy(){return this._modeTransitionPreparing||this._modeTransition.active}_cssColor(t,e){const i=String(t||"").trim();if(!i)return e;const s=document.createElement("span");s.style.cssText=`position:absolute;visibility:hidden;color:${i}`,this.renderRoot.append(s);const n=getComputedStyle(s).color||e;return s.remove(),n}_currentModeVisual(t=this._mode){const e=this._modeTransition.presented||this._modeTransitionVisual;if(e)return{...e,viewport:{...e.viewport,viewBox:{...e.viewport.viewBox}}};const i=this._stageEl;if(!i||i.clientWidth<=0||i.clientHeight<=0)return null;const s=this.renderRoot.querySelector(".editorchrome"),n=this._viewOr(this._baseVb()),o=this.renderRoot.querySelector(".hp-paper"),a=this.renderRoot.querySelector(".hp-backdrop"),r=this.renderRoot.querySelector(".zoomwrap"),l=r?getComputedStyle(r).filter:"",c=Number(/brightness\(([^)]+)\)/.exec(l)?.[1]);return{presentedMode:t,editorChromeHeight:"view"===t?0:s?.getBoundingClientRect().height||0,stageWidth:i.clientWidth,stageHeight:i.clientHeight,viewport:Sg(n,i.clientWidth),stageColor:getComputedStyle(i).backgroundColor||"rgb(255, 255, 255)",paperColor:o?getComputedStyle(o).fill:"rgb(255, 255, 255)",sceneBrightness:Number.isFinite(c)?c:1,architectureOpacity:"decor"===t?.35:1,backdropOpacity:a&&Number(getComputedStyle(a).opacity)||1,viewWeight:"view"===t?1:0,editorWeight:"view"===t?0:1,toolbarContentOpacity:"view"===t?0:1}}_viewForModeTarget(t,e,i,s,n){const o=Ni(this._baseVb(),s/Math.max(1,n)),a=Math.min(pv.ZOOM_MAX,Math.max(pv.ZOOM_MIN,t)),r=o.w/a,l=o.h/a,c=e??o.x+o.w/2,h=i??o.y+o.h/2;return this._clampView({x:c-r/2,y:h-l/2,w:r,h:l},o)}_targetStageColor(t){return"view"!==t?"rgb(255, 255, 255)":this._cssColor(this._stageBg(this._spaceDisplayForRender()),this._cssColor("var(--ha-card-background, var(--card-background-color, #111))","rgb(17, 17, 17)"))}_targetPaperColor(t){return"view"===t&&this._spaceModel()?.bg?this._cssColor("var(--ha-card-background, var(--card-background-color, #111))","rgb(17, 17, 17)"):"rgb(255, 255, 255)"}_targetBrightness(t){return 1}_applyModeTransitionFrame(t){t.targetMode===this._mode&&(this._modeTransitionVisual=t.presented,this._view={...t.presented.viewport.viewBox},this.requestUpdate())}_settleModeTransition(t){if(t.targetMode!==this._mode)return;const e=this._modeTransitionRequest;this._view={...t.to.viewport.viewBox},this._zoom=this._modeTransitionTargetZoom,this._modeTransitionVisual=null,this._modeTransitionPreparing=!1,this._lastValidStageSize=[t.to.stageWidth,t.to.stageHeight],"view"===this._mode&&(this._saveZoom(),this._viewModeSnap=null,this._modeTransitionEditorCamera=null),this.requestUpdate(),this.updateComplete.then(()=>{if(!this.isConnected||e!==this._modeTransitionRequest||this._modeTransitionBusy||t.targetMode!==this._mode)return;const i=this._stageEl;if(i&&i.clientWidth>0&&i.clientHeight>0&&(Math.abs(i.clientWidth-t.to.stageWidth)>.5||Math.abs(i.clientHeight-t.to.stageHeight)>.5)){const t=this._view;this._lastValidStageSize=[i.clientWidth,i.clientHeight],this._applyView(this._zoom,t?t.x+t.w/2:void 0,t?t.y+t.h/2:void 0),this.requestUpdate()}const s=this.renderRoot.activeElement;(!s||!s.isConnected||!!s.closest?.(".editorchrome, .stage"))&&this.renderRoot.querySelector(".modetab.active")?.focus?.({preventScroll:!0})})}_cancelModeTransition(t=!0){const e=!!this._modeTransition.state;this._modeTransitionRequest++,this._modeTransitionPreparing=!1,this._modeTransitionForceAtomic=!1,this._modeTransition.cancel(t),t&&e||(this._modeTransitionVisual=null)}_adoptMode(t){this._cancelModeTransition(!1),this._mode=t,"view"!==t&&(this._editorChromeMode=t)}_commitViewModeAtomic(t,e,i,s){if(this._modeTransitionPreparing=!1,this._modeTransitionVisual=null,this._modeTransitionForceAtomic=!1,this._zoom=e,t){const n=this._stageEl?.clientWidth||t.stageWidth,o=Math.max(1,t.stageHeight+t.editorChromeHeight);this._view=this._viewForModeTarget(e,i,s,n,o),this._lastValidStageSize=[n,o]}else this._view=null;this._viewModeSnap=null,this._modeTransitionEditorCamera=null,this._saveZoom(),this.requestUpdate()}_prepareModeTransition(t,e,i,s,n,o){this.updateComplete.then(()=>{if(!this.isConnected||t!==this._modeTransitionRequest||this._mode!==i)return void(t===this._modeTransitionRequest&&(this._modeTransitionPreparing=!1,this._modeTransitionVisual=null,this._modeTransitionForceAtomic=!1,this.requestUpdate()));const a=this.renderRoot.querySelector(".editorchrome"),r=a?.querySelector(".editorchrome-inner"),l="view"===i?0:r?.scrollHeight||r?.getBoundingClientRect().height||0,c=Math.max(1,e.stageHeight+e.editorChromeHeight),h=Math.max(1,c-l),d=this._stageEl?.clientWidth||e.stageWidth;if(d<=0||h<=0)return this._modeTransitionPreparing=!1,this._modeTransitionVisual=null,this._applyView(s,n,o),void this.requestUpdate();const p=this._viewForModeTarget(s,n,o,d,h),u={presentedMode:i,editorChromeHeight:l,stageWidth:d,stageHeight:h,viewport:Sg(p,d),stageColor:this._targetStageColor(i),paperColor:this._targetPaperColor(i),sceneBrightness:this._targetBrightness(i),architectureOpacity:"decor"===i?.35:1,backdropOpacity:"decor"===i&&"backdrop"!==this._decorTool?.5:1,viewWeight:"view"===i?1:0,editorWeight:"view"===i?0:1,toolbarContentOpacity:"view"===i?0:1};this._modeTransitionPreparing=!1;const _=this._modeTransitionForceAtomic;this._modeTransitionForceAtomic=!1,this._modeTransition.start(e,u,i,this._reducedMotion||_?0:220)})}get _hasFixedFloor(){return!!this._config&&Object.prototype.hasOwnProperty.call(this._config,"floor")}_fixedFloorState(t=this._model,e=this._loadOk){const i=this._config?.floor,s=function(t){if(!t.hasFloor)return{kind:"absent"};const e=t.floor;if("string"==typeof e)return e.length?t.spaceIds.includes(e)?{kind:"valid",id:e,source:"id"}:{kind:"invalid",reason:"unknown-id",value:e}:{kind:"invalid",reason:"empty-id",value:e};if("number"==typeof e){if(!Number.isFinite(e))return{kind:"invalid",reason:"non-finite-index",value:e};if(!Number.isInteger(e))return{kind:"invalid",reason:"fractional-index",value:e};if(e<0)return{kind:"invalid",reason:"negative-index",value:e};const i=t.spaceIds[e];return void 0===i?{kind:"invalid",reason:"out-of-range-index",value:e}:{kind:"valid",id:i,source:"index"}}return{kind:"invalid",reason:"invalid-type",value:e}}({spaceIds:t.map(t=>t.id),hasFloor:this._hasFixedFloor,floor:i});return!this._hasFixedFloor||e?s:"number"==typeof i?"valid"===s.kind||"invalid"===s.kind&&"out-of-range-index"===s.reason?{kind:"pending",value:i}:s:"valid"===s.kind||"invalid"===s.kind&&"unknown-id"!==s.reason?s:{kind:"pending",value:i}}_canCommitSpace(t,e=!1){if(e||!this._hasFixedFloor)return!0;const i=this._fixedFloorState();return"valid"===i.kind&&i.id===t}_commitSpace(t,e=!1){return!!this._canCommitSpace(t,e)&&(t!==this._space&&(this._clearTransientHover(!0),this._cancelDevicePressFeedback()),this._space=t,!0)}_slideTo(t,e){if(t===this._space)return!0;if(!this._canCommitSpace(t))return!1;if(this._wallFaceBatch&&this._roomDialogCancel(),"plan"===this._mode&&"draw"===this._tool&&!this._finishWallChain())return!1;this._cancelModeTransition(!0);const i=window.matchMedia?.("(prefers-reduced-motion: reduce)")?.matches;return this._activeDraftId&&(this._resumeDraftBySpace[this._space]=this._activeDraftId),this._commitSpace(t),this._path=[],this._clearPlanSnapHover(),this._clearOpeningPlacement(!0),this._tool="draw",this._activeDraftId=null,this._draftSegmentCms=[],this._closingWallCm=null,this._selId=null,this._physicalSel=null,this._editorSecondary.closeForNavigation(),this._physicalDialog=null,this._physicalDrag=null,"plan"===this._mode&&"draw"===this._tool&&this._resumeLastDraft(),this._restoreZoom(),i||(this._slide=e,clearTimeout(this._slideTimer),this._slideTimer=window.setTimeout(()=>{this._slideTimer=void 0,this._slide="",this.requestUpdate()},190),this.requestUpdate()),!0}get _canReorderTabs(){return Ef({canEdit:this._canEdit,kiosk:this._kiosk,mode:this._mode,pointerType:"mouse",spaceCount:this._model.length,fixedFloor:this._hasFixedFloor})}_tabPointerDown(t,e){Ef({canEdit:this._canEdit,kiosk:this._kiosk,mode:this._mode,pointerType:t.pointerType,spaceCount:this._model.length,fixedFloor:this._hasFixedFloor})&&(dv(t),this._tabDragRelease=t=>this._tabPointerUp(t),window.addEventListener("pointerup",this._tabDragRelease),window.addEventListener("pointercancel",this._tabDragRelease),this._tabDrag={id:e,pointerId:t.pointerId,x:t.clientX,y:t.clientY,moved:!1,targetId:null,placement:null})}_tabDropTargetAt(t,e,i){const s=this._model.map(t=>t.id),n=s.indexOf(i);if(n<0)return null;const o=this.renderRoot.querySelectorAll('[data-hp="space-tab"]');for(const a of o){const o=a.dataset.id||"";if(!o||o===i)continue;const r=a.getBoundingClientRect();if(tr.right||er.bottom)continue;const l=s.indexOf(o);return l<0?null:{targetId:o,placement:l=4)))return;var i,s;const n=this._tabDropTargetAt(t.clientX,t.clientY,e.id);e.moved&&e.targetId===n?.targetId&&e.placement===n?.placement||(this._tabDrag={...e,moved:!0,targetId:n?.targetId||null,placement:n?.placement||null})}_tabPointerUp(t){const e=this._tabDrag;if(e&&e.pointerId!==t.pointerId)return;const i="pointerup"===t.type&&e?.moved?this._tabDropTargetAt(t.clientX,t.clientY,e.id):null;"pointerup"===t.type&&e?.moved&&this._suppressNextTabClick(),this._endTabDrag(),e?.moved&&i&&this._commitTabOrder(e.id,i.targetId)}_endTabDrag(){this._tabDrag=null,this._tabDragRelease&&(window.removeEventListener("pointerup",this._tabDragRelease),window.removeEventListener("pointercancel",this._tabDragRelease),this._tabDragRelease=null)}_tabClick(t){if(this._tabSuppressClick)return this._tabSuppressClick=!1,clearTimeout(this._tabSuppressClickTimer),void(this._tabSuppressClickTimer=void 0);this._pickSpace(t)}_suppressNextTabClick(){this._tabSuppressClick=!0,clearTimeout(this._tabSuppressClickTimer),this._tabSuppressClickTimer=window.setTimeout(()=>{this._tabSuppressClick=!1,this._tabSuppressClickTimer=void 0},0)}_commitTabOrder(t,e){const i=this._serverCfg;if(!i||!this._canReorderTabs)return;const s=this._model.map(t=>t.id),n=function(t,e,i){const s=t.indexOf(e),n=t.indexOf(i);if(s<0||n<0||s===n)return t;const o=t.slice();return o.splice(s,1),o.splice(n,0,e),o}(s,t,e);if(n===s)return;const o=new Map(this._devices.map(t=>[String(t.id),String(t.area||"")])),a=function(t,e,i,s=()=>""){if(!i)return[];const n=[];for(const o of t){if(!o||!0===o.removed)continue;const t="string"==typeof o.id?o.id:"";if(!t)continue;if("string"==typeof o.space&&o.space)continue;const a=("string"==typeof o.area?o.area:"")||s(t)||"";a&&e[a]||n.push({id:t,space:i})}return n}(i.markers||[],Object.fromEntries(Object.entries(this._areaToSpace).map(([t,e])=>[t,e.space])),s[0]||"",t=>o.get(t)||"");if(a.length){const t=new Map(a.map(t=>[t.id,t.space]));for(const e of i.markers||[]){const i=t.get(String(e.id));i&&(e.space=i)}}i.spaces=function(t,e){const i=new Map(e.map((t,e)=>[t,e]));return t.map((t,e)=>({space:t,index:e})).sort((t,e)=>(i.get(String(t.space?.id))??Number.MAX_SAFE_INTEGER)-(i.get(String(e.space?.id))??Number.MAX_SAFE_INTEGER)||t.index-e.index).map(t=>t.space)}(i.spaces||[],n),this._saveConfig(),this._tabOrderWarned||(this._tabOrderWarned=!0,this._showToast(this._t("toast.space_order_changed")))}_pickSpace(t){if(this._endTabDrag(),t===this._space)return;const e=this._model.map(t=>t.id),i=e.indexOf(this._space),s=e.indexOf(t);this._navApplied=!0,this._showFar=!1,this._frame=null,this._slideTo(t,i>=0&&s0&&Date.now()>=this._cyclePausedUntil&&this._model.length>1&&this._zoom<=1.001){const t=this._model.map(t=>t.id),e=t.indexOf(this._space);this._slideTo(t[(e+1)%t.length],"left"),this._showKioskDots()}}_syncCycleTimer(){clearInterval(this._cycleTimer),this._cycleTimer=void 0,this.isConnected&&!this._hasFixedFloor&&this._config?.kiosk&&Number(this._config.cycle)>0&&(this._cycleTimer=window.setInterval(()=>this._cycleTick(),1e3*Number(this._config.cycle)))}get _editing(){return"plan"===this._mode||"devices"===this._mode||"decor"===this._mode}get _markup(){return"plan"===this._mode}get _wallUnionCache(){return this._wallUnionCacheValue}set _wallUnionCache(t){this._wallUnionCacheValue=t,null===t&&this._wallUnionPool.clear()}_newContinuityController(){return new bd(()=>{this._resumeSettling="steady"!==this._continuity.state,this._continuityEpoch++,this.isConnected&&this.requestUpdate()})}get _labsIso(){return this._labs.active.includes("iso")}get _desiredProjection(){return"view"===this._mode&&this._labsIso&&"iso"===this._viewPreference[this._space]?"iso":"flat"}_saveViewPreference(){try{localStorage.setItem(ev,JSON.stringify(this._viewPreference))}catch{}}_logicalViewCenter(t){const e=this._view;if(!e)return null;const i=[e.x+e.w/2,e.y+e.h/2],s="iso"===t?Zg(i):i;return{x:s[0],y:s[1]}}_convertProjectionView(t,e){if(t===e)return;const i=this._logicalViewCenter(t);this._view=null;const s=i?"iso"===e?Xg([i.x,i.y],0):[i.x,i.y]:null;this._applyView(this._zoom,s?.[0],s?.[1]),this._warmPatch({vp:this._warmViewportState()}),this.requestUpdate()}_setProjection(t){if(!this._labsIso||"view"!==this._mode)return;const e=this._effectiveProjection();if(this._viewPreference={...this._viewPreference,[this._space]:t},"iso"===t){const t=this._isoSceneKey();t&&this._isoFallback.delete(t)}this._saveViewPreference();const i=this._effectiveProjection();this._convertProjectionView(e,i)}_hashSpace(){return Og(window.location.hash||"")}connectedCallback(){this._connectedPath=location.pathname,this._routeDepartureHandled=!1,window.addEventListener("location-changed",this._onLocationChanged),window.addEventListener("popstate",this._onLocationChanged),this._continuityDisposed&&(this._continuity=this._newContinuityController(),this._continuityDisposed=!1,this._continuityPaintToken=-1);const t=(e=this.ownerDocument,vg.get(e)?.resolved);var e;void 0!==t&&(this._glowScreenBlend=t),this._continuityUnsub?.(),this._continuityUnsub=vd(this.ownerDocument,this._pageVisibility),super.connectedCallback(),this._pointerModality.connect(this.ownerDocument.defaultView);const i=this.ownerDocument.defaultView?.MutationObserver;i&&(this._pointerHoverObserver=new i(t=>{for(const e of t)for(const t of e.addedNodes)this._syncPointerHoverSubtree(t)}),this._pointerHoverObserver.observe(this.renderRoot,{childList:!0,subtree:!0})),this._motionMedia=window.matchMedia?.("(prefers-reduced-motion: reduce)"),this._reducedMotion=!!this._motionMedia?.matches,this._motionMedia?.addEventListener?.("change",this._onMotionChange),function(t){const e=vg.get(t);if(e)return e.promise;const i={promise:Promise.resolve(!1)};return i.promise=bg(t).catch(()=>!1).then(t=>(i.resolved=t,t)),vg.set(t,i),i.promise}(this.ownerDocument).then(t=>{t!==this._glowScreenBlend&&(this._glowScreenBlend=t,this.isConnected&&this.requestUpdate())}),this.hass&&this._ensureHaRegistryAuthority(),window.addEventListener("keydown",this._keyHandler),this._signer.start(()=>this.hass,()=>Is(this._serverCfg)),this._syncCycleTimer(),window.addEventListener("hashchange",this._onHashChange),this._labsUnsub?.(),this._labsUnsub=function(t,e){Ug.add(e);const i=Kg(t);return"undefined"==typeof window&&e(i),()=>{Ug.delete(e)}}(Nf,this._onLabsSnapshot),this._booting?this._bootWatch():this._bootFading&&(clearTimeout(this._bootTimer),this._bootTimer=window.setTimeout(()=>{this._bootFading=!1},220)),this._bootSoft&&(clearTimeout(this._bootSoftTimer),this._bootSoftTimer=window.setTimeout(()=>{this._bootSoft=!1},qf)),!this._loadOk&&this._serverCfg&&this.hass&&this._scheduleLoadRetry(),!this._warmSlot&&this._config&&this._warmAdopt(),this._loadOk&&this._ensureLiveSyncSubscriptions(),this._warmVp&&!this._warmRevivePending&&void 0===this._warmReviveTimer&&(this._warmRevivePending=!0,this._warmReviveTimer=window.setTimeout(()=>this._warmReviveDialog(),0)),this._warmLongReturn&&this._beginResumeSettle(),this._warmLongReturn=!1,this.requestUpdate()}disconnectedCallback(){this._connectedPath&&location.pathname!==this._connectedPath&&this._leaveCardRoute(),window.removeEventListener("location-changed",this._onLocationChanged),window.removeEventListener("popstate",this._onLocationChanged),this._continuityUnsub?.(),this._continuityUnsub=void 0,this._motionMedia?.removeEventListener?.("change",this._onMotionChange),this._motionMedia=void 0,this._vacRaf&&(cancelAnimationFrame(this._vacRaf),this._vacRaf=0),this._refitRaf&&(cancelAnimationFrame(this._refitRaf),this._refitRaf=0),this._dayCycleTimer&&(clearInterval(this._dayCycleTimer),this._dayCycleTimer=0),this._dayCycleClockKey="",this._bootSettleRaf&&(cancelAnimationFrame(this._bootSettleRaf),this._bootSettleRaf=0),this._bootSettling=!1;for(const t of this._activityRt.values())clearTimeout(t.timer);window.removeEventListener("keydown",this._keyHandler),this._endTabDrag(),clearTimeout(this._tabSuppressClickTimer),this._tabSuppressClickTimer=void 0,this._tabSuppressClick=!1,clearInterval(this._cycleTimer),clearTimeout(this._kioskDotsTimer),clearTimeout(this._kioskHoldTimer),clearTimeout(this._reloadRetry),clearTimeout(this._loadRetryTimer),this._loadRetryTimer=void 0,this._connHooked?.removeEventListener?.("ready",this._onConnReady),this._connHooked?.removeEventListener?.("disconnected",this._onConnLost),this._connHooked?.removeEventListener?.("reconnect-error",this._onConnLost),this._connHooked=null,this._haRegistryRelease?.(),this._haRegistryRelease=void 0,this._haRegistryConnection=null,this._signer.dispose(),clearTimeout(this._toastTimer),clearTimeout(this._slideTimer),this._modeTransition.dispose(),this._modeTransitionVisual=null,this._modeTransitionPreparing=!1,this._modeTransitionForceAtomic=!1,this._modeTransitionRequest++,this._slideTimer=void 0,this._slide="",clearTimeout(this._bootTimer),this._bootTimer=void 0,clearTimeout(this._bootSoftTimer),this._saveConfigDebounced.flush(),window.removeEventListener("hashchange",this._onHashChange),this._labsUnsub?.(),this._labsUnsub=void 0,clearTimeout(this._holdTimer),this._roViewport?.disconnect(),this._roViewport=void 0,this._roHdr?.disconnect(),this._roHdr=void 0,this._onWinResize&&(window.removeEventListener("resize",this._onWinResize),this._onWinResize=void 0),this._unsubCfg&&(this._unsubCfg(),this._unsubCfg=null),this._unsubLayout&&(this._unsubLayout(),this._unsubLayout=null),this._unsubVirtual&&(this._unsubVirtual(),this._unsubVirtual=null),this._unsubTrail&&(this._unsubTrail(),this._unsubTrail=void 0),this._liveSyncGeneration++,this._liveSyncAttempt=null,this._liveSyncConnection=null,clearTimeout(this._layoutSyncTimer),clearTimeout(this._duplicateColumnTimer);for(const t of this._glowFadeTimers.values())clearTimeout(t);for(const t of this._glowEnterRafs.values())cancelAnimationFrame(t);clearTimeout(this._glowFeatherResumeTimer),this._glowFeatherResumeTimer=0,this._glowFeatherSuspendUntil=0,this._glowFadeTimers.clear(),this._glowEnterRafs.clear(),this._glowEnteringSources.clear(),this._glowRenderedSources.clear(),this._glowLastAppearance.clear(),this._glowSourceSeq=0,this._warmSnapshot(),this._warmRevivePending=!1,clearTimeout(this._warmReviveTimer),this._warmReviveTimer=void 0,this._warmRelease(),this._clearPlanSnapHover(),this._clearOpeningPlacement(!0),this._touchContacts.clear(),this._touchSequenceMultitouch=!1,this._touchClickBlockUntil=0,this._clearTransientHover(!0),this._cancelDevicePressFeedback(),this._pointerHoverObserver?.disconnect(),this._pointerHoverObserver=void 0,this._pointerModality.disconnect(),this._editorSecondary.reset(),this._resumeSettling=!1,this._continuityHistory=[...this._continuityHistory,...this._continuity.trace].slice(-80),this._continuity.dispose(),this._continuityDisposed=!0,super.disconnectedCallback()}_onKey(t){if("Escape"===t.key&&this._vacFit)return this._vacFit=null,this._showToast(this._t("vac.cal_cancelled")),void t.stopPropagation();if("Escape"===t.key){if(this._tapConfirm)return void(this._tapConfirm=null);if(this._vacCalConfirm)return void(this._vacCalConfirm=null);if(this._decorEraseConfirm)return void(this._decorEraseConfirm=null);if(this._openingInfo)return void(this._openingInfo=null);if(this._infoCard)return void this._closeInfoCard();if(this._rulesDialog)return void(this._rulesDialog=null);if(this._alignDialog)return this._alignDialog=null,void(this._preflightClipboardFallback=null);if(this._backupImportDialog)return void(this._backupImportDialog=null);if(this._backupExportDialog)return void(this._backupExportDialog=null);if(this._settingsDialog)return void(this._settingsDialog=null);if(this._markerDialog)return void(this._markerDialog=null);if(this._openingDialog)return void(this._openingDialog=null);if(this._physicalDialog)return void(this._physicalDialog=null);if(this._backdropDialog)return void(this._backdropDialog=null);if(this._decorShapeDialog)return void(this._decorShapeDialog=null);if(this._decorTextDialog)return void(this._decorTextDialog=null);if(this._spaceDialog&&!this._roomDialog)return this._spaceDialog=null,this._importQueue=[],void(this._importTotal=0);if(this._editorSecondary.hasOpenGroup)return t.preventDefault(),void this._editorSecondary.closeGroup(!0)}const e=t.composedPath?.()||[t.target],i=e.some(t=>t?.matches?.('input, textarea, select, [contenteditable="true"]')),s=e.some(t=>t?.classList?.contains?.("editor-secondary")),n=t.ctrlKey||t.metaKey,o=t.key.toLowerCase(),a=/^[a-z]$/.test(o),r="z"===o||!a&&"KeyZ"===t.code,l="y"===o||!a&&"KeyY"===t.code,c=n&&(r&&t.shiftKey||l),h=n&&r&&!t.shiftKey;if("decor"===this._mode){if((h||c)&&i)return;return c?(t.preventDefault(),void this._redoGeometry()):h?(t.preventDefault(),this._decorDraft?void(this._decorDraft=null):this._decorMove||this._dtDrag||this._bdDrag?void this._cancelDecorGesture():void this._undoGeometry()):"Delete"!==t.key&&"Backspace"!==t.key||!this._decorSel||i||s?void("Escape"===t.key&&(t.preventDefault(),this._decorDraft?this._decorDraft=null:this._decorMove||this._dtDrag||this._bdDrag?this._cancelDecorGesture():"furniture"===this._decorTool?(this._furnPalette=null,this._decorTool="select"):this._decorSel?this._decorSel=null:"select"!==this._decorTool?this._decorTool="select":this._setMode("view"))):(t.preventDefault(),void this._decorDeleteSel())}if(this._markup&&(!h&&!c||!i)){if(("Delete"===t.key||"Backspace"===t.key)&&this._physicalSel&&!i&&!s)return t.preventDefault(),void this._deletePhysicalSelection();if(c)return t.preventDefault(),void this._redoGeometry();if(h)return t.preventDefault(),this._rszDrag?void this._rszCancelDrag():this._wallFaceBatch?(this._roomDialogCancel(),void(this._activeDraftId&&this._path.length>1?this._undoActiveDraftPoint():this._undoPoint())):"draw"===this._tool&&this._path.length?void(this._activeDraftId&&this._path.length>1?this._undoActiveDraftPoint():this._undoPoint()):"split"===this._tool&&this._splitSel?.pts?.length?(this._splitSel={...this._splitSel,pts:this._splitSel.pts.slice(0,-1)},void(this._splitSel.pts.length||(this._cursorPt=null))):void this._undoGeometry();if("Escape"===t.key)return this._physicalDrag||this._physicalRotate?(t.preventDefault(),void this._cancelPhysicalGesture()):this._roomDialog?(t.preventDefault(),void this._roomDialogCancel()):"draw"===this._tool&&this._path.length?(t.preventDefault(),void this._finishWallChain()):this._physicalSel?(t.preventDefault(),void(this._physicalSel=null)):"resize"===this._tool?(t.preventDefault(),this._rszDrag?void this._rszCancelDrag():void(this._rszSel?this._rszSel=null:this._tool="draw")):"split"===this._tool?(t.preventDefault(),void(this._splitSel?.pts?.length?(this._splitSel={...this._splitSel,pts:this._splitSel.pts.slice(0,-1)},this._splitSel.pts.length||(this._cursorPt=null)):this._splitSel?this._splitSel=null:this._tool="draw")):"merge"===this._tool?(t.preventDefault(),void(this._mergeSel?this._mergeSel=null:this._tool="draw")):this._wallDialog?(t.preventDefault(),void(this._wallDialog=null)):void("opening"!==this._tool&&"wallthick"!==this._tool&&"delroom"!==this._tool&&"column"!==this._tool||(t.preventDefault(),"opening"===this._tool&&this._clearOpeningPlacement(!0),this._tool="draw"))}}_undoPoint(){if(this._path.length){if(this._contourClosed)return this._path=this._path.slice(0,-1),void(this._closingWallCm=null);if(this._activeDraftId&&this._path.length>1&&this._curSpaceCfg){const t=this._geometrySnapshot();this._path=this._path.slice(0,-1),this._draftSegmentCms=this._draftSegmentCms.slice(0,-1);const e=this._curSpaceCfg,i=(e.room_drafts||[]).findIndex(t=>t.id===this._activeDraftId);if(i>=0){const s=Array.isArray(e.room_drafts[i]?.segments)?e.room_drafts[i].segments:[];this._path.length<2?(e.room_drafts.splice(i,1),e.room_drafts.length||delete e.room_drafts,this._activeDraftId=null):e.room_drafts[i]={id:this._activeDraftId,points:this._path.map(t=>[t[0]/sv,t[1]/sv]),segments:this._draftSegmentCms.map((t,e)=>({...s[e]||{},cm:t}))},this._commitPhysicalGeometry(this._t("history.draft_segment_delete"),t)}return}this._path=this._path.slice(0,-1)}}_undoActiveDraftPoint(){const t=this._activeDraftId,e=this._path[0]?[...this._path[0]]:null,i=this._geometryHistory.undo();if(!i)return void this._undoPoint();if(!this._applyGeometryState(i.before,!0))return void this._geometryHistory.clear();const s=t?this._spaceModel()?.room_drafts.find(e=>e.id===t):null;s?(this._activeDraftId=s.id,this._path=s.points.map(t=>[...t]),this._draftSegmentCms=this._adoptDraftCms(this._path,s.segments.map(t=>t.cm),s.id),this._resumeDraftBySpace[this._space]=s.id):(this._activeDraftId=null,this._path=e?[e]:[],this._draftSegmentCms=[],t&&this._resumeDraftBySpace[this._space]===t&&delete this._resumeDraftBySpace[this._space]),this._clearPlanSnapHover(),this._showToast(this._t("history.undone",{name:i.name}))}static getConfigElement(){return document.createElement("houseplan-card-editor")}static getStubConfig(){return{type:"custom:houseplan-card"}}static _warmBootReset(t){for(const t of Gf.values())for(const e of t)clearTimeout(e.evict);Gf.clear(),Yf=t&&t>0?t:1e4}static _warmBootStats(){let t=0,e=0;const i=[];for(const s of Gf.values())for(const n of s)t++,n.dlg&&(e++,i.push(n.dlg.kind));return{keys:Gf.size,slots:t,dlgs:e,drafts:i}}setConfig(t){const e=this._config,i=!!e&&Object.prototype.hasOwnProperty.call(e,"floor");this._config={icon_size:2.5,show_temperature:!0,live_states:!0,show_signal:!0,...t};(i!==this._hasFixedFloor||e?.floor!==this._config.floor)&&(this._hashApplied=!1,this._navApplied=!1,this._warmVpArmed=!1),this._config.kiosk&&(this._booting=!1,this._bootFading=!1),!this._hasFixedFloor&&t.default_floor&&this._commitSpace(t.default_floor,!0);try{this._zoomBySpace=JSON.parse(localStorage.getItem(Zf)||"{}")||{}}catch{this._zoomBySpace={}}try{const t=JSON.parse(localStorage.getItem(ev)||"{}")||{};this._viewPreference=Object.fromEntries(Object.entries(t).filter(t=>"flat"===t[1]||"iso"===t[1]))}catch{this._viewPreference={}}this._labs=Kg(Nf);try{const t=JSON.parse(localStorage.getItem(tv)||"null");this._kioskScale={icon:Es(t?.icon),font:Es(t?.font)}}catch{}try{const t=JSON.parse(localStorage.getItem(Xf)||"null");t&&t.config&&Array.isArray(t.config.spaces)&&(this._serverCfg=t.config,this._cfgEpoch++,this._cfgRev=t.rev||0,this._cfgContentFingerprint=t.config_fingerprint||wd(t.config),this._layout=t.layout||{},this._layoutRev=t.layout_rev||0,this._layoutContentFingerprint=t.layout_fingerprint||wd(this._layout),this._virtualLights=mn(t.virtual_lights,this._cfgRev),this._serverStorage=!0)}catch{}this._adoptInitialSpace(this._model,this._loadOk),"view"!==this._mode||this._view||(this._zoom=this._zoomBySpace[this._space]||1),this.isConnected&&(this._syncCycleTimer(),this._warmAdopt(),this._warmLongReturn&&this._beginResumeSettle(),this._warmLongReturn=!1)}_warmAdopt(){if(this._config?.kiosk)return;const t=Kf(this._config);if(this._warmKey===t&&this._warmSlot)return;this._warmSlot&&this._warmRelease();const e=this.parentNode,i=this._warmIdx(e),s=Gf.get(t);if(!s||!s.length)return;const n=s.find(t=>t.owner===this._warmGen);if(n)return this._warmLongReturn=!!n.freed&&Date.now()-n.freed>=md,clearTimeout(n.evict),n.evict=0,n.freed=0,n.live=!0,this._warmSlot=n,this._warmKey=t,n.frameFingerprint&&this._continuity.adoptCompleteFrame(n.frameFingerprint),void(!this._devices.length&&n.devices?.length&&(this._devices=[...n.devices]));const{slot:o,sure:a}=((t,e,i,s)=>{const n=t=>{const e=!!i&&t.place?.deref()===i;return e&&t.idx===s?4:t.live?0:e?3:2};let o=null,a=0,r=0,l=null;for(const i of t){if(i.owner===e)continue;l=i;const t=n(i);t<=0||(t>a?(o=i,a=t,r=1):t===a&&r++)}return!o||r>1?{slot:o||l,sure:!1}:{slot:o,sure:!0}})(s,this._warmGen,e,i);o&&(this._warmLongReturn=!!o.freed&&Date.now()-o.freed>=md,this._booting=!1,this._bootFading=!1,this._hdrH=o.hdrH,this._bootSoft=!0,this.isConnected&&(clearTimeout(this._bootSoftTimer),this._bootSoftTimer=window.setTimeout(()=>{this._bootSoft=!1},qf)),this._warmKey=t,a?(clearTimeout(o.evict),o.evict=0,o.owner=this._warmGen,o.place=e?new WeakRef(e):null,o.idx=i,o.live=!0,this._warmSlot=o,this._warmVp=o.vp,o.frameFingerprint&&this._continuity.adoptCompleteFrame(o.frameFingerprint),!this._devices.length&&o.devices?.length&&(this._devices=[...o.devices]),this._warmAdoptViewport(this._config)):(this._warmSlot={owner:this._warmGen,path:location.pathname,place:e?new WeakRef(e):null,idx:i,live:!0,hdrH:o.hdrH,stageH:o.stageH,vp:null,frameFingerprint:"",devices:null,dlg:null,freed:0,evict:0},s.push(this._warmSlot),this._warmTrim(s)))}_warmIdx(t){const e=t?.children;if(!e)return-1;for(let t=0;t4;){const e=t.findIndex(t=>!t.live);if(e<0)break;clearTimeout(t[e].evict),t.splice(e,1)}}_warmScheduleEvict(t,e){if(clearTimeout(t.evict),!(t.dlg||t.vp&&"view"!==t.vp.mode))return;const i=t.freed,s=t.owner;t.evict=window.setTimeout(()=>{if(t.evict=0,t.freed!==i||t.owner!==s)return;var n;t.dlg=null,t.vp=(n=t.vp)&&"view"!==n.mode?{...n,mode:"view",zoom:n.snap?.space===n.space?n.snap.zoom:n.zoom,view:null,snap:null,tool:"draw",decorTool:"select",showHidden:!1,selId:null,rszSel:null,decorSel:null}:n,t.frameFingerprint="";const o=Gf.get(e);if(!t.live&&o&&o.length>1){const e=o.indexOf(t);e>=0&&o.splice(e,1)}},Yf+250)}_warmAdoptViewport(t){const e=this._warmVp;if(!e||this._warmSlot?.path!==location.pathname)return void(this._warmVp=null);const i=this._fixedFloorState();if(this._hashApplied||!this._model.find(t=>t.id===e.space)||"valid"===i.kind&&i.id!==e.space||this._hasFixedFloor&&"valid"!==i.kind)return void(this._warmVp=null);this._commitSpace(e.space,!0),this._navApplied=!0,this._adoptMode("view"!==e.mode&&this._canEdit&&!t.kiosk?e.mode:"view"),this._pendingNavMode="view"===e.mode||this._canEdit||t.kiosk?null:e.mode,this._zoom=e.zoom;const s=this._effectiveProjection(),n=s===e.projection&&this._labsIso===e.activeLabsIso;if(this._view=n&&e.view?{...e.view}:null,this._viewModeSnap=n&&e.snap?{...e.snap}:null,!n&&e.logicalCenter){const t="iso"===s?Xg([e.logicalCenter.x,e.logicalCenter.y],0):[e.logicalCenter.x,e.logicalCenter.y];this._applyView(e.zoom,t[0],t[1])}var o;this._tool="opening"===(o=function(t){return"partition"===t?"draw":t}(o=e.tool))?"draw":"string"==typeof o&&av.has(o)?o:"draw",this._decorTool=e.decorTool,this._showHidden=e.showHidden,this._showFar!==e.showFar&&(this._showFar=e.showFar,this._frame=null),this._selId=e.selId,this._rszSel=e.rszSel,this._decorSel=e.decorSel,this._warmVpArmed=!0}_warmPatch(t,e=!1){if(this._config?.kiosk)return;const i=Kf(this._config);if(!this._warmSlot||this._warmKey===i){if(!this._warmSlot){if(!e)return;const t=this.parentNode;this._warmKey=i,this._warmSlot={owner:this._warmGen,path:location.pathname,place:t?new WeakRef(t):null,idx:this._warmIdx(t),live:!0,hdrH:this._hdrH,stageH:0,vp:null,frameFingerprint:"",devices:null,dlg:null,freed:0,evict:0};const s=Gf.get(i)||[];for(s.push(this._warmSlot),Gf.set(i,s),this._warmTrim(s);Gf.size>8;){const t=Gf.keys().next().value;if(void 0===t||t===i)break;for(const e of Gf.get(t)||[])clearTimeout(e.evict);Gf.delete(t)}}Object.assign(this._warmSlot,t)}}_warmViewportState(){const t=this._effectiveProjection();return{space:this._space,mode:this._mode,projection:t,activeLabsIso:this._labsIso,logicalCenter:this._logicalViewCenter(t),zoom:this._zoom,view:this._view?{...this._view}:null,snap:this._viewModeSnap?{...this._viewModeSnap}:null,tool:this._tool,decorTool:this._decorTool,showHidden:this._showHidden,showFar:this._showFar,selId:this._selId,rszSel:this._rszSel,decorSel:this._decorSel}}_warmDialogState(){const t=(t,e)=>({kind:t,space:this._space,mode:this._mode,data:e});return this._tapConfirm||this._alignDialog||this._mergeDialog||this._importDialog||this._backupExportDialog||this._backupImportDialog?null:this._openingInfo?t("openingInfo",this._openingInfo.id):this._infoCard?t("info",this._infoCard.id):this._rulesDialog?this._rulesDialog.busy?null:t("rules",this._rulesDialog):this._settingsDialog?this._settingsDialog.busy?null:t("settings",this._settingsDialog):this._markerDialog?this._markerDialog.busy?null:t("marker",this._markerDialog):this._openingDialog?t("opening",this._openingDialog):this._backdropDialog?t("backdrop",this._backdropDialog):this._decorShapeDialog?t("decorShape",this._decorShapeDialog):this._decorTextDialog?t("decorText",this._decorTextDialog):this._roomDialog?t("room",{editId:this._roomEditId,fill:this._roomFill,customFill:this._roomCustomFill,tempSrc:this._roomTempSrc,humSrc:this._roomHumSrc,srcOpen:this._roomSrcOpen,srcFilter:this._roomSrcFilter,nameScale:this._roomNameScale,labelScale:this._roomLabelScale,areaSel:this._areaSel,nameSel:this._nameSel,pendingSplit:this._pendingSplit,wallFaceBatch:this._wallFaceBatch,path:this._path}):this._spaceDialog?this._spaceDialog.busy?null:t("space",this._spaceDialog):null}_warmSnapshot(){if(this._booting||this._config?.kiosk||"steady"!==this._continuity.state)return;const t={vp:this._warmViewportState(),frameFingerprint:this._continuity.frameFingerprint,devices:this._devices};if(this._warmRevivePending||(t.dlg=this._warmDialogState()),this.isConnected&&this._warmSlot?.owner===this._warmGen){const e=this.parentNode;t.place=e?new WeakRef(e):null,t.idx=this._warmIdx(e)}this._warmPatch(t)}_warmReviveDialog(){this._warmRevivePending=!1;const t=this._warmSlot;if(this._warmReviveTimer=void 0,!t||!t.dlg)return;const e=t.dlg,i=t.freed;if(t.dlg=null,t.freed=0,clearTimeout(t.evict),t.evict=0,i&&!(Date.now()-i>Yf)&&e.space===this._space&&e.mode===this._mode){switch(e.kind){case"space":this._spaceDialog={...e.data,busy:!1,savedBusy:!1};break;case"marker":this._markerDialog={...e.data,busy:!1};break;case"settings":this._settingsDialog={...e.data,busy:!1};break;case"rules":this._rulesDialog={...e.data,busy:!1};break;case"opening":this._openingDialog={...e.data};break;case"backdrop":this._backdropDialog={...e.data};break;case"decorShape":this._decorShapeDialog={...e.data};break;case"decorText":{this._decorTextDialog={...e.data};const t=String(this._decorTextDialog?.text??"").length;this._decorTextSelection={start:t,end:t};break}case"room":{const t=e.data;this._roomEditId=t.editId,this._roomFill=t.fill,this._roomCustomFill=t.customFill||null,this._roomTempSrc=t.tempSrc,this._roomHumSrc=t.humSrc,this._roomSrcOpen=t.srcOpen,this._roomSrcFilter=t.srcFilter,this._roomNameScale=t.nameScale,this._roomLabelScale=t.labelScale,this._areaSel=t.areaSel,this._nameSel=t.nameSel,this._pendingSplit=t.pendingSplit,this._wallFaceBatch=t.wallFaceBatch||null,this._path=t.path,this._wallFaceBatch&&(this._activeDraftId=this._wallFaceBatch.activeDraftId,this._draftSegmentCms=[...this._wallFaceBatch.activeCms]),this._roomDialog=!0;break}case"info":{const t=this._devices.find(t=>t.id===e.data);t&&(this._infoCard=t);break}case"openingInfo":{const t=(this._curSpaceCfg?.openings||[]).find(t=>t.id===e.data);t&&(this._openingInfo=t);break}}this.requestUpdate()}}_cacheSnapshot(){if(this._serverCfg)try{this._cfgContentFingerprint=wd(this._serverCfg),this._layoutContentFingerprint=wd(this._layout),this._virtualLights=function(t,e,i){if(t.configRev===i)return t;const s=new Set((Array.isArray(e?.markers)?e.markers:[]).filter(yn).map(t=>t.id));return{...t,configRev:i,off:new Set([...t.off].filter(t=>s.has(t)))}}(this._virtualLights,this._serverCfg,this._cfgRev),localStorage.setItem(Xf,JSON.stringify({config:this._serverCfg,rev:this._cfgRev,config_fingerprint:this._cfgContentFingerprint,layout:this._layout,layout_rev:this._layoutRev,layout_fingerprint:this._layoutContentFingerprint,virtual_lights:fn(this._virtualLights)}))}catch{}}_beginContinuityCandidate(t,e,i="plan"){return this._booting&&!this._continuity.hasCompleteFrame?this._continuity.token:(this._continuityDataReady=e,this._continuityPaintToken=-1,this._stagedDeviceSnapshotToken=-1,this._resumeSettling=!0,this._continuity.beginCandidate(t,i))}_continuityStageValid(){const t=this._stageEl;return!!t&&t.clientWidth>0&&t.clientHeight>0}_continuityAssetsReady(){if(!this._model.length)return!1;const t=this._model.length?this._spaceModel():null;return!t?.bg?.href||this._signer.isReady(this.hass,t.bg.href)}_initialSpaceSelection(t,e=this._loadOk){const i=this._fixedFloorState(t,e);return"valid"===i.kind?{id:i.id,source:"fixed"}:this._hasFixedFloor?{id:null,source:"none"}:function(t){const e=new Set(t.spaceIds.filter(t=>!!t));if(!e.size)return{id:null,source:"none"};const i=[["hash",!1===t.acceptHash?null:t.hashSpace],["current",t.preserveCurrent?t.currentSpace:null],["saved",t.savedSpace],["default",t.defaultSpace],["first",t.spaceIds[0]]];for(const[t,s]of i)if(s&&e.has(s))return{id:s,source:t};return{id:null,source:"none"}}({spaceIds:t.map(t=>t.id),hashSpace:this._hashSpace(),acceptHash:!this._hashApplied,currentSpace:this._space,preserveCurrent:this._hashApplied||this._navApplied||this._warmVpArmed,savedSpace:this._savedNav()?.space,defaultSpace:this._config?.default_floor})}_adoptInitialSpace(t,e=this._loadOk){const i=this._initialSpaceSelection(t,e);return i.id?(this._commitSpace(i.id,!0),"hash"===i.source&&(this._hashApplied=!0),"saved"===i.source&&(this._navApplied=!0),i):i}_candidateBackdrop(t,e=this._space){const i=Sh(t),s=this._fixedFloorState(i,!0);if(this._hasFixedFloor&&"valid"!==s.kind)return"";const n=this._initialSpaceSelection(i,!0).id||(i.some(t=>t.id===e)?e:i[0]?.id);return i.find(t=>t.id===n)?.bg?.href||""}_visualFrameFingerprint(){const t=this._stageEl,e=t?[t.clientWidth,t.clientHeight]:[0,0];return kd([this._cfgRev,this._cfgContentFingerprint||wd(this._serverCfg),this._layoutRev,this._layoutContentFingerprint||wd(this._layout),this._space,this._mode,this._view,e,this._glowScreenBlend?"screen":"normal",this.hass?.themes?.darkMode??this.hass?.themes?.default_theme??""])}_settleContinuityFrame(){if(this._booting||!this._continuityStageValid())return;if(!this._continuity.hasCompleteFrame&&"steady"===this._continuity.state)return void(this._continuityAssetsReady()&&(this._renderSnapshotAt=Date.now(),this._continuity.markCompleteFrame(this._visualFrameFingerprint())));if(!this._continuityDataReady)return;if(!["holding","offline-stale","overlay-pending","overlay-visible","candidate-ready"].includes(this._continuity.state))return;const t=this._continuity.token;if(this._candidateDeviceSnapshot&&this._candidateDeviceSnapshot!==this._visibleDeviceSnapshot&&this._stagedDeviceSnapshotToken!==t)return this._stagedDeviceSnapshotToken=t,void this.requestUpdate();this._continuityPaintToken!==t&&(this._continuityPaintToken=t,this._continuity.candidateReady(t)&&this._continuity.commitAfterPaint(t,{updateComplete:()=>this.updateComplete,stageValid:()=>this.isConnected&&this._continuityStageValid(),assetsReady:()=>this._continuityAssetsReady(),frameFingerprint:()=>this._visualFrameFingerprint()}).then(e=>{e&&t===this._continuity.token?(this._resumeSettling=!1,this._renderSnapshotAt=Date.now(),this._candidateDeviceSnapshot&&(this._visibleDeviceSnapshot=this._candidateDeviceSnapshot),this._candidateDeviceSnapshot=null,this._stagedDeviceSnapshotToken=-1,this._warmSnapshot()):t===this._continuity.token&&(this._continuityPaintToken=-1,this._stagedDeviceSnapshotToken=-1,this._candidateDeviceSnapshot=null,this.requestUpdate())}))}_onBackdropLoaded(t,e){this._signer.markLoaded(this.hass,t,e),this._continuity.note("asset-ready"),this._continuityPaintToken=-1,"steady"!==this._continuity.state&&this.requestUpdate()}_renderRecoveryOverlay(){if(!this._continuity.overlayVisible&&"recovery-error"!==this._continuity.state)return G;const t="connection"===this._continuity.recoveryReason;return W`
`}afterRender(){const t=this.host.root();this._blocked&&(this._openGroupId?this.closeGroup(!1):"palette"===this._currentModel?.kind&&this._currentModel.dismiss?.()),this._syncGlobalDismissListener();const e=t.querySelector(".editor-secondary"),i=this._renderedContext,s=e?.dataset.contextId||"";if(s&&i&&s!==i&&!window.matchMedia?.("(prefers-reduced-motion: reduce)")?.matches&&(this._contentAnimation?.cancel(),this._contentAnimation=e?.querySelector(".editor-secondary-content")?.animate([{opacity:.35,transform:"translateY(-4px)"},{opacity:1,transform:"translateY(0)"}],{duration:100,easing:"ease-out"})),this._renderedContext=s,i&&s!==i&&this._focusOwned){const i=s?e?.querySelector('[tabindex="0"], button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled])'):t.querySelector(".editbar-tools");i?.focus?.(),this._focusOwned=!!s}if("palette"===this._currentModel?.kind&&this._currentModel.launcherId){const e=[...t.querySelectorAll("[data-editor-palette]")].find(t=>t.dataset.editorPalette===this._currentModel?.launcherId);e&&null!==e.offsetParent||this._currentModel.dismiss?.()}if(!this._openGroupId)return;const n=[...t.querySelectorAll("[data-editor-group]")].find(t=>t.dataset.editorGroup===this._openGroupId);n&&null!==n.offsetParent||this.closeGroup(!0)}handleOutsideDismiss(t){if(q_(t,t=>t.hasAttribute("data-editor-navigation")))return"pointerdown"===t.type?this.closeForNavigation():"click"===t.type&&this._dismissPointerTarget&&this._clearDismissClick(),!1;if("click"===t.type&&this._dismissPointerTarget){return!!(t.composedPath?.()||[t.target]).includes(this._dismissPointerTarget)&&(this._clearDismissClick(),t.preventDefault(),t.stopImmediatePropagation(),!0)}const e=this._openGroupId||this._blocked||"palette"!==this._currentModel?.kind?null:this._currentModel;if("pointerdown"===t.type&&(this._openGroupId||e)){const i=q_(t,t=>t.classList.contains("editor-secondary")),s=q_(t,t=>!!t.dataset.editorGroup),n=q_(t,t=>!!t.dataset.editorPalette),o=q_(t,t=>t.classList.contains("stage"));if(!(i||s||n||"stay-open-on-canvas"===e?.dismissPolicy&&o))return t.preventDefault(),t.stopImmediatePropagation(),this._dismissPointerTarget=t.target,clearTimeout(this._dismissTimer),this._dismissTimer=window.setTimeout(()=>{this._clearDismissClick()},800),this._openGroupId?this.closeGroup(!1):e?.dismiss?.(),this._syncGlobalDismissListener(),!0}return!1}_activateGroupItem(t,e,i){if(t.id!==this._openGroupId)return;const s=t.items.find(t=>t.id===e);if(!s||s.disabled)return;const n="toggle"===s.role&&"stay-open"===s.closePolicy,o=0===i.detail;n||(this._openGroupId=null,this.host.requestUpdate(),this._syncGlobalDismissListener()),s.invoke(),!n&&o&&this.host.updateComplete().then(()=>{const e=[...this.host.root().querySelectorAll("[data-editor-group]")].find(e=>e.dataset.editorGroup===t.id&&null!==e.offsetParent);e?.focus()})}_groupKeydown(t){if(!["ArrowLeft","ArrowRight","Home","End"].includes(t.key))return;const e=[...t.currentTarget.querySelectorAll(".editor-group-item:not([disabled])")];if(!e.length)return;t.preventDefault();const i=e.indexOf(this.host.root().activeElement),s="Home"===t.key?0:"End"===t.key?e.length-1:"ArrowLeft"===t.key?i<=0?e.length-1:i-1:(i+1)%e.length;e[s]?.focus()}_clearDismissClick(){this._dismissPointerTarget=null,clearTimeout(this._dismissTimer),this._dismissTimer=void 0,this._syncGlobalDismissListener()}_syncGlobalDismissListener(){const t=!this._blocked&&"palette"===this._currentModel?.kind,e=!!this._openGroupId||t||!!this._dismissPointerTarget;e!==this._globalDismissListening&&(this._globalDismissListening=e,e?(window.addEventListener("pointerdown",this._globalDismissGuard,!0),window.addEventListener("click",this._globalDismissGuard,!0)):(window.removeEventListener("pointerdown",this._globalDismissGuard,!0),window.removeEventListener("click",this._globalDismissGuard,!0)))}}const j_=t=>t.stopPropagation(),U_=4.166666666666667e-9;function G_(t){return Number.isFinite(t)?Math.round(t/Th)*Th:t}const V_=(t,e,i,s)=>Math.hypot(i-t,s-e),K_=(t,e,i,s,n,o,a,r)=>Math.hypot(Math.max(Math.abs(n-t),Math.abs(n+a-(t+i))),Math.max(Math.abs(o-e),Math.abs(o+r-(e+s)))),Y_=(t,e,i,s,n,o,a)=>{const r=Math.max(Number(s)||0,0)/2,l=Math.PI/180,c=Math.cos(i*l)*r,h=Math.sin(i*l)*r,d=Math.cos(a*l)*r,p=Math.sin(a*l)*r,u=Math.max(V_(t+c,e+h,n+d,o+p),V_(t-c,e-h,n-d,o-p)),_=Math.max(V_(t+c,e+h,n-d,o-p),V_(t-c,e-h,n+d,o+p));return Math.min(u,_)},J_=t=>{const e=Number(t?.cell_cm);return e>0?e:5};function X_(t,e){const i=JSON.parse(JSON.stringify(t||[])),s=JSON.parse(JSON.stringify(e||{}));let n=0,o=0,a=0,r=0,l="",c=0,h=0,d=0;const p=(t,e)=>{Number.isFinite(t)&&Number.isFinite(e)&&t!==e&&Math.abs(e-t)<=U_&&h++},u=(t,e)=>{p(t[0],e[0]),p(t[1],e[1])},_={};let m=5;for(const t of i){const e=J_(t);null!=t?.id&&(_[String(t.id)]=e),e>m&&(m=e)}const g=(t,e,i,s=!1)=>{if(!(t>U_||s))return;n++,t>a&&(a=t);const o=t*Dh*e;o>r&&(r=o,l=i)};for(const t of i){const e=J_(t),i=null!=t?.id?String(t.id):"";for(const s of t.rooms||[]){o++;let t=0;if(s.poly?.length)s.poly=s.poly.map(e=>{const i=[G_(e[0]),G_(e[1])];return t=Math.max(t,V_(e[0],e[1],i[0],i[1])),u(e,i),i});else if(null!=s.x&&null!=s.y){const e=s.x,i=s.y,n=s.w||0,o=s.h||0,a=G_(e+n),r=G_(i+o),l=G_(e),c=G_(i),h=Math.max(Th,a-l),d=Math.max(Th,r-c);t=K_(e,i,n,o,l,c,h,d),s.x=l,s.y=c,s.w=h,s.h=d,p(e,l),p(i,c),p(e+n,l+h),p(i+o,c+d)}g(t,e,i)}for(const s of t.room_drafts||[]){o++;let t=0;const n=s.points||[],a=n.map(e=>{const i=[G_(e[0]),G_(e[1])];return t=Math.max(t,V_(e[0],e[1],i[0],i[1])),i}),r=a.length?[a[0]]:[],l=a.length?[[n[0],a[0]]]:[],c=[];for(let t=0;t+1=2)for(const[t,e]of l)u(t,e);g(t,e,i)}if(Array.isArray(t.room_drafts)){const e=t.room_drafts.length;t.room_drafts=t.room_drafts.filter(t=>t.points?.length>=2),d+=e-t.room_drafts.length,t.room_drafts.length||delete t.room_drafts}for(const s of t.partitions||[]){o++;const n=[s.a[0],s.a[1]],a=[s.b[0],s.b[1]],r=[G_(n[0]),G_(n[1])],l=[G_(a[0]),G_(a[1])];let c=Math.max(V_(n[0],n[1],r[0],r[1]),V_(a[0],a[1],l[0],l[1]));const h=V_(r[0],r[1],l[0],l[1]),d=(t.openings||[]).filter(t=>"partition"===t.host?.kind&&t.host.id===s.id).every(t=>{const e=Number(t.length),i=Number(t.host.t),s=i*h;return Number.isFinite(e)&&e>0&&Number.isFinite(i)&&i>=0&&i<=1&&s-e/2>=-U_&&s+e/2<=h+U_});h>U_&&d?(s.a=r,s.b=l,u(n,r),u(a,l)):c=0,g(c,e,i)}for(const s of t.wall_columns||[]){o++;const t=[s.center[0],s.center[1]],n=[G_(t[0]),G_(t[1])],a=V_(t[0],t[1],n[0],n[1]);s.center=n,u(t,n),g(a,e,i)}for(const s of t.decor||[]){o++;let t=0;if("line"===s.kind){const e=[s.x1,s.y1],i=[s.x2,s.y2],n=[G_(e[0]),G_(e[1])],o=[G_(i[0]),G_(i[1])];t=Math.max(V_(e[0],e[1],n[0],n[1]),V_(i[0],i[1],o[0],o[1])),s.x1=n[0],s.y1=n[1],s.x2=o[0],s.y2=o[1],u(e,n),u(i,o)}else{const e=s.x,i=s.y,n=s.w,o=s.h,a=G_(e),r=G_(i);if(null!=s.w&&null!=s.h){const l=G_(e+n),c=G_(i+o),h=Math.max(Th,l-a),d=Math.max(Th,c-r);t=K_(e,i,n,o,a,r,h,d),s.w=h,s.h=d,p(e+n,a+h),p(i+o,r+d)}else t=V_(e,i,a,r);s.x=a,s.y=r,p(e,a),p(i,r)}g(t,e,i)}for(const s of t.openings||[]){if(o++,"partition"===s.host?.kind){const n=(t.partitions||[]).find(t=>t.id===s.host.id),o=Number(s.host.t);if(!n||!Number.isFinite(o)||o<0||o>1)continue;const a=n.b[0]-n.a[0],r=n.b[1]-n.a[1];if(Math.hypot(a,r)<=U_)continue;const l=n.a[0]+a*o,h=n.a[1]+r*o;let d=180*Math.atan2(r,a)/Math.PI;d>=90?d-=180:d<-90&&(d+=180);const p=Number(s.angle),u=!(Number.isFinite(p)&&p===d),_=Y_(s.x,s.y,Number.isFinite(p)?p:d,Number(s.length)||0,l,h,d);s.x=l,s.y=h,s.angle=d,u&&c++,g(_,e,i,u);continue}const n=ui([s.x,s.y],t.rooms||[],.025,{step:Th,length:Number(s.length)||0});if(!n)continue;const a=Number(s.angle),r=!(Number.isFinite(a)&&a===n.angle),l=Y_(s.x,s.y,Number.isFinite(a)?a:n.angle,Number(s.length)||0,n.x,n.y,n.angle);s.x=n.x,s.y=n.y,s.angle=n.angle,r&&c++,g(l,e,i,r)}}for(const[t,e]of Object.entries(s)){if(!e||"object"!=typeof e)continue;const i=e;if("number"!=typeof i.x||"number"!=typeof i.y)continue;o++;const n=G_(i.x),a=G_(i.y),r=V_(i.x,i.y,n,a);s[t]={...i,x:n,y:a},p(i.x,n),p(i.y,a);const l="string"==typeof i.s?i.s:"";g(r,_[l]??m,l)}return{spaces:i,layout:s,report:{moved:n,coordsCanonicalized:h,total:o,maxShift:a,maxShiftCm:r,maxSpace:l,rotated:c,removedDrafts:d},changed:n>0||h>0}}function Z_(t,e){const i=e.base+t*e.span;return Math.min(1,Math.max(0,i))}const Q_=t=>Array.isArray(t)&&t.length>=2&&Number.isFinite(t[0])&&Number.isFinite(t[1]),tm=(t,e)=>Math.hypot(t[0]-e[0],t[1]-e[1]);function em(t,e,i){const s=i[0]-e[0],n=i[1]-e[1],o=s*s+n*n;if(o<=0)return tm(t,e);let a=((t[0]-e[0])*s+(t[1]-e[1])*n)/o;return a=Math.max(0,Math.min(1,a)),Math.hypot(t[0]-(e[0]+s*a),t[1]-(e[1]+n*a))}function im(t,e,i,s,n){for(const s of e)if(s&&!i.has(s.id)&&Q_(s.a)&&Q_(s.b)&&(tm(t,s.a)<=n||tm(t,s.b)<=n))return!0;for(const e of s?.roomPolygons||[])for(let i=0;i0&&r>0))return null;if(Math.abs(n[0]/a*(o[1]/r)-n[1]/a*(o[0]/r))>i)return null;for(const[i,n]of[[t.a,e.a],[t.a,e.b],[t.b,e.a],[t.b,e.b]])if(tm(i,n)<=s)return[(i[0]+n[0])/2,(i[1]+n[1])/2];return null}function nm(t,e){const i=.05*(Number(e.pitch)>0?Number(e.pitch):1),s=new Map;let n=(t||[]).filter(t=>!!t&&"string"==typeof t.id&&Q_(t.a)&&Q_(t.b));if(n.length<2)return{partitions:[...t||[]],merged:0,openingMoves:[]};const o=e.seedIds&&e.seedIds.length?new Set(e.seedIds):null;let a=0;for(let t=0;ttm(e,t.at)>i);let h=c[0]??r.a,d=c[c.length-1]??l.b;if(c.length<2&&(h=r.a,d=l.b),d[0]0?(d[0]-h[0])/u:0,m=u>0?(d[1]-h[1])/u:0,g=t=>u>0?((t[0]-h[0])*_+(t[1]-h[1])*m)/u:0;for(const t of[r,l]){const e=g(t.a),i=g(t.b)-e;for(const[n,o]of s)o.toId===t.id&&s.set(n,{fromId:o.fromId,toId:p.id,base:e+o.base*i,span:o.span*i});s.set(t.id,{fromId:t.id,toId:p.id,base:e,span:i})}o&&o.add(p.id),n=n.filter((e,i)=>i!==t.i&&i!==t.j),n.splice(t.i,0,p),a++}return{partitions:n,merged:a,openingMoves:[...s.values()]}}function om(t,e,i,s){if(!t?.length||!i.length)return 0;const n=new Map(i.map(t=>[t.fromId,t]));let o=0;for(const i of t){const t=i?.host;if(!t||"partition"!==t.kind)continue;const a=n.get(t.id);if(!a)continue;i.host={...t,id:a.toId,t:Z_(t.t,a)},o++;const r=Sp(i,e,s.coordScale,s.cellCm,s.gridPitch).resolved;r&&Object.assign(i,Ip(i,r,s.coordScale))}return o}function am(t,e){const i=e?.excludeDraftId||null;return{roomPolygons:(t?.rooms||[]).map(t=>hi(t)).filter(t=>!!t),columns:t?.wall_columns||[],draftEnds:(t?.room_drafts||[]).flatMap(t=>{if(i&&t?.id===i)return[];const e=t?.points||[];return e.length?[e[0],e[e.length-1]]:[]})}}const rm=t=>!!t&&t.length>=2&&Number.isFinite(t[0])&&Number.isFinite(t[1]),lm=(t,e)=>t[0]-e[0]||t[1]-e[1],cm=(t,e,i,s)=>[t[0]+e*s,t[1]+i*s],hm=(t,e,i,s)=>(t[0]-e[0])*i+(t[1]-e[1])*s,dm=(t,e,i,s,n)=>{const o=e[0]-t[0],a=e[1]-t[1],r=Math.hypot(o,a);if(!(r>n))return null;const l=o/r,c=a/r,h=e=>Math.abs((e[0]-t[0])*c-(e[1]-t[1])*l);if(h(i)>n||h(s)>n)return null;const d=hm(i,t,l,c),p=hm(s,t,l,c),u=Math.max(0,Math.min(d,p)),_=Math.min(r,Math.max(d,p));return _-u>n?{lo:u,hi:_}:null},pm=(t,e,i)=>Math.min(t.hi,e.hi)-Math.max(t.lo,e.lo)>i,um=t=>{const e=new Set(["id","a","b","cm"]);return Object.keys(t||{}).every(t=>e.has(t))},_m=(t,e,i,s)=>{const n=t.b[0]-t.a[0],o=t.b[1]-t.a[1],a=Math.hypot(n,o);if(!(a>s))return!0;const r=n/a,l=o/a,c=gl(t.cm,i.cellCm,i.gridPitch)/2;return e.some(e=>{const n=e?.center;if(!rm(n))return!0;const o=hm(n,t.a,r,l),h=Math.abs((n[0]-t.a[0])*l-(n[1]-t.a[1])*r),d=gl(Number(e.cm),i.cellCm,i.gridPitch)*("square"===e.shape?Math.SQRT1_2:.5);return!(Number.isFinite(d)&&d>0)||o>=-d-s&&o<=a+d+s&&h<=c+d+s})},mm=(t,e,i)=>{if(t.host){const s=Sp(t,e,i.coordScale,i.cellCm,i.gridPitch).resolved;return s?{center:s.center,angle:s.angle,length:s.length}:null}const s=Number(t.x)*i.coordScale,n=Number(t.y)*i.coordScale,o=Number(t.angle),a=Number(t.length)*i.coordScale;return[s,n,o,a].every(Number.isFinite)&&a>0?{center:[s,n],angle:o,length:a}:null},gm=(t,e,i)=>{const s=t.angle*Math.PI/180,n=Math.cos(s),o=Math.sin(s),a=e.angle*Math.PI/180,r=Math.cos(a),l=Math.sin(a);if(Math.abs(n*l-o*r)>1e-6)return!1;const c=e.center[0]-t.center[0],h=e.center[1]-t.center[1];if(Math.abs(c*o-h*n)>i)return!1;const d=c*n+h*o;return Math.max(-t.length/2,d-e.length/2)({...t,a:[t.a[0]*e,t.a[1]*e],b:[t.b[0]*e,t.b[1]*e]}),vm=(t,e,i,s)=>{const n=`~r-${(t=>{let e=2166136261;for(let i=0;i>>0;return e.toString(36)})(`${t}|${e[0].toFixed(9)},${e[1].toFixed(9)}|${i[0].toFixed(9)},${i[1].toFixed(9)}`)}`,o=`${t.slice(0,Math.max(1,64-n.length))}${n}`;let a=o;for(let t=2;s.has(a);t++){const e=`-${t}`;a=`${o.slice(0,64-e.length)}${e}`}return s.add(a),a},ym=(t,e)=>{const i=[];for(const s of t){const t=i[i.length-1];!(t&&Math.abs(t.hi-s.lo)<=e&&t.safe===s.safe)||s.safe&&t.signature!==s.signature?i.push({lo:s.lo,hi:s.hi,a:s.a,b:s.b,safe:s.safe,signature:s.signature,roomIds:s.roomIds,finalCm:s.finalCm}):(t.hi=s.hi,t.b=s.b)}return i};function bm(t,e,i,s,n){const o=i||[],a=Array.isArray(t?.partitions)?t.partitions:[],r=Array.isArray(t?.openings)?t.openings:[],l=Array.isArray(t?.room_drafts)?t.room_drafts:[],c={walls:o,partitions:a,openings:r,roomDrafts:l,partitionsReconciled:0,openingsRehosted:0,removedDrafts:0};if(!a.length&&!l.length)return c;const h=Math.max(2e-4*n.gridPitch,1e-9);let d=o,p=a,u=r;const _=dc(e.rooms,d,s,n.pitch,n.cellCm,n.gridPitch,n.coordScale),m=((t,e,i,s)=>{const n=new Map(t.map(t=>[t.id,t])),o=new Set;for(const t of e){if(!n.get(t.id)||!Array.isArray(t.points)||t.points.length<2||t.segments.length!==t.points.length-1)continue;let e=!0;for(let n=0;n+10)){e=!1;break}const l=Math.hypot(a[0]-o[0],a[1]-o[1]);if(!(l>s)){e=!1;break}const c=i.flatMap(t=>{const e=t.cm>0?t.cm:ll;if(t.open||"outer"!==t.kind&&"shared"!==t.kind||e+st.lo-e.lo||t.hi-e.hi);let h=0;for(const t of c){if(t.lo>h+s)break;if(h=Math.max(h,t.hi),h>=l-s)break}h!m.has(t.id));let f=0,v=0;const y=new Map(e.partitions.map(t=>[t.id,t]));for(const t of[...a].sort((t,e)=>t.id.localeCompare(e.id))){if(!p.some(e=>e.id===t.id))continue;if(!um(t))continue;const i=y.get(t.id);if(!(i&&rm(i.a)&&rm(i.b)&&Number.isFinite(i.cm)&&i.cm>0))continue;const[o,a]=lm(i.a,i.b)<=0?[[i.a[0],i.a[1]],[i.b[0],i.b[1]]]:[[i.b[0],i.b[1]],[i.a[0],i.a[1]]],r=a[0]-o[0],l=a[1]-o[1],c=Math.hypot(r,l);if(!(c>h))continue;const _=r/c,g=l/c,b=dc(e.rooms,d,s,n.pitch,n.cellCm,n.gridPitch,n.coordScale),w=b.flatMap(t=>{if(t.open||"outer"!==t.kind&&"shared"!==t.kind)return[];const e=dm(o,a,t.a,t.b,h);return e?[{interval:t,range:e}]:[]});if(!w.length)continue;const k=u.filter(t=>"partition"===t.host?.kind&&t.host.id===i.id).map(t=>({opening:t,resolved:Sp(t,e.partitions,n.coordScale,n.cellCm,n.gridPitch).resolved}));if(k.some(t=>!t.resolved))continue;const x=[0,c];for(const{range:t}of w)x.push(t.lo,t.hi);const $=x.slice(),S=new Map;for(const{opening:t,resolved:e}of k){const i=hm(e.center,o,_,g),s={lo:i-e.length/2,hi:i+e.length/2};S.set(t.id,s),$.push(Math.max(0,s.lo),Math.min(c,s.hi))}const M=[...new Set($.filter(t=>Number.isFinite(t)&&t>=-h&&t<=c+h).map(t=>Math.max(0,Math.min(c,t)).toFixed(9)))].map(Number).sort((t,e)=>t-e),C=p.map(t=>fm(t,n.coordScale)).filter(t=>t.id!==i.id),D=e.room_drafts.filter(t=>!m.has(t.id)),P=[];for(let t=0;t+1h))continue;const r=cm(o,_,g,s),l=cm(o,_,g,a),c=w.filter(({range:t})=>t.lo<=s+h&&t.hi>=a-h).map(({interval:t})=>t),d=new Map;for(const t of c)d.set(t.roomId,t);const p=[...d.values()],u=new Set(p.map(t=>t.kind)),m=new Set(p.map(t=>t.cm>0?t.cm:ll)),f=p[0]?.kind,v=[...d.keys()].sort(),y=1===u.size&&1===m.size&&("outer"===f&&1===v.length||"shared"===f&&2===v.length),b={id:i.id,a:r,b:l,cm:i.cm},k=C.some(t=>!!dm(r,l,t.a,t.b,h)),x=D.some(t=>t.points.some((e,i)=>i+10?p[0].cm:ll:0,T=y?Math.max(S,i.cm):i.cm;P.push({lo:s,hi:a,a:r,b:l,safe:$,signature:$?`${f}|${v.join(",")}|${T}`:"",roomIds:v,roomCm:S,finalCm:T})}if(!P.some(t=>t.safe))continue;const T=new Map;for(const{opening:t,resolved:e}of k){const s=S.get(t.id),o=x.some(t=>t>s.lo+h&&tpm(t,s,h)),r=new Set(a.filter(t=>t.safe).map(t=>t.signature));if(!o&&a.length>0&&a.every(t=>t.safe)&&1===r.size&&Rp(e,b,h)){T.set(t.id,{resolved:e,signature:[...r][0]});continue}const l=xp(i,n.cellCm,n.gridPitch),c={lo:s.lo-l,hi:s.hi+l};for(const t of P)pm(t,c,h)&&(t.safe=!1,t.signature="")}let R=!0;for(;R;){R=!1;for(const[t,e]of[...T.entries()]){const s=S.get(t),o=P.filter(t=>pm(t,s,h));if(o.length>0&&o.every(t=>t.safe)&&o.every(t=>t.signature===e.signature))continue;T.delete(t);const a=xp(i,n.cellCm,n.gridPitch),r={lo:s.lo-a,hi:s.hi+a};for(const t of P)pm(t,r,h)&&(t.safe=!1,t.signature="");R=!0}}const I=ym(P,h),A=I.filter(t=>t.safe),z=I.filter(t=>!t.safe);if(!A.length)continue;if(p.length-1+z.length>2e3)continue;let F=d;for(const t of A){const[e,s]=lm(i.a,i.b)<=0?[t.a,t.b]:[t.b,t.a];F=Fl(F,e,s,t.finalCm,n.pitch,n.coordScale)}if(F=uc(e.rooms,F,s,n.pitch,n.cellCm,n.gridPitch,n.coordScale),F.length>500)continue;const E=new Set(p.map(t=>t.id));E.delete(i.id);const N=z.map((t,e)=>{const s=[t.a[0]/n.coordScale,t.a[1]/n.coordScale],o=[t.b[0]/n.coordScale,t.b[1]/n.coordScale],a=0===e?i.id:vm(i.id,s,o,E);return E.add(a),{id:a,a:s,b:o,cm:i.cm}}),O=p.findIndex(t=>t.id===i.id),L=p.slice();L.splice(O,1,...N);const H=L.map(t=>fm(t,n.coordScale)),B=new Map;let q=!0;for(const{opening:t,resolved:e}of k){const i=T.get(t.id);if(i){const e=Ip(t,i.resolved,n.coordScale),{host:s,...o}=e;B.set(t.id,o);continue}const s=S.get(t.id),o=N[z.findIndex(t=>t.lo<=s.lo+h&&t.hi>=s.hi-h)],a=o&&H.find(t=>t.id===o.id);if(!o||!a){q=!1;break}const r=a.b[0]-a.a[0],l=a.b[1]-a.a[1],c=Math.hypot(r,l),d=hm(e.center,a.a,r/c,l/c),p={...Ip(t,e,n.coordScale),host:{kind:"partition",id:o.id,t:d/c}};if(!Mp(p,H,n.coordScale,n.cellCm,n.gridPitch).resolved){q=!1;break}B.set(t.id,p)}if(!q)continue;const W=u.map(t=>B.get(t.id)||t),j=[...T.keys()].map(t=>B.get(t)),U=j.map(t=>mm(t,H,n));if(U.some(t=>!t))continue;let G=!1;for(let t=0;tt.id));for(const t of W){if(V.has(t.id))continue;const e=mm(t,H,n);e&&U.some(t=>gm(t,e,h))&&(G=!0)}if(G)continue;const K=Ec(e.rooms,F,s,n.pitch,n.cellCm,n.gridPitch,n.coordScale);[...T.entries()].every(([t,e])=>{const i=B.get(t),s=Lc(K,{x:i.x*n.coordScale,y:i.y*n.coordScale,angle:i.angle,length:i.length*n.coordScale},!0),o=[s.negative,s.positive].filter(t=>!!t?.full),a=e.signature.split("|")[1].split(","),r=new Set(o.map(t=>t.roomId));return o.length===a.length&&r.size===a.length&&a.every(t=>r.has(t))})&&(d=F,p=L,u=W,f+=A.length,v+=T.size)}return{walls:d,partitions:p,openings:u,roomDrafts:g,partitionsReconciled:f,openingsRehosted:v,removedDrafts:m.size}}const wm=t=>JSON.parse(JSON.stringify(t)),km=(t,e)=>Object.prototype.hasOwnProperty.call(t,e),xm=(t,e)=>e.length>0&&e.length<=35&&("space"===t?/^[a-z0-9_-]+$/.test(e):/^[A-Za-z0-9_-]+$/.test(e));function $m(t,e){let i=String(e??"");const s=t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),n=new RegExp(`^${s}_(.+)_([0-9a-f]{8})$`);let o=0;for(;o<16;o++){const t=n.exec(i);if(!t)return{root:i,layers:o,bounded:!1};i=t[1]}return{root:i,layers:o,bounded:n.test(i)}}const Sm=(t,e,i)=>{const s=t.get(e)||[];s.push(i),t.set(e,s)};const Mm=1e-9;class Cm extends Error{constructor(t,e=""){super(e?`${t}: ${e}`:t),this.reason=t,this.name="WallSegmentModelError"}}const Dm=t=>JSON.parse(JSON.stringify(t)),Pm=t=>Array.isArray(t)&&t.length>=2&&Number.isFinite(Number(t[0]))&&Number.isFinite(Number(t[1])),Tm=t=>[Number(t[0]),Number(t[1])],Rm=t=>`${Number(t[0]).toFixed(12)},${Number(t[1]).toFixed(12)}`,Im=(t,e)=>{const i=Rm(t),s=Rm(e);return iRm(t)<=Rm(e)?[Tm(t),Tm(e)]:[Tm(e),Tm(t)],zm=(t,e)=>Math.hypot(e[0]-t[0],e[1]-t[1]),Fm=t=>{const e=[[Number(t.points[0][0]),Number(t.points[0][1])]],i=[];for(let s=1;s{const i=new Set,s=t=>{const e=Number(t);if(!Number.isFinite(e))return;const s=e/Th;Math.abs(s-Math.round(s))>=Ur&&i.add(e.toFixed(12))};for(const e of Array.isArray(t?.rooms)?t.rooms:[])for(const t of hi(e)||[])s(t[0]),s(t[1]);for(const e of[t?.wall_segments,t?.walls])for(const t of Array.isArray(e)?e:[])s(t?.a?.[0]),s(t?.a?.[1]),s(t?.b?.[0]),s(t?.b?.[1]);for(const t of e)s(t?.[0]),s(t?.[1]);return i.size},Nm=(t,e,i)=>{const s=i[0]-e[0],n=i[1]-e[1],o=s*s+n*n;return o>1e-18?((t[0]-e[0])*s+(t[1]-e[1])*n)/o:0},Om=(t,e,i)=>{const s=Math.max(0,Math.min(1,Nm(t,e,i)));return Math.hypot(t[0]-(e[0]+(i[0]-e[0])*s),t[1]-(e[1]+(i[1]-e[1])*s))},Lm=(t,e,i,s,n=Mm)=>{const o=e[0]-t[0],a=e[1]-t[1],r=Math.hypot(o,a);if(r<=n)return 0;const l=e=>Math.abs((e[0]-t[0])*a-(e[1]-t[1])*o)/r;if(l(i)>n||l(s)>n)return 0;const c=Nm(i,t,e),h=Nm(s,t,e);return Math.max(0,Math.min(1,Math.max(c,h))-Math.max(0,Math.min(c,h)))*r},Hm=t=>{const e=(new TextEncoder).encode(t),i=8*e.length,s=64*Math.ceil((e.length+9)/64),n=new Uint8Array(s);n.set(e),n[e.length]=128;const o=new DataView(n.buffer);o.setUint32(s-8,Math.floor(i/4294967296),!1),o.setUint32(s-4,i>>>0,!1);const a=new Uint32Array([1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298]),r=new Uint32Array([1779033703,3144134277,1013904242,2773480762,1359893119,2600822924,528734635,1541459225]),l=new Uint32Array(64),c=(t,e)=>t>>>e|t<<32-e;for(let t=0;t>>3,n=c(i,17)^c(i,19)^i>>>10;l[t]=l[t-16]+s+l[t-7]+n>>>0}let[e,i,s,n,h,d,p,u]=r;for(let t=0;t<64;t++){const o=u+(c(h,6)^c(h,11)^c(h,25))+(h&d^~h&p)+a[t]+l[t]>>>0,r=e&i^e&s^i&s;u=p,p=d,d=h,h=n+o>>>0,n=s,s=i,i=e,e=o+((c(e,2)^c(e,13)^c(e,22))+r>>>0)>>>0}r[0]=r[0]+e>>>0,r[1]=r[1]+i>>>0,r[2]=r[2]+s>>>0,r[3]=r[3]+n>>>0,r[4]=r[4]+h>>>0,r[5]=r[5]+d>>>0,r[6]=r[6]+p>>>0,r[7]=r[7]+u>>>0}const h=new Uint8Array(32),d=new DataView(h.buffer);for(let t=0;t{const e="abcdefghijklmnopqrstuvwxyz234567";let i=0,s=0,n="";for(const o of t)for(s=s<<8|o,i+=8;i>=5;)n+=e[s>>>i-5&31],i-=5;return i&&(n+=e[s<<5-i&31]),n},qm=(t,e,i,s,n="")=>{const[o,a]=Am(e,i),r=`${t}|${Rm(o)}|${Rm(a)}|${[...s].sort().join(",")}${n}`;return`wall-${Bm(Hm(r)).slice(0,20)}`};let Wm=0;const jm=t=>{for(let e=0;e<1e3;e++){const e=globalThis.crypto?.randomUUID?.(),i=`wall-${e||Bm(Hm(`${Date.now()}|${Wm++}|${Math.random()}`)).slice(0,26)}`;if(!t.has(i))return i}throw new Cm("duplicate-id","id factory exhausted")},Um=t=>{const e=new Map;for(const i of Array.isArray(t?.wall_segments)?t.wall_segments:[])if(i&&"string"==typeof i.id&&Pm(i.a)&&Pm(i.b)){if(e.has(i.id))throw new Cm("duplicate-id",i.id);e.set(i.id,i)}return e},Gm=(t,e,i)=>{const s=(i,s)=>{const n=t[0]-i[0],o=t[1]-i[1];return Math.abs(e[0]-s[0]-n)<=Mm&&Math.abs(e[1]-s[1]-o)<=Mm?[n,o]:null};return s(i.a,i.b)||s(i.b,i.a)},Vm=(t,e)=>{const i=Array.isArray(t.rooms)?t.rooms:[],s=ud(t.open_spans).map(t=>[t.a[0],t.a[1],t.b[0],t.b[1]]),n=s.length?s:_d(i,null,1,.04*Th,!0),o=[];for(const t of i){const i=hi(t),s=Array.isArray(t?.wall_ids)?t.wall_ids:[];if(i&&s.length===i.length)for(let t=0;t"partition"!==t.host?.kind&&[Number(t.x),Number(t.y)].every(Number.isFinite)&&Number.isFinite(Number(t.angle))&&Number(t.length)>0&&n.some(e=>Om([Number(t.x),Number(t.y)],[e[0],e[1]],[e[2],e[3]])<=.04*Th)):[],l=r.map(t=>{const e=Number(t.angle)*Math.PI/180,i=[Math.cos(e),Math.sin(e)],s=Number(t.length)/2,n=[Number(t.x),Number(t.y)];return{a:[n[0]-i[0]*s,n[1]-i[1]*s],b:[n[0]+i[0]*s,n[1]+i[1]*s]}}),c=(t,e)=>r.some(i=>{const s=[Number(i.x),Number(i.y)];if(!Rl(t,e,Number(i.angle)))return!1;if(Om(s,t,e)>.02*Th)return!1;const n=zm(t,e),o=Nm(s,t,e)*n,a=Number(i.length)/2;return o+a>=-Mm&&o-a<=n+Mm}),h=new Map,d=[];for(const s of i){const r=String(s?.id||""),p=hi(s);if(!r||!p||p.length<3)throw new Cm("invalid-room",r);const u=ec(i,r,a,Th,1,[...t.walls||[],...l]);if(!u||u.poly.length<3)throw new Cm("invalid-room",r);const _=Array.isArray(s.wall_ids)?s.wall_ids:[],m=_.length===p.length;let g=null,f=m;if(f)for(let t=0;tMm||Math.abs(s[1]-g[1])>Mm)){f=!1;break}g=s}const v=[];for(let t=0;t2)throw new Cm("third-owner",a);const d=m?_[u.parent[t]]:void 0;if("string"==typeof d&&d){const n=e.get(d);f||!n||Lm(i,s,n.a,n.b)>Mm?l.preferredIds.add(d):l.positionalIds.add(d),l.preferredCarriers.set(d,{a:Tm(p[u.parent[t]]),b:Tm(p[(u.parent[t]+1)%p.length])})}const g=u.parent[t];l.parentKeys.add(wl(p[g],p[(g+1)%p.length],Th));const y=[(i[0]+s[0])/2,(i[1]+s[1])/2],b=t=>t.some(t=>Om(y,[t[0],t[1]],[t[2],t[3]])<=.04*Th);l.zeroWall||=b(o)||b(n)&&!c(i,s),v.push(a)}const y={...s};delete y.wall_ids,d.push({...y,poly:u.poly.map(t=>[t[0],t[1]]),wall_ids:v})}return{atoms:[...h.values()].sort((t,e)=>t.key.localeCompare(e.key)),rooms:d}},Km=(t,e,i,s,n)=>{const o=new Map([...i.values()].map(t=>[Im(t.a,t.b),t])),a=(t=>{const e=new Map;for(const i of t)"wall"===i.host?.kind&&e.set(i.host.id,(e.get(i.host.id)||0)+1);return e})(t.openings||[]),r=new Map;for(const t of e){const e=n?.get(t.key);if(e){const s=i.get(e);if(!s)throw new Cm("duplicate-id",e);r.set(t,s);continue}if(t.preferredIds.size>1)throw new Cm("duplicate-id",[...t.preferredIds].sort().join(","));const s=[...t.preferredIds][0],l=s?i.get(s):void 0;if(l){r.set(t,l);continue}const c=s?t.preferredCarriers.get(s):void 0;if(s&&c){r.set(t,{id:s,a:c.a,b:c.b,cm:0});continue}const h=o.get(t.key);if(h){r.set(t,h);continue}const d=[...i.values()].filter(e=>Lm(t.a,t.b,e.a,e.b)>Mm),p=[...new Map(d.map(t=>[t.id,t])).values()];if(p.sort((t,e)=>(a.get(e.id)||0)-(a.get(t.id)||0)||zm(e.a,e.b)-zm(t.a,t.b)||t.id.localeCompare(e.id)),p[0])r.set(t,p[0]);else if(1===t.positionalIds.size){const e=i.get([...t.positionalIds][0]);e&&r.set(t,e)}}const l=new Map;for(const[t,e]of r){const i=l.get(e.id)||[];i.push(t),l.set(e.id,i)}for(const[t,e]of l){const s=i.get(t)||r.get(e[0]);if(!s)throw new Cm("duplicate-id",t);const n=[(s.a[0]+s.b[0])/2,(s.a[1]+s.b[1])/2];e.sort((t,e)=>{const i=Om(n,t.a,t.b)<=Mm?0:1,o=Om(n,e.a,e.b)<=Mm?0:1;if(i!==o)return i-o;return(Om(s.a,t.a,t.b)<=Mm?0:1)-(Om(s.a,e.a,e.b)<=Mm?0:1)||t.key.localeCompare(e.key)}),e[0].id=t}const c=(t=>{const e=new Set;for(const i of[t.rooms,t.openings,t.decor,t.room_drafts,t.partitions,t.wall_columns])for(const t of Array.isArray(i)?i:[])"string"==typeof t?.id&&t.id&&e.add(t.id);for(const i of Array.isArray(t.room_drafts)?t.room_drafts:[])for(const t of Array.isArray(i?.segments)?i.segments:[])"string"==typeof t?.id&&t.id&&e.add(t.id);return e})(t);for(const t of e)if(t.id){if(c.has(t.id))throw new Cm("duplicate-id",t.id);c.add(t.id)}const h=e.filter(t=>!t.id);if(s){const e=h.map(e=>{const[i,s]=Am(e.a,e.b),n=`${String(t.id||"")}|${Rm(i)}|${Rm(s)}|${[...e.owners].sort().join(",")}`,o=Bm(Hm(n));return{atom:e,seed:n,digest:o,base:`wall-${o.slice(0,20)}`}}).sort((t,e)=>t.digest.localeCompare(e.digest)||t.atom.key.localeCompare(e.atom.key)),i=new Map;for(const t of e){const e=i.get(t.digest);if(e&&e!==t.seed)throw new Cm("duplicate-id",t.digest);i.set(t.digest,t.seed);let s=1,n=t.base;for(;c.has(n);)n=`${t.base}-${++s}`;t.atom.id=n,c.add(n)}}else for(const t of h)t.id=jm(c),c.add(t.id)},Ym=(t,e)=>{if("partition"===t.host?.kind)return null;const i=[Number(t.x),Number(t.y)];if(!i.every(Number.isFinite))return null;const s=e=>{if(!(Number(e.cm)>0))return!1;const s=Nm(i,e.a,e.b),n=zm(e.a,e.b),o=Number(t.length)/2;return s>=-Mm&&s<=1+Mm&&Om(i,e.a,e.b)<=.02*Th&&Rl(e.a,e.b,Number(t.angle))&&Number.isFinite(o)&&o>=0&&s*n-o>=-Mm&&s*n+o<=n+Mm},n="wall"===t.host?.kind?e.find(e=>e.id===t.host.id):null,o=n&&s(n)?[n]:e.filter(s);if(1!==o.length)return null;const a=o[0];return{kind:"wall",id:a.id,t:Math.max(0,Math.min(1,Nm(i,a.a,a.b)))}},Jm=(t,e)=>{const i=[Number(t.x),Number(t.y)];if(!i.every(Number.isFinite))return null;const s=Number(t.length)/2,n=e.filter(e=>{if(!(Number(e.cm)>0))return!1;const n=Nm(i,e.a,e.b),o=zm(e.a,e.b);return n>=-Mm&&n<=1+Mm&&Om(i,e.a,e.b)<=.02*Th&&Rl(e.a,e.b,Number(t.angle))&&Number.isFinite(s)&&s>=0&&n*o-s>=-Mm&&n*o+s<=o+Mm}),o=(e=>{if(!e.length)return null;const s="wall"===t.host?.kind?e.find(e=>e.id===t.host.id):null;return s||[...e].sort((t,e)=>Om(i,t.a,t.b)-Om(i,e.a,e.b)||Number(e.cm)-Number(t.cm)||(t.ide.id?1:0))[0]})(n);return o?{kind:"wall",id:o.id,t:Math.max(0,Math.min(1,Nm(i,o.a,o.b)))}:null},Xm=(t,e,i)=>{const s=Um(t),{atoms:n,rooms:o}=Vm(t,s);Km(t,n,s,e,i);const a=n.map(e=>{const i=e.id?s.get(e.id):void 0,n=((t,e,i)=>{if(e.zeroWall)return 0;const s=Array.isArray(t.walls)?t.walls:[],n=wl(e.a,e.b,Th),o=s.filter(t=>Number(t.cm)>0&&(!(t.key!==n&&!e.parentKeys.has(t.key))||!(!Pm(t.a)||!Pm(t.b))&&Lm(e.a,e.b,t.a,t.b)>=zm(e.a,e.b)-Mm)).map(t=>Math.max(1,Math.min(100,Number(t.cm))));if(new Set(o.map(t=>t.toFixed(9))).size>1)throw new Cm("thickness-conflict",e.key);if(o.length)return o[0];const a=Pl(s,e.a,e.b,Th,1);return a>0?a:Number(i?.cm)>0?Number(i.cm):0})(t,e,i);return{...i||{},id:e.id,a:[...e.a],b:[...e.b],cm:n}}),r=new Map(n.map(t=>[t.key,t.id]));for(const t of o)t.wall_ids=t.wall_ids.map(t=>r.get(t));t.rooms=o,t.wall_segments=a,t.walls=a.filter(t=>t.cm>0).map(t=>({key:wl(t.a,t.b,Th),cm:t.cm,a:[...t.a],b:[...t.b]})),t.walls.length||delete t.walls,delete t.open_spans;for(const e of t.rooms)delete e.open_to;return((t,e)=>{const i=new Set;for(const e of[t.rooms,t.openings,t.decor,t.room_drafts,t.partitions,t.wall_columns,t.wall_segments])for(const t of Array.isArray(e)?e:[])"string"==typeof t?.id&&t.id&&i.add(t.id);for(const s of Array.isArray(t.room_drafts)?t.room_drafts:[]){const n=Array.isArray(s.segments)?s.segments:[];for(let o=0;o{const s=Array.isArray(t.openings)?t.openings:[];for(const t of s){if("partition"===t.host?.kind)continue;if(!t.host&&!i){const i=Ym(t,e);i&&(t.host=i);continue}const s=Ym(t,e)??(i?Jm(t,e):null);if(s)t.host=s;else{if(!i)throw new Cm("opening-host",t.id);delete t.host}}})(t,a,e),a.reduce((t,e)=>t+(s.has(e.id)?0:1),0)};function Zm(t,e={}){const i=JSON.stringify(t),s=Dm(t);rl(s);let n=0;const o=Number(s?.model_version||0)<9;for(const t of Array.isArray(s?.spaces)?s.spaces:[]){const i=e.lineageSpaceId===String(t?.id||"")?e.lineageHints:void 0;n+=Xm(t,o,i)}return s.model_version=9,rl(s),{config:s,changed:i!==JSON.stringify(s),migratedSegments:n}}const Qm=t=>!!t&&"object"==typeof t&&!Array.isArray(t);function tg(t,e){const i=(t,e)=>{if(Array.isArray(t)&&Array.isArray(e)){const s=new Map;for(const e of t)Qm(e)&&"string"==typeof e.id&&e.id&&s.set(e.id,e);const n=e.map((e,n)=>{if(Qm(e)&&"string"==typeof e.id&&e.id){const t=s.get(e.id);return t?i(t,e):Dm(e)}return n[e,e in t?i(t[e],s):Dm(s)]);for(const e of Object.keys(t))delete t[e];for(const[e,i]of s)t[e]=i;return t}return Dm(e)};return i(t,e)}const eg=(t,e)=>Object.prototype.hasOwnProperty.call(t,e),ig=(t,e,i)=>Math.min(i,Math.max(e,t)),sg=t=>Sh({spaces:[t]})[0],ng=(t,e,i)=>{const s=i>0?i:1,n=t=>`${(t[0]/s).toFixed(12)},${(t[1]/s).toFixed(12)}`,o=n(t),a=n(e);return o0?a:1,l=Math.max(s*r*.02,1e-9),c=[];for(const e of t||[])for(const t of hi(e)||[])c.push([t[0],t[1]]);const h=[];for(const t of i||[])Array.isArray(t)&&t.length>=4&&t.slice(0,4).every(Number.isFinite)&&h.push([t[0],t[1]],[t[2],t[3]]);const d=(t,e)=>e.some(e=>Math.hypot(t[0]-e[0],t[1]-e[1])<=2*l),p=new Map;for(const a of t||[]){if(!a?.id)continue;const u=hc(t,a.id,e,i,s,n,o,r);if(u)for(let t=0;t0&&_>0&&a===m&&_!==a))continue;const g=u.poly[s],f=u.poly[(s+1)%u.poly.length],v=Math.hypot(f[0]-g[0],f[1]-g[1]);if(!(v>l&&v<.5*o-1e-9*o))continue;if(d(g,h)||d(f,h))continue;if(d(g,c)&&d(f,c))continue;const y=ng(g,f,r),b=p.get(y);b?b.targets.add(a):p.set(y,{a:[g[0],g[1]],b:[f[0],f[1]],targets:new Set([a])})}}}let u=e.slice();const _=(t,e)=>Math.hypot(t[0]-e[0],t[1]-e[1])<=2*l,m=(t,e)=>{if(!Array.isArray(t.a)||!Array.isArray(t.b)||t.a.length<2||t.b.length<2)return!1;const i=[Number(t.a[0])*r,Number(t.a[1])*r],s=[Number(t.b[0])*r,Number(t.b[1])*r];return!![...i,...s].every(Number.isFinite)&&(_(i,e.a)&&_(s,e.b)||_(i,e.b)&&_(s,e.a))};for(const t of[...p.values()].filter(t=>1===t.targets.size).sort((t,e)=>ng(t.a,t.b,r).localeCompare(ng(e.a,e.b,r)))){const e=[...t.targets][0],i=u.filter(e=>m(e,t));if(new Set(i.map(t=>t.cm)).size>1)continue;let n=!1;u=u.map(i=>m(i,t)?(n=!0,i.cm===e?i:{...i,cm:e}):i),n||(u=Fl(u,t.a,t.b,e,s,r))}return u}const ag=t=>{const e=[];for(const i of t||[]){const t=hi(i);if(t?.length)for(let i=0;i"string"==typeof t?.id?t.id:"").filter(Boolean),h=new Set(c),d=new Map;for(const t of c){const e=$m("space",t);e.layers>0&&xm("space",e.root)&&Sm(d,e.root,t)}const p=new Map,u=new Map,_=new Map,m=new Map;for(const t of r){const e="string"==typeof t?.id?t.id:"";if(!e)continue;const i=new Map;for(const s of Array.isArray(t.rooms)?t.rooms:[]){const t="string"==typeof s?.id?s.id:"";if(!t)continue;const n=$m("room",t);n.layers>0&&xm("room",n.root)&&Sm(i,n.root,t),u.has(t)||u.set(t,e),_.has(t)||_.set(t,String(s.name||""));const o="string"==typeof s.area?s.area:"";if(o){const i=m.get(o)||[];i.push({spaceId:e,roomId:t}),m.set(o,i)}}p.set(e,i)}const g=new Set(u.keys()),f=new Map,v=new Map;for(const t of l)"string"==typeof t?.id&&t.id&&(!0===t.removed?v.set(t.id,t):f.set(t.id,t));const y={spaceRefsRemapped:0,roomRefsRemapped:0,positionsRemapped:0,markersDetached:0,positionsUnresolved:0,nestedRefsUnresolved:0,deadSpaceIds:[],orphanRoomLabelsRemoved:0,orphanDevicePositionsRemoved:0,orphanGroupPositionsRemoved:0,liveMissingPositionsRemoved:0,removedPositions:[],liveMissingPositions:[],unverifiedPositions:[]},b=new Set,w=t=>h.has(t)?null:(()=>{const e=$m("space",t).root;if(!xm("space",e))return null;const i=d.get(e)||[];return 1===i.length?i[0]:null})(),k=(t,e)=>{const i=$m("room",t).root;if(!xm("room",i))return null;const s=p.get(e)?.get(i)||[];return 1===s.length?s[0]:null},x=t=>{const e=i.effectiveAreaByMarker?.[t]||"",s=e&&m.get(e)||[];return 1===s.length?s[0]:null},$=(t,e,i)=>{if("string"==typeof t.room_id&&t.room_id&&!g.has(t.room_id)){const s=e?k(t.room_id,e):null;s?(t.room_id=s,y.roomRefsRemapped++):i?(t.room_id=i.roomId,y.roomRefsRemapped++):!0!==t.removed&&delete t.room_id}const s=t.vacuum?.segment_map;if(s&&"object"==typeof s&&!Array.isArray(s))for(const t of Object.keys(s)){const i=s[t];if("string"!=typeof i||!i||g.has(i))continue;const n=e?k(i,e):null;n?(s[t]=n,y.roomRefsRemapped++):y.nestedRefsUnresolved++}};for(const t of l){const e="string"==typeof t?.id?t.id:"";if(!e)continue;const i="string"==typeof t.space?t.space:"",s=i&&!h.has(i),o=n[e],a="string"==typeof o?.s?o.s:"",r=a&&!h.has(a),l=!0===t.removed;let c=i&&h.has(i)?i:null,d=null,p=!1;if(s){const s=w(i);s?(t.space=s,c=s,p=!0,y.spaceRefsRemapped++):l||"virtual"===t.binding?l||(delete t.space,c=null,y.markersDetached++):(d=x(e),d?(t.space=d.spaceId,c=d.spaceId,y.spaceRefsRemapped++):(delete t.space,c=null,y.markersDetached++))}l&&!p||$(t,c,d),r&&p&&a===i&&c&&(n[e]={...o,s:c},y.positionsRemapped++,b.add(e))}for(const t of Object.keys(n)){if(b.has(t))continue;const e=n[t],i="string"==typeof e?.s?e.s:"";if(!i||h.has(i))continue;const s=w(i);if(s){if(t.startsWith("rl_")){const i=t.slice(3),o=k(i,s);if(o){const i=`rl_${o}`;km(n,i)||(n[i]={...e,s:s}),delete n[t],y.roomRefsRemapped++,y.positionsRemapped++;continue}}n[t]={...e,s:s},y.positionsRemapped++}}const S=i.ownerRoster,M=!0===S?.authoritative,C=new Set(S?.deviceIds||[]),D=new Set(S?.entityIds||[]),P=new Set(Array.isArray(s.settings?.known_devices)?s.settings.known_devices.filter(t=>"string"==typeof t):[]),T=(t,e="")=>{const i=String(S?.names?.[t]||e||"").trim();return i&&i!==t?i:""},R=(t,e,i,s="",n)=>({id:t,spaceId:e,kind:i,name:T(t,s),...n?{reason:n}:{}}),I=t=>{"room_label"===t?y.orphanRoomLabelsRemoved++:"group"===t?y.orphanGroupPositionsRemoved++:y.orphanDevicePositionsRemoved++},A=new Set;for(const[t,e]of Object.entries(n)){const s="string"==typeof e?.s?e.s:"";if(!s||h.has(s))continue;let o,a;const r=f.get(t),l=v.get(t);if(r)o=R(t,s,"device",String(r.name||"")),a="live";else if(l)o=R(t,s,"device",String(l.name||"")),a="absent";else if(t.startsWith("rl_")){const e=t.slice(3);o=R(t,s,"room_label",_.get(e)||""),a=g.has(e)?"live":"absent"}else if(t.startsWith("lg_")){const e=t.slice(3);o=R(t,s,"group"),a=D.has(e)?"live":M?"absent":"unverified","unverified"===a&&(o.reason="registry_unavailable")}else C.has(t)?(o=R(t,s,"device"),a="live"):P.has(t)?(o=R(t,s,"device"),a=M?"absent":"unverified","unverified"===a&&(o.reason="registry_unavailable")):(o=R(t,s,"unknown","","unknown_owner"),a="unverified");if("absent"!==a){if("live"===a){if(y.liveMissingPositions.push(o),!0===i.removeLiveMissingPositions){delete n[t],y.liveMissingPositionsRemoved++,I(o.kind),y.removedPositions.push(o);continue}}else y.unverifiedPositions.push(o);y.positionsUnresolved++,A.add(s)}else delete n[t],I(o.kind),y.removedPositions.push(o)}return y.deadSpaceIds=[...A].sort((t,e)=>t.localeCompare(e)),{config:s,layout:n,report:y,changed:JSON.stringify(s)!==o||JSON.stringify(n)!==a}}(t,e,i),a=o.config,r=nl(a,o.layout);rl(a),al(o.layout);const l=JSON.stringify(t||{}),c=JSON.stringify(e||{}),h=Number.isInteger(Number(a.model_version))?Number(a.model_version):0,d=(t=>{let e=0,i=0,s=0;for(const i of t.markers||[]){if("ripple"===i.display&&(i.display="icon_ripple",e++),Array.isArray(i.controls)){const t="string"==typeof i.binding&&i.binding.startsWith("entity:")?i.binding.slice(7):"",s=t?i.controls.filter(e=>e!==t):i.controls;JSON.stringify(s)!==JSON.stringify(i.controls)&&(i.controls=s.length?s:null,e++)}const t=i.vacuum;t&&eg(t,"trail")&&(["never","cleaning","always"].includes(t.trail_mode)||(t.trail_mode=!1===t.trail?"never":"cleaning"),delete t.trail,e++)}for(const n of t.spaces||[]){const t=n.settings;"glow"===t?.fill_mode&&("boolean"!=typeof t.glow_enabled&&(t.glow_enabled=!0),t.fill_mode="none",e++,i++);for(const t of n.rooms||[]){const i=t.settings;"glow"===i?.fill_mode&&("boolean"!=typeof i.glow&&(i.glow=!0),delete i.fill_mode,e++,s++)}if(eg(n,"segments")&&(delete n.segments,e++),eg(n,"plan_scale")){const t=Number(n.plan_scale);Number.isFinite(t)&&t>=wh&&t<=kh&&(eg(n,"plan_scale_x")||(n.plan_scale_x=t),eg(n,"plan_scale_y")||(n.plan_scale_y=t),delete n.plan_scale,e++)}const o=Number(n.cell_cm);eg(n,"cell_cm")&&(!Number.isFinite(o)||o<.1||o>1e3)&&(n.cell_cm=Number.isFinite(o)&&o>0?ig(o,.1,1e3):5,e++);const a=Number(n.cell_cm),r=Number.isFinite(a)&&a>0?a:5;for(const t of n.wall_columns||[])if("circle"===t.shape)eg(t,"angle")&&(delete t.angle,e++);else if("square"===t.shape&&eg(t,"angle")){const i=((Number(t.angle)||0)%90+90)%90;t.angle!==i&&(t.angle=i,e++)}for(const t of n.decor||[]){if(eg(t,"width")){const i=Number(t.width);(eg(t,"width_cm")||Number.isFinite(i))&&(eg(t,"width_cm")||(t.width_cm=Number(ig(i/Ph*r,.1,100).toFixed(6))),delete t.width,e++)}if("rect"!==t?.kind&&"ellipse"!==t?.kind||!0!==t.fill||(eg(t,"fill_color")||(t.fill_color=t.color||"#607d8b",e++),eg(t,"fill_opacity")||(t.fill_opacity=.25,e++)),"text"!==t?.kind)continue;void 0===t.size_cm?(t.size_cm=Number(ig(es*is(t)/Ph*r,.1,2e3).toFixed(6)),delete t.scale,delete t.size,e++):(eg(t,"scale")||eg(t,"size"))&&(delete t.scale,delete t.size,e++);let i=String(t.text??"");const s=[...i.matchAll(/\{([^{}\r\n]+)\}/g)].some(t=>!!Yi(t[1]));if(!(eg(t,"entity")||eg(t,"attr")||eg(t,"unit")))continue;const n=String(t.unit??"").trim(),o="state"===String(t.attr??"").trim().toLowerCase()?null:t.attr,a=s||n?"":Ji(t.entity,o);if(s||a){if(a){const e=i.indexOf("{}");i=e>=0?i.slice(0,e)+a+i.slice(e+2):`${i}${i?" ":""}${a}`,t.text=i}delete t.entity,delete t.attr,delete t.unit,e++}}}return{total:e,glowSpaces:i,glowRooms:s}})(a);let p=d.total;const u=(_=a.spaces||[],JSON.parse(JSON.stringify(_)));var _;const m=X_(a.spaces||[],o.layout);let g=0,f=0,v=0,y="";const b=m.spaces.map(t=>{const e=function(t){const e=JSON.parse(JSON.stringify(t||{}));let i=Array.isArray(e.rooms)?e.rooms:[];const s=new Map;for(const t of i){const e=hi(t);if(e)for(let t=0;tt.key.localeCompare(e.key))){let e=null;for(const s of $a(t,i)){const t=r.get(_a(s.from));if(t&&t!==_a(s.to))continue;const n=wa(i,s);if(ka(i,n,s)){e=s,i=n;break}}e?(r.set(_a(e.from),_a(e.to)),n++,a=Math.max(a,Math.hypot(e.to[0]-e.from[0],e.to[1]-e.from[1]))):o++}e.rooms=i;for(const t of e.room_drafts||[]){if(!Array.isArray(t?.points)||t.points.length<2)continue;const e=t.points.map(t=>[...t]),i=e.slice(0,-1).flatMap((i,s)=>{const n=e[s+1],o=pa(i,n);return o?[{key:`${String(t.id||"")}:${s}`,a:[...i],b:[...n],axis:o.axis}]:[]});let s=e;for(const t of i){let e=null;for(const i of $a(t,[{poly:s}])){const t=s.map(t=>ba(t,i)),n=t.length>=4&&ma(t[0],t[t.length-1]),o=n?t.slice(0,-1):t;if(n?va(o):ya(o)){e=i,s=t;break}}e?(n++,a=Math.max(a,Math.hypot(e.to[0]-e.from[0],e.to[1]-e.from[1]))):o++}t.points=s}for(const t of e.partitions||[]){if(!Array.isArray(t?.a)||!Array.isArray(t?.b))continue;const i=pa(t.a,t.b);if(!i)continue;const s={key:String(t.id||ga(t.a,t.b)),a:[...t.a],b:[...t.b],axis:i.axis};let r=null;for(const i of $a(s,[{poly:[t.a,t.b]}])){const s=ba(t.a,i),n=ba(t.b,i),o=Math.hypot(n[0]-s[0],n[1]-s[1]);if(!(o>0))continue;const a=(e.openings||[]).filter(e=>"partition"===e?.host?.kind&&e.host.id===t.id).every(t=>{const e=Number(t.host.t),i=Number(t.length);return Number.isFinite(e)&&e>=0&&e<=1&&Number.isFinite(i)&&i>0&&e*o-i/2>=-1e-12&&e*o+i/2<=o+1e-12});if(a){r=i,t.a=s,t.b=n;break}}r?(n++,a=Math.max(a,Math.hypot(r.to[0]-r.from[0],r.to[1]-r.from[1]))):o++}return{space:e,report:{wallsStraightened:n,wallsStraightenSkipped:o,maxStraightenShift:a},changed:n>0}}(t);g+=e.report.wallsStraightened,f+=e.report.wallsStraightenSkipped;const i=Number(t?.cell_cm)>0?Number(t.cell_cm):5,s=e.report.maxStraightenShift/Th*i;return s>v&&(v=s,y=String(t?.id||"")),e.space}),w=g?X_(b,m.layout):{...m,spaces:b};a.spaces=w.spaces;const k=g?{...m.report,moved:m.report.moved+w.report.moved,coordsCanonicalized:m.report.coordsCanonicalized+w.report.coordsCanonicalized,maxShift:Math.max(m.report.maxShift,w.report.maxShift),maxShiftCm:Math.max(m.report.maxShiftCm,w.report.maxShiftCm),maxSpace:w.report.maxShiftCm>m.report.maxShiftCm?w.report.maxSpace:m.report.maxSpace,rotated:m.report.rotated+w.report.rotated,removedDrafts:m.report.removedDrafts+w.report.removedDrafts}:{...m.report};let x=0,$=0,S=0,M=0,C=0,D=0,P=0,T=0;for(let t=0;t0===Number(t.cm)),walls:e.walls||[]}),o=sg(e),r=sg(i);if(!o||!r)continue;const l=ag(o.rooms),c=ag(r.rooms),h=.02*Ph,d=(e.wall_segments||[]).filter(t=>0===Number(t.cm)).map(t=>({...t,key:wl(t.a,t.b,Th),cm:0})),p=new Set(d.map(t=>t.key)),_=m_(e,o.rooms,yh,h);$+=_.length;for(const t of _){const e=[t[0]/yh,t[1]/yh],i=[t[2]/yh,t[3]/yh],s=wl(e,i,Th);p.has(s)||(p.add(s),d.push({key:s,a:e,b:i,cm:0}))}const m=d.length,g=Al(d,l,c,Th,yh),f=(t,e,i)=>{const s=i[0]-e[0],n=i[1]-e[1],o=s*s+n*n;if(!(o>0))return Math.hypot(t[0]-e[0],t[1]-e[1]);const a=Math.max(0,Math.min(1,((t[0]-e[0])*s+(t[1]-e[1])*n)/o));return Math.hypot(t[0]-(e[0]+s*a),t[1]-(e[1]+n*a))},v=g.filter(t=>{if(!Array.isArray(t.a)||!Array.isArray(t.b))return!1;const e=t.a.map(t=>t*yh),i=t.b.map(t=>t*yh);return c.some(([t,s])=>f(e,t,s)<=4*h&&f(i,t,s)<=4*h)});S+=Math.max(0,m-v.length);const y=(i.wall_segments||[]).filter(t=>Number(t.cm)>0);i.wall_segments=[...y,...v.map(({key:t,...e})=>e)];const b=v.map(t=>[t.a[0]*yh,t.a[1]*yh,t.b[0]*yh,t.b[1]*yh]),w=Array.isArray(e.walls)?e.walls.length:0;let k=Al(e.walls,l,c,Th,yh);k=og(r.rooms,k,b,Th,Number(i.cell_cm)>0?Number(i.cell_cm):5,Ph,yh),k=uc(r.rooms,k,b,Th,Number(i.cell_cm)>0?Number(i.cell_cm):5,Ph,yh),k=Tl(k,i.rooms||[],Th,1,b.map(t=>[t[0]/yh,t[1]/yh,t[2]/yh,t[3]/yh])),x+=Math.max(0,w-k.length),k.length?i.walls=k:delete i.walls;const R=nm(i.partitions||[],{pitch:Th,geometry:am(i)});R.merged&&(M+=R.merged,i.partitions=R.partitions,om(i.openings,i.partitions,R.openingMoves,{coordScale:yh,cellCm:Number(i.cell_cm)>0?Number(i.cell_cm):5,gridPitch:Ph}));const I=sg(i);if(I){const t=n(i,I,i.walls||[],b,{pitch:Th,cellCm:Number(i.cell_cm)>0?Number(i.cell_cm):5,gridPitch:Ph,coordScale:yh});t.partitionsReconciled&&(C+=t.partitionsReconciled,D+=t.openingsRehosted,t.partitions.length?i.partitions=t.partitions:delete i.partitions,t.openings.length?i.openings=t.openings:delete i.openings,t.walls.length?i.walls=t.walls:delete i.walls),t.removedDrafts&&(P+=t.removedDrafts,t.roomDrafts.length?i.room_drafts=t.roomDrafts:delete i.room_drafts)}JSON.stringify({zero:(i.wall_segments||[]).filter(t=>0===Number(t.cm)),walls:i.walls||[]})!==s&&T++}let R=0;h<=9&&(R=function(t){const e=Zm(t);return tg(t,e.config),{...e,config:t}}(a).migratedSegments);const I=rl(a),A=al(w.layout),z=JSON.stringify(I)!==l||JSON.stringify(A)!==c;h<9&&z&&(I.model_version=9);const F=JSON.stringify(I)!==l||JSON.stringify(A)!==c,E=Number.isInteger(Number(I.model_version))?Number(I.model_version):h,N=F?k:{...k,moved:0,coordsCanonicalized:0,maxShift:0,maxShiftCm:0,maxSpace:"",rotated:0,removedDrafts:0},O=F?o.report:{...o.report,spaceRefsRemapped:0,roomRefsRemapped:0,positionsRemapped:0,markersDetached:0,orphanRoomLabelsRemoved:0,orphanDevicePositionsRemoved:0,orphanGroupPositionsRemoved:0,liveMissingPositionsRemoved:0};return{config:I,layout:A,report:{...N,modelFrom:h,modelTo:E,migrated:F?p:0,glowSpacesMigrated:F?d.glowSpaces:0,glowRoomsMigrated:F?d.glowRooms:0,canonicalized:F?T:0,wallSegmentsMigrated:F?R:0,legacyZeroWallsMigrated:F?$:0,wallsMerged:F?x:0,spansMerged:F?S:0,partitionsMerged:F?M:0,partitionsReconciled:F?C:0,openingsRehosted:F?D:0,redundantDraftsRemoved:F?P:0,wallsStraightened:F?g:0,wallsStraightenSkipped:f,maxStraightenShiftCm:F?v:0,maxStraightenSpace:F?y:"",latticeCoordinatesCanonicalized:F?r.canonicalized:0,latticeCoordinatesFar:F?r.far:0,latticeMaxShift:F?r.maxShift:0,latticeMaxShiftCm:F?r.maxShiftCm:0,latticeSpaces:F?r.spaces:[],...O},changed:F}}function lg(t,e,i){const s=(t?.spaces||[]).find(t=>t?.id===i),n=new Set((s?.rooms||[]).map(t=>String(t?.id||"")).filter(Boolean)),o=[...new Set((t?.markers||[]).filter(t=>!0!==t?.removed&&"string"==typeof t?.id).filter(t=>t.space===i||"string"==typeof t.room_id&&n.has(t.room_id)||e?.[t.id]?.s===i).map(t=>t.id))].sort((t,e)=>t.localeCompare(e));return{markerIds:o,count:o.length}}function cg(t){return t instanceof Error?t.name||"Error":typeof t}function hg(t){return wd({id:t?.id??"",cell_cm:t?.cell_cm,rooms:t?.rooms||[],walls:t?.walls||[],wall_segments:t?.wall_segments||[],open_spans:t?.open_spans||[],openings:t?.openings||[],partitions:t?.partitions||[],room_drafts:t?.room_drafts||[],wall_columns:t?.wall_columns||[]})}function dg(t,e,i,s=Ph,n=1e3){return(Array.isArray(t?.openings)?t.openings:[]).flatMap(t=>{const o={...t,rx:Number(t.x)*n,ry:Number(t.y)*n,rlen:Number(t.length)*n};if(!t.host||"wall"===t.host.kind)return[o];const a=Sp(t,e.partitions,n,i,s);return a.resolved?[{...t,rx:a.resolved.center[0],ry:a.resolved.center[1],rlen:a.resolved.length,angle:a.resolved.angle,partitionHost:a.resolved}]:[]})}function pg(t,e=()=>!0){return t.flatMap(t=>t.host&&t.partitionHost&&e(t)?[Dp(t.partitionHost)]:[])}function ug(t,e,i,s,n,o,a=Ph,r=1e3){const l=dc(e.rooms,[...i],s,n,o,a,r);return t.flatMap(t=>{const e={x:t.rx,y:t.ry,angle:Number(t.angle)||0,length:t.rlen};return t.host&&"wall"!==t.host.kind?t.partitionHost&&Rp(t.partitionHost,l,2e-4*a)?[e]:[]:[e]})}function _g(t,e){const i=Th,s=Ph,n=yh,o=Number.isFinite(Number(e.cellCm))&&Number(e.cellCm)>0?Number(e.cellCm):5,a=Array.isArray(t?.walls)?t.walls:[],r=function(t,e,i=Ph,s=1e3){return _d(e.rooms,t?.open_spans,s,.02*i)}(t,e,s,n),l=function(t,e,i=Ph){if(!e.length)return[];const s=t.filter(t=>t?.id),n=.02*i,o=[];for(let t=0;t{const e=[(t[0]+t[2])/2,(t[1]+t[3])/2];return h.some(t=>Ls(e,t)<4*n)}).map(t=>[...t]);d.length&&o.push({a:a,b:r,segs:d})}return o}(e.rooms,r,s).flatMap(t=>t.segs),c=dg(t,e,o,s,n),h=pg(c),d=ih(e,o,s,2e-4*s,h).all;return{space:e,walls:a,openCuts:l,openings:c,roomOpenings:ug(c,e,a,l,i,o,s,n),partitionCuts:h,physicalBodies:d,wallKeyPitch:i,cellCm:o,gridPitch:s,coordScale:n}}function mg(t,e,i){const s="string"==typeof t?.title?t.title.trim():"",n=null==t?.id?"":String(t.id).trim();return{spaceId:n,displayName:s||n||i(e+1)}}function gg(t,e={}){const i=(e.fingerprint||wd)(t),s=Array.isArray(t?.spaces)?t.spaces:[],n=e.fallbackSpaceName||(t=>`Space ${t}`),o=e.prepareSpace||_g,a=e.wallPass||Rc,r=e.floorPass||Pc,l=[];for(let i=0;i0||d.physicalBodies.length>0;if(!d.space.rooms.length&&!p){l.push({...h,status:"not-applicable"});continue}let u=null;if(p){try{u=a(d.space.rooms,d.walls,d.openCuts,d.roomOpenings,d.wallKeyPitch,d.cellCm,d.gridPitch,d.coordScale,d.physicalBodies)}catch(t){l.push({...h,status:"failed",reason:"wall-exception",detail:cg(t)});continue}if(null==u){l.push({...h,status:"failed",reason:"wall-null"});continue}if("degraded-extra"===u.status){l.push({...h,status:"failed",reason:"wall-degraded-extra"});continue}if("failed-core"===u.status){l.push({...h,status:"failed",reason:"wall-failed-core"});continue}e.captureWallGeometry?.(d,u)}if(d.space.rooms.length&&null==u?.paperGeom){let t;try{t=r(d.space.rooms,d.walls,d.openCuts,d.wallKeyPitch,d.cellCm,d.gridPitch,d.coordScale)}catch(t){l.push({...h,status:"failed",reason:"floor-exception",detail:cg(t)});continue}if(null==t){l.push({...h,status:"failed",reason:"floor-null"});continue}}l.push({...h,status:"ok"})}const c=l.filter(t=>"failed"===t.status);return{fingerprint:i,spaces:l,failures:c,ok:0===c.length}}class fg{constructor(t=50){this._undo=[],this._redo=[],this._limit=Math.max(30,Math.floor(t))}get canUndo(){return this._undo.length>0}get canRedo(){return this._redo.length>0}get undoName(){return this._undo[this._undo.length-1]?.name??null}get redoName(){return this._redo[this._redo.length-1]?.name??null}get size(){return this._undo.length}push(t){this._undo.push(t),this._undo.length>this._limit&&this._undo.splice(0,this._undo.length-this._limit),this._redo=[]}undo(){const t=this._undo.pop()??null;return t&&this._redo.push(t),t}redo(){const t=this._redo.pop()??null;return t&&this._undo.push(t),t}clear(){this._undo=[],this._redo=[]}}const vg=new WeakMap;const yg=(t,e,i)=>255===t[i+3]&&e.every((e,s)=>Math.abs(t[i+s]-e)<=2);async function bg(t){const e=t.defaultView;if(!e||!e.CSS?.supports?.("mix-blend-mode","screen"))return!1;const i=[128,32,16],s=[16,64,128],n=[9,19,29],o=`\n \n \n \n \n \n `,a=e.URL.createObjectURL(new Blob([o],{type:"image/svg+xml"}));try{const o=await new Promise((t,i)=>{const s=new e.Image,n=e.setTimeout(()=>i(new Error("SVG blend probe timeout")),1e3);s.onload=()=>{e.clearTimeout(n),t(s)},s.onerror=()=>{e.clearTimeout(n),i(new Error("SVG blend probe failed"))},s.src=a}),r=t.createElement("canvas");r.width=4,r.height=1;const l=r.getContext("2d",{willReadFrequently:!0});if(!l)return!1;l.drawImage(o,0,0,4,1);const c=l.getImageData(0,0,4,1).data;return yg(c,i,0)&&yg(c,function(t,e){return[0,1,2].map(i=>Math.round(255-(255-t[i])*(255-e[i])/255))}(i,s),4)&&yg(c,s,8)&&yg(c,n,12)}catch{return!1}finally{e.URL.revokeObjectURL(a)}}const wg={now:()=>performance.now(),requestFrame:t=>requestAnimationFrame(t),cancelFrame:t=>cancelAnimationFrame(t)},kg=t=>Math.max(0,Math.min(1,t)),xg=(t,e,i)=>t+(e-t)*i,$g=(t,e,i)=>{const s=1-t;return 3*s*s*t*e+3*s*t*t*i+t*t*t};function Sg(t,e){return{centerX:t.x+t.w/2,centerY:t.y+t.h/2,pixelsPerUnit:e>0&&t.w>0?e/t.w:1,viewBox:{...t}}}function Mg(t,e,i){const s=Math.max(1e-9,t.pixelsPerUnit),n=Math.max(1e-9,e/s),o=Math.max(1e-9,i/s);return{x:t.centerX-n/2,y:t.centerY-o/2,w:n,h:o}}function Cg(t){const e=t.trim(),i=/^rgba?\(\s*([\d.]+)[, ]+([\d.]+)[, ]+([\d.]+)(?:\s*[,/]\s*([\d.]+))?\s*\)$/i.exec(e);if(i)return[Number(i[1]),Number(i[2]),Number(i[3]),null==i[4]?1:Number(i[4])];const s=/^#([0-9a-f]{6}|[0-9a-f]{8})$/i.exec(e)?.[1];return s?[parseInt(s.slice(0,2),16),parseInt(s.slice(2,4),16),parseInt(s.slice(4,6),16),8===s.length?parseInt(s.slice(6,8),16)/255:1]:null}function Dg(t,e,i){const s=Cg(t),n=Cg(e);if(!s||!n)return i<.5?t:e;const o=kg(i);return`rgba(${Math.round(xg(s[0],n[0],o))}, ${Math.round(xg(s[1],n[1],o))}, ${Math.round(xg(s[2],n[2],o))}, ${xg(s[3],n[3],o).toFixed(3)})`}function Pg(t,e,i){const s=(t=>{const e=kg(t);if(0===e||1===e)return e;let i=0,s=1,n=e;for(let t=0;t<12;t++)n=(i+s)/2,$g(n,.2,.2){const e=this._state;if(!e||e.token!==n)return;const i=kg((t-e.startedAt)/e.duration);e.presented=i>=1?e.to:Pg(e.from,e.to,i),e.phase=i>=1?"settling":"running",this._hooks.frame(e),i<1?this._raf=this._clock.requestFrame(a):(this._raf=0,this._hooks.settled(e),this._state?.token===n&&(this._state=null))};return this._raf=this._clock.requestFrame(a),n}cancel(t=!0){this._raf&&this._clock.cancelFrame(this._raf),this._raf=0;const e=this._state;this._state=null,this._token++,e&&t&&(e.phase="settling",e.presented=e.to,this._hooks.frame(e),this._hooks.settled(e))}dispose(){this.cancel(!1)}}const Rg="houseplan_card_labs_v1",Ig=Object.freeze([Object.freeze({id:"iso",issue:89,since:"1.62.0",expires:"1.65.0",summary:"Volumetric plan renderer"})]);function Ag(t){const e=/^(\d+)\.(\d+)\.(\d+)(?:-[0-9A-Za-z.-]+)?$/.exec(String(t||"").trim());if(!e)return null;const i=e.slice(1).map(Number);return i.every(t=>Number.isSafeInteger(t))?i:null}function zg(t,e){for(let i=0;i<3;i++)if(t[i]!==e[i])return t[i]t.split(",")).map(t=>t.trim()).filter(Boolean)}function Hg(t,e,i,s=Ig){const n=function(t,e=Ig){const i=Ag(t),s=new Map;if(!i||!Eg(e))return s;for(const t of e){const e=Ag(t.since),n=Ag(t.expires);zg(i,e)>=0&&zg(i,n)<0&&s.set(t.id,t)}return s}(i,s),o=new Set(Eg(s)?s.map(t=>t.id):[]),a=new Set(function(t){if(!t)return[];try{const e=JSON.parse(t);return Array.isArray(e)?e.filter(t=>"string"==typeof t):[]}catch{return[]}}(e).filter(t=>n.has(t)));let r=!1;const l=t=>{if("off"===t)return a.clear(),void(r=!0);const e=t.startsWith("-"),i=e?t.slice(1):t;o.has(i)&&(r=!0,e||!n.has(i)?a.delete(i):a.add(i))};for(const e of Lg(new URLSearchParams(String(t.search||"").replace(/^\?/,""))))l(e);for(const e of Lg(Ng(t.hash)))l(e);const c=Object.freeze([...a].sort());return{active:c,space:Og(t.hash),persist:r?JSON.stringify(c):void 0,knownUrlOperation:r}}let Bg={active:Object.freeze([]),space:""},qg="",Wg=!1,jg="";const Ug=new Set;function Gg(){if("undefined"==typeof window)return Bg;const t=Hg(window.location,function(){try{return window.localStorage.getItem(Rg)}catch{return null}}(),qg);void 0!==t.persist&&function(t){try{window.localStorage.setItem(Rg,t)}catch{}}(t.persist),Bg={active:t.active,space:t.space},window.__hpLabs=t.active;for(const t of Ug)t(Bg);return Bg}function Vg(){Gg()}function Kg(t){return qg=t,"undefined"==typeof window?Bg:(Wg||(Wg=!0,window.addEventListener("hashchange",Vg),window.addEventListener("popstate",Vg)),Gg())}const Yg=Object.freeze({rotDeg:0,tiltDeg:20,xyScale:1,zScale:1,origin:Object.freeze([500,500])});function Jg(t){return[t.rotDeg,t.tiltDeg,t.xyScale,t.zScale,t.origin[0],t.origin[1]].every(Number.isFinite)&&Math.abs(t.xyScale)>1e-12&&Math.abs(Math.cos(t.tiltDeg*Math.PI/180))>1e-12}function Xg(t,e,i=Yg){if(!(Jg(i)&&Number.isFinite(t[0])&&Number.isFinite(t[1])&&Number.isFinite(e)))throw new Error("invalid isometric projection input");const s=i.rotDeg*Math.PI/180,n=i.tiltDeg*Math.PI/180,o=t[0]-i.origin[0],a=t[1]-i.origin[1],r=(o*Math.cos(s)-a*Math.sin(s))*i.xyScale,l=(o*Math.sin(s)+a*Math.cos(s))*i.xyScale;return[i.origin[0]+r,i.origin[1]+l*Math.cos(n)-e*i.zScale*Math.sin(n)]}function Zg(t,e=Yg){if(!Jg(e)||!Number.isFinite(t[0])||!Number.isFinite(t[1]))throw new Error("invalid isometric projection input");const i=e.rotDeg*Math.PI/180,s=e.tiltDeg*Math.PI/180,n=(t[0]-e.origin[0])/e.xyScale,o=(t[1]-e.origin[1])/(e.xyScale*Math.cos(s));return[e.origin[0]+n*Math.cos(i)+o*Math.sin(i),e.origin[1]-n*Math.sin(i)+o*Math.cos(i)]}function Qg(t=Yg){return`matrix(${function(t=Yg){if(!Jg(t))throw new Error("invalid isometric camera");const e=t.rotDeg*Math.PI/180,i=t.tiltDeg*Math.PI/180,s=t.xyScale*Math.cos(e),n=-t.xyScale*Math.sin(e),o=t.xyScale*Math.sin(e)*Math.cos(i),a=t.xyScale*Math.cos(e)*Math.cos(i);return[s,o,n,a,t.origin[0]-s*t.origin[0]-n*t.origin[1],t.origin[1]-o*t.origin[0]-a*t.origin[1]]}(t).map(t=>Number(t.toFixed(12))).join(" ")})`}function tf(t,e=Yg){const{rect:i,wallHeight:s}=t,n=t.openingHeight??s,o=t.floorDepth??0;if(!(i.w>=0)||!(i.h>=0)||!Number.isFinite(s)||!Number.isFinite(n)||!Number.isFinite(o)||s<0||n<0||o<0)throw new Error("invalid isometric frame");const a=[[i.x,i.y],[i.x+i.w,i.y],[i.x+i.w,i.y+i.h],[i.x,i.y+i.h]],r=Math.max(s,n),l=a.flatMap(t=>[Xg(t,-o,e),Xg(t,r,e)]),c=l.map(t=>t[0]),h=l.map(t=>t[1]),d=Math.min(...c),p=Math.min(...h);return{x:d,y:p,w:Math.max(...c)-d,h:Math.max(...h)-p}}const ef=t=>`${Number(t[0].toFixed(4))} ${Number(t[1].toFixed(4))}`;function sf(t){let e=0;for(let i=0;iArray.isArray(t)&&Number.isFinite(t[0])&&Number.isFinite(t[1])).map(t=>[Number(t[0]),Number(t[1])]),i=e[e.length-1];return e.length>1&&e[0][0]===i[0]&&e[0][1]===i[1]&&e.pop(),e}(t);if(i.length<3)return[];const s=!e;return sf(i)>0===s?i:[...i].reverse()}function of(t,e,i){return t.length?`M ${t.map(t=>ef(Xg(t,i,e))).join(" L ")} Z`:""}function af(t,e,i){const s=e[1]-t[1],n=-(e[0]-t[0]),o=i.rotDeg*Math.PI/180;return s*Math.sin(o)+n*Math.cos(o)}function rf(t,e,i=Yg){if(!Number.isFinite(e)||e<0)throw new Error("invalid floor edge height");const s=(t||[]).map(t=>(t||[]).map((t,e)=>function(t,e){const i=nf(t,e);if(!i.length)return i;let s=0;for(let t=1;t0)).filter(t=>t.length>=3&&Math.abs(sf(t))>=1e-9)).filter(t=>t.length&&sf(t[0])>0);s.sort((t,e)=>{const i=t[0][0],s=e[0][0];return i[0]-s[0]||i[1]-s[1]||Math.abs(sf(e[0]))-Math.abs(sf(t[0]))});const n=[],o=[];let a=0;for(let t=0;tt.depth-e.depth||t.component-e.component||t.edge-e.edge),{footprintPath:n.join(" "),sides:o,componentCount:s.length,edgeCount:a}}function lf(t,e){return t^=Math.round(64*(Number.isFinite(e)?e:0)),Math.imul(t,16777619)>>>0}const cf=t=>t.every(Number.isFinite);function hf(t,e,i,s){const n=t[0]*i,o=t[1]*s,a=e*Math.PI/180;return[n*Math.cos(a)-o*Math.sin(a),n*Math.sin(a)+o*Math.cos(a)]}function df(t,e,i,s,n,o,a){const r=t.flipH?-1:1,l="gate"===t.type?1:t.flipV?-1:1,c=(t.type,t.flipV,t.angle,t.face,{ox:0,oy:0}),h=function(t,e){return[t[0]+e[0],t[1]+e[1]]}([t.x+c.ox,t.y+c.oy],hf(i,t.angle,r,l));return{leaf:e,hinge:h,closedVector:hf(s,t.angle,r,l),quarterVector:hf([-s[1],s[0]],t.angle,r,l),turnDeg:n,bottom:o,top:a}}const pf=t=>`${Number(t[0].toFixed(4))} ${Number(t[1].toFixed(4))}`;function uf(t,e,i=Yg){const s=Math.max(0,Math.min(1,Number.isFinite(e)?e:0));return t.leaves.map(e=>{const n=function(t,e){const i=t.turnDeg*e*Math.PI/180;return[t.hinge[0]+t.closedVector[0]*Math.cos(i)+t.quarterVector[0]*Math.sin(i),t.hinge[1]+t.closedVector[1]*Math.cos(i)+t.quarterVector[1]*Math.sin(i)]}(e,s),o=Xg(e.hinge,e.bottom,i),a=Xg(n,e.bottom,i),r=Xg(n,e.top,i),l=Xg(e.hinge,e.top,i);return{id:t.id,sourceIndex:t.sourceIndex,type:t.type,leaf:e.leaf,d:`M ${pf(o)} L ${pf(a)} L ${pf(r)} L ${pf(l)} Z`,shadowD:`M ${pf(Xg(e.hinge,0,i))} L ${pf(Xg(n,0,i))}`,depth:Math.max(o[1],a[1])}})}const _f={window:120,door:90,passage:90,gate:300};function mf(t){return _f[t]}function gf(t,e){const i=[t[0],t[1]],s=[e[0],e[1]];return function(t,e){return t[0]-e[0]||t[1]-e[1]}(i,s)<=0?{a:i,b:s}:{a:s,b:i}}function ff(t){const e=new Map;return t.forEach((t,i)=>{if(!t.kind||t.open)return;const s=gf(t.a,t.b);if(Math.hypot(s.b[0]-s.a[0],s.b[1]-s.a[1])<=1e-9)return;const n=function(t,e){const i=t=>(Math.abs(t)<=5e-10?0:Math.round(1e6*t)/1e6).toFixed(6);return`${i(t[0])},${i(t[1])}>${i(e[0])},${i(e[1])}`}(s.a,s.b),o=e.get(n);if(o)return o.physicalHalfWidth=Math.max(o.physicalHalfWidth,t.half||0),o.sourceOrder=Math.min(o.sourceOrder,i),void(t.partitionHost&&(o.partitionHost&&o.partitionHost.id!==t.partitionHost.id?o.ambiguousPartitionHost=!0:o.partitionHost=t.partitionHost));e.set(n,{segmentKey:n,a:s.a,b:s.b,physicalHalfWidth:Math.max(0,t.half||0),sourceOrder:i,...t.partitionHost?{partitionHost:t.partitionHost}:{}})}),[...e.values()]}function vf(t,e){if(Math.abs(t.distance-e.distance)>1e-9)return t.distance-e.distance;if(Math.abs(t.perpendicular-e.perpendicular)>1e-9)return t.perpendicular-e.perpendicular;return(t.target.segmentKeye.target.segmentKey?1:0)||t.target.sourceOrder-e.target.sourceOrder}function yf(t){const e=ff(t.intervals).map(e=>{const i=function(t,e){const i=e.b[0]-e.a[0],s=e.b[1]-e.a[1],n=Math.hypot(i,s),o=i/n,a=s/n,r=(t[0]-e.a[0])*o+(t[1]-e.a[1])*a,l=Math.max(0,Math.min(n,r)),c=e.a[0]+l*o,h=e.a[1]+l*a;return{along:l,length:n,x:c,y:h,distance:Math.hypot(t[0]-c,t[1]-h),perpendicular:Math.abs((t[0]-e.a[0])*a-(t[1]-e.a[1])*o)}}(t.pointer,e);return{target:e,...i,envelope:Math.max(t.baseTolerance,e.physicalHalfWidth+t.bodyPointerPadding)}}).filter(t=>t.distance<=t.envelope+1e-9).filter(e=>!function(t,e,i,s,n){const o=e.b[0]-e.a[0],a=e.b[1]-e.a[1],r=Math.hypot(o,a);if(!(r>1e-9))return!1;const l=o/r,c=a/r;for(const o of i){if(!o.open&&o.kind)continue;const i=gf(o.a,o.b),a=i.b[0]-i.a[0],r=i.b[1]-i.a[1],h=Math.hypot(a,r);if(!(h>1e-9))continue;const d=a/h,p=r/h;if(Math.abs(l*p-c*d)>1e-6)continue;if(Math.abs((i.a[0]-e.a[0])*c-(i.a[1]-e.a[1])*l)>n)continue;const u=(t[0]-i.a[0])*d+(t[1]-i.a[1])*p,_=1e-9;if(!(u<=_||u>=h-_)&&Math.abs((t[0]-i.a[0])*p-(t[1]-i.a[1])*d)<=s+1e-9)return!0}return!1}(t.pointer,e.target,t.intervals,e.envelope,Math.max(1e-9,Math.min(t.baseTolerance,.04*t.gridStep)))),i=e.filter(e=>!!e.target.partitionHost&&t.renderedLength+2*e.target.physicalHalfWidth>e.length+1e-9).sort(vf),s=e.filter(e=>!e.target.partitionHost||t.renderedLength+2*e.target.physicalHalfWidth<=e.length+1e-9).sort(vf);let n=s[0];if(!n)return{candidate:null,jambBlockedTarget:i[0]?.target||null};const o=s.filter(t=>Math.abs(t.distance-n.distance)<=1e-9&&Math.abs(t.perpendicular-n.perpendicular)<=1e-9),a=o.filter(t=>t.target.partitionHost);if(a.length){if(1!==new Set(a.map(t=>t.target.partitionHost.id)).size||a.some(t=>t.target.ambiguousPartitionHost))return{candidate:null,jambBlockedTarget:null};const t=a[0],e=t.target.b[0]-t.target.a[0],i=t.target.b[1]-t.target.a[1],s=Math.hypot(e,i),r=e/s,l=i/s,c=o.every(e=>{const i=e.target.b[0]-e.target.a[0],s=e.target.b[1]-e.target.a[1],n=Math.hypot(i,s),o=i/n,a=s/n,c=Math.abs(r*a-l*o)<=1e-6,h=Math.abs((e.target.a[0]-t.target.a[0])*l-(e.target.a[1]-t.target.a[1])*r);return c&&h<=1e-9});if(!c)return{candidate:null,jambBlockedTarget:null};n=t}if(n.target.ambiguousPartitionHost)return{candidate:null,jambBlockedTarget:null};const{target:r,length:l}=n,c=r.b[0]-r.a[0],h=r.b[1]-r.a[1],d=c/l,p=h/l,u=r.partitionHost?r.physicalHalfWidth:0,_=Math.min(Math.max(0,t.renderedLength)/2+u,l/2);let m=n.along;const g=Math.max(t.gridStep,1e-9),f=l/2;m=Math.abs(m-f)<=g/2?f:Math.round(m/g)*g,m=Math.max(_,Math.min(l-_,m));const v=r.a[0]+d*m,y=r.a[1]+p*m,b=Math.max(0,t.renderedLength)/2,w=m-b,k=m+b,x=Math.max(0,w),$=Math.max(0,l-k),S=[r.a[0]+d*(w-x/2),r.a[1]+p*(w-x/2)],M=[r.a[0]+d*(k+$/2),r.a[1]+p*(k+$/2)];let C=180*Math.atan2(h,c)/Math.PI;C>=90?C-=180:C<-90&&(C+=180);const D=Math.abs(m-f)<=1e-9;return{candidate:{presetRevision:t.preset.revision,geometryRevision:t.geometryRevision,pointer:[t.pointer[0],t.pointer[1]],type:t.preset.type,lengthCm:t.preset.lengthCm,flipH:t.preset.flipH,flipV:t.preset.flipV,x:v,y:y,angle:C,renderedLength:t.renderedLength,target:r,...r.partitionHost?{host:{...r.partitionHost,t:l>0?m/l:0}}:{},measure:{labels:[{distance:x,midpoint:S},{distance:$,midpoint:M}],guide:D?{x:v,y:y,angle:C}:null}},jambBlockedTarget:null}}function bf(t,e,i,s,n=1e-6){return t.presetRevision===i&&t.geometryRevision===s&&Math.hypot(t.pointer[0]-e[0],t.pointer[1]-e[1])<=n}const wf=(t,e)=>t[0]*e[1]-t[1]*e[0],kf=(t,e)=>t[0]*e[0]+t[1]*e[1],xf=(t,e)=>[t[0]-e[0],t[1]-e[1]],$f=(t,e,i)=>[t[0]+e[0]*i,t[1]+e[1]*i];function Sf(t,e,i){return Math.abs(wf(t,e))<=i}function Mf(t,e,i){return Math.abs(wf(xf(t,e),i))}function Cf(t,e,i,s,n){const o=e[0]-t[0],a=e[1]-t[1],r=Math.hypot(o,a);if(!(r>n&&i>0))return[];const l=[o/r,a/r];return function(t,e,i){const s=e.map(([e,i])=>[Math.max(0,Math.min(e,i)),Math.min(t,Math.max(e,i))]).filter(([t,e])=>e>t+i).sort((t,e)=>t[0]-e[0]||t[1]-e[1]),n=[];for(const t of s){const e=n[n.length-1];!e||t[0]>e[1]+i?n.push([...t]):e[1]=Math.max(e[1],t[1])}const o=[];let a=0;for(const[t,e]of n)t>a+i&&o.push([a,t]),a=Math.max(a,e);return t>a+i&&o.push([a,t]),o}(r,s.flatMap(e=>{const s=e.b[0]-e.a[0],o=e.b[1]-e.a[1],a=Math.hypot(s,o);if(!(a>n&&Sf(l,[s/a,o/a],1e-6)))return[];if(Mf(e.a,t,l)>1.1*Math.max(i,n)||Mf(e.b,t,l)>1.1*Math.max(i,n))return[];return[[kf(xf(e.a,t),l),kf(xf(e.b,t),l)]]}),n).flatMap(([e,s])=>{const n=Ol({a:$f(t,l,e),b:$f(t,l,s),halfDepth:i});return n?[n]:[]})}function Df(t){const e=t.coordScale??1,i=Math.max(t.epsilon??2e-4*t.gridPitch,1e-9),s=[];for(const i of t.rooms||[]){if(!i?.id)continue;const n=hc(t.rooms,i.id,t.walls,t.openCuts,t.pitch,t.cellCm,t.gridPitch,e);if(!n||n.poly.length<3)continue;const o=Zl(n.poly,n.offsets);!o||o.length<3||s.push({roomId:i.id,profile:n,inner:o})}s.sort((t,e)=>t.roomId.localeCompare(e.roomId));const n=(t.roomOpenings||[]).map(t=>{const e=t.angle*Math.PI/180,i=[Math.cos(e),Math.sin(e)],s=Math.max(0,t.length)/2;return{a:$f([t.x,t.y],i,-s),b:$f([t.x,t.y],i,s)}}),o=[];for(const s of zc(t.rooms,t.walls,t.openCuts,t.pitch,t.cellCm,t.gridPitch,e))for(const t of Cf(s.a,s.b,s.depthUnits/2,n,i))o.push({body:t});const a=new Map;for(const e of t.partitionCuts||[]){const t=a.get(e.hostId)||[];t.push(e),a.set(e.hostId,t)}for(const e of t.partitions||[]){const s=gl(e.cm,t.cellCm,t.gridPitch)/2;for(const t of Cf(e.a,e.b,s,a.get(e.id)||[],i))o.push({body:t,partitionId:e.id})}return{rooms:s,boundaries:o,epsilon:i}}function Pf(t,e,i,s){const n=t.profile.offsets[e];if(!(n>0))return null;const o=function(t,e){const i=t[e],s=t[(e+1)%t.length],n=s[0]-i[0],o=s[1]-i[1],a=Math.hypot(n,o)||1;return function(t){let e=0;for(let i=0;i=0?[-o/a,n/a]:[o/a,-n/a]}(t.profile.poly,e),a=$f(i.center,o,n),r=[];for(let e=0;es&&Sf(i.axis,[l[0]/c,l[1]/c],1e-6)))continue;if(Mf(n,a,i.axis)>s||Mf(o,a,i.axis)>s)continue;const h=kf(xf(n,a),i.axis),d=kf(xf(o,a),i.axis);r.push([Math.min(h,d),Math.max(h,d)])}const l=function(t,e){t.sort((t,e)=>t[0]-e[0]||t[1]-e[1]);const i=[];for(const s of t){const t=i[i.length-1];!t||s[0]>t[1]+e?i.push([...s]):t[1]=Math.max(t[1],s[1])}return i}(r,s).find(([t,e])=>t<=s&&e>=-s);if(!l)return null;const[c,h]=l,d=$f(a,i.axis,-i.half),p=$f(a,i.axis,i.half),u=Math.max(0,-i.half-c),_=Math.max(0,h-i.half),m=u>0?$f(a,i.axis,c):d,g=_>0?$f(a,i.axis,h):p,f=kf(o,i.normal)>=0?1:-1,v=(e,s,n)=>({from:e,to:s,label:[(e[0]+s[0])/2,(e[1]+s[1])/2],axis:i.axis,labelNormal:o,distance:n,roomId:t.roomId,roomSide:f,source:"room-face"});return{left:v(d,m,u),right:v(p,g,_)}}function Tf(t){const e=$f(t.center,t.axis,-t.half),i=$f(t.center,t.axis,t.half),s=$f(t.center,t.axis,Math.min(-t.half,t.targetLo)),n=$f(t.center,t.axis,Math.max(t.half,t.targetHi)),o=(e,i)=>({from:e,to:i,label:[(e[0]+i[0])/2,(e[1]+i[1])/2],axis:t.axis,labelNormal:t.normal,distance:Math.hypot(i[0]-e[0],i[1]-e[1]),source:"host-end"});return[o(e,s),o(i,n)]}function Rf(t,e,i,s){const n=xf(i,e),o=kf(n,n);if(!(o>s*s))return Math.hypot(...xf(t,e))<=s;const a=kf(xf(t,e),n)/o;if(a<-s||a>1+s)return!1;const r=$f(e,n,Math.max(0,Math.min(1,a)));return Math.hypot(...xf(t,r))<=s}function If(t,e,i){let s=!1;for(let n=0,o=e.length-1;nt[1]!=c>t[1]&&t[0]<(l-a)*(t[1]-r)/(c-r)+a&&(s=!s)}return s}function Af(t,e,i,s,n,o){const a=xf(s,i),r=wf(e,a);if(Math.abs(r)<=o)return null;const l=xf(i,t),c=wf(l,a)/r,h=wf(l,e)/r;return c<-o||c>n+o||h<-o||h>1+o?null:Math.max(0,Math.min(n,c))}function zf(t,e,i){const s=Tf(i),n="partition"===t.host?.kind?t.host.id:void 0;return[{base:s[0],direction:[-i.axis[0],-i.axis[1]]},{base:s[1],direction:i.axis}].map(({base:t,direction:i})=>{const s=t.distance,o=function(t,e,i,s,n,o){let a=null;for(const r of s)if(!n||r.partitionId!==n){if(If(t,r.body,o))return 0;for(let s=0;skf(xf(t,n),i));return{center:n,axis:i,normal:s,half:Math.max(0,t.renderedLength)/2,targetLo:Math.min(...o),targetHi:Math.max(...o)}}(t),s=e.rooms.flatMap(t=>{const s=function(t,e,i){const{profile:s}=t;let n=null;for(let t=0;t0))continue;const o=s.poly[t],a=s.poly[(t+1)%s.poly.length],r=xf(a,o),l=Math.hypot(r[0],r[1]);if(!(l>i&&Sf(e.axis,[r[0]/l,r[1]/l],1e-6)))continue;if(Mf(o,e.center,e.axis)>i||Mf(a,e.center,e.axis)>i)continue;const c=kf(xf(o,e.center),e.axis),h=kf(xf(a,e.center),e.axis),d=Math.min(c,h),p=Math.max(c,h);if(d>-e.half+i||p0?d:p<0?-p:0);(!n||u2)return Tf(i);if(s.length){const t=s.map(({room:t,edge:s})=>Pf(t,s,i,e.epsilon));if(t.some(t=>!t))return Tf(i);const n=t;return[...n.map(t=>t.left),...n.map(t=>t.right)]}return zf(t,e,i)}function Ef(t){return!(!t.canEdit||t.kiosk||t.fixedFloor)&&("view"!==t.mode&&("mouse"===t.pointerType&&t.spaceCount>1))}const Nf="1.68.1",Of={badge:"display.badge",icon_ripple:"display.icon_ripple",value:"display.value",static_icon:"display.static_icon"},Lf={badge:"marker.display_hint_badge",icon_ripple:"marker.display_hint_icon_ripple",value:"marker.display_hint_value",static_icon:"marker.display_hint_static_icon"},Hf=2e3,Bf=1e3,qf=1500,Wf=t=>{const e=String(t??"").trim().replace(",",".");if(!/^[+-]?(?:\d+(?:\.\d*)?|\.\d+)$/.test(e))return null;const i=Number(e);return Number.isFinite(i)?i:null},jf=(t,e)=>{if(!t.has(e))return{hit:!1};const i=t.get(e);return t.delete(e),t.set(e,i),{hit:!0,value:i}},Uf=(t,e,i,s)=>{for(t.delete(e),t.set(e,i);t.size>s;){const e=t.keys().next().value;if(void 0===e)break;t.delete(e)}},Gf=new Map;let Vf=0;const Kf=t=>`${window.innerWidth}x${window.innerHeight}|${location.pathname}|${JSON.stringify(t??{})}`;let Yf=1e4;const Jf="houseplan_card_layout_v1",Xf="houseplan_card_cfg_v1",Zf="houseplan_card_zoom_v1",Qf="houseplan_card_nav_v1",tv="houseplan_card_kiosk_v1",ev="houseplan_card_view_v1",iv="hp-dialog, hp-help, hp-color-opacity, hp-device-preview",sv=1e3,nv=[[0,1],[45,.88],[70,.62],[86,.32],[100,0]],ov=(t,e)=>{const i=Math.min(t.x,e.x),s=Math.min(t.y,e.y);return{x:i,y:s,w:Math.max(t.x+t.w,e.x+e.w)-i,h:Math.max(t.y+t.h,e.y+e.h)-s}},av=new Set(["select","draw","column","merge","split","resize","opening","wallthick","delroom"]),rv=2e3,lv=(t,e,i)=>{const s=new Event(e,{bubbles:!0,composed:!0});s.detail=i??{},t.dispatchEvent(s)},cv=t=>{history.pushState(null,"",t),lv(window,"location-changed",{replace:!1})},hv=(t,e)=>{let i,s=null;const n=(...n)=>{clearTimeout(i),s=n,i=window.setTimeout(()=>{i=void 0;const e=s;s=null,e&&t(...e)},e)};return n.flush=()=>{if(void 0===i)return;clearTimeout(i),i=void 0;const e=s;s=null,e&&t(...e)},n.cancel=()=>{clearTimeout(i),i=void 0,s=null},n.pending=()=>void 0!==i,n},dv=t=>{try{t.target?.setPointerCapture?.(t.pointerId)}catch{}};class pv extends ht{constructor(){super(...arguments),this._space="f1",this._layout={},this._serverStorage=!1,this._loadOk=!1,this._serverCanWrite=null,this._loading=!1,this._loadTries=0,this._serverCfg=null,this._cfgRev=0,this._cfgContentFingerprint="",this._unsubCfg=null,this._unsubLayout=null,this._unsubVirtual=null,this._liveSyncAttempt=null,this._liveSyncGeneration=0,this._liveSyncConnection=null,this._layoutRev=0,this._layoutContentFingerprint="",this._virtualLights=mn(null),this._canOptimizeUndo=!1,this._undoKind=null,this._devices=[],this._regSignature="",this._defPos={},this._newSyncKey="",this._tip=null,this._hoverRoom=null,this._pointerModality=new N_(this,()=>this._syncPointerHoverTargets()),this._devicePressAnimations=new Map,this._selId=null,this._toast="",this._mode="view",this._pendingNavMode=null,this._decorTool="select",this._decorStyle={...Rr},this._decorDraft=null,this._decorMove=null,this._decorSel=null,this._decorEraseConfirm=null,this._decorTextDialog=null,this._decorShapeDialog=null,this._backdropDialog=null,this._decorTextSelection={start:0,end:0},this._furnPalette=null,this._dtBox=null,this._dtDrag=null,this._bdDrag=null,this._slide="",this._reducedMotion=!1,this._onMotionChange=t=>{this._reducedMotion=t.matches,this._cancelDevicePressFeedback(),t.matches&&this._modeTransitionPreparing?this._modeTransitionForceAtomic=!0:t.matches&&this._modeTransition.active&&this._cancelModeTransition(!0),this.requestUpdate()},this._editorChromeMode="plan",this._modeTransitionVisual=null,this._modeTransitionPreparing=!1,this._modeTransitionForceAtomic=!1,this._modeTransitionRequest=0,this._modeTransitionTargetZoom=1,this._modeTransitionEditorCamera=null,this._modeTransition=new Tg({frame:t=>this._applyModeTransitionFrame(t),settled:t=>this._settleModeTransition(t)}),this._editorSecondary=new W_({root:()=>this.renderRoot,requestUpdate:()=>this.requestUpdate(),updateComplete:()=>this.updateComplete,clearTip:()=>{this._tip=null}}),this._editorSecondaryCopy={groupActive:(t,e)=>this._t("editor.group_active",{group:t,item:e}),openGroup:t=>this._t("editor.open_group",{group:t}),disabledAction:(t,e)=>this._t("editor.disabled_action",{action:t,reason:e})},this._tool="draw",this._geometryHistory=new fg(50),this._wallDialog=null,this._drawWallField=null,this._activeDraftId=null,this._resumeDraftBySpace={},this._physicalSel=null,this._physicalDialog=null,this._partitionDeleteDialog=null,this._roomDeleteDialog=null,this._physicalDrag=null,this._physicalRotate=null,this._physicalLastTap=null,this._physicalPickCycle=null,this._wallUnionCacheValue=null,this._wallUnionPool=new Map,this._isoGeometryCache=new Map,this._isoFallback=new Set,this._openingTunnelCache=null,this._openingWallIndexCache=new Map,this._openingPlacementIntervalsCache=null,this._openingDimensionContextCache=null,this._planSnapGeometryCache=null,this._planStructuralGeometryCache=null,this._hiddenWallDiagnosticCache=null,this._physicalBodiesCache=null,this._lightPhysicalBodiesCache=null,this._cleanFloorCache=new Map,this._innerContourCache=new Map,this._glowClipCache=new Map,this._glowGeometryWarnings=new Set,this._lightBarrierCache=null,this._lightBarrierPool=new Map,this._glowFeatherUnits=null,this._glowRenderedSources=new Map,this._glowLastAppearance=new Map,this._glowEnteringSources=new Set,this._glowEnterRafs=new Map,this._glowFadeTimers=new Map,this._glowFeatherSuspendUntil=0,this._glowFeatherResumeTimer=0,this._glowSourceSeq=0,this._glowScreenBlend=!1,this._duplicateColumnId=null,this._duplicateColumnTimer=0,this._rszSel=null,this._rszDrag=null,this._rszEligibilityCache=null,this._rszPreview=null,this._rszLive=null,this._path=[],this._cursorPt=null,this._planSnapHover=null,this._mergeSel=null,this._openingPreset=null,this._openingRebindId=null,this._openingPresetRevision=0,this._openingHoverCandidate=null,this._openingJambBlockCm=null,this._openingDialog=null,this._openingInfo=null,this._opDrag=null,this._opMeasure=null,this._mergeDialog=null,this._splitSel=null,this._pendingSplit=null,this._wallFaceBatch=null,this._wallRepairDiagnostic=null,this._wallFaceGraphCache=[],this._areaSel="",this._nameSel="",this._roomDialog=!1,this._roomEditId=null,this._roomFill="",this._roomCustomFill=null,this._roomTempSrc="",this._roomHumSrc="",this._roomSrcOpen=null,this._roomSrcFilter="",this._roomNameScale=1,this._roomLabelScale=1,this._zoom=1,this._view=null,this._zoomBySpace={},this._viewModeSnap=null,this._pointers=new Map,this._panStart=null,this._panLock=null,this._pinchStart=null,this._suppressClick=!1,this._touchContacts=new Map,this._touchSequenceMultitouch=!1,this._touchClickBlockUntil=0,this._connectedPath="",this._routeDepartureHandled=!1,this._onLocationChanged=()=>{this._connectedPath&&location.pathname!==this._connectedPath?this._leaveCardRoute():location.pathname===this._connectedPath&&(this._routeDepartureHandled=!1)},this._touchGestureGuard={capture:!0,handleEvent:t=>this._guardTouchGesture(t)},this._hdrH=118,this._booting=!0,this._bootFading=!1,this._bootSettling=!1,this._bootSettleRaf=0,this._bootLastH=-1,this._bootStart=0,this._bootLastChange=0,this._bootSoft=!1,this._tapConfirm=null,this._onboardingShown=!1,this._rulesDialog=null,this._preflightClipboardFallback=null,this._haIntegrationVersion=null,this._alignDialog=null,this._settingsDialog=null,this._backupExportDialog=null,this._backupImportDialog=null,this._sunRaysCache=null,this._dayCycleTimer=0,this._dayCycleClockKey="",this._compassDrag=!1,this._importDialog=null,this._importQueue=[],this._importTotal=0,this._rulesCompiledSrc="",this._infoCard=null,this._nativeMoreInfoEntity=null,this._markerDialog=null,this._spaceDialog=null,this._keyHandler=t=>this._onKey(t),this._warmVp=null,this._warmVpArmed=!1,this._warmLongReturn=!1,this._warmRevivePending=!1,this._warmGen=++Vf,this._warmKey=null,this._warmSlot=null,this._hashApplied=!1,this._navApplied=!1,this._labs={active:Object.freeze([]),space:""},this._viewPreference={},this._renderProjection="flat",this._kioskScale={icon:1,font:1},this._kioskDialog=!1,this._activityRt=new Map,this._vacRt=new Map,this._vacViewKey="",this._vacLastView=null,this._vacRaf=0,this._vacSrvTrails={},this._vacJumpOnce=!1,this._continuity=this._newContinuityController(),this._continuityHistory=[],this._continuityEpoch=0,this._continuityDataReady=!0,this._continuityPaintToken=-1,this._continuityDisposed=!1,this._renderSnapshotAt=Date.now(),this._hassSequence=0,this._visibleDeviceSnapshot=null,this._candidateDeviceSnapshot=null,this._stagedDeviceSnapshotToken=-1,this._capturedSnapshotSequence=-1,this._capturedSnapshotDevices=null,this._capturedSnapshotLayout=null,this._capturedSnapshotActivity="",this._capturedSnapshotConfigEpoch=-1,this._capturedSnapshotVirtual="",this._lastValidStageSize=null,this._pendingRefitSize=null,this._refitRaf=0,this._pageVisibility=t=>{if(this._continuity.visibility(t),this._dayCycleVisibility(t),"hidden"===t.kind)return this._clearTransientHover(!0),this._cancelDevicePressFeedback(),void(this._modeTransitionPreparing?this._modeTransitionForceAtomic=!0:this._cancelModeTransition(!0));if(this._vacJumpOnce=!0,!t.long){const t=Date.now();let e=!1;for(const i of this._activityRt.values())!i.flashKind||(i.expiresAt||i.flashTs+I_)>t||(i.flashTs=0,i.flashKind=null,i.expiresAt=0,e=!0);return void(e&&this.requestUpdate())}Date.now()-this._renderSnapshotAt>1e3&&this._continuity.note("device-snapshot-stale"),this._continuityDataReady=!1,this._continuityPaintToken=-1,this._resumeSettling=!0,this._loading?this.requestUpdate():this._loadFromServer()},this._resumeSettling=!1,this._viewportInvalidAt=0,this._vacFit=null,this._vacAllCamerasFor=null,this._vacAllCameraCache=null,this._vacCalConfirm=null,this._kioskDots=!1,this._cyclePausedUntil=0,this._swipeStart=null,this._tabDrag=null,this._tabDragRelease=null,this._tabSuppressClick=!1,this._tabOrderWarned=!1,this._lastTap=0,this._onLabsSnapshot=t=>{const e=this._effectiveProjection();this._labs=t;const i=this._effectiveProjection();this._convertProjectionView(e,i),this.requestUpdate()},this._onHashChange=()=>{if(this._hasFixedFloor)return;const t=this._hashSpace();if(t&&this._model.find(e=>e.id===t)&&t!==this._space){if(this._wallFaceBatch&&this._roomDialogCancel(),"plan"===this._mode&&"draw"===this._tool&&!this._finishWallChain())return;this._activeDraftId&&(this._resumeDraftBySpace[this._space]=this._activeDraftId),this._commitSpace(t),this._selId=null,this._path=[],this._clearPlanSnapHover(),this._clearOpeningPlacement(!0),this._tool="draw",this._activeDraftId=null,this._draftSegmentCms=[],this._closingWallCm=null,"plan"===this._mode&&"draw"===this._tool&&this._resumeLastDraft(),this._restoreZoom(),this.requestUpdate()}},this._drag=null,this._rlResize=null,this._holdFired=!1,this._retryContinuity=()=>{this._continuityDataReady=!1,this._continuityPaintToken=-1,this._continuity.retry(this._continuity.recoveryReason||"plan"),this._loading||this._loadFromServer()},this._cfgEpoch=0,this._modelCache=null,this._emptySpaceStateActive=!1,this._decorSnapCache=null,this._markerPreviewMemo=null,this._markerPreviewDevicesMemo=null,this._showHidden=!1,this._connHooked=null,this._connectionWasLost=!1,this._haRegistryConnection=null,this._haRegistryRev=-1,this._haBindingCacheKey="",this._planHassMemo=null,this._onHaRegistryUpdate=()=>{const t=An(this.hass);t.revision===this._haRegistryRev&&this._devices.length||(this._haRegistryRev=t.revision,this._planHassMemo=null,this._regSignature="",this._maybeRebuildDevices(),this.requestUpdate())},this._onConnReady=()=>{if(this._loadTries=0,clearTimeout(this._loadRetryTimer),this._loadRetryTimer=void 0,function(t){const e=Cn(t);e&&(Tn(t,e),Rn(t,e))}(this.hass),this._saveConfigDebounced.pending()&&this._saveConfigDebounced.flush(),this._cfgWriting)return clearTimeout(this._reloadRetry),void(this._reloadRetry=window.setTimeout(this._onConnReady,400));!this._connectionWasLost&&this._continuity.hasCompleteFrame?this._beginContinuityCandidate("connection-ready",!1,"plan"):(this._continuityDataReady=!1,this._continuityPaintToken=-1),this._loading||this._loadFromServer()},this._onConnLost=()=>{this._booting&&!this._continuity.hasCompleteFrame||(this._connectionWasLost=!0,this._continuityDataReady=!1,this._continuityPaintToken=-1,this._continuity.connectionLost())},this._signer=new $d(()=>this.requestUpdate()),this._dirtyPos=new Set,this._sentPos=new Map,this._persistLayout=hv(()=>{if(this._serverStorage){const t=[...this._dirtyPos];this._dirtyPos.clear();for(const e of t){const t=ol(this._layout[e]);t&&(this._layout={...this._layout,[e]:t},this._sentPos.set(e,t),this.hass.callWS({type:"houseplan/layout/update",device_id:e,pos:t}).then(t=>this._noteLayoutRev(t)).catch(t=>this._showToast(this._t("toast.pos_save_failed",{err:this._errText(t)}))).finally(()=>{this._sentPos.get(e)===t&&this._sentPos.delete(e)}))}this._cacheSnapshot()}else this._layout=al(Gr(this._layout)),localStorage.setItem(Jf,JSON.stringify(this._layout))},600),this._frame=null,this._showFar=!1,this._writesPending=0,this._writeChain=Promise.resolve(),this._pendingPhysicalWrites=new Map,this._undoGeometry=()=>{if(this._physicalDrag||this._physicalRotate)return void this._cancelPhysicalGesture();if(this._decorDraft)return this._decorDraft=null,void this.requestUpdate();if(this._decorMove||this._dtDrag||this._bdDrag)return void this._cancelDecorGesture();if(this._rszDrag)return void this._rszCancelDrag();const t=this._geometryHistory.undo();t&&(this._applyGeometryState(t.before,!0)?this._showToast(this._t("history.undone",{name:t.name})):this._geometryHistory.clear())},this._redoGeometry=()=>{if(this._physicalDrag||this._physicalRotate)return void this._cancelPhysicalGesture();if(this._decorDraft)return this._decorDraft=null,void this.requestUpdate();if(this._decorMove||this._dtDrag||this._bdDrag)return void this._cancelDecorGesture();if(this._rszDrag)return void this._rszCancelDrag();const t=this._geometryHistory.redo();t&&(this._applyGeometryState(t.after,!0)?this._showToast(this._t("history.redone",{name:t.name})):this._geometryHistory.clear())},this._saveConfigDebounced=hv(()=>{this._serverCfg&&this._writeConfig().catch(t=>{const e=!0===t?.physicalGeometryRolledBack;"geometry-unsafe"!==t?.code&&("wall_model_client_outdated"===t?.code?this._showToast(this._t("toast.wall_model_client_outdated")):"conflict"===t?.code?(this._showToast(this._t("toast.conflict")),e||(this._cancelPath(),this._reloadConfigOnly(!0))):this._showToast(this._t("toast.cfg_save_failed",{err:this._errText(t)})),e&&this._reloadRejectedPhysicalWrite())})},500),this._draftSegmentCms=[],this._closingWallCm=null,this._savePhysicalDialog=()=>{const t=this._physicalDialog,e=this._curSpaceCfg,i=this._spaceModel();if(!t||!e||!i)return;const s=Wf(t.cm);if(null==s)return void this._showPhysicalRange("column"===t.kind?jc:100,"column"===t.kind?1:0);const n=this._imperial?2.54*s:s,o="column"===t.kind?jc:100,a="column"===t.kind?1:0;if(!Number.isFinite(n)||no)return void this._showPhysicalRange(o,a);if("column"===t.kind){const e=i.wall_columns.find(e=>e.id===t.id);if(!e)return;const s=Wf(t.angle||"0");if("circle"!==t.shape&&(null==s||s<0||s>=90))return void this._showToast(this._t("toast.physical_angle"));const o="circle"===t.shape?{id:t.id,shape:"circle",center:e.center,cm:n}:{id:t.id,shape:"square",center:e.center,cm:n,angle:s};if(i.wall_columns.some(e=>e.id!==t.id&&uh(e,o,.02*this._gridPitch)))return void this._showToast(this._t("toast.column_duplicate"))}const r=this._geometrySnapshot();if("partition"===t.kind){const i=(e.partitions||[]).find(e=>e.id===t.id);if(i&&0===n&&f_(e.openings,{kind:"partition",id:t.id}))return void this._showToast(this._t("toast.zero_wall_opening_conflict"));i&&(i.cm=n)}else if("column"===t.kind){const i=(e.wall_columns||[]).find(e=>e.id===t.id);i&&(i.cm=Gc(n),i.shape="circle"===t.shape?"circle":"square","square"===i.shape?i.angle=Wf(t.angle||"0"):delete i.angle)}else{const i=(e.room_drafts||[]).find(e=>e.id===t.id);i?.segments?.[t.segment||0]&&(i.segments[t.segment||0].cm=n)}const l=this._commitPhysicalGeometry(this._t("history.physical_edit"),r);this._physicalDialog=null,l||this.requestUpdate()},this._deletePhysicalSelection=()=>{const t=this._physicalSel,e=this._curSpaceCfg;if(!t||!e)return;if("draft"===t.kind)return void this._deleteDraftWhole();const i=this._geometrySnapshot();if("partition"===t.kind){const i=(e.openings||[]).filter(e=>"partition"===e.host?.kind&&e.host.id===t.id).sort((t,e)=>(t.host?.t||0)-(e.host?.t||0));if(i.length)return void(this._partitionDeleteDialog={id:t.id,openings:i.map(t=>JSON.parse(JSON.stringify(t)))})}const s="partition"===t.kind?"partitions":"column"===t.kind?"wall_columns":"room_drafts";e[s]=(e[s]||[]).filter(e=>e.id!==t.id),e[s].length||delete e[s],this._activeDraftId===t.id&&this._cancelPath(),this._physicalSel=null,this._physicalDialog=null,this._commitPhysicalGeometry(this._t("history.physical_delete"),i)},this._confirmPartitionDelete=()=>{const t=this._partitionDeleteDialog,e=this._curSpaceCfg;if(!t||!e)return;const i=this._geometrySnapshot();e.partitions=(e.partitions||[]).filter(e=>e.id!==t.id),e.partitions.length||delete e.partitions,e.openings=(e.openings||[]).filter(e=>"partition"!==e.host?.kind||e.host.id!==t.id),e.openings.length||delete e.openings,this._partitionDeleteDialog=null,this._physicalSel=null,this._physicalDialog=null,this._commitPhysicalGeometry(this._t("history.physical_delete"),i)},this._deleteDraftWhole=()=>{const t="draft"===this._physicalDialog?.kind?this._physicalDialog.id:"draft"===this._physicalSel?.kind?this._physicalSel.id:null,e=this._curSpaceCfg;if(!t||!e||!confirm(this._t("confirm.delete_draft")))return;const i=this._geometrySnapshot();e.room_drafts=(e.room_drafts||[]).filter(e=>e.id!==t),e.room_drafts.length||delete e.room_drafts,this._activeDraftId===t&&this._cancelPath(),this._physicalSel=null,this._physicalDialog=null,this._commitPhysicalGeometry(this._t("history.physical_delete"),i)},this._deleteDraftSegment=()=>{const t=this._physicalDialog,e=this._curSpaceCfg;if(!t||"draft"!==t.kind||!e)return;if(!confirm(this._t("confirm.delete_draft_segment")))return;const i=(e.room_drafts||[]).findIndex(e=>e.id===t.id);if(i<0)return;const s=e.room_drafts[i],n=Math.max(0,Math.min(s.segments.length-1,t.segment||0)),o=[],a=s.points.slice(0,n+1),r=s.points.slice(n+1);if(a.length>=2&&o.push({id:s.id,points:a,segments:s.segments.slice(0,n)}),r.length>=2&&o.push({id:o.length?`${s.id}-${Date.now().toString(36)}`:s.id,points:r,segments:s.segments.slice(n+1)}),2===o.length&&e.room_drafts.length>=200)return void this._showToast(this._t("toast.physical_limit"));const l=this._geometrySnapshot();e.room_drafts.splice(i,1,...o),e.room_drafts.length||delete e.room_drafts,this._activeDraftId===s.id&&this._cancelPath(),this._physicalDialog=null,this._physicalSel=o.length?{kind:"draft",id:o[0].id}:null,this._commitPhysicalGeometry(this._t("history.draft_segment_delete"),l)},this._confirmRoomDelete=t=>{const e=this._roomDeleteDialog,i=this._curSpaceCfg,s=this._spaceModel();if(!e||!i||!s)return;const n=s.rooms.find(t=>t.id===e.roomId);if(!n)return void(this._roomDeleteDialog=null);const o=this._openCuts(),a=$u(dc(s.rooms,this._spaceWalls,o,this._wallKeyPitch,this._cellCm,this._gridPitch,sv).filter(t=>t.roomId===n.id),s.partitions,this._openingsR.map(t=>({...t,x:t.rx,y:t.ry})),.02*this._gridPitch),r=new Set(a.materialize.filter(t=>!t.reusePartitionId).map(t=>t.interval.key)).size;if(t&&(i.partitions||[]).length+r>rv)return void this._showToast(this._t("toast.physical_limit"));const l=this._geometrySnapshot(),c=pc(s.rooms,this._spaceWalls,o,this._wallKeyPitch,this._cellCm,this._gridPitch,sv);if(t){i.partitions||=[];const t=new Map,e=new Map,s=t=>{const e=(i.wall_segments||[]).find(e=>{const i=[Number(e.a?.[0])*sv,Number(e.a?.[1])*sv],s=[Number(e.b?.[0])*sv,Number(e.b?.[1])*sv];return this._samePt(t.a,i)&&this._samePt(t.b,s)||this._samePt(t.a,s)&&this._samePt(t.b,i)});return"string"==typeof e?.id&&e.id?e.id:null},n=Date.now().toString(36);for(const o of a.materialize){let a=o.reusePartitionId?i.partitions.find(t=>t.id===o.reusePartitionId):e.get(o.interval.key);a||(a={id:s(o.interval)||`partition-room-${n}-${e.size}`,a:[o.interval.a[0]/sv,o.interval.a[1]/sv],b:[o.interval.b[0]/sv,o.interval.b[1]/sv],cm:o.interval.cm},i.partitions.push(a),e.set(o.interval.key,a)),t.set(o.interval.key,a)}for(const e of i.openings||[]){const i=a.openingIntervals.get(e.id),s=i?t.get(i):null,n=this._openingsR.find(t=>t.id===e.id);if(!s||!n)continue;const o={a:[s.a[0]*sv,s.a[1]*sv],b:[s.b[0]*sv,s.b[1]*sv]};e.host={kind:"partition",id:s.id,t:Su([n.rx,n.ry],o)}}}else if(a.removeOpeningIds.length){const t=new Set(a.removeOpeningIds);i.openings=(i.openings||[]).filter(e=>!t.has(e.id)),i.openings.length||delete i.openings}i.rooms=i.rooms.filter(t=>t.id!==n.id),this._cfgEpoch++;const h=this._normalizeWalls(c,this._openCuts());h.length?i.walls=h:delete i.walls,this._roomDeleteDialog=null,this._commitPhysicalGeometry(this._t(t?"history.delete_room_keep_walls":"history.delete_room_with_walls"),l),this._regSignature="",this._maybeRebuildDevices(),this.requestUpdate()},this._rebindPartitionOpening=()=>{const t=this._openingDialog;if(!t?.id)return;const e=t.id;this._activateMarkupTool("opening"),"opening"===this._tool&&(this._openingRebindId=e,this._openingPreset={type:t.type,lengthCm:t.lengthCm,flipH:t.flipH,flipV:t.flipV,revision:++this._openingPresetRevision},this._openingDialog=null,this._openingHoverCandidate=null)},this._keepClosedAsPartitions=()=>{if(this._wallFaceBatch)return void this._decideWallFace(!1);if(!this._contourClosed||this._pendingSplit||!this._curSpaceCfg)return;const t=this._curSpaceCfg,e=this._path.slice(0,-1);if((t.partitions||[]).length+e.length>rv)return void this._showToast(this._t("toast.physical_limit"));const i=this._geometrySnapshot(),s=Xp(e.length,[...this._draftSegmentCms,this._closingWallCm??void 0],this._drawWallCm,ll);t.partitions||=[];const n=Date.now().toString(36),o=this._activeDraftId?(t.room_drafts||[]).find(t=>t.id===this._activeDraftId):null,a=this._draftSegmentsForPath(this._path,o,s);for(let i=0;it.id!==this._activeDraftId),t.room_drafts.length||delete t.room_drafts),this._commitPhysicalGeometry(this._t("history.contour_to_partitions"),i),this._roomDialog=!1,this._path=[],delete this._resumeDraftBySpace[this._space],this._activeDraftId=null,this._draftSegmentCms=[],this._closingWallCm=null},this._toggleServerPlans=async()=>{const t=this._spaceDialog;if(t)if(t.pickSaved)this._spaceDialog={...t,pickSaved:!1};else{this._spaceDialog={...t,pickSaved:!0,savedBusy:!0};try{const t=await this.hass.callWS({type:"houseplan/plans/list"}),e=this._spaceDialog;e&&(this._spaceDialog={...e,saved:t?.plans||[],savedBusy:!1})}catch(t){const e=this._spaceDialog;e&&(this._spaceDialog={...e,saved:[],savedBusy:!1}),this._showToast(this._t("toast.plans_list_failed",{err:this._errText(t)}))}}},this._aspectJob=null,this._dayCycleTick=()=>{if(!this.isConnected||"hidden"===this.ownerDocument.visibilityState)return;const t=this._dayCycleState();if(!t)return this._dayCycleTimer&&(clearInterval(this._dayCycleTimer),this._dayCycleTimer=0),void(this._dayCycleClockKey="");const e=mr(t);e!==this._dayCycleClockKey&&(this._dayCycleClockKey=e,this.requestUpdate())},this._sunShown=!1,this._sunOut=!1,this._sunOutTimer=0,this._openSettingsDialog=()=>{if(!this._norm)return;const t=this._glowRadiusCm,e=this._imperial?Math.round(t/30.48*10)/10:Math.round(t)/100;this._settingsDialog={colors:JSON.parse(JSON.stringify(this._fillColors)),glowRadius:e,bgColor:hs(this._settings,{bgColor:null})||null,northDeg:$r(this._settings,{}),bgMode:Sr(this._settings,{}),sunRays:Mr(this._settings,{}),busy:!1}},this._reportedPreflightFingerprint=null,this._openAlignDialog=()=>this._previewAlignDialog(!1),this._toggleOptimizeLivePositions=()=>{const t=this._alignDialog;t&&!t.busy&&t.report.liveMissingPositions.length&&this._previewAlignDialog(!t.removeLiveMissingPositions)},this._optimizeUndoBusy=!1,this._openBackupExport=()=>{this._settingsDialog=null,this._backupExportDialog={kind:"full",planOnly:!1,busy:!1,error:""}},this._openRulesDialog=()=>{if(!this._norm)return;const t=this._settings.icon_rules,e=(t&&t.length?t:Jt).map(t=>({...t}));this._rulesDialog={rules:e,test:"",busy:!1}},this._climateCache=null,this._gearPtCache=new WeakMap}get _canEdit(){return!!this._norm&&(!0===this._serverCanWrite||!1!==this._serverCanWrite&&!0===this.hass?.user?.is_admin)}get _kiosk(){return!!this._config?.kiosk}_showKioskDots(){this._kioskDots=!0,clearTimeout(this._kioskDotsTimer),this._kioskDotsTimer=window.setTimeout(()=>this._kioskDots=!1,2500)}get _modeTransitionBusy(){return this._modeTransitionPreparing||this._modeTransition.active}_cssColor(t,e){const i=String(t||"").trim();if(!i)return e;const s=document.createElement("span");s.style.cssText=`position:absolute;visibility:hidden;color:${i}`,this.renderRoot.append(s);const n=getComputedStyle(s).color||e;return s.remove(),n}_currentModeVisual(t=this._mode){const e=this._modeTransition.presented||this._modeTransitionVisual;if(e)return{...e,viewport:{...e.viewport,viewBox:{...e.viewport.viewBox}}};const i=this._stageEl;if(!i||i.clientWidth<=0||i.clientHeight<=0)return null;const s=this.renderRoot.querySelector(".editorchrome"),n=this._viewOr(this._baseVb()),o=this.renderRoot.querySelector(".hp-paper"),a=this.renderRoot.querySelector(".hp-backdrop"),r=this.renderRoot.querySelector(".zoomwrap"),l=r?getComputedStyle(r).filter:"",c=Number(/brightness\(([^)]+)\)/.exec(l)?.[1]);return{presentedMode:t,editorChromeHeight:"view"===t?0:s?.getBoundingClientRect().height||0,stageWidth:i.clientWidth,stageHeight:i.clientHeight,viewport:Sg(n,i.clientWidth),stageColor:getComputedStyle(i).backgroundColor||"rgb(255, 255, 255)",paperColor:o?getComputedStyle(o).fill:"rgb(255, 255, 255)",sceneBrightness:Number.isFinite(c)?c:1,architectureOpacity:"decor"===t?.35:1,backdropOpacity:a&&Number(getComputedStyle(a).opacity)||1,viewWeight:"view"===t?1:0,editorWeight:"view"===t?0:1,toolbarContentOpacity:"view"===t?0:1}}_viewForModeTarget(t,e,i,s,n){const o=Ni(this._baseVb(),s/Math.max(1,n)),a=Math.min(pv.ZOOM_MAX,Math.max(pv.ZOOM_MIN,t)),r=o.w/a,l=o.h/a,c=e??o.x+o.w/2,h=i??o.y+o.h/2;return this._clampView({x:c-r/2,y:h-l/2,w:r,h:l},o)}_targetStageColor(t){return"view"!==t?"rgb(255, 255, 255)":this._cssColor(this._stageBg(this._spaceDisplayForRender()),this._cssColor("var(--ha-card-background, var(--card-background-color, #111))","rgb(17, 17, 17)"))}_targetPaperColor(t){return"view"===t&&this._spaceModel()?.bg?this._cssColor("var(--ha-card-background, var(--card-background-color, #111))","rgb(17, 17, 17)"):"rgb(255, 255, 255)"}_targetBrightness(t){return 1}_applyModeTransitionFrame(t){t.targetMode===this._mode&&(this._modeTransitionVisual=t.presented,this._view={...t.presented.viewport.viewBox},this.requestUpdate())}_settleModeTransition(t){if(t.targetMode!==this._mode)return;const e=this._modeTransitionRequest;this._view={...t.to.viewport.viewBox},this._zoom=this._modeTransitionTargetZoom,this._modeTransitionVisual=null,this._modeTransitionPreparing=!1,this._lastValidStageSize=[t.to.stageWidth,t.to.stageHeight],"view"===this._mode&&(this._saveZoom(),this._viewModeSnap=null,this._modeTransitionEditorCamera=null),this.requestUpdate(),this.updateComplete.then(()=>{if(!this.isConnected||e!==this._modeTransitionRequest||this._modeTransitionBusy||t.targetMode!==this._mode)return;const i=this._stageEl;if(i&&i.clientWidth>0&&i.clientHeight>0&&(Math.abs(i.clientWidth-t.to.stageWidth)>.5||Math.abs(i.clientHeight-t.to.stageHeight)>.5)){const t=this._view;this._lastValidStageSize=[i.clientWidth,i.clientHeight],this._applyView(this._zoom,t?t.x+t.w/2:void 0,t?t.y+t.h/2:void 0),this.requestUpdate()}const s=this.renderRoot.activeElement;(!s||!s.isConnected||!!s.closest?.(".editorchrome, .stage"))&&this.renderRoot.querySelector(".modetab.active")?.focus?.({preventScroll:!0})})}_cancelModeTransition(t=!0){const e=!!this._modeTransition.state;this._modeTransitionRequest++,this._modeTransitionPreparing=!1,this._modeTransitionForceAtomic=!1,this._modeTransition.cancel(t),t&&e||(this._modeTransitionVisual=null)}_adoptMode(t){this._cancelModeTransition(!1),this._mode=t,"view"!==t&&(this._editorChromeMode=t)}_commitViewModeAtomic(t,e,i,s){if(this._modeTransitionPreparing=!1,this._modeTransitionVisual=null,this._modeTransitionForceAtomic=!1,this._zoom=e,t){const n=this._stageEl?.clientWidth||t.stageWidth,o=Math.max(1,t.stageHeight+t.editorChromeHeight);this._view=this._viewForModeTarget(e,i,s,n,o),this._lastValidStageSize=[n,o]}else this._view=null;this._viewModeSnap=null,this._modeTransitionEditorCamera=null,this._saveZoom(),this.requestUpdate()}_prepareModeTransition(t,e,i,s,n,o){this.updateComplete.then(()=>{if(!this.isConnected||t!==this._modeTransitionRequest||this._mode!==i)return void(t===this._modeTransitionRequest&&(this._modeTransitionPreparing=!1,this._modeTransitionVisual=null,this._modeTransitionForceAtomic=!1,this.requestUpdate()));const a=this.renderRoot.querySelector(".editorchrome"),r=a?.querySelector(".editorchrome-inner"),l="view"===i?0:r?.scrollHeight||r?.getBoundingClientRect().height||0,c=Math.max(1,e.stageHeight+e.editorChromeHeight),h=Math.max(1,c-l),d=this._stageEl?.clientWidth||e.stageWidth;if(d<=0||h<=0)return this._modeTransitionPreparing=!1,this._modeTransitionVisual=null,this._applyView(s,n,o),void this.requestUpdate();const p=this._viewForModeTarget(s,n,o,d,h),u={presentedMode:i,editorChromeHeight:l,stageWidth:d,stageHeight:h,viewport:Sg(p,d),stageColor:this._targetStageColor(i),paperColor:this._targetPaperColor(i),sceneBrightness:this._targetBrightness(i),architectureOpacity:"decor"===i?.35:1,backdropOpacity:"decor"===i&&"backdrop"!==this._decorTool?.5:1,viewWeight:"view"===i?1:0,editorWeight:"view"===i?0:1,toolbarContentOpacity:"view"===i?0:1};this._modeTransitionPreparing=!1;const _=this._modeTransitionForceAtomic;this._modeTransitionForceAtomic=!1,this._modeTransition.start(e,u,i,this._reducedMotion||_?0:220)})}get _hasFixedFloor(){return!!this._config&&Object.prototype.hasOwnProperty.call(this._config,"floor")}_fixedFloorState(t=this._model,e=this._loadOk){const i=this._config?.floor,s=function(t){if(!t.hasFloor)return{kind:"absent"};const e=t.floor;if("string"==typeof e)return e.length?t.spaceIds.includes(e)?{kind:"valid",id:e,source:"id"}:{kind:"invalid",reason:"unknown-id",value:e}:{kind:"invalid",reason:"empty-id",value:e};if("number"==typeof e){if(!Number.isFinite(e))return{kind:"invalid",reason:"non-finite-index",value:e};if(!Number.isInteger(e))return{kind:"invalid",reason:"fractional-index",value:e};if(e<0)return{kind:"invalid",reason:"negative-index",value:e};const i=t.spaceIds[e];return void 0===i?{kind:"invalid",reason:"out-of-range-index",value:e}:{kind:"valid",id:i,source:"index"}}return{kind:"invalid",reason:"invalid-type",value:e}}({spaceIds:t.map(t=>t.id),hasFloor:this._hasFixedFloor,floor:i});return!this._hasFixedFloor||e?s:"number"==typeof i?"valid"===s.kind||"invalid"===s.kind&&"out-of-range-index"===s.reason?{kind:"pending",value:i}:s:"valid"===s.kind||"invalid"===s.kind&&"unknown-id"!==s.reason?s:{kind:"pending",value:i}}_canCommitSpace(t,e=!1){if(e||!this._hasFixedFloor)return!0;const i=this._fixedFloorState();return"valid"===i.kind&&i.id===t}_commitSpace(t,e=!1){return!!this._canCommitSpace(t,e)&&(t!==this._space&&(this._clearTransientHover(!0),this._cancelDevicePressFeedback()),this._space=t,!0)}_slideTo(t,e){if(t===this._space)return!0;if(!this._canCommitSpace(t))return!1;if(this._wallFaceBatch&&this._roomDialogCancel(),"plan"===this._mode&&"draw"===this._tool&&!this._finishWallChain())return!1;this._cancelModeTransition(!0);const i=window.matchMedia?.("(prefers-reduced-motion: reduce)")?.matches;return this._activeDraftId&&(this._resumeDraftBySpace[this._space]=this._activeDraftId),this._commitSpace(t),this._path=[],this._clearPlanSnapHover(),this._clearOpeningPlacement(!0),this._tool="draw",this._activeDraftId=null,this._draftSegmentCms=[],this._closingWallCm=null,this._selId=null,this._physicalSel=null,this._editorSecondary.closeForNavigation(),this._physicalDialog=null,this._physicalDrag=null,"plan"===this._mode&&"draw"===this._tool&&this._resumeLastDraft(),this._restoreZoom(),i||(this._slide=e,clearTimeout(this._slideTimer),this._slideTimer=window.setTimeout(()=>{this._slideTimer=void 0,this._slide="",this.requestUpdate()},190),this.requestUpdate()),!0}get _canReorderTabs(){return Ef({canEdit:this._canEdit,kiosk:this._kiosk,mode:this._mode,pointerType:"mouse",spaceCount:this._model.length,fixedFloor:this._hasFixedFloor})}_tabPointerDown(t,e){Ef({canEdit:this._canEdit,kiosk:this._kiosk,mode:this._mode,pointerType:t.pointerType,spaceCount:this._model.length,fixedFloor:this._hasFixedFloor})&&(dv(t),this._tabDragRelease=t=>this._tabPointerUp(t),window.addEventListener("pointerup",this._tabDragRelease),window.addEventListener("pointercancel",this._tabDragRelease),this._tabDrag={id:e,pointerId:t.pointerId,x:t.clientX,y:t.clientY,moved:!1,targetId:null,placement:null})}_tabDropTargetAt(t,e,i){const s=this._model.map(t=>t.id),n=s.indexOf(i);if(n<0)return null;const o=this.renderRoot.querySelectorAll('[data-hp="space-tab"]');for(const a of o){const o=a.dataset.id||"";if(!o||o===i)continue;const r=a.getBoundingClientRect();if(tr.right||er.bottom)continue;const l=s.indexOf(o);return l<0?null:{targetId:o,placement:l=4)))return;var i,s;const n=this._tabDropTargetAt(t.clientX,t.clientY,e.id);e.moved&&e.targetId===n?.targetId&&e.placement===n?.placement||(this._tabDrag={...e,moved:!0,targetId:n?.targetId||null,placement:n?.placement||null})}_tabPointerUp(t){const e=this._tabDrag;if(e&&e.pointerId!==t.pointerId)return;const i="pointerup"===t.type&&e?.moved?this._tabDropTargetAt(t.clientX,t.clientY,e.id):null;"pointerup"===t.type&&e?.moved&&this._suppressNextTabClick(),this._endTabDrag(),e?.moved&&i&&this._commitTabOrder(e.id,i.targetId)}_endTabDrag(){this._tabDrag=null,this._tabDragRelease&&(window.removeEventListener("pointerup",this._tabDragRelease),window.removeEventListener("pointercancel",this._tabDragRelease),this._tabDragRelease=null)}_tabClick(t){if(this._tabSuppressClick)return this._tabSuppressClick=!1,clearTimeout(this._tabSuppressClickTimer),void(this._tabSuppressClickTimer=void 0);this._pickSpace(t)}_suppressNextTabClick(){this._tabSuppressClick=!0,clearTimeout(this._tabSuppressClickTimer),this._tabSuppressClickTimer=window.setTimeout(()=>{this._tabSuppressClick=!1,this._tabSuppressClickTimer=void 0},0)}_commitTabOrder(t,e){const i=this._serverCfg;if(!i||!this._canReorderTabs)return;const s=this._model.map(t=>t.id),n=function(t,e,i){const s=t.indexOf(e),n=t.indexOf(i);if(s<0||n<0||s===n)return t;const o=t.slice();return o.splice(s,1),o.splice(n,0,e),o}(s,t,e);if(n===s)return;const o=new Map(this._devices.map(t=>[String(t.id),String(t.area||"")])),a=function(t,e,i,s=()=>""){if(!i)return[];const n=[];for(const o of t){if(!o||!0===o.removed)continue;const t="string"==typeof o.id?o.id:"";if(!t)continue;if("string"==typeof o.space&&o.space)continue;const a=("string"==typeof o.area?o.area:"")||s(t)||"";a&&e[a]||n.push({id:t,space:i})}return n}(i.markers||[],Object.fromEntries(Object.entries(this._areaToSpace).map(([t,e])=>[t,e.space])),s[0]||"",t=>o.get(t)||"");if(a.length){const t=new Map(a.map(t=>[t.id,t.space]));for(const e of i.markers||[]){const i=t.get(String(e.id));i&&(e.space=i)}}i.spaces=function(t,e){const i=new Map(e.map((t,e)=>[t,e]));return t.map((t,e)=>({space:t,index:e})).sort((t,e)=>(i.get(String(t.space?.id))??Number.MAX_SAFE_INTEGER)-(i.get(String(e.space?.id))??Number.MAX_SAFE_INTEGER)||t.index-e.index).map(t=>t.space)}(i.spaces||[],n),this._saveConfig(),this._tabOrderWarned||(this._tabOrderWarned=!0,this._showToast(this._t("toast.space_order_changed")))}_pickSpace(t){if(this._endTabDrag(),t===this._space)return;const e=this._model.map(t=>t.id),i=e.indexOf(this._space),s=e.indexOf(t);this._navApplied=!0,this._showFar=!1,this._frame=null,this._slideTo(t,i>=0&&s0&&Date.now()>=this._cyclePausedUntil&&this._model.length>1&&this._zoom<=1.001){const t=this._model.map(t=>t.id),e=t.indexOf(this._space);this._slideTo(t[(e+1)%t.length],"left"),this._showKioskDots()}}_syncCycleTimer(){clearInterval(this._cycleTimer),this._cycleTimer=void 0,this.isConnected&&!this._hasFixedFloor&&this._config?.kiosk&&Number(this._config.cycle)>0&&(this._cycleTimer=window.setInterval(()=>this._cycleTick(),1e3*Number(this._config.cycle)))}get _editing(){return"plan"===this._mode||"devices"===this._mode||"decor"===this._mode}get _markup(){return"plan"===this._mode}get _wallUnionCache(){return this._wallUnionCacheValue}set _wallUnionCache(t){this._wallUnionCacheValue=t,null===t&&this._wallUnionPool.clear()}_newContinuityController(){return new bd(()=>{this._resumeSettling="steady"!==this._continuity.state,this._continuityEpoch++,this.isConnected&&this.requestUpdate()})}get _labsIso(){return this._labs.active.includes("iso")}get _desiredProjection(){return"view"===this._mode&&this._labsIso&&"iso"===this._viewPreference[this._space]?"iso":"flat"}_saveViewPreference(){try{localStorage.setItem(ev,JSON.stringify(this._viewPreference))}catch{}}_logicalViewCenter(t){const e=this._view;if(!e)return null;const i=[e.x+e.w/2,e.y+e.h/2],s="iso"===t?Zg(i):i;return{x:s[0],y:s[1]}}_convertProjectionView(t,e){if(t===e)return;const i=this._logicalViewCenter(t);this._view=null;const s=i?"iso"===e?Xg([i.x,i.y],0):[i.x,i.y]:null;this._applyView(this._zoom,s?.[0],s?.[1]),this._warmPatch({vp:this._warmViewportState()}),this.requestUpdate()}_setProjection(t){if(!this._labsIso||"view"!==this._mode)return;const e=this._effectiveProjection();if(this._viewPreference={...this._viewPreference,[this._space]:t},"iso"===t){const t=this._isoSceneKey();t&&this._isoFallback.delete(t)}this._saveViewPreference();const i=this._effectiveProjection();this._convertProjectionView(e,i)}_hashSpace(){return Og(window.location.hash||"")}connectedCallback(){this._connectedPath=location.pathname,this._routeDepartureHandled=!1,window.addEventListener("location-changed",this._onLocationChanged),window.addEventListener("popstate",this._onLocationChanged),this._continuityDisposed&&(this._continuity=this._newContinuityController(),this._continuityDisposed=!1,this._continuityPaintToken=-1);const t=(e=this.ownerDocument,vg.get(e)?.resolved);var e;void 0!==t&&(this._glowScreenBlend=t),this._continuityUnsub?.(),this._continuityUnsub=vd(this.ownerDocument,this._pageVisibility),super.connectedCallback(),this._pointerModality.connect(this.ownerDocument.defaultView);const i=this.ownerDocument.defaultView?.MutationObserver;i&&(this._pointerHoverObserver=new i(t=>{for(const e of t)for(const t of e.addedNodes)this._syncPointerHoverSubtree(t)}),this._pointerHoverObserver.observe(this.renderRoot,{childList:!0,subtree:!0})),this._motionMedia=window.matchMedia?.("(prefers-reduced-motion: reduce)"),this._reducedMotion=!!this._motionMedia?.matches,this._motionMedia?.addEventListener?.("change",this._onMotionChange),function(t){const e=vg.get(t);if(e)return e.promise;const i={promise:Promise.resolve(!1)};return i.promise=bg(t).catch(()=>!1).then(t=>(i.resolved=t,t)),vg.set(t,i),i.promise}(this.ownerDocument).then(t=>{t!==this._glowScreenBlend&&(this._glowScreenBlend=t,this.isConnected&&this.requestUpdate())}),this.hass&&this._ensureHaRegistryAuthority(),window.addEventListener("keydown",this._keyHandler),this._signer.start(()=>this.hass,()=>Is(this._serverCfg)),this._syncCycleTimer(),window.addEventListener("hashchange",this._onHashChange),this._labsUnsub?.(),this._labsUnsub=function(t,e){Ug.add(e);const i=Kg(t);return"undefined"==typeof window&&e(i),()=>{Ug.delete(e)}}(Nf,this._onLabsSnapshot),this._booting?this._bootWatch():this._bootFading&&(clearTimeout(this._bootTimer),this._bootTimer=window.setTimeout(()=>{this._bootFading=!1},220)),this._bootSoft&&(clearTimeout(this._bootSoftTimer),this._bootSoftTimer=window.setTimeout(()=>{this._bootSoft=!1},qf)),!this._loadOk&&this._serverCfg&&this.hass&&this._scheduleLoadRetry(),!this._warmSlot&&this._config&&this._warmAdopt(),this._loadOk&&this._ensureLiveSyncSubscriptions(),this._warmVp&&!this._warmRevivePending&&void 0===this._warmReviveTimer&&(this._warmRevivePending=!0,this._warmReviveTimer=window.setTimeout(()=>this._warmReviveDialog(),0)),this._warmLongReturn&&this._beginResumeSettle(),this._warmLongReturn=!1,this.requestUpdate()}disconnectedCallback(){this._connectedPath&&location.pathname!==this._connectedPath&&this._leaveCardRoute(),window.removeEventListener("location-changed",this._onLocationChanged),window.removeEventListener("popstate",this._onLocationChanged),this._continuityUnsub?.(),this._continuityUnsub=void 0,this._motionMedia?.removeEventListener?.("change",this._onMotionChange),this._motionMedia=void 0,this._vacRaf&&(cancelAnimationFrame(this._vacRaf),this._vacRaf=0),this._refitRaf&&(cancelAnimationFrame(this._refitRaf),this._refitRaf=0),this._dayCycleTimer&&(clearInterval(this._dayCycleTimer),this._dayCycleTimer=0),this._dayCycleClockKey="",this._bootSettleRaf&&(cancelAnimationFrame(this._bootSettleRaf),this._bootSettleRaf=0),this._bootSettling=!1;for(const t of this._activityRt.values())clearTimeout(t.timer);window.removeEventListener("keydown",this._keyHandler),this._endTabDrag(),clearTimeout(this._tabSuppressClickTimer),this._tabSuppressClickTimer=void 0,this._tabSuppressClick=!1,clearInterval(this._cycleTimer),clearTimeout(this._kioskDotsTimer),clearTimeout(this._kioskHoldTimer),clearTimeout(this._reloadRetry),clearTimeout(this._loadRetryTimer),this._loadRetryTimer=void 0,this._connHooked?.removeEventListener?.("ready",this._onConnReady),this._connHooked?.removeEventListener?.("disconnected",this._onConnLost),this._connHooked?.removeEventListener?.("reconnect-error",this._onConnLost),this._connHooked=null,this._haRegistryRelease?.(),this._haRegistryRelease=void 0,this._haRegistryConnection=null,this._signer.dispose(),clearTimeout(this._toastTimer),clearTimeout(this._slideTimer),this._modeTransition.dispose(),this._modeTransitionVisual=null,this._modeTransitionPreparing=!1,this._modeTransitionForceAtomic=!1,this._modeTransitionRequest++,this._slideTimer=void 0,this._slide="",clearTimeout(this._bootTimer),this._bootTimer=void 0,clearTimeout(this._bootSoftTimer),this._saveConfigDebounced.flush(),window.removeEventListener("hashchange",this._onHashChange),this._labsUnsub?.(),this._labsUnsub=void 0,clearTimeout(this._holdTimer),this._roViewport?.disconnect(),this._roViewport=void 0,this._roHdr?.disconnect(),this._roHdr=void 0,this._onWinResize&&(window.removeEventListener("resize",this._onWinResize),this._onWinResize=void 0),this._unsubCfg&&(this._unsubCfg(),this._unsubCfg=null),this._unsubLayout&&(this._unsubLayout(),this._unsubLayout=null),this._unsubVirtual&&(this._unsubVirtual(),this._unsubVirtual=null),this._unsubTrail&&(this._unsubTrail(),this._unsubTrail=void 0),this._liveSyncGeneration++,this._liveSyncAttempt=null,this._liveSyncConnection=null,clearTimeout(this._layoutSyncTimer),clearTimeout(this._duplicateColumnTimer);for(const t of this._glowFadeTimers.values())clearTimeout(t);for(const t of this._glowEnterRafs.values())cancelAnimationFrame(t);clearTimeout(this._glowFeatherResumeTimer),this._glowFeatherResumeTimer=0,this._glowFeatherSuspendUntil=0,this._glowFadeTimers.clear(),this._glowEnterRafs.clear(),this._glowEnteringSources.clear(),this._glowRenderedSources.clear(),this._glowLastAppearance.clear(),this._glowSourceSeq=0,this._warmSnapshot(),this._warmRevivePending=!1,clearTimeout(this._warmReviveTimer),this._warmReviveTimer=void 0,this._warmRelease(),this._clearPlanSnapHover(),this._clearOpeningPlacement(!0),this._touchContacts.clear(),this._touchSequenceMultitouch=!1,this._touchClickBlockUntil=0,this._clearTransientHover(!0),this._cancelDevicePressFeedback(),this._pointerHoverObserver?.disconnect(),this._pointerHoverObserver=void 0,this._pointerModality.disconnect(),this._editorSecondary.reset(),this._resumeSettling=!1,this._continuityHistory=[...this._continuityHistory,...this._continuity.trace].slice(-80),this._continuity.dispose(),this._continuityDisposed=!0,super.disconnectedCallback()}_onKey(t){if("Escape"===t.key&&this._vacFit)return this._vacFit=null,this._showToast(this._t("vac.cal_cancelled")),void t.stopPropagation();if("Escape"===t.key){if(this._tapConfirm)return void(this._tapConfirm=null);if(this._vacCalConfirm)return void(this._vacCalConfirm=null);if(this._decorEraseConfirm)return void(this._decorEraseConfirm=null);if(this._openingInfo)return void(this._openingInfo=null);if(this._infoCard)return void this._closeInfoCard();if(this._rulesDialog)return void(this._rulesDialog=null);if(this._alignDialog)return this._alignDialog=null,void(this._preflightClipboardFallback=null);if(this._backupImportDialog)return void(this._backupImportDialog=null);if(this._backupExportDialog)return void(this._backupExportDialog=null);if(this._settingsDialog)return void(this._settingsDialog=null);if(this._markerDialog)return void(this._markerDialog=null);if(this._openingDialog)return void(this._openingDialog=null);if(this._physicalDialog)return void(this._physicalDialog=null);if(this._backdropDialog)return void(this._backdropDialog=null);if(this._decorShapeDialog)return void(this._decorShapeDialog=null);if(this._decorTextDialog)return void(this._decorTextDialog=null);if(this._spaceDialog&&!this._roomDialog)return this._spaceDialog=null,this._importQueue=[],void(this._importTotal=0);if(this._editorSecondary.hasOpenGroup)return t.preventDefault(),void this._editorSecondary.closeGroup(!0)}const e=t.composedPath?.()||[t.target],i=e.some(t=>t?.matches?.('input, textarea, select, [contenteditable="true"]')),s=e.some(t=>t?.classList?.contains?.("editor-secondary")),n=t.ctrlKey||t.metaKey,o=t.key.toLowerCase(),a=/^[a-z]$/.test(o),r="z"===o||!a&&"KeyZ"===t.code,l="y"===o||!a&&"KeyY"===t.code,c=n&&(r&&t.shiftKey||l),h=n&&r&&!t.shiftKey;if("decor"===this._mode){if((h||c)&&i)return;return c?(t.preventDefault(),void this._redoGeometry()):h?(t.preventDefault(),this._decorDraft?void(this._decorDraft=null):this._decorMove||this._dtDrag||this._bdDrag?void this._cancelDecorGesture():void this._undoGeometry()):"Delete"!==t.key&&"Backspace"!==t.key||!this._decorSel||i||s?void("Escape"===t.key&&(t.preventDefault(),this._decorDraft?this._decorDraft=null:this._decorMove||this._dtDrag||this._bdDrag?this._cancelDecorGesture():"furniture"===this._decorTool?(this._furnPalette=null,this._decorTool="select"):this._decorSel?this._decorSel=null:"select"!==this._decorTool?this._decorTool="select":this._setMode("view"))):(t.preventDefault(),void this._decorDeleteSel())}if(this._markup&&(!h&&!c||!i)){if(("Delete"===t.key||"Backspace"===t.key)&&this._physicalSel&&!i&&!s)return t.preventDefault(),void this._deletePhysicalSelection();if(c)return t.preventDefault(),void this._redoGeometry();if(h)return t.preventDefault(),this._rszDrag?void this._rszCancelDrag():this._wallFaceBatch?(this._roomDialogCancel(),void(this._activeDraftId&&this._path.length>1?this._undoActiveDraftPoint():this._undoPoint())):"draw"===this._tool&&this._path.length?void(this._activeDraftId&&this._path.length>1?this._undoActiveDraftPoint():this._undoPoint()):"split"===this._tool&&this._splitSel?.pts?.length?(this._splitSel={...this._splitSel,pts:this._splitSel.pts.slice(0,-1)},void(this._splitSel.pts.length||(this._cursorPt=null))):void this._undoGeometry();if("Escape"===t.key)return this._physicalDrag||this._physicalRotate?(t.preventDefault(),void this._cancelPhysicalGesture()):this._roomDialog?(t.preventDefault(),void this._roomDialogCancel()):"draw"===this._tool&&this._path.length?(t.preventDefault(),void this._finishWallChain()):this._physicalSel?(t.preventDefault(),void(this._physicalSel=null)):"resize"===this._tool?(t.preventDefault(),this._rszDrag?void this._rszCancelDrag():void(this._rszSel?this._rszSel=null:this._tool="draw")):"split"===this._tool?(t.preventDefault(),void(this._splitSel?.pts?.length?(this._splitSel={...this._splitSel,pts:this._splitSel.pts.slice(0,-1)},this._splitSel.pts.length||(this._cursorPt=null)):this._splitSel?this._splitSel=null:this._tool="draw")):"merge"===this._tool?(t.preventDefault(),void(this._mergeSel?this._mergeSel=null:this._tool="draw")):this._wallDialog?(t.preventDefault(),void(this._wallDialog=null)):void("opening"!==this._tool&&"wallthick"!==this._tool&&"delroom"!==this._tool&&"column"!==this._tool||(t.preventDefault(),"opening"===this._tool&&this._clearOpeningPlacement(!0),this._tool="draw"))}}_undoPoint(){if(this._path.length){if(this._contourClosed)return this._path=this._path.slice(0,-1),void(this._closingWallCm=null);if(this._activeDraftId&&this._path.length>1&&this._curSpaceCfg){const t=this._geometrySnapshot();this._path=this._path.slice(0,-1),this._draftSegmentCms=this._draftSegmentCms.slice(0,-1);const e=this._curSpaceCfg,i=(e.room_drafts||[]).findIndex(t=>t.id===this._activeDraftId);if(i>=0){const s=Array.isArray(e.room_drafts[i]?.segments)?e.room_drafts[i].segments:[];this._path.length<2?(e.room_drafts.splice(i,1),e.room_drafts.length||delete e.room_drafts,this._activeDraftId=null):e.room_drafts[i]={id:this._activeDraftId,points:this._path.map(t=>[t[0]/sv,t[1]/sv]),segments:this._draftSegmentCms.map((t,e)=>({...s[e]||{},cm:t}))},this._commitPhysicalGeometry(this._t("history.draft_segment_delete"),t)}return}this._path=this._path.slice(0,-1)}}_undoActiveDraftPoint(){const t=this._activeDraftId,e=this._path[0]?[...this._path[0]]:null,i=this._geometryHistory.undo();if(!i)return void this._undoPoint();if(!this._applyGeometryState(i.before,!0))return void this._geometryHistory.clear();const s=t?this._spaceModel()?.room_drafts.find(e=>e.id===t):null;s?(this._activeDraftId=s.id,this._path=s.points.map(t=>[...t]),this._draftSegmentCms=this._adoptDraftCms(this._path,s.segments.map(t=>t.cm),s.id),this._resumeDraftBySpace[this._space]=s.id):(this._activeDraftId=null,this._path=e?[e]:[],this._draftSegmentCms=[],t&&this._resumeDraftBySpace[this._space]===t&&delete this._resumeDraftBySpace[this._space]),this._clearPlanSnapHover(),this._showToast(this._t("history.undone",{name:i.name}))}static getConfigElement(){return document.createElement("houseplan-card-editor")}static getStubConfig(){return{type:"custom:houseplan-card"}}static _warmBootReset(t){for(const t of Gf.values())for(const e of t)clearTimeout(e.evict);Gf.clear(),Yf=t&&t>0?t:1e4}static _warmBootStats(){let t=0,e=0;const i=[];for(const s of Gf.values())for(const n of s)t++,n.dlg&&(e++,i.push(n.dlg.kind));return{keys:Gf.size,slots:t,dlgs:e,drafts:i}}setConfig(t){const e=this._config,i=!!e&&Object.prototype.hasOwnProperty.call(e,"floor");this._config={icon_size:2.5,show_temperature:!0,live_states:!0,show_signal:!0,...t};(i!==this._hasFixedFloor||e?.floor!==this._config.floor)&&(this._hashApplied=!1,this._navApplied=!1,this._warmVpArmed=!1),this._config.kiosk&&(this._booting=!1,this._bootFading=!1),!this._hasFixedFloor&&t.default_floor&&this._commitSpace(t.default_floor,!0);try{this._zoomBySpace=JSON.parse(localStorage.getItem(Zf)||"{}")||{}}catch{this._zoomBySpace={}}try{const t=JSON.parse(localStorage.getItem(ev)||"{}")||{};this._viewPreference=Object.fromEntries(Object.entries(t).filter(t=>"flat"===t[1]||"iso"===t[1]))}catch{this._viewPreference={}}this._labs=Kg(Nf);try{const t=JSON.parse(localStorage.getItem(tv)||"null");this._kioskScale={icon:Es(t?.icon),font:Es(t?.font)}}catch{}try{const t=JSON.parse(localStorage.getItem(Xf)||"null");t&&t.config&&Array.isArray(t.config.spaces)&&(this._serverCfg=t.config,this._cfgEpoch++,this._cfgRev=t.rev||0,this._cfgContentFingerprint=t.config_fingerprint||wd(t.config),this._layout=t.layout||{},this._layoutRev=t.layout_rev||0,this._layoutContentFingerprint=t.layout_fingerprint||wd(this._layout),this._virtualLights=mn(t.virtual_lights,this._cfgRev),this._serverStorage=!0)}catch{}this._adoptInitialSpace(this._model,this._loadOk),"view"!==this._mode||this._view||(this._zoom=this._zoomBySpace[this._space]||1),this.isConnected&&(this._syncCycleTimer(),this._warmAdopt(),this._warmLongReturn&&this._beginResumeSettle(),this._warmLongReturn=!1)}_warmAdopt(){if(this._config?.kiosk)return;const t=Kf(this._config);if(this._warmKey===t&&this._warmSlot)return;this._warmSlot&&this._warmRelease();const e=this.parentNode,i=this._warmIdx(e),s=Gf.get(t);if(!s||!s.length)return;const n=s.find(t=>t.owner===this._warmGen);if(n)return this._warmLongReturn=!!n.freed&&Date.now()-n.freed>=md,clearTimeout(n.evict),n.evict=0,n.freed=0,n.live=!0,this._warmSlot=n,this._warmKey=t,n.frameFingerprint&&this._continuity.adoptCompleteFrame(n.frameFingerprint),void(!this._devices.length&&n.devices?.length&&(this._devices=[...n.devices]));const{slot:o,sure:a}=((t,e,i,s)=>{const n=t=>{const e=!!i&&t.place?.deref()===i;return e&&t.idx===s?4:t.live?0:e?3:2};let o=null,a=0,r=0,l=null;for(const i of t){if(i.owner===e)continue;l=i;const t=n(i);t<=0||(t>a?(o=i,a=t,r=1):t===a&&r++)}return!o||r>1?{slot:o||l,sure:!1}:{slot:o,sure:!0}})(s,this._warmGen,e,i);o&&(this._warmLongReturn=!!o.freed&&Date.now()-o.freed>=md,this._booting=!1,this._bootFading=!1,this._hdrH=o.hdrH,this._bootSoft=!0,this.isConnected&&(clearTimeout(this._bootSoftTimer),this._bootSoftTimer=window.setTimeout(()=>{this._bootSoft=!1},qf)),this._warmKey=t,a?(clearTimeout(o.evict),o.evict=0,o.owner=this._warmGen,o.place=e?new WeakRef(e):null,o.idx=i,o.live=!0,this._warmSlot=o,this._warmVp=o.vp,o.frameFingerprint&&this._continuity.adoptCompleteFrame(o.frameFingerprint),!this._devices.length&&o.devices?.length&&(this._devices=[...o.devices]),this._warmAdoptViewport(this._config)):(this._warmSlot={owner:this._warmGen,path:location.pathname,place:e?new WeakRef(e):null,idx:i,live:!0,hdrH:o.hdrH,stageH:o.stageH,vp:null,frameFingerprint:"",devices:null,dlg:null,freed:0,evict:0},s.push(this._warmSlot),this._warmTrim(s)))}_warmIdx(t){const e=t?.children;if(!e)return-1;for(let t=0;t4;){const e=t.findIndex(t=>!t.live);if(e<0)break;clearTimeout(t[e].evict),t.splice(e,1)}}_warmScheduleEvict(t,e){if(clearTimeout(t.evict),!(t.dlg||t.vp&&"view"!==t.vp.mode))return;const i=t.freed,s=t.owner;t.evict=window.setTimeout(()=>{if(t.evict=0,t.freed!==i||t.owner!==s)return;var n;t.dlg=null,t.vp=(n=t.vp)&&"view"!==n.mode?{...n,mode:"view",zoom:n.snap?.space===n.space?n.snap.zoom:n.zoom,view:null,snap:null,tool:"draw",decorTool:"select",showHidden:!1,selId:null,rszSel:null,decorSel:null}:n,t.frameFingerprint="";const o=Gf.get(e);if(!t.live&&o&&o.length>1){const e=o.indexOf(t);e>=0&&o.splice(e,1)}},Yf+250)}_warmAdoptViewport(t){const e=this._warmVp;if(!e||this._warmSlot?.path!==location.pathname)return void(this._warmVp=null);const i=this._fixedFloorState();if(this._hashApplied||!this._model.find(t=>t.id===e.space)||"valid"===i.kind&&i.id!==e.space||this._hasFixedFloor&&"valid"!==i.kind)return void(this._warmVp=null);this._commitSpace(e.space,!0),this._navApplied=!0,this._adoptMode("view"!==e.mode&&this._canEdit&&!t.kiosk?e.mode:"view"),this._pendingNavMode="view"===e.mode||this._canEdit||t.kiosk?null:e.mode,this._zoom=e.zoom;const s=this._effectiveProjection(),n=s===e.projection&&this._labsIso===e.activeLabsIso;if(this._view=n&&e.view?{...e.view}:null,this._viewModeSnap=n&&e.snap?{...e.snap}:null,!n&&e.logicalCenter){const t="iso"===s?Xg([e.logicalCenter.x,e.logicalCenter.y],0):[e.logicalCenter.x,e.logicalCenter.y];this._applyView(e.zoom,t[0],t[1])}var o;this._tool="opening"===(o=function(t){return"partition"===t?"draw":t}(o=e.tool))?"draw":"string"==typeof o&&av.has(o)?o:"draw",this._decorTool=e.decorTool,this._showHidden=e.showHidden,this._showFar!==e.showFar&&(this._showFar=e.showFar,this._frame=null),this._selId=e.selId,this._rszSel=e.rszSel,this._decorSel=e.decorSel,this._warmVpArmed=!0}_warmPatch(t,e=!1){if(this._config?.kiosk)return;const i=Kf(this._config);if(!this._warmSlot||this._warmKey===i){if(!this._warmSlot){if(!e)return;const t=this.parentNode;this._warmKey=i,this._warmSlot={owner:this._warmGen,path:location.pathname,place:t?new WeakRef(t):null,idx:this._warmIdx(t),live:!0,hdrH:this._hdrH,stageH:0,vp:null,frameFingerprint:"",devices:null,dlg:null,freed:0,evict:0};const s=Gf.get(i)||[];for(s.push(this._warmSlot),Gf.set(i,s),this._warmTrim(s);Gf.size>8;){const t=Gf.keys().next().value;if(void 0===t||t===i)break;for(const e of Gf.get(t)||[])clearTimeout(e.evict);Gf.delete(t)}}Object.assign(this._warmSlot,t)}}_warmViewportState(){const t=this._effectiveProjection();return{space:this._space,mode:this._mode,projection:t,activeLabsIso:this._labsIso,logicalCenter:this._logicalViewCenter(t),zoom:this._zoom,view:this._view?{...this._view}:null,snap:this._viewModeSnap?{...this._viewModeSnap}:null,tool:this._tool,decorTool:this._decorTool,showHidden:this._showHidden,showFar:this._showFar,selId:this._selId,rszSel:this._rszSel,decorSel:this._decorSel}}_warmDialogState(){const t=(t,e)=>({kind:t,space:this._space,mode:this._mode,data:e});return this._tapConfirm||this._alignDialog||this._mergeDialog||this._importDialog||this._backupExportDialog||this._backupImportDialog?null:this._openingInfo?t("openingInfo",this._openingInfo.id):this._infoCard?t("info",this._infoCard.id):this._rulesDialog?this._rulesDialog.busy?null:t("rules",this._rulesDialog):this._settingsDialog?this._settingsDialog.busy?null:t("settings",this._settingsDialog):this._markerDialog?this._markerDialog.busy?null:t("marker",this._markerDialog):this._openingDialog?t("opening",this._openingDialog):this._backdropDialog?t("backdrop",this._backdropDialog):this._decorShapeDialog?t("decorShape",this._decorShapeDialog):this._decorTextDialog?t("decorText",this._decorTextDialog):this._roomDialog?t("room",{editId:this._roomEditId,fill:this._roomFill,customFill:this._roomCustomFill,tempSrc:this._roomTempSrc,humSrc:this._roomHumSrc,srcOpen:this._roomSrcOpen,srcFilter:this._roomSrcFilter,nameScale:this._roomNameScale,labelScale:this._roomLabelScale,areaSel:this._areaSel,nameSel:this._nameSel,pendingSplit:this._pendingSplit,wallFaceBatch:this._wallFaceBatch,path:this._path}):this._spaceDialog?this._spaceDialog.busy?null:t("space",this._spaceDialog):null}_warmSnapshot(){if(this._booting||this._config?.kiosk||"steady"!==this._continuity.state)return;const t={vp:this._warmViewportState(),frameFingerprint:this._continuity.frameFingerprint,devices:this._devices};if(this._warmRevivePending||(t.dlg=this._warmDialogState()),this.isConnected&&this._warmSlot?.owner===this._warmGen){const e=this.parentNode;t.place=e?new WeakRef(e):null,t.idx=this._warmIdx(e)}this._warmPatch(t)}_warmReviveDialog(){this._warmRevivePending=!1;const t=this._warmSlot;if(this._warmReviveTimer=void 0,!t||!t.dlg)return;const e=t.dlg,i=t.freed;if(t.dlg=null,t.freed=0,clearTimeout(t.evict),t.evict=0,i&&!(Date.now()-i>Yf)&&e.space===this._space&&e.mode===this._mode){switch(e.kind){case"space":this._spaceDialog={...e.data,busy:!1,savedBusy:!1};break;case"marker":this._markerDialog={...e.data,busy:!1};break;case"settings":this._settingsDialog={...e.data,busy:!1};break;case"rules":this._rulesDialog={...e.data,busy:!1};break;case"opening":this._openingDialog={...e.data};break;case"backdrop":this._backdropDialog={...e.data};break;case"decorShape":this._decorShapeDialog={...e.data};break;case"decorText":{this._decorTextDialog={...e.data};const t=String(this._decorTextDialog?.text??"").length;this._decorTextSelection={start:t,end:t};break}case"room":{const t=e.data;this._roomEditId=t.editId,this._roomFill=t.fill,this._roomCustomFill=t.customFill||null,this._roomTempSrc=t.tempSrc,this._roomHumSrc=t.humSrc,this._roomSrcOpen=t.srcOpen,this._roomSrcFilter=t.srcFilter,this._roomNameScale=t.nameScale,this._roomLabelScale=t.labelScale,this._areaSel=t.areaSel,this._nameSel=t.nameSel,this._pendingSplit=t.pendingSplit,this._wallFaceBatch=t.wallFaceBatch||null,this._path=t.path,this._wallFaceBatch&&(this._activeDraftId=this._wallFaceBatch.activeDraftId,this._draftSegmentCms=[...this._wallFaceBatch.activeCms]),this._roomDialog=!0;break}case"info":{const t=this._devices.find(t=>t.id===e.data);t&&(this._infoCard=t);break}case"openingInfo":{const t=(this._curSpaceCfg?.openings||[]).find(t=>t.id===e.data);t&&(this._openingInfo=t);break}}this.requestUpdate()}}_cacheSnapshot(){if(this._serverCfg)try{this._cfgContentFingerprint=wd(this._serverCfg),this._layoutContentFingerprint=wd(this._layout),this._virtualLights=function(t,e,i){if(t.configRev===i)return t;const s=new Set((Array.isArray(e?.markers)?e.markers:[]).filter(yn).map(t=>t.id));return{...t,configRev:i,off:new Set([...t.off].filter(t=>s.has(t)))}}(this._virtualLights,this._serverCfg,this._cfgRev),localStorage.setItem(Xf,JSON.stringify({config:this._serverCfg,rev:this._cfgRev,config_fingerprint:this._cfgContentFingerprint,layout:this._layout,layout_rev:this._layoutRev,layout_fingerprint:this._layoutContentFingerprint,virtual_lights:fn(this._virtualLights)}))}catch{}}_beginContinuityCandidate(t,e,i="plan"){return this._booting&&!this._continuity.hasCompleteFrame?this._continuity.token:(this._continuityDataReady=e,this._continuityPaintToken=-1,this._stagedDeviceSnapshotToken=-1,this._resumeSettling=!0,this._continuity.beginCandidate(t,i))}_continuityStageValid(){const t=this._stageEl;return!!t&&t.clientWidth>0&&t.clientHeight>0}_continuityAssetsReady(){if(!this._model.length)return!1;const t=this._model.length?this._spaceModel():null;return!t?.bg?.href||this._signer.isReady(this.hass,t.bg.href)}_initialSpaceSelection(t,e=this._loadOk){const i=this._fixedFloorState(t,e);return"valid"===i.kind?{id:i.id,source:"fixed"}:this._hasFixedFloor?{id:null,source:"none"}:function(t){const e=new Set(t.spaceIds.filter(t=>!!t));if(!e.size)return{id:null,source:"none"};const i=[["hash",!1===t.acceptHash?null:t.hashSpace],["current",t.preserveCurrent?t.currentSpace:null],["saved",t.savedSpace],["default",t.defaultSpace],["first",t.spaceIds[0]]];for(const[t,s]of i)if(s&&e.has(s))return{id:s,source:t};return{id:null,source:"none"}}({spaceIds:t.map(t=>t.id),hashSpace:this._hashSpace(),acceptHash:!this._hashApplied,currentSpace:this._space,preserveCurrent:this._hashApplied||this._navApplied||this._warmVpArmed,savedSpace:this._savedNav()?.space,defaultSpace:this._config?.default_floor})}_adoptInitialSpace(t,e=this._loadOk){const i=this._initialSpaceSelection(t,e);return i.id?(this._commitSpace(i.id,!0),"hash"===i.source&&(this._hashApplied=!0),"saved"===i.source&&(this._navApplied=!0),i):i}_candidateBackdrop(t,e=this._space){const i=Sh(t),s=this._fixedFloorState(i,!0);if(this._hasFixedFloor&&"valid"!==s.kind)return"";const n=this._initialSpaceSelection(i,!0).id||(i.some(t=>t.id===e)?e:i[0]?.id);return i.find(t=>t.id===n)?.bg?.href||""}_visualFrameFingerprint(){const t=this._stageEl,e=t?[t.clientWidth,t.clientHeight]:[0,0];return kd([this._cfgRev,this._cfgContentFingerprint||wd(this._serverCfg),this._layoutRev,this._layoutContentFingerprint||wd(this._layout),this._space,this._mode,this._view,e,this._glowScreenBlend?"screen":"normal",this.hass?.themes?.darkMode??this.hass?.themes?.default_theme??""])}_settleContinuityFrame(){if(this._booting||!this._continuityStageValid())return;if(!this._continuity.hasCompleteFrame&&"steady"===this._continuity.state)return void(this._continuityAssetsReady()&&(this._renderSnapshotAt=Date.now(),this._continuity.markCompleteFrame(this._visualFrameFingerprint())));if(!this._continuityDataReady)return;if(!["holding","offline-stale","overlay-pending","overlay-visible","candidate-ready"].includes(this._continuity.state))return;const t=this._continuity.token;if(this._candidateDeviceSnapshot&&this._candidateDeviceSnapshot!==this._visibleDeviceSnapshot&&this._stagedDeviceSnapshotToken!==t)return this._stagedDeviceSnapshotToken=t,void this.requestUpdate();this._continuityPaintToken!==t&&(this._continuityPaintToken=t,this._continuity.candidateReady(t)&&this._continuity.commitAfterPaint(t,{updateComplete:()=>this.updateComplete,stageValid:()=>this.isConnected&&this._continuityStageValid(),assetsReady:()=>this._continuityAssetsReady(),frameFingerprint:()=>this._visualFrameFingerprint()}).then(e=>{e&&t===this._continuity.token?(this._resumeSettling=!1,this._renderSnapshotAt=Date.now(),this._candidateDeviceSnapshot&&(this._visibleDeviceSnapshot=this._candidateDeviceSnapshot),this._candidateDeviceSnapshot=null,this._stagedDeviceSnapshotToken=-1,this._warmSnapshot()):t===this._continuity.token&&(this._continuityPaintToken=-1,this._stagedDeviceSnapshotToken=-1,this._candidateDeviceSnapshot=null,this.requestUpdate())}))}_onBackdropLoaded(t,e){this._signer.markLoaded(this.hass,t,e),this._continuity.note("asset-ready"),this._continuityPaintToken=-1,"steady"!==this._continuity.state&&this.requestUpdate()}_renderRecoveryOverlay(){if(!this._continuity.overlayVisible&&"recovery-error"!==this._continuity.state)return G;const t="connection"===this._continuity.recoveryReason;return W`
t.stopPropagation()} @click=${t=>t.stopPropagation()} diff --git a/custom_components/houseplan/manifest.json b/custom_components/houseplan/manifest.json index 3090c2da..da9dbde6 100755 --- a/custom_components/houseplan/manifest.json +++ b/custom_components/houseplan/manifest.json @@ -16,5 +16,5 @@ "issue_tracker": "https://github.com/Matysh/houseplan-card/issues", "requirements": [], "single_config_entry": true, - "version": "1.68.0" + "version": "1.68.1" } diff --git a/dist/houseplan-card.js b/dist/houseplan-card.js index bc35b11d..8901591b 100755 --- a/dist/houseplan-card.js +++ b/dist/houseplan-card.js @@ -1,4 +1,4 @@ -globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="bf3bb218d73d1895f6f7e87b49dc82893e856d6621324930a6ef6fe7f80f232d";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:p}=Object,u=globalThis,_=u.trustedTypes,m=_?_.emptyScript:"",g=u.reactiveElementPolyfillSupport,f=(t,e)=>t,v={toAttribute(t,e){switch(e){case Boolean:t=t?m: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"),u.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=p(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,g?.({ReactiveElement:w}),(u.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,P=`<${D}>`,T=document,R=()=>T.createComment(""),I=t=>null===t||"object"!=typeof t&&"function"!=typeof t,A=Array.isArray,z="[ \t\n\f\r]",F=/<(?:(!--|\/[^a-zA-Z])|(\/?[a-zA-Z][^>\s]*)|(\/?$))/g,E=/-->/g,N=/>/g,O=RegExp(`>|${z}(?:([^\\s"'>=/]+)(${z}*=${z}*(?:[^ \t\n\f\r"'\`<>=]|("|')|))|$)`,"g"),L=/'/g,H=/"/g,B=/^(?:script|style|textarea|title)$/i,q=t=>(e,...i)=>({_$litType$:t,strings:e,values:i}),W=q(1),j=q(2),U=Symbol.for("lit-noChange"),G=Symbol.for("lit-nothing"),V=new WeakMap,K=T.createTreeWalker(T,129);function Y(t,e){if(!A(t)||!t.hasOwnProperty("raw"))throw Error("invalid template strings array");return void 0!==S?S.createHTML(e):e}const J=(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]?O:'"'===l[3]?H:L):a===H||a===L?a=O:a===E||a===N?a=F:(a=O,n=void 0);const d=a===O&&t[e+1].startsWith("/>")?" ":"";o+=a===F?i+P: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 X{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]=J(t,e);if(this.el=X.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;iA(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&&I(this._$AH)?this._$AA.nextSibling.data=t:this.T(T.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=X.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 X(t)),e}k(t){A(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=!I(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 pt=2,ut=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 mt={},gt=ut(class extends _t{constructor(){super(...arguments),this.ot=mt}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=ut(class extends _t{constructor(t){if(super(t),t.type!==pt)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,p=n.length-1,u=0,_=o.length-1;for(;d<=p&&u<=_;)if(null===n[d])d++;else if(null===n[p])p--;else if(r[d]===a[u])l[u]=wt(n[d],o[u]),d++,u++;else if(r[p]===a[_])l[_]=wt(n[p],o[_]),p--,_--;else if(r[d]===a[_])l[_]=wt(n[d],o[_]),bt(t,l[_+1],n[d]),d++,_--;else if(r[p]===a[u])l[u]=wt(n[p],o[u]),bt(t,n[d],n[p]),p--,u++;else if(void 0===c&&(c=St(a,u,_),h=St(r,d,p)),c.has(r[d]))if(c.has(r[p])){const e=h.get(a[u]),i=void 0!==e?n[e]:null;if(null===i){const e=bt(t,n[d]);wt(e,o[u]),l[u]=e}else l[u]=wt(i,o[u]),bt(t,n[d],i),n[e]=null;u++}else $t(n[p]),p--;else $t(n[d]),d++;for(;u<=_;){const e=bt(t,l[_+1]);wt(e,o[u]),l[u++]=e}for(;d<=p;){const t=n[d++];null!==t&&$t(t)}return this.ut=a,xt(t,l),U}}),Ct=new WeakMap;let Dt=0;class Pt 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=W` +globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="f7fe0cda471359472c0fbec24cff665db6e165d00ccae0a32823a686c5f53f1f";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:p}=Object,u=globalThis,_=u.trustedTypes,m=_?_.emptyScript:"",g=u.reactiveElementPolyfillSupport,f=(t,e)=>t,v={toAttribute(t,e){switch(e){case Boolean:t=t?m: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"),u.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=p(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,g?.({ReactiveElement:w}),(u.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,P=`<${D}>`,T=document,R=()=>T.createComment(""),I=t=>null===t||"object"!=typeof t&&"function"!=typeof t,A=Array.isArray,z="[ \t\n\f\r]",F=/<(?:(!--|\/[^a-zA-Z])|(\/?[a-zA-Z][^>\s]*)|(\/?$))/g,E=/-->/g,N=/>/g,O=RegExp(`>|${z}(?:([^\\s"'>=/]+)(${z}*=${z}*(?:[^ \t\n\f\r"'\`<>=]|("|')|))|$)`,"g"),L=/'/g,H=/"/g,B=/^(?:script|style|textarea|title)$/i,q=t=>(e,...i)=>({_$litType$:t,strings:e,values:i}),W=q(1),j=q(2),U=Symbol.for("lit-noChange"),G=Symbol.for("lit-nothing"),V=new WeakMap,K=T.createTreeWalker(T,129);function Y(t,e){if(!A(t)||!t.hasOwnProperty("raw"))throw Error("invalid template strings array");return void 0!==S?S.createHTML(e):e}const J=(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]?O:'"'===l[3]?H:L):a===H||a===L?a=O:a===E||a===N?a=F:(a=O,n=void 0);const d=a===O&&t[e+1].startsWith("/>")?" ":"";o+=a===F?i+P: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 X{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]=J(t,e);if(this.el=X.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;iA(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&&I(this._$AH)?this._$AA.nextSibling.data=t:this.T(T.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=X.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 X(t)),e}k(t){A(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=!I(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 pt=2,ut=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 mt={},gt=ut(class extends _t{constructor(){super(...arguments),this.ot=mt}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=ut(class extends _t{constructor(t){if(super(t),t.type!==pt)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,p=n.length-1,u=0,_=o.length-1;for(;d<=p&&u<=_;)if(null===n[d])d++;else if(null===n[p])p--;else if(r[d]===a[u])l[u]=wt(n[d],o[u]),d++,u++;else if(r[p]===a[_])l[_]=wt(n[p],o[_]),p--,_--;else if(r[d]===a[_])l[_]=wt(n[d],o[_]),bt(t,l[_+1],n[d]),d++,_--;else if(r[p]===a[u])l[u]=wt(n[p],o[u]),bt(t,n[d],n[p]),p--,u++;else if(void 0===c&&(c=St(a,u,_),h=St(r,d,p)),c.has(r[d]))if(c.has(r[p])){const e=h.get(a[u]),i=void 0!==e?n[e]:null;if(null===i){const e=bt(t,n[d]);wt(e,o[u]),l[u]=e}else l[u]=wt(i,o[u]),bt(t,n[d],i),n[e]=null;u++}else $t(n[p]),p--;else $t(n[d]),d++;for(;u<=_;){const e=bt(t,l[_+1]);wt(e,o[u]),l[u++]=e}for(;d<=p;){const t=n[d++];null!==t&&$t(t)}return this.ut=a,xt(t,l),U}}),Ct=new WeakMap;let Dt=0;class Pt 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=W` ${this.icon?W``:G} ${this.title} `;return this._useHaDialog?W`${t.visibleLabel}`:G}
${t?.content||G}
-
`}afterRender(){const t=this.host.root();this._blocked&&(this._openGroupId?this.closeGroup(!1):"palette"===this._currentModel?.kind&&this._currentModel.dismiss?.()),this._syncGlobalDismissListener();const e=t.querySelector(".editor-secondary"),i=this._renderedContext,s=e?.dataset.contextId||"";if(s&&i&&s!==i&&!window.matchMedia?.("(prefers-reduced-motion: reduce)")?.matches&&(this._contentAnimation?.cancel(),this._contentAnimation=e?.querySelector(".editor-secondary-content")?.animate([{opacity:.35,transform:"translateY(-4px)"},{opacity:1,transform:"translateY(0)"}],{duration:100,easing:"ease-out"})),this._renderedContext=s,i&&s!==i&&this._focusOwned){const i=s?e?.querySelector('[tabindex="0"], button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled])'):t.querySelector(".editbar-tools");i?.focus?.(),this._focusOwned=!!s}if("palette"===this._currentModel?.kind&&this._currentModel.launcherId){const e=[...t.querySelectorAll("[data-editor-palette]")].find(t=>t.dataset.editorPalette===this._currentModel?.launcherId);e&&null!==e.offsetParent||this._currentModel.dismiss?.()}if(!this._openGroupId)return;const n=[...t.querySelectorAll("[data-editor-group]")].find(t=>t.dataset.editorGroup===this._openGroupId);n&&null!==n.offsetParent||this.closeGroup(!0)}handleOutsideDismiss(t){if(q_(t,t=>t.hasAttribute("data-editor-navigation")))return"pointerdown"===t.type?this.closeForNavigation():"click"===t.type&&this._dismissPointerTarget&&this._clearDismissClick(),!1;if("click"===t.type&&this._dismissPointerTarget){return!!(t.composedPath?.()||[t.target]).includes(this._dismissPointerTarget)&&(this._clearDismissClick(),t.preventDefault(),t.stopImmediatePropagation(),!0)}const e=this._openGroupId||this._blocked||"palette"!==this._currentModel?.kind?null:this._currentModel;if("pointerdown"===t.type&&(this._openGroupId||e)){const i=q_(t,t=>t.classList.contains("editor-secondary")),s=q_(t,t=>!!t.dataset.editorGroup),n=q_(t,t=>!!t.dataset.editorPalette),o=q_(t,t=>t.classList.contains("stage"));if(!(i||s||n||"stay-open-on-canvas"===e?.dismissPolicy&&o))return t.preventDefault(),t.stopImmediatePropagation(),this._dismissPointerTarget=t.target,clearTimeout(this._dismissTimer),this._dismissTimer=window.setTimeout(()=>{this._clearDismissClick()},800),this._openGroupId?this.closeGroup(!1):e?.dismiss?.(),this._syncGlobalDismissListener(),!0}return!1}_activateGroupItem(t,e,i){if(t.id!==this._openGroupId)return;const s=t.items.find(t=>t.id===e);if(!s||s.disabled)return;const n="toggle"===s.role&&"stay-open"===s.closePolicy,o=0===i.detail;n||(this._openGroupId=null,this.host.requestUpdate(),this._syncGlobalDismissListener()),s.invoke(),!n&&o&&this.host.updateComplete().then(()=>{const e=[...this.host.root().querySelectorAll("[data-editor-group]")].find(e=>e.dataset.editorGroup===t.id&&null!==e.offsetParent);e?.focus()})}_groupKeydown(t){if(!["ArrowLeft","ArrowRight","Home","End"].includes(t.key))return;const e=[...t.currentTarget.querySelectorAll(".editor-group-item:not([disabled])")];if(!e.length)return;t.preventDefault();const i=e.indexOf(this.host.root().activeElement),s="Home"===t.key?0:"End"===t.key?e.length-1:"ArrowLeft"===t.key?i<=0?e.length-1:i-1:(i+1)%e.length;e[s]?.focus()}_clearDismissClick(){this._dismissPointerTarget=null,clearTimeout(this._dismissTimer),this._dismissTimer=void 0,this._syncGlobalDismissListener()}_syncGlobalDismissListener(){const t=!this._blocked&&"palette"===this._currentModel?.kind,e=!!this._openGroupId||t||!!this._dismissPointerTarget;e!==this._globalDismissListening&&(this._globalDismissListening=e,e?(window.addEventListener("pointerdown",this._globalDismissGuard,!0),window.addEventListener("click",this._globalDismissGuard,!0)):(window.removeEventListener("pointerdown",this._globalDismissGuard,!0),window.removeEventListener("click",this._globalDismissGuard,!0)))}}const j_=t=>t.stopPropagation(),U_=4.166666666666667e-9;function G_(t){return Number.isFinite(t)?Math.round(t/Th)*Th:t}const V_=(t,e,i,s)=>Math.hypot(i-t,s-e),K_=(t,e,i,s,n,o,a,r)=>Math.hypot(Math.max(Math.abs(n-t),Math.abs(n+a-(t+i))),Math.max(Math.abs(o-e),Math.abs(o+r-(e+s)))),Y_=(t,e,i,s,n,o,a)=>{const r=Math.max(Number(s)||0,0)/2,l=Math.PI/180,c=Math.cos(i*l)*r,h=Math.sin(i*l)*r,d=Math.cos(a*l)*r,p=Math.sin(a*l)*r,u=Math.max(V_(t+c,e+h,n+d,o+p),V_(t-c,e-h,n-d,o-p)),_=Math.max(V_(t+c,e+h,n-d,o-p),V_(t-c,e-h,n+d,o+p));return Math.min(u,_)},J_=t=>{const e=Number(t?.cell_cm);return e>0?e:5};function X_(t,e){const i=JSON.parse(JSON.stringify(t||[])),s=JSON.parse(JSON.stringify(e||{}));let n=0,o=0,a=0,r=0,l="",c=0,h=0,d=0;const p=(t,e)=>{Number.isFinite(t)&&Number.isFinite(e)&&t!==e&&Math.abs(e-t)<=U_&&h++},u=(t,e)=>{p(t[0],e[0]),p(t[1],e[1])},_={};let m=5;for(const t of i){const e=J_(t);null!=t?.id&&(_[String(t.id)]=e),e>m&&(m=e)}const g=(t,e,i,s=!1)=>{if(!(t>U_||s))return;n++,t>a&&(a=t);const o=t*Dh*e;o>r&&(r=o,l=i)};for(const t of i){const e=J_(t),i=null!=t?.id?String(t.id):"";for(const s of t.rooms||[]){o++;let t=0;if(s.poly?.length)s.poly=s.poly.map(e=>{const i=[G_(e[0]),G_(e[1])];return t=Math.max(t,V_(e[0],e[1],i[0],i[1])),u(e,i),i});else if(null!=s.x&&null!=s.y){const e=s.x,i=s.y,n=s.w||0,o=s.h||0,a=G_(e+n),r=G_(i+o),l=G_(e),c=G_(i),h=Math.max(Th,a-l),d=Math.max(Th,r-c);t=K_(e,i,n,o,l,c,h,d),s.x=l,s.y=c,s.w=h,s.h=d,p(e,l),p(i,c),p(e+n,l+h),p(i+o,c+d)}g(t,e,i)}for(const s of t.room_drafts||[]){o++;let t=0;const n=s.points||[],a=n.map(e=>{const i=[G_(e[0]),G_(e[1])];return t=Math.max(t,V_(e[0],e[1],i[0],i[1])),i}),r=a.length?[a[0]]:[],l=a.length?[[n[0],a[0]]]:[],c=[];for(let t=0;t+1=2)for(const[t,e]of l)u(t,e);g(t,e,i)}if(Array.isArray(t.room_drafts)){const e=t.room_drafts.length;t.room_drafts=t.room_drafts.filter(t=>t.points?.length>=2),d+=e-t.room_drafts.length,t.room_drafts.length||delete t.room_drafts}for(const s of t.partitions||[]){o++;const n=[s.a[0],s.a[1]],a=[s.b[0],s.b[1]],r=[G_(n[0]),G_(n[1])],l=[G_(a[0]),G_(a[1])];let c=Math.max(V_(n[0],n[1],r[0],r[1]),V_(a[0],a[1],l[0],l[1]));const h=V_(r[0],r[1],l[0],l[1]),d=(t.openings||[]).filter(t=>"partition"===t.host?.kind&&t.host.id===s.id).every(t=>{const e=Number(t.length),i=Number(t.host.t),s=i*h;return Number.isFinite(e)&&e>0&&Number.isFinite(i)&&i>=0&&i<=1&&s-e/2>=-U_&&s+e/2<=h+U_});h>U_&&d?(s.a=r,s.b=l,u(n,r),u(a,l)):c=0,g(c,e,i)}for(const s of t.wall_columns||[]){o++;const t=[s.center[0],s.center[1]],n=[G_(t[0]),G_(t[1])],a=V_(t[0],t[1],n[0],n[1]);s.center=n,u(t,n),g(a,e,i)}for(const s of t.decor||[]){o++;let t=0;if("line"===s.kind){const e=[s.x1,s.y1],i=[s.x2,s.y2],n=[G_(e[0]),G_(e[1])],o=[G_(i[0]),G_(i[1])];t=Math.max(V_(e[0],e[1],n[0],n[1]),V_(i[0],i[1],o[0],o[1])),s.x1=n[0],s.y1=n[1],s.x2=o[0],s.y2=o[1],u(e,n),u(i,o)}else{const e=s.x,i=s.y,n=s.w,o=s.h,a=G_(e),r=G_(i);if(null!=s.w&&null!=s.h){const l=G_(e+n),c=G_(i+o),h=Math.max(Th,l-a),d=Math.max(Th,c-r);t=K_(e,i,n,o,a,r,h,d),s.w=h,s.h=d,p(e+n,a+h),p(i+o,r+d)}else t=V_(e,i,a,r);s.x=a,s.y=r,p(e,a),p(i,r)}g(t,e,i)}for(const s of t.openings||[]){if(o++,"partition"===s.host?.kind){const n=(t.partitions||[]).find(t=>t.id===s.host.id),o=Number(s.host.t);if(!n||!Number.isFinite(o)||o<0||o>1)continue;const a=n.b[0]-n.a[0],r=n.b[1]-n.a[1];if(Math.hypot(a,r)<=U_)continue;const l=n.a[0]+a*o,h=n.a[1]+r*o;let d=180*Math.atan2(r,a)/Math.PI;d>=90?d-=180:d<-90&&(d+=180);const p=Number(s.angle),u=!(Number.isFinite(p)&&p===d),_=Y_(s.x,s.y,Number.isFinite(p)?p:d,Number(s.length)||0,l,h,d);s.x=l,s.y=h,s.angle=d,u&&c++,g(_,e,i,u);continue}const n=ui([s.x,s.y],t.rooms||[],.025,{step:Th,length:Number(s.length)||0});if(!n)continue;const a=Number(s.angle),r=!(Number.isFinite(a)&&a===n.angle),l=Y_(s.x,s.y,Number.isFinite(a)?a:n.angle,Number(s.length)||0,n.x,n.y,n.angle);s.x=n.x,s.y=n.y,s.angle=n.angle,r&&c++,g(l,e,i,r)}}for(const[t,e]of Object.entries(s)){if(!e||"object"!=typeof e)continue;const i=e;if("number"!=typeof i.x||"number"!=typeof i.y)continue;o++;const n=G_(i.x),a=G_(i.y),r=V_(i.x,i.y,n,a);s[t]={...i,x:n,y:a},p(i.x,n),p(i.y,a);const l="string"==typeof i.s?i.s:"";g(r,_[l]??m,l)}return{spaces:i,layout:s,report:{moved:n,coordsCanonicalized:h,total:o,maxShift:a,maxShiftCm:r,maxSpace:l,rotated:c,removedDrafts:d},changed:n>0||h>0}}function Z_(t,e){const i=e.base+t*e.span;return Math.min(1,Math.max(0,i))}const Q_=t=>Array.isArray(t)&&t.length>=2&&Number.isFinite(t[0])&&Number.isFinite(t[1]),tm=(t,e)=>Math.hypot(t[0]-e[0],t[1]-e[1]);function em(t,e,i){const s=i[0]-e[0],n=i[1]-e[1],o=s*s+n*n;if(o<=0)return tm(t,e);let a=((t[0]-e[0])*s+(t[1]-e[1])*n)/o;return a=Math.max(0,Math.min(1,a)),Math.hypot(t[0]-(e[0]+s*a),t[1]-(e[1]+n*a))}function im(t,e,i,s,n){for(const s of e)if(s&&!i.has(s.id)&&Q_(s.a)&&Q_(s.b)&&(tm(t,s.a)<=n||tm(t,s.b)<=n))return!0;for(const e of s?.roomPolygons||[])for(let i=0;i0&&r>0))return null;if(Math.abs(n[0]/a*(o[1]/r)-n[1]/a*(o[0]/r))>i)return null;for(const[i,n]of[[t.a,e.a],[t.a,e.b],[t.b,e.a],[t.b,e.b]])if(tm(i,n)<=s)return[(i[0]+n[0])/2,(i[1]+n[1])/2];return null}function nm(t,e){const i=.05*(Number(e.pitch)>0?Number(e.pitch):1),s=new Map;let n=(t||[]).filter(t=>!!t&&"string"==typeof t.id&&Q_(t.a)&&Q_(t.b));if(n.length<2)return{partitions:[...t||[]],merged:0,openingMoves:[]};const o=e.seedIds&&e.seedIds.length?new Set(e.seedIds):null;let a=0;for(let t=0;ttm(e,t.at)>i);let h=c[0]??r.a,d=c[c.length-1]??l.b;if(c.length<2&&(h=r.a,d=l.b),d[0]0?(d[0]-h[0])/u:0,m=u>0?(d[1]-h[1])/u:0,g=t=>u>0?((t[0]-h[0])*_+(t[1]-h[1])*m)/u:0;for(const t of[r,l]){const e=g(t.a),i=g(t.b)-e;for(const[n,o]of s)o.toId===t.id&&s.set(n,{fromId:o.fromId,toId:p.id,base:e+o.base*i,span:o.span*i});s.set(t.id,{fromId:t.id,toId:p.id,base:e,span:i})}o&&o.add(p.id),n=n.filter((e,i)=>i!==t.i&&i!==t.j),n.splice(t.i,0,p),a++}return{partitions:n,merged:a,openingMoves:[...s.values()]}}function om(t,e,i,s){if(!t?.length||!i.length)return 0;const n=new Map(i.map(t=>[t.fromId,t]));let o=0;for(const i of t){const t=i?.host;if(!t||"partition"!==t.kind)continue;const a=n.get(t.id);if(!a)continue;i.host={...t,id:a.toId,t:Z_(t.t,a)},o++;const r=Sp(i,e,s.coordScale,s.cellCm,s.gridPitch).resolved;r&&Object.assign(i,Ip(i,r,s.coordScale))}return o}function am(t,e){const i=e?.excludeDraftId||null;return{roomPolygons:(t?.rooms||[]).map(t=>hi(t)).filter(t=>!!t),columns:t?.wall_columns||[],draftEnds:(t?.room_drafts||[]).flatMap(t=>{if(i&&t?.id===i)return[];const e=t?.points||[];return e.length?[e[0],e[e.length-1]]:[]})}}const rm=t=>!!t&&t.length>=2&&Number.isFinite(t[0])&&Number.isFinite(t[1]),lm=(t,e)=>t[0]-e[0]||t[1]-e[1],cm=(t,e,i,s)=>[t[0]+e*s,t[1]+i*s],hm=(t,e,i,s)=>(t[0]-e[0])*i+(t[1]-e[1])*s,dm=(t,e,i,s,n)=>{const o=e[0]-t[0],a=e[1]-t[1],r=Math.hypot(o,a);if(!(r>n))return null;const l=o/r,c=a/r,h=e=>Math.abs((e[0]-t[0])*c-(e[1]-t[1])*l);if(h(i)>n||h(s)>n)return null;const d=hm(i,t,l,c),p=hm(s,t,l,c),u=Math.max(0,Math.min(d,p)),_=Math.min(r,Math.max(d,p));return _-u>n?{lo:u,hi:_}:null},pm=(t,e,i)=>Math.min(t.hi,e.hi)-Math.max(t.lo,e.lo)>i,um=t=>{const e=new Set(["id","a","b","cm"]);return Object.keys(t||{}).every(t=>e.has(t))},_m=(t,e,i,s)=>{const n=t.b[0]-t.a[0],o=t.b[1]-t.a[1],a=Math.hypot(n,o);if(!(a>s))return!0;const r=n/a,l=o/a,c=gl(t.cm,i.cellCm,i.gridPitch)/2;return e.some(e=>{const n=e?.center;if(!rm(n))return!0;const o=hm(n,t.a,r,l),h=Math.abs((n[0]-t.a[0])*l-(n[1]-t.a[1])*r),d=gl(Number(e.cm),i.cellCm,i.gridPitch)*("square"===e.shape?Math.SQRT1_2:.5);return!(Number.isFinite(d)&&d>0)||o>=-d-s&&o<=a+d+s&&h<=c+d+s})},mm=(t,e,i)=>{if(t.host){const s=Sp(t,e,i.coordScale,i.cellCm,i.gridPitch).resolved;return s?{center:s.center,angle:s.angle,length:s.length}:null}const s=Number(t.x)*i.coordScale,n=Number(t.y)*i.coordScale,o=Number(t.angle),a=Number(t.length)*i.coordScale;return[s,n,o,a].every(Number.isFinite)&&a>0?{center:[s,n],angle:o,length:a}:null},gm=(t,e,i)=>{const s=t.angle*Math.PI/180,n=Math.cos(s),o=Math.sin(s),a=e.angle*Math.PI/180,r=Math.cos(a),l=Math.sin(a);if(Math.abs(n*l-o*r)>1e-6)return!1;const c=e.center[0]-t.center[0],h=e.center[1]-t.center[1];if(Math.abs(c*o-h*n)>i)return!1;const d=c*n+h*o;return Math.max(-t.length/2,d-e.length/2)({...t,a:[t.a[0]*e,t.a[1]*e],b:[t.b[0]*e,t.b[1]*e]}),vm=(t,e,i,s)=>{const n=`~r-${(t=>{let e=2166136261;for(let i=0;i>>0;return e.toString(36)})(`${t}|${e[0].toFixed(9)},${e[1].toFixed(9)}|${i[0].toFixed(9)},${i[1].toFixed(9)}`)}`,o=`${t.slice(0,Math.max(1,64-n.length))}${n}`;let a=o;for(let t=2;s.has(a);t++){const e=`-${t}`;a=`${o.slice(0,64-e.length)}${e}`}return s.add(a),a},ym=(t,e)=>{const i=[];for(const s of t){const t=i[i.length-1];!(t&&Math.abs(t.hi-s.lo)<=e&&t.safe===s.safe)||s.safe&&t.signature!==s.signature?i.push({lo:s.lo,hi:s.hi,a:s.a,b:s.b,safe:s.safe,signature:s.signature,roomIds:s.roomIds,finalCm:s.finalCm}):(t.hi=s.hi,t.b=s.b)}return i};function bm(t,e,i,s,n){const o=i||[],a=Array.isArray(t?.partitions)?t.partitions:[],r=Array.isArray(t?.openings)?t.openings:[],l=Array.isArray(t?.room_drafts)?t.room_drafts:[],c={walls:o,partitions:a,openings:r,roomDrafts:l,partitionsReconciled:0,openingsRehosted:0,removedDrafts:0};if(!a.length&&!l.length)return c;const h=Math.max(2e-4*n.gridPitch,1e-9);let d=o,p=a,u=r;const _=dc(e.rooms,d,s,n.pitch,n.cellCm,n.gridPitch,n.coordScale),m=((t,e,i,s)=>{const n=new Map(t.map(t=>[t.id,t])),o=new Set;for(const t of e){if(!n.get(t.id)||!Array.isArray(t.points)||t.points.length<2||t.segments.length!==t.points.length-1)continue;let e=!0;for(let n=0;n+10)){e=!1;break}const l=Math.hypot(a[0]-o[0],a[1]-o[1]);if(!(l>s)){e=!1;break}const c=i.flatMap(t=>{const e=t.cm>0?t.cm:ll;if(t.open||"outer"!==t.kind&&"shared"!==t.kind||e+st.lo-e.lo||t.hi-e.hi);let h=0;for(const t of c){if(t.lo>h+s)break;if(h=Math.max(h,t.hi),h>=l-s)break}h!m.has(t.id));let f=0,v=0;const y=new Map(e.partitions.map(t=>[t.id,t]));for(const t of[...a].sort((t,e)=>t.id.localeCompare(e.id))){if(!p.some(e=>e.id===t.id))continue;if(!um(t))continue;const i=y.get(t.id);if(!(i&&rm(i.a)&&rm(i.b)&&Number.isFinite(i.cm)&&i.cm>0))continue;const[o,a]=lm(i.a,i.b)<=0?[[i.a[0],i.a[1]],[i.b[0],i.b[1]]]:[[i.b[0],i.b[1]],[i.a[0],i.a[1]]],r=a[0]-o[0],l=a[1]-o[1],c=Math.hypot(r,l);if(!(c>h))continue;const _=r/c,g=l/c,b=dc(e.rooms,d,s,n.pitch,n.cellCm,n.gridPitch,n.coordScale),w=b.flatMap(t=>{if(t.open||"outer"!==t.kind&&"shared"!==t.kind)return[];const e=dm(o,a,t.a,t.b,h);return e?[{interval:t,range:e}]:[]});if(!w.length)continue;const k=u.filter(t=>"partition"===t.host?.kind&&t.host.id===i.id).map(t=>({opening:t,resolved:Sp(t,e.partitions,n.coordScale,n.cellCm,n.gridPitch).resolved}));if(k.some(t=>!t.resolved))continue;const x=[0,c];for(const{range:t}of w)x.push(t.lo,t.hi);const $=x.slice(),S=new Map;for(const{opening:t,resolved:e}of k){const i=hm(e.center,o,_,g),s={lo:i-e.length/2,hi:i+e.length/2};S.set(t.id,s),$.push(Math.max(0,s.lo),Math.min(c,s.hi))}const M=[...new Set($.filter(t=>Number.isFinite(t)&&t>=-h&&t<=c+h).map(t=>Math.max(0,Math.min(c,t)).toFixed(9)))].map(Number).sort((t,e)=>t-e),C=p.map(t=>fm(t,n.coordScale)).filter(t=>t.id!==i.id),D=e.room_drafts.filter(t=>!m.has(t.id)),P=[];for(let t=0;t+1h))continue;const r=cm(o,_,g,s),l=cm(o,_,g,a),c=w.filter(({range:t})=>t.lo<=s+h&&t.hi>=a-h).map(({interval:t})=>t),d=new Map;for(const t of c)d.set(t.roomId,t);const p=[...d.values()],u=new Set(p.map(t=>t.kind)),m=new Set(p.map(t=>t.cm>0?t.cm:ll)),f=p[0]?.kind,v=[...d.keys()].sort(),y=1===u.size&&1===m.size&&("outer"===f&&1===v.length||"shared"===f&&2===v.length),b={id:i.id,a:r,b:l,cm:i.cm},k=C.some(t=>!!dm(r,l,t.a,t.b,h)),x=D.some(t=>t.points.some((e,i)=>i+10?p[0].cm:ll:0,T=y?Math.max(S,i.cm):i.cm;P.push({lo:s,hi:a,a:r,b:l,safe:$,signature:$?`${f}|${v.join(",")}|${T}`:"",roomIds:v,roomCm:S,finalCm:T})}if(!P.some(t=>t.safe))continue;const T=new Map;for(const{opening:t,resolved:e}of k){const s=S.get(t.id),o=x.some(t=>t>s.lo+h&&tpm(t,s,h)),r=new Set(a.filter(t=>t.safe).map(t=>t.signature));if(!o&&a.length>0&&a.every(t=>t.safe)&&1===r.size&&Rp(e,b,h)){T.set(t.id,{resolved:e,signature:[...r][0]});continue}const l=xp(i,n.cellCm,n.gridPitch),c={lo:s.lo-l,hi:s.hi+l};for(const t of P)pm(t,c,h)&&(t.safe=!1,t.signature="")}let R=!0;for(;R;){R=!1;for(const[t,e]of[...T.entries()]){const s=S.get(t),o=P.filter(t=>pm(t,s,h));if(o.length>0&&o.every(t=>t.safe)&&o.every(t=>t.signature===e.signature))continue;T.delete(t);const a=xp(i,n.cellCm,n.gridPitch),r={lo:s.lo-a,hi:s.hi+a};for(const t of P)pm(t,r,h)&&(t.safe=!1,t.signature="");R=!0}}const I=ym(P,h),A=I.filter(t=>t.safe),z=I.filter(t=>!t.safe);if(!A.length)continue;if(p.length-1+z.length>2e3)continue;let F=d;for(const t of A){const[e,s]=lm(i.a,i.b)<=0?[t.a,t.b]:[t.b,t.a];F=Fl(F,e,s,t.finalCm,n.pitch,n.coordScale)}if(F=uc(e.rooms,F,s,n.pitch,n.cellCm,n.gridPitch,n.coordScale),F.length>500)continue;const E=new Set(p.map(t=>t.id));E.delete(i.id);const N=z.map((t,e)=>{const s=[t.a[0]/n.coordScale,t.a[1]/n.coordScale],o=[t.b[0]/n.coordScale,t.b[1]/n.coordScale],a=0===e?i.id:vm(i.id,s,o,E);return E.add(a),{id:a,a:s,b:o,cm:i.cm}}),O=p.findIndex(t=>t.id===i.id),L=p.slice();L.splice(O,1,...N);const H=L.map(t=>fm(t,n.coordScale)),B=new Map;let q=!0;for(const{opening:t,resolved:e}of k){const i=T.get(t.id);if(i){const e=Ip(t,i.resolved,n.coordScale),{host:s,...o}=e;B.set(t.id,o);continue}const s=S.get(t.id),o=N[z.findIndex(t=>t.lo<=s.lo+h&&t.hi>=s.hi-h)],a=o&&H.find(t=>t.id===o.id);if(!o||!a){q=!1;break}const r=a.b[0]-a.a[0],l=a.b[1]-a.a[1],c=Math.hypot(r,l),d=hm(e.center,a.a,r/c,l/c),p={...Ip(t,e,n.coordScale),host:{kind:"partition",id:o.id,t:d/c}};if(!Mp(p,H,n.coordScale,n.cellCm,n.gridPitch).resolved){q=!1;break}B.set(t.id,p)}if(!q)continue;const W=u.map(t=>B.get(t.id)||t),j=[...T.keys()].map(t=>B.get(t)),U=j.map(t=>mm(t,H,n));if(U.some(t=>!t))continue;let G=!1;for(let t=0;tt.id));for(const t of W){if(V.has(t.id))continue;const e=mm(t,H,n);e&&U.some(t=>gm(t,e,h))&&(G=!0)}if(G)continue;const K=Ec(e.rooms,F,s,n.pitch,n.cellCm,n.gridPitch,n.coordScale);[...T.entries()].every(([t,e])=>{const i=B.get(t),s=Lc(K,{x:i.x*n.coordScale,y:i.y*n.coordScale,angle:i.angle,length:i.length*n.coordScale},!0),o=[s.negative,s.positive].filter(t=>!!t?.full),a=e.signature.split("|")[1].split(","),r=new Set(o.map(t=>t.roomId));return o.length===a.length&&r.size===a.length&&a.every(t=>r.has(t))})&&(d=F,p=L,u=W,f+=A.length,v+=T.size)}return{walls:d,partitions:p,openings:u,roomDrafts:g,partitionsReconciled:f,openingsRehosted:v,removedDrafts:m.size}}const wm=t=>JSON.parse(JSON.stringify(t)),km=(t,e)=>Object.prototype.hasOwnProperty.call(t,e),xm=(t,e)=>e.length>0&&e.length<=35&&("space"===t?/^[a-z0-9_-]+$/.test(e):/^[A-Za-z0-9_-]+$/.test(e));function $m(t,e){let i=String(e??"");const s=t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),n=new RegExp(`^${s}_(.+)_([0-9a-f]{8})$`);let o=0;for(;o<16;o++){const t=n.exec(i);if(!t)return{root:i,layers:o,bounded:!1};i=t[1]}return{root:i,layers:o,bounded:n.test(i)}}const Sm=(t,e,i)=>{const s=t.get(e)||[];s.push(i),t.set(e,s)};const Mm=1e-9;class Cm extends Error{constructor(t,e=""){super(e?`${t}: ${e}`:t),this.reason=t,this.name="WallSegmentModelError"}}const Dm=t=>JSON.parse(JSON.stringify(t)),Pm=t=>Array.isArray(t)&&t.length>=2&&Number.isFinite(Number(t[0]))&&Number.isFinite(Number(t[1])),Tm=t=>[Number(t[0]),Number(t[1])],Rm=t=>`${Number(t[0]).toFixed(12)},${Number(t[1]).toFixed(12)}`,Im=(t,e)=>{const i=Rm(t),s=Rm(e);return iRm(t)<=Rm(e)?[Tm(t),Tm(e)]:[Tm(e),Tm(t)],zm=(t,e)=>Math.hypot(e[0]-t[0],e[1]-t[1]),Fm=t=>{const e=[[Number(t.points[0][0]),Number(t.points[0][1])]],i=[];for(let s=1;s{const i=new Set,s=t=>{const e=Number(t);if(!Number.isFinite(e))return;const s=e/Th;Math.abs(s-Math.round(s))>=Ur&&i.add(e.toFixed(12))};for(const e of Array.isArray(t?.rooms)?t.rooms:[])for(const t of hi(e)||[])s(t[0]),s(t[1]);for(const e of[t?.wall_segments,t?.walls])for(const t of Array.isArray(e)?e:[])s(t?.a?.[0]),s(t?.a?.[1]),s(t?.b?.[0]),s(t?.b?.[1]);for(const t of e)s(t?.[0]),s(t?.[1]);return i.size},Nm=(t,e,i)=>{const s=i[0]-e[0],n=i[1]-e[1],o=s*s+n*n;return o>1e-18?((t[0]-e[0])*s+(t[1]-e[1])*n)/o:0},Om=(t,e,i)=>{const s=Math.max(0,Math.min(1,Nm(t,e,i)));return Math.hypot(t[0]-(e[0]+(i[0]-e[0])*s),t[1]-(e[1]+(i[1]-e[1])*s))},Lm=(t,e,i,s,n=Mm)=>{const o=e[0]-t[0],a=e[1]-t[1],r=Math.hypot(o,a);if(r<=n)return 0;const l=e=>Math.abs((e[0]-t[0])*a-(e[1]-t[1])*o)/r;if(l(i)>n||l(s)>n)return 0;const c=Nm(i,t,e),h=Nm(s,t,e);return Math.max(0,Math.min(1,Math.max(c,h))-Math.max(0,Math.min(c,h)))*r},Hm=t=>{const e=(new TextEncoder).encode(t),i=8*e.length,s=64*Math.ceil((e.length+9)/64),n=new Uint8Array(s);n.set(e),n[e.length]=128;const o=new DataView(n.buffer);o.setUint32(s-8,Math.floor(i/4294967296),!1),o.setUint32(s-4,i>>>0,!1);const a=new Uint32Array([1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298]),r=new Uint32Array([1779033703,3144134277,1013904242,2773480762,1359893119,2600822924,528734635,1541459225]),l=new Uint32Array(64),c=(t,e)=>t>>>e|t<<32-e;for(let t=0;t>>3,n=c(i,17)^c(i,19)^i>>>10;l[t]=l[t-16]+s+l[t-7]+n>>>0}let[e,i,s,n,h,d,p,u]=r;for(let t=0;t<64;t++){const o=u+(c(h,6)^c(h,11)^c(h,25))+(h&d^~h&p)+a[t]+l[t]>>>0,r=e&i^e&s^i&s;u=p,p=d,d=h,h=n+o>>>0,n=s,s=i,i=e,e=o+((c(e,2)^c(e,13)^c(e,22))+r>>>0)>>>0}r[0]=r[0]+e>>>0,r[1]=r[1]+i>>>0,r[2]=r[2]+s>>>0,r[3]=r[3]+n>>>0,r[4]=r[4]+h>>>0,r[5]=r[5]+d>>>0,r[6]=r[6]+p>>>0,r[7]=r[7]+u>>>0}const h=new Uint8Array(32),d=new DataView(h.buffer);for(let t=0;t{const e="abcdefghijklmnopqrstuvwxyz234567";let i=0,s=0,n="";for(const o of t)for(s=s<<8|o,i+=8;i>=5;)n+=e[s>>>i-5&31],i-=5;return i&&(n+=e[s<<5-i&31]),n},qm=(t,e,i,s,n="")=>{const[o,a]=Am(e,i),r=`${t}|${Rm(o)}|${Rm(a)}|${[...s].sort().join(",")}${n}`;return`wall-${Bm(Hm(r)).slice(0,20)}`};let Wm=0;const jm=t=>{for(let e=0;e<1e3;e++){const e=globalThis.crypto?.randomUUID?.(),i=`wall-${e||Bm(Hm(`${Date.now()}|${Wm++}|${Math.random()}`)).slice(0,26)}`;if(!t.has(i))return i}throw new Cm("duplicate-id","id factory exhausted")},Um=t=>{const e=new Map;for(const i of Array.isArray(t?.wall_segments)?t.wall_segments:[])if(i&&"string"==typeof i.id&&Pm(i.a)&&Pm(i.b)){if(e.has(i.id))throw new Cm("duplicate-id",i.id);e.set(i.id,i)}return e},Gm=(t,e,i)=>{const s=(i,s)=>{const n=t[0]-i[0],o=t[1]-i[1];return Math.abs(e[0]-s[0]-n)<=Mm&&Math.abs(e[1]-s[1]-o)<=Mm?[n,o]:null};return s(i.a,i.b)||s(i.b,i.a)},Vm=(t,e)=>{const i=Array.isArray(t.rooms)?t.rooms:[],s=ud(t.open_spans).map(t=>[t.a[0],t.a[1],t.b[0],t.b[1]]),n=s.length?s:_d(i,null,1,.04*Th,!0),o=[];for(const t of i){const i=hi(t),s=Array.isArray(t?.wall_ids)?t.wall_ids:[];if(i&&s.length===i.length)for(let t=0;t"partition"!==t.host?.kind&&[Number(t.x),Number(t.y)].every(Number.isFinite)&&Number.isFinite(Number(t.angle))&&Number(t.length)>0&&n.some(e=>Om([Number(t.x),Number(t.y)],[e[0],e[1]],[e[2],e[3]])<=.04*Th)):[],l=r.map(t=>{const e=Number(t.angle)*Math.PI/180,i=[Math.cos(e),Math.sin(e)],s=Number(t.length)/2,n=[Number(t.x),Number(t.y)];return{a:[n[0]-i[0]*s,n[1]-i[1]*s],b:[n[0]+i[0]*s,n[1]+i[1]*s]}}),c=(t,e)=>r.some(i=>{const s=[Number(i.x),Number(i.y)];if(!Rl(t,e,Number(i.angle)))return!1;if(Om(s,t,e)>.02*Th)return!1;const n=zm(t,e),o=Nm(s,t,e)*n,a=Number(i.length)/2;return o+a>=-Mm&&o-a<=n+Mm}),h=new Map,d=[];for(const s of i){const r=String(s?.id||""),p=hi(s);if(!r||!p||p.length<3)throw new Cm("invalid-room",r);const u=ec(i,r,a,Th,1,[...t.walls||[],...l]);if(!u||u.poly.length<3)throw new Cm("invalid-room",r);const _=Array.isArray(s.wall_ids)?s.wall_ids:[],m=_.length===p.length;let g=null,f=m;if(f)for(let t=0;tMm||Math.abs(s[1]-g[1])>Mm)){f=!1;break}g=s}const v=[];for(let t=0;t2)throw new Cm("third-owner",a);const d=m?_[u.parent[t]]:void 0;if("string"==typeof d&&d){const n=e.get(d);f||!n||Lm(i,s,n.a,n.b)>Mm?l.preferredIds.add(d):l.positionalIds.add(d),l.preferredCarriers.set(d,{a:Tm(p[u.parent[t]]),b:Tm(p[(u.parent[t]+1)%p.length])})}const g=u.parent[t];l.parentKeys.add(wl(p[g],p[(g+1)%p.length],Th));const y=[(i[0]+s[0])/2,(i[1]+s[1])/2],b=t=>t.some(t=>Om(y,[t[0],t[1]],[t[2],t[3]])<=.04*Th);l.zeroWall||=b(o)||b(n)&&!c(i,s),v.push(a)}const y={...s};delete y.wall_ids,d.push({...y,poly:u.poly.map(t=>[t[0],t[1]]),wall_ids:v})}return{atoms:[...h.values()].sort((t,e)=>t.key.localeCompare(e.key)),rooms:d}},Km=(t,e,i,s,n)=>{const o=new Map([...i.values()].map(t=>[Im(t.a,t.b),t])),a=(t=>{const e=new Map;for(const i of t)"wall"===i.host?.kind&&e.set(i.host.id,(e.get(i.host.id)||0)+1);return e})(t.openings||[]),r=new Map;for(const t of e){const e=n?.get(t.key);if(e){const s=i.get(e);if(!s)throw new Cm("duplicate-id",e);r.set(t,s);continue}if(t.preferredIds.size>1)throw new Cm("duplicate-id",[...t.preferredIds].sort().join(","));const s=[...t.preferredIds][0],l=s?i.get(s):void 0;if(l){r.set(t,l);continue}const c=s?t.preferredCarriers.get(s):void 0;if(s&&c){r.set(t,{id:s,a:c.a,b:c.b,cm:0});continue}const h=o.get(t.key);if(h){r.set(t,h);continue}const d=[...i.values()].filter(e=>Lm(t.a,t.b,e.a,e.b)>Mm),p=[...new Map(d.map(t=>[t.id,t])).values()];if(p.sort((t,e)=>(a.get(e.id)||0)-(a.get(t.id)||0)||zm(e.a,e.b)-zm(t.a,t.b)||t.id.localeCompare(e.id)),p[0])r.set(t,p[0]);else if(1===t.positionalIds.size){const e=i.get([...t.positionalIds][0]);e&&r.set(t,e)}}const l=new Map;for(const[t,e]of r){const i=l.get(e.id)||[];i.push(t),l.set(e.id,i)}for(const[t,e]of l){const s=i.get(t)||r.get(e[0]);if(!s)throw new Cm("duplicate-id",t);const n=[(s.a[0]+s.b[0])/2,(s.a[1]+s.b[1])/2];e.sort((t,e)=>{const i=Om(n,t.a,t.b)<=Mm?0:1,o=Om(n,e.a,e.b)<=Mm?0:1;if(i!==o)return i-o;return(Om(s.a,t.a,t.b)<=Mm?0:1)-(Om(s.a,e.a,e.b)<=Mm?0:1)||t.key.localeCompare(e.key)}),e[0].id=t}const c=(t=>{const e=new Set;for(const i of[t.rooms,t.openings,t.decor,t.room_drafts,t.partitions,t.wall_columns])for(const t of Array.isArray(i)?i:[])"string"==typeof t?.id&&t.id&&e.add(t.id);for(const i of Array.isArray(t.room_drafts)?t.room_drafts:[])for(const t of Array.isArray(i?.segments)?i.segments:[])"string"==typeof t?.id&&t.id&&e.add(t.id);return e})(t);for(const t of e)if(t.id){if(c.has(t.id))throw new Cm("duplicate-id",t.id);c.add(t.id)}const h=e.filter(t=>!t.id);if(s){const e=h.map(e=>{const[i,s]=Am(e.a,e.b),n=`${String(t.id||"")}|${Rm(i)}|${Rm(s)}|${[...e.owners].sort().join(",")}`,o=Bm(Hm(n));return{atom:e,seed:n,digest:o,base:`wall-${o.slice(0,20)}`}}).sort((t,e)=>t.digest.localeCompare(e.digest)||t.atom.key.localeCompare(e.atom.key)),i=new Map;for(const t of e){const e=i.get(t.digest);if(e&&e!==t.seed)throw new Cm("duplicate-id",t.digest);i.set(t.digest,t.seed);let s=1,n=t.base;for(;c.has(n);)n=`${t.base}-${++s}`;t.atom.id=n,c.add(n)}}else for(const t of h)t.id=jm(c),c.add(t.id)},Ym=(t,e)=>{if("partition"===t.host?.kind)return null;const i=[Number(t.x),Number(t.y)];if(!i.every(Number.isFinite))return null;const s=e=>{if(!(Number(e.cm)>0))return!1;const s=Nm(i,e.a,e.b),n=zm(e.a,e.b),o=Number(t.length)/2;return s>=-Mm&&s<=1+Mm&&Om(i,e.a,e.b)<=.02*Th&&Rl(e.a,e.b,Number(t.angle))&&Number.isFinite(o)&&o>=0&&s*n-o>=-Mm&&s*n+o<=n+Mm},n="wall"===t.host?.kind?e.find(e=>e.id===t.host.id):null,o=n&&s(n)?[n]:e.filter(s);if(1!==o.length)return null;const a=o[0];return{kind:"wall",id:a.id,t:Math.max(0,Math.min(1,Nm(i,a.a,a.b)))}},Jm=(t,e)=>{const i=[Number(t.x),Number(t.y)];if(!i.every(Number.isFinite))return null;const s=Number(t.length)/2,n=e.filter(e=>{if(!(Number(e.cm)>0))return!1;const n=Nm(i,e.a,e.b),o=zm(e.a,e.b);return n>=-Mm&&n<=1+Mm&&Om(i,e.a,e.b)<=.02*Th&&Rl(e.a,e.b,Number(t.angle))&&Number.isFinite(s)&&s>=0&&n*o-s>=-Mm&&n*o+s<=o+Mm}),o=(e=>{if(!e.length)return null;const s="wall"===t.host?.kind?e.find(e=>e.id===t.host.id):null;return s||[...e].sort((t,e)=>Om(i,t.a,t.b)-Om(i,e.a,e.b)||Number(e.cm)-Number(t.cm)||(t.ide.id?1:0))[0]})(n);return o?{kind:"wall",id:o.id,t:Math.max(0,Math.min(1,Nm(i,o.a,o.b)))}:null},Xm=(t,e,i)=>{const s=Um(t),{atoms:n,rooms:o}=Vm(t,s);Km(t,n,s,e,i);const a=n.map(e=>{const i=e.id?s.get(e.id):void 0,n=((t,e,i)=>{if(e.zeroWall)return 0;const s=Array.isArray(t.walls)?t.walls:[],n=wl(e.a,e.b,Th),o=s.filter(t=>Number(t.cm)>0&&(!(t.key!==n&&!e.parentKeys.has(t.key))||!(!Pm(t.a)||!Pm(t.b))&&Lm(e.a,e.b,t.a,t.b)>=zm(e.a,e.b)-Mm)).map(t=>Math.max(1,Math.min(100,Number(t.cm))));if(new Set(o.map(t=>t.toFixed(9))).size>1)throw new Cm("thickness-conflict",e.key);if(o.length)return o[0];const a=Pl(s,e.a,e.b,Th,1);return a>0?a:Number(i?.cm)>0?Number(i.cm):0})(t,e,i);return{...i||{},id:e.id,a:[...e.a],b:[...e.b],cm:n}}),r=new Map(n.map(t=>[t.key,t.id]));for(const t of o)t.wall_ids=t.wall_ids.map(t=>r.get(t));t.rooms=o,t.wall_segments=a,t.walls=a.filter(t=>t.cm>0).map(t=>({key:wl(t.a,t.b,Th),cm:t.cm,a:[...t.a],b:[...t.b]})),t.walls.length||delete t.walls,delete t.open_spans;for(const e of t.rooms)delete e.open_to;return((t,e)=>{const i=new Set;for(const e of[t.rooms,t.openings,t.decor,t.room_drafts,t.partitions,t.wall_columns,t.wall_segments])for(const t of Array.isArray(e)?e:[])"string"==typeof t?.id&&t.id&&i.add(t.id);for(const s of Array.isArray(t.room_drafts)?t.room_drafts:[]){const n=Array.isArray(s.segments)?s.segments:[];for(let o=0;o{const s=Array.isArray(t.openings)?t.openings:[];for(const t of s){if("partition"===t.host?.kind)continue;if(!t.host&&!i){const i=Ym(t,e);i&&(t.host=i);continue}const s=Ym(t,e)??(i?Jm(t,e):null);if(s)t.host=s;else{if(!i)throw new Cm("opening-host",t.id);delete t.host}}})(t,a,e),a.reduce((t,e)=>t+(s.has(e.id)?0:1),0)};function Zm(t,e={}){const i=JSON.stringify(t),s=Dm(t);rl(s);let n=0;const o=Number(s?.model_version||0)<9;for(const t of Array.isArray(s?.spaces)?s.spaces:[]){const i=e.lineageSpaceId===String(t?.id||"")?e.lineageHints:void 0;n+=Xm(t,o,i)}return s.model_version=9,rl(s),{config:s,changed:i!==JSON.stringify(s),migratedSegments:n}}const Qm=t=>!!t&&"object"==typeof t&&!Array.isArray(t);function tg(t,e){const i=(t,e)=>{if(Array.isArray(t)&&Array.isArray(e)){const s=new Map;for(const e of t)Qm(e)&&"string"==typeof e.id&&e.id&&s.set(e.id,e);const n=e.map((e,n)=>{if(Qm(e)&&"string"==typeof e.id&&e.id){const t=s.get(e.id);return t?i(t,e):Dm(e)}return n[e,e in t?i(t[e],s):Dm(s)]);for(const e of Object.keys(t))delete t[e];for(const[e,i]of s)t[e]=i;return t}return Dm(e)};return i(t,e)}const eg=(t,e)=>Object.prototype.hasOwnProperty.call(t,e),ig=(t,e,i)=>Math.min(i,Math.max(e,t)),sg=t=>Sh({spaces:[t]})[0],ng=(t,e,i)=>{const s=i>0?i:1,n=t=>`${(t[0]/s).toFixed(12)},${(t[1]/s).toFixed(12)}`,o=n(t),a=n(e);return o0?a:1,l=Math.max(s*r*.02,1e-9),c=[];for(const e of t||[])for(const t of hi(e)||[])c.push([t[0],t[1]]);const h=[];for(const t of i||[])Array.isArray(t)&&t.length>=4&&t.slice(0,4).every(Number.isFinite)&&h.push([t[0],t[1]],[t[2],t[3]]);const d=(t,e)=>e.some(e=>Math.hypot(t[0]-e[0],t[1]-e[1])<=2*l),p=new Map;for(const a of t||[]){if(!a?.id)continue;const u=hc(t,a.id,e,i,s,n,o,r);if(u)for(let t=0;t0&&_>0&&a===m&&_!==a))continue;const g=u.poly[s],f=u.poly[(s+1)%u.poly.length],v=Math.hypot(f[0]-g[0],f[1]-g[1]);if(!(v>l&&v<.5*o-1e-9*o))continue;if(d(g,h)||d(f,h))continue;if(d(g,c)&&d(f,c))continue;const y=ng(g,f,r),b=p.get(y);b?b.targets.add(a):p.set(y,{a:[g[0],g[1]],b:[f[0],f[1]],targets:new Set([a])})}}}let u=e.slice();const _=(t,e)=>Math.hypot(t[0]-e[0],t[1]-e[1])<=2*l,m=(t,e)=>{if(!Array.isArray(t.a)||!Array.isArray(t.b)||t.a.length<2||t.b.length<2)return!1;const i=[Number(t.a[0])*r,Number(t.a[1])*r],s=[Number(t.b[0])*r,Number(t.b[1])*r];return!![...i,...s].every(Number.isFinite)&&(_(i,e.a)&&_(s,e.b)||_(i,e.b)&&_(s,e.a))};for(const t of[...p.values()].filter(t=>1===t.targets.size).sort((t,e)=>ng(t.a,t.b,r).localeCompare(ng(e.a,e.b,r)))){const e=[...t.targets][0],i=u.filter(e=>m(e,t));if(new Set(i.map(t=>t.cm)).size>1)continue;let n=!1;u=u.map(i=>m(i,t)?(n=!0,i.cm===e?i:{...i,cm:e}):i),n||(u=Fl(u,t.a,t.b,e,s,r))}return u}const ag=t=>{const e=[];for(const i of t||[]){const t=hi(i);if(t?.length)for(let i=0;i"string"==typeof t?.id?t.id:"").filter(Boolean),h=new Set(c),d=new Map;for(const t of c){const e=$m("space",t);e.layers>0&&xm("space",e.root)&&Sm(d,e.root,t)}const p=new Map,u=new Map,_=new Map,m=new Map;for(const t of r){const e="string"==typeof t?.id?t.id:"";if(!e)continue;const i=new Map;for(const s of Array.isArray(t.rooms)?t.rooms:[]){const t="string"==typeof s?.id?s.id:"";if(!t)continue;const n=$m("room",t);n.layers>0&&xm("room",n.root)&&Sm(i,n.root,t),u.has(t)||u.set(t,e),_.has(t)||_.set(t,String(s.name||""));const o="string"==typeof s.area?s.area:"";if(o){const i=m.get(o)||[];i.push({spaceId:e,roomId:t}),m.set(o,i)}}p.set(e,i)}const g=new Set(u.keys()),f=new Map,v=new Map;for(const t of l)"string"==typeof t?.id&&t.id&&(!0===t.removed?v.set(t.id,t):f.set(t.id,t));const y={spaceRefsRemapped:0,roomRefsRemapped:0,positionsRemapped:0,markersDetached:0,positionsUnresolved:0,nestedRefsUnresolved:0,deadSpaceIds:[],orphanRoomLabelsRemoved:0,orphanDevicePositionsRemoved:0,orphanGroupPositionsRemoved:0,liveMissingPositionsRemoved:0,removedPositions:[],liveMissingPositions:[],unverifiedPositions:[]},b=new Set,w=t=>h.has(t)?null:(()=>{const e=$m("space",t).root;if(!xm("space",e))return null;const i=d.get(e)||[];return 1===i.length?i[0]:null})(),k=(t,e)=>{const i=$m("room",t).root;if(!xm("room",i))return null;const s=p.get(e)?.get(i)||[];return 1===s.length?s[0]:null},x=t=>{const e=i.effectiveAreaByMarker?.[t]||"",s=e&&m.get(e)||[];return 1===s.length?s[0]:null},$=(t,e,i)=>{if("string"==typeof t.room_id&&t.room_id&&!g.has(t.room_id)){const s=e?k(t.room_id,e):null;s?(t.room_id=s,y.roomRefsRemapped++):i?(t.room_id=i.roomId,y.roomRefsRemapped++):!0!==t.removed&&delete t.room_id}const s=t.vacuum?.segment_map;if(s&&"object"==typeof s&&!Array.isArray(s))for(const t of Object.keys(s)){const i=s[t];if("string"!=typeof i||!i||g.has(i))continue;const n=e?k(i,e):null;n?(s[t]=n,y.roomRefsRemapped++):y.nestedRefsUnresolved++}};for(const t of l){const e="string"==typeof t?.id?t.id:"";if(!e)continue;const i="string"==typeof t.space?t.space:"",s=i&&!h.has(i),o=n[e],a="string"==typeof o?.s?o.s:"",r=a&&!h.has(a),l=!0===t.removed;let c=i&&h.has(i)?i:null,d=null,p=!1;if(s){const s=w(i);s?(t.space=s,c=s,p=!0,y.spaceRefsRemapped++):l||"virtual"===t.binding?l||(delete t.space,c=null,y.markersDetached++):(d=x(e),d?(t.space=d.spaceId,c=d.spaceId,y.spaceRefsRemapped++):(delete t.space,c=null,y.markersDetached++))}l&&!p||$(t,c,d),r&&p&&a===i&&c&&(n[e]={...o,s:c},y.positionsRemapped++,b.add(e))}for(const t of Object.keys(n)){if(b.has(t))continue;const e=n[t],i="string"==typeof e?.s?e.s:"";if(!i||h.has(i))continue;const s=w(i);if(s){if(t.startsWith("rl_")){const i=t.slice(3),o=k(i,s);if(o){const i=`rl_${o}`;km(n,i)||(n[i]={...e,s:s}),delete n[t],y.roomRefsRemapped++,y.positionsRemapped++;continue}}n[t]={...e,s:s},y.positionsRemapped++}}const S=i.ownerRoster,M=!0===S?.authoritative,C=new Set(S?.deviceIds||[]),D=new Set(S?.entityIds||[]),P=new Set(Array.isArray(s.settings?.known_devices)?s.settings.known_devices.filter(t=>"string"==typeof t):[]),T=(t,e="")=>{const i=String(S?.names?.[t]||e||"").trim();return i&&i!==t?i:""},R=(t,e,i,s="",n)=>({id:t,spaceId:e,kind:i,name:T(t,s),...n?{reason:n}:{}}),I=t=>{"room_label"===t?y.orphanRoomLabelsRemoved++:"group"===t?y.orphanGroupPositionsRemoved++:y.orphanDevicePositionsRemoved++},A=new Set;for(const[t,e]of Object.entries(n)){const s="string"==typeof e?.s?e.s:"";if(!s||h.has(s))continue;let o,a;const r=f.get(t),l=v.get(t);if(r)o=R(t,s,"device",String(r.name||"")),a="live";else if(l)o=R(t,s,"device",String(l.name||"")),a="absent";else if(t.startsWith("rl_")){const e=t.slice(3);o=R(t,s,"room_label",_.get(e)||""),a=g.has(e)?"live":"absent"}else if(t.startsWith("lg_")){const e=t.slice(3);o=R(t,s,"group"),a=D.has(e)?"live":M?"absent":"unverified","unverified"===a&&(o.reason="registry_unavailable")}else C.has(t)?(o=R(t,s,"device"),a="live"):P.has(t)?(o=R(t,s,"device"),a=M?"absent":"unverified","unverified"===a&&(o.reason="registry_unavailable")):(o=R(t,s,"unknown","","unknown_owner"),a="unverified");if("absent"!==a){if("live"===a){if(y.liveMissingPositions.push(o),!0===i.removeLiveMissingPositions){delete n[t],y.liveMissingPositionsRemoved++,I(o.kind),y.removedPositions.push(o);continue}}else y.unverifiedPositions.push(o);y.positionsUnresolved++,A.add(s)}else delete n[t],I(o.kind),y.removedPositions.push(o)}return y.deadSpaceIds=[...A].sort((t,e)=>t.localeCompare(e)),{config:s,layout:n,report:y,changed:JSON.stringify(s)!==o||JSON.stringify(n)!==a}}(t,e,i),a=o.config,r=nl(a,o.layout);rl(a),al(o.layout);const l=JSON.stringify(t||{}),c=JSON.stringify(e||{}),h=Number.isInteger(Number(a.model_version))?Number(a.model_version):0,d=(t=>{let e=0,i=0,s=0;for(const i of t.markers||[]){if("ripple"===i.display&&(i.display="icon_ripple",e++),Array.isArray(i.controls)){const t="string"==typeof i.binding&&i.binding.startsWith("entity:")?i.binding.slice(7):"",s=t?i.controls.filter(e=>e!==t):i.controls;JSON.stringify(s)!==JSON.stringify(i.controls)&&(i.controls=s.length?s:null,e++)}const t=i.vacuum;t&&eg(t,"trail")&&(["never","cleaning","always"].includes(t.trail_mode)||(t.trail_mode=!1===t.trail?"never":"cleaning"),delete t.trail,e++)}for(const n of t.spaces||[]){const t=n.settings;"glow"===t?.fill_mode&&("boolean"!=typeof t.glow_enabled&&(t.glow_enabled=!0),t.fill_mode="none",e++,i++);for(const t of n.rooms||[]){const i=t.settings;"glow"===i?.fill_mode&&("boolean"!=typeof i.glow&&(i.glow=!0),delete i.fill_mode,e++,s++)}if(eg(n,"segments")&&(delete n.segments,e++),eg(n,"plan_scale")){const t=Number(n.plan_scale);Number.isFinite(t)&&t>=wh&&t<=kh&&(eg(n,"plan_scale_x")||(n.plan_scale_x=t),eg(n,"plan_scale_y")||(n.plan_scale_y=t),delete n.plan_scale,e++)}const o=Number(n.cell_cm);eg(n,"cell_cm")&&(!Number.isFinite(o)||o<.1||o>1e3)&&(n.cell_cm=Number.isFinite(o)&&o>0?ig(o,.1,1e3):5,e++);const a=Number(n.cell_cm),r=Number.isFinite(a)&&a>0?a:5;for(const t of n.wall_columns||[])if("circle"===t.shape)eg(t,"angle")&&(delete t.angle,e++);else if("square"===t.shape&&eg(t,"angle")){const i=((Number(t.angle)||0)%90+90)%90;t.angle!==i&&(t.angle=i,e++)}for(const t of n.decor||[]){if(eg(t,"width")){const i=Number(t.width);(eg(t,"width_cm")||Number.isFinite(i))&&(eg(t,"width_cm")||(t.width_cm=Number(ig(i/Ph*r,.1,100).toFixed(6))),delete t.width,e++)}if("rect"!==t?.kind&&"ellipse"!==t?.kind||!0!==t.fill||(eg(t,"fill_color")||(t.fill_color=t.color||"#607d8b",e++),eg(t,"fill_opacity")||(t.fill_opacity=.25,e++)),"text"!==t?.kind)continue;void 0===t.size_cm?(t.size_cm=Number(ig(es*is(t)/Ph*r,.1,2e3).toFixed(6)),delete t.scale,delete t.size,e++):(eg(t,"scale")||eg(t,"size"))&&(delete t.scale,delete t.size,e++);let i=String(t.text??"");const s=[...i.matchAll(/\{([^{}\r\n]+)\}/g)].some(t=>!!Yi(t[1]));if(!(eg(t,"entity")||eg(t,"attr")||eg(t,"unit")))continue;const n=String(t.unit??"").trim(),o="state"===String(t.attr??"").trim().toLowerCase()?null:t.attr,a=s||n?"":Ji(t.entity,o);if(s||a){if(a){const e=i.indexOf("{}");i=e>=0?i.slice(0,e)+a+i.slice(e+2):`${i}${i?" ":""}${a}`,t.text=i}delete t.entity,delete t.attr,delete t.unit,e++}}}return{total:e,glowSpaces:i,glowRooms:s}})(a);let p=d.total;const u=(_=a.spaces||[],JSON.parse(JSON.stringify(_)));var _;const m=X_(a.spaces||[],o.layout);let g=0,f=0,v=0,y="";const b=m.spaces.map(t=>{const e=function(t){const e=JSON.parse(JSON.stringify(t||{}));let i=Array.isArray(e.rooms)?e.rooms:[];const s=new Map;for(const t of i){const e=hi(t);if(e)for(let t=0;tt.key.localeCompare(e.key))){let e=null;for(const s of $a(t,i)){const t=r.get(_a(s.from));if(t&&t!==_a(s.to))continue;const n=wa(i,s);if(ka(i,n,s)){e=s,i=n;break}}e?(r.set(_a(e.from),_a(e.to)),n++,a=Math.max(a,Math.hypot(e.to[0]-e.from[0],e.to[1]-e.from[1]))):o++}e.rooms=i;for(const t of e.room_drafts||[]){if(!Array.isArray(t?.points)||t.points.length<2)continue;const e=t.points.map(t=>[...t]),i=e.slice(0,-1).flatMap((i,s)=>{const n=e[s+1],o=pa(i,n);return o?[{key:`${String(t.id||"")}:${s}`,a:[...i],b:[...n],axis:o.axis}]:[]});let s=e;for(const t of i){let e=null;for(const i of $a(t,[{poly:s}])){const t=s.map(t=>ba(t,i)),n=t.length>=4&&ma(t[0],t[t.length-1]),o=n?t.slice(0,-1):t;if(n?va(o):ya(o)){e=i,s=t;break}}e?(n++,a=Math.max(a,Math.hypot(e.to[0]-e.from[0],e.to[1]-e.from[1]))):o++}t.points=s}for(const t of e.partitions||[]){if(!Array.isArray(t?.a)||!Array.isArray(t?.b))continue;const i=pa(t.a,t.b);if(!i)continue;const s={key:String(t.id||ga(t.a,t.b)),a:[...t.a],b:[...t.b],axis:i.axis};let r=null;for(const i of $a(s,[{poly:[t.a,t.b]}])){const s=ba(t.a,i),n=ba(t.b,i),o=Math.hypot(n[0]-s[0],n[1]-s[1]);if(!(o>0))continue;const a=(e.openings||[]).filter(e=>"partition"===e?.host?.kind&&e.host.id===t.id).every(t=>{const e=Number(t.host.t),i=Number(t.length);return Number.isFinite(e)&&e>=0&&e<=1&&Number.isFinite(i)&&i>0&&e*o-i/2>=-1e-12&&e*o+i/2<=o+1e-12});if(a){r=i,t.a=s,t.b=n;break}}r?(n++,a=Math.max(a,Math.hypot(r.to[0]-r.from[0],r.to[1]-r.from[1]))):o++}return{space:e,report:{wallsStraightened:n,wallsStraightenSkipped:o,maxStraightenShift:a},changed:n>0}}(t);g+=e.report.wallsStraightened,f+=e.report.wallsStraightenSkipped;const i=Number(t?.cell_cm)>0?Number(t.cell_cm):5,s=e.report.maxStraightenShift/Th*i;return s>v&&(v=s,y=String(t?.id||"")),e.space}),w=g?X_(b,m.layout):{...m,spaces:b};a.spaces=w.spaces;const k=g?{...m.report,moved:m.report.moved+w.report.moved,coordsCanonicalized:m.report.coordsCanonicalized+w.report.coordsCanonicalized,maxShift:Math.max(m.report.maxShift,w.report.maxShift),maxShiftCm:Math.max(m.report.maxShiftCm,w.report.maxShiftCm),maxSpace:w.report.maxShiftCm>m.report.maxShiftCm?w.report.maxSpace:m.report.maxSpace,rotated:m.report.rotated+w.report.rotated,removedDrafts:m.report.removedDrafts+w.report.removedDrafts}:{...m.report};let x=0,$=0,S=0,M=0,C=0,D=0,P=0,T=0;for(let t=0;t0===Number(t.cm)),walls:e.walls||[]}),o=sg(e),r=sg(i);if(!o||!r)continue;const l=ag(o.rooms),c=ag(r.rooms),h=.02*Ph,d=(e.wall_segments||[]).filter(t=>0===Number(t.cm)).map(t=>({...t,key:wl(t.a,t.b,Th),cm:0})),p=new Set(d.map(t=>t.key)),_=m_(e,o.rooms,yh,h);$+=_.length;for(const t of _){const e=[t[0]/yh,t[1]/yh],i=[t[2]/yh,t[3]/yh],s=wl(e,i,Th);p.has(s)||(p.add(s),d.push({key:s,a:e,b:i,cm:0}))}const m=d.length,g=Al(d,l,c,Th,yh),f=(t,e,i)=>{const s=i[0]-e[0],n=i[1]-e[1],o=s*s+n*n;if(!(o>0))return Math.hypot(t[0]-e[0],t[1]-e[1]);const a=Math.max(0,Math.min(1,((t[0]-e[0])*s+(t[1]-e[1])*n)/o));return Math.hypot(t[0]-(e[0]+s*a),t[1]-(e[1]+n*a))},v=g.filter(t=>{if(!Array.isArray(t.a)||!Array.isArray(t.b))return!1;const e=t.a.map(t=>t*yh),i=t.b.map(t=>t*yh);return c.some(([t,s])=>f(e,t,s)<=4*h&&f(i,t,s)<=4*h)});S+=Math.max(0,m-v.length);const y=(i.wall_segments||[]).filter(t=>Number(t.cm)>0);i.wall_segments=[...y,...v.map(({key:t,...e})=>e)];const b=v.map(t=>[t.a[0]*yh,t.a[1]*yh,t.b[0]*yh,t.b[1]*yh]),w=Array.isArray(e.walls)?e.walls.length:0;let k=Al(e.walls,l,c,Th,yh);k=og(r.rooms,k,b,Th,Number(i.cell_cm)>0?Number(i.cell_cm):5,Ph,yh),k=uc(r.rooms,k,b,Th,Number(i.cell_cm)>0?Number(i.cell_cm):5,Ph,yh),k=Tl(k,i.rooms||[],Th,1,b.map(t=>[t[0]/yh,t[1]/yh,t[2]/yh,t[3]/yh])),x+=Math.max(0,w-k.length),k.length?i.walls=k:delete i.walls;const R=nm(i.partitions||[],{pitch:Th,geometry:am(i)});R.merged&&(M+=R.merged,i.partitions=R.partitions,om(i.openings,i.partitions,R.openingMoves,{coordScale:yh,cellCm:Number(i.cell_cm)>0?Number(i.cell_cm):5,gridPitch:Ph}));const I=sg(i);if(I){const t=n(i,I,i.walls||[],b,{pitch:Th,cellCm:Number(i.cell_cm)>0?Number(i.cell_cm):5,gridPitch:Ph,coordScale:yh});t.partitionsReconciled&&(C+=t.partitionsReconciled,D+=t.openingsRehosted,t.partitions.length?i.partitions=t.partitions:delete i.partitions,t.openings.length?i.openings=t.openings:delete i.openings,t.walls.length?i.walls=t.walls:delete i.walls),t.removedDrafts&&(P+=t.removedDrafts,t.roomDrafts.length?i.room_drafts=t.roomDrafts:delete i.room_drafts)}JSON.stringify({zero:(i.wall_segments||[]).filter(t=>0===Number(t.cm)),walls:i.walls||[]})!==s&&T++}let R=0;h<=9&&(R=function(t){const e=Zm(t);return tg(t,e.config),{...e,config:t}}(a).migratedSegments);const I=rl(a),A=al(w.layout),z=JSON.stringify(I)!==l||JSON.stringify(A)!==c;h<9&&z&&(I.model_version=9);const F=JSON.stringify(I)!==l||JSON.stringify(A)!==c,E=Number.isInteger(Number(I.model_version))?Number(I.model_version):h,N=F?k:{...k,moved:0,coordsCanonicalized:0,maxShift:0,maxShiftCm:0,maxSpace:"",rotated:0,removedDrafts:0},O=F?o.report:{...o.report,spaceRefsRemapped:0,roomRefsRemapped:0,positionsRemapped:0,markersDetached:0,orphanRoomLabelsRemoved:0,orphanDevicePositionsRemoved:0,orphanGroupPositionsRemoved:0,liveMissingPositionsRemoved:0};return{config:I,layout:A,report:{...N,modelFrom:h,modelTo:E,migrated:F?p:0,glowSpacesMigrated:F?d.glowSpaces:0,glowRoomsMigrated:F?d.glowRooms:0,canonicalized:F?T:0,wallSegmentsMigrated:F?R:0,legacyZeroWallsMigrated:F?$:0,wallsMerged:F?x:0,spansMerged:F?S:0,partitionsMerged:F?M:0,partitionsReconciled:F?C:0,openingsRehosted:F?D:0,redundantDraftsRemoved:F?P:0,wallsStraightened:F?g:0,wallsStraightenSkipped:f,maxStraightenShiftCm:F?v:0,maxStraightenSpace:F?y:"",latticeCoordinatesCanonicalized:F?r.canonicalized:0,latticeCoordinatesFar:F?r.far:0,latticeMaxShift:F?r.maxShift:0,latticeMaxShiftCm:F?r.maxShiftCm:0,latticeSpaces:F?r.spaces:[],...O},changed:F}}function lg(t,e,i){const s=(t?.spaces||[]).find(t=>t?.id===i),n=new Set((s?.rooms||[]).map(t=>String(t?.id||"")).filter(Boolean)),o=[...new Set((t?.markers||[]).filter(t=>!0!==t?.removed&&"string"==typeof t?.id).filter(t=>t.space===i||"string"==typeof t.room_id&&n.has(t.room_id)||e?.[t.id]?.s===i).map(t=>t.id))].sort((t,e)=>t.localeCompare(e));return{markerIds:o,count:o.length}}function cg(t){return t instanceof Error?t.name||"Error":typeof t}function hg(t){return wd({id:t?.id??"",cell_cm:t?.cell_cm,rooms:t?.rooms||[],walls:t?.walls||[],wall_segments:t?.wall_segments||[],open_spans:t?.open_spans||[],openings:t?.openings||[],partitions:t?.partitions||[],room_drafts:t?.room_drafts||[],wall_columns:t?.wall_columns||[]})}function dg(t,e,i,s=Ph,n=1e3){return(Array.isArray(t?.openings)?t.openings:[]).flatMap(t=>{const o={...t,rx:Number(t.x)*n,ry:Number(t.y)*n,rlen:Number(t.length)*n};if(!t.host||"wall"===t.host.kind)return[o];const a=Sp(t,e.partitions,n,i,s);return a.resolved?[{...t,rx:a.resolved.center[0],ry:a.resolved.center[1],rlen:a.resolved.length,angle:a.resolved.angle,partitionHost:a.resolved}]:[]})}function pg(t,e=()=>!0){return t.flatMap(t=>t.host&&t.partitionHost&&e(t)?[Dp(t.partitionHost)]:[])}function ug(t,e,i,s,n,o,a=Ph,r=1e3){const l=dc(e.rooms,[...i],s,n,o,a,r);return t.flatMap(t=>{const e={x:t.rx,y:t.ry,angle:Number(t.angle)||0,length:t.rlen};return t.host&&"wall"!==t.host.kind?t.partitionHost&&Rp(t.partitionHost,l,2e-4*a)?[e]:[]:[e]})}function _g(t,e){const i=Th,s=Ph,n=yh,o=Number.isFinite(Number(e.cellCm))&&Number(e.cellCm)>0?Number(e.cellCm):5,a=Array.isArray(t?.walls)?t.walls:[],r=function(t,e,i=Ph,s=1e3){return _d(e.rooms,t?.open_spans,s,.02*i)}(t,e,s,n),l=function(t,e,i=Ph){if(!e.length)return[];const s=t.filter(t=>t?.id),n=.02*i,o=[];for(let t=0;t{const e=[(t[0]+t[2])/2,(t[1]+t[3])/2];return h.some(t=>Ls(e,t)<4*n)}).map(t=>[...t]);d.length&&o.push({a:a,b:r,segs:d})}return o}(e.rooms,r,s).flatMap(t=>t.segs),c=dg(t,e,o,s,n),h=pg(c),d=ih(e,o,s,2e-4*s,h).all;return{space:e,walls:a,openCuts:l,openings:c,roomOpenings:ug(c,e,a,l,i,o,s,n),partitionCuts:h,physicalBodies:d,wallKeyPitch:i,cellCm:o,gridPitch:s,coordScale:n}}function mg(t,e,i){const s="string"==typeof t?.title?t.title.trim():"",n=null==t?.id?"":String(t.id).trim();return{spaceId:n,displayName:s||n||i(e+1)}}function gg(t,e={}){const i=(e.fingerprint||wd)(t),s=Array.isArray(t?.spaces)?t.spaces:[],n=e.fallbackSpaceName||(t=>`Space ${t}`),o=e.prepareSpace||_g,a=e.wallPass||Rc,r=e.floorPass||Pc,l=[];for(let i=0;i0||d.physicalBodies.length>0;if(!d.space.rooms.length&&!p){l.push({...h,status:"not-applicable"});continue}let u=null;if(p){try{u=a(d.space.rooms,d.walls,d.openCuts,d.roomOpenings,d.wallKeyPitch,d.cellCm,d.gridPitch,d.coordScale,d.physicalBodies)}catch(t){l.push({...h,status:"failed",reason:"wall-exception",detail:cg(t)});continue}if(null==u){l.push({...h,status:"failed",reason:"wall-null"});continue}if("degraded-extra"===u.status){l.push({...h,status:"failed",reason:"wall-degraded-extra"});continue}if("failed-core"===u.status){l.push({...h,status:"failed",reason:"wall-failed-core"});continue}e.captureWallGeometry?.(d,u)}if(d.space.rooms.length&&null==u?.paperGeom){let t;try{t=r(d.space.rooms,d.walls,d.openCuts,d.wallKeyPitch,d.cellCm,d.gridPitch,d.coordScale)}catch(t){l.push({...h,status:"failed",reason:"floor-exception",detail:cg(t)});continue}if(null==t){l.push({...h,status:"failed",reason:"floor-null"});continue}}l.push({...h,status:"ok"})}const c=l.filter(t=>"failed"===t.status);return{fingerprint:i,spaces:l,failures:c,ok:0===c.length}}class fg{constructor(t=50){this._undo=[],this._redo=[],this._limit=Math.max(30,Math.floor(t))}get canUndo(){return this._undo.length>0}get canRedo(){return this._redo.length>0}get undoName(){return this._undo[this._undo.length-1]?.name??null}get redoName(){return this._redo[this._redo.length-1]?.name??null}get size(){return this._undo.length}push(t){this._undo.push(t),this._undo.length>this._limit&&this._undo.splice(0,this._undo.length-this._limit),this._redo=[]}undo(){const t=this._undo.pop()??null;return t&&this._redo.push(t),t}redo(){const t=this._redo.pop()??null;return t&&this._undo.push(t),t}clear(){this._undo=[],this._redo=[]}}const vg=new WeakMap;const yg=(t,e,i)=>255===t[i+3]&&e.every((e,s)=>Math.abs(t[i+s]-e)<=2);async function bg(t){const e=t.defaultView;if(!e||!e.CSS?.supports?.("mix-blend-mode","screen"))return!1;const i=[128,32,16],s=[16,64,128],n=[9,19,29],o=`\n \n \n \n \n \n `,a=e.URL.createObjectURL(new Blob([o],{type:"image/svg+xml"}));try{const o=await new Promise((t,i)=>{const s=new e.Image,n=e.setTimeout(()=>i(new Error("SVG blend probe timeout")),1e3);s.onload=()=>{e.clearTimeout(n),t(s)},s.onerror=()=>{e.clearTimeout(n),i(new Error("SVG blend probe failed"))},s.src=a}),r=t.createElement("canvas");r.width=4,r.height=1;const l=r.getContext("2d",{willReadFrequently:!0});if(!l)return!1;l.drawImage(o,0,0,4,1);const c=l.getImageData(0,0,4,1).data;return yg(c,i,0)&&yg(c,function(t,e){return[0,1,2].map(i=>Math.round(255-(255-t[i])*(255-e[i])/255))}(i,s),4)&&yg(c,s,8)&&yg(c,n,12)}catch{return!1}finally{e.URL.revokeObjectURL(a)}}const wg={now:()=>performance.now(),requestFrame:t=>requestAnimationFrame(t),cancelFrame:t=>cancelAnimationFrame(t)},kg=t=>Math.max(0,Math.min(1,t)),xg=(t,e,i)=>t+(e-t)*i,$g=(t,e,i)=>{const s=1-t;return 3*s*s*t*e+3*s*t*t*i+t*t*t};function Sg(t,e){return{centerX:t.x+t.w/2,centerY:t.y+t.h/2,pixelsPerUnit:e>0&&t.w>0?e/t.w:1,viewBox:{...t}}}function Mg(t,e,i){const s=Math.max(1e-9,t.pixelsPerUnit),n=Math.max(1e-9,e/s),o=Math.max(1e-9,i/s);return{x:t.centerX-n/2,y:t.centerY-o/2,w:n,h:o}}function Cg(t){const e=t.trim(),i=/^rgba?\(\s*([\d.]+)[, ]+([\d.]+)[, ]+([\d.]+)(?:\s*[,/]\s*([\d.]+))?\s*\)$/i.exec(e);if(i)return[Number(i[1]),Number(i[2]),Number(i[3]),null==i[4]?1:Number(i[4])];const s=/^#([0-9a-f]{6}|[0-9a-f]{8})$/i.exec(e)?.[1];return s?[parseInt(s.slice(0,2),16),parseInt(s.slice(2,4),16),parseInt(s.slice(4,6),16),8===s.length?parseInt(s.slice(6,8),16)/255:1]:null}function Dg(t,e,i){const s=Cg(t),n=Cg(e);if(!s||!n)return i<.5?t:e;const o=kg(i);return`rgba(${Math.round(xg(s[0],n[0],o))}, ${Math.round(xg(s[1],n[1],o))}, ${Math.round(xg(s[2],n[2],o))}, ${xg(s[3],n[3],o).toFixed(3)})`}function Pg(t,e,i){const s=(t=>{const e=kg(t);if(0===e||1===e)return e;let i=0,s=1,n=e;for(let t=0;t<12;t++)n=(i+s)/2,$g(n,.2,.2){const e=this._state;if(!e||e.token!==n)return;const i=kg((t-e.startedAt)/e.duration);e.presented=i>=1?e.to:Pg(e.from,e.to,i),e.phase=i>=1?"settling":"running",this._hooks.frame(e),i<1?this._raf=this._clock.requestFrame(a):(this._raf=0,this._hooks.settled(e),this._state?.token===n&&(this._state=null))};return this._raf=this._clock.requestFrame(a),n}cancel(t=!0){this._raf&&this._clock.cancelFrame(this._raf),this._raf=0;const e=this._state;this._state=null,this._token++,e&&t&&(e.phase="settling",e.presented=e.to,this._hooks.frame(e),this._hooks.settled(e))}dispose(){this.cancel(!1)}}const Rg="houseplan_card_labs_v1",Ig=Object.freeze([Object.freeze({id:"iso",issue:89,since:"1.62.0",expires:"1.65.0",summary:"Volumetric plan renderer"})]);function Ag(t){const e=/^(\d+)\.(\d+)\.(\d+)(?:-[0-9A-Za-z.-]+)?$/.exec(String(t||"").trim());if(!e)return null;const i=e.slice(1).map(Number);return i.every(t=>Number.isSafeInteger(t))?i:null}function zg(t,e){for(let i=0;i<3;i++)if(t[i]!==e[i])return t[i]t.split(",")).map(t=>t.trim()).filter(Boolean)}function Hg(t,e,i,s=Ig){const n=function(t,e=Ig){const i=Ag(t),s=new Map;if(!i||!Eg(e))return s;for(const t of e){const e=Ag(t.since),n=Ag(t.expires);zg(i,e)>=0&&zg(i,n)<0&&s.set(t.id,t)}return s}(i,s),o=new Set(Eg(s)?s.map(t=>t.id):[]),a=new Set(function(t){if(!t)return[];try{const e=JSON.parse(t);return Array.isArray(e)?e.filter(t=>"string"==typeof t):[]}catch{return[]}}(e).filter(t=>n.has(t)));let r=!1;const l=t=>{if("off"===t)return a.clear(),void(r=!0);const e=t.startsWith("-"),i=e?t.slice(1):t;o.has(i)&&(r=!0,e||!n.has(i)?a.delete(i):a.add(i))};for(const e of Lg(new URLSearchParams(String(t.search||"").replace(/^\?/,""))))l(e);for(const e of Lg(Ng(t.hash)))l(e);const c=Object.freeze([...a].sort());return{active:c,space:Og(t.hash),persist:r?JSON.stringify(c):void 0,knownUrlOperation:r}}let Bg={active:Object.freeze([]),space:""},qg="",Wg=!1,jg="";const Ug=new Set;function Gg(){if("undefined"==typeof window)return Bg;const t=Hg(window.location,function(){try{return window.localStorage.getItem(Rg)}catch{return null}}(),qg);void 0!==t.persist&&function(t){try{window.localStorage.setItem(Rg,t)}catch{}}(t.persist),Bg={active:t.active,space:t.space},window.__hpLabs=t.active;for(const t of Ug)t(Bg);return Bg}function Vg(){Gg()}function Kg(t){return qg=t,"undefined"==typeof window?Bg:(Wg||(Wg=!0,window.addEventListener("hashchange",Vg),window.addEventListener("popstate",Vg)),Gg())}const Yg=Object.freeze({rotDeg:0,tiltDeg:20,xyScale:1,zScale:1,origin:Object.freeze([500,500])});function Jg(t){return[t.rotDeg,t.tiltDeg,t.xyScale,t.zScale,t.origin[0],t.origin[1]].every(Number.isFinite)&&Math.abs(t.xyScale)>1e-12&&Math.abs(Math.cos(t.tiltDeg*Math.PI/180))>1e-12}function Xg(t,e,i=Yg){if(!(Jg(i)&&Number.isFinite(t[0])&&Number.isFinite(t[1])&&Number.isFinite(e)))throw new Error("invalid isometric projection input");const s=i.rotDeg*Math.PI/180,n=i.tiltDeg*Math.PI/180,o=t[0]-i.origin[0],a=t[1]-i.origin[1],r=(o*Math.cos(s)-a*Math.sin(s))*i.xyScale,l=(o*Math.sin(s)+a*Math.cos(s))*i.xyScale;return[i.origin[0]+r,i.origin[1]+l*Math.cos(n)-e*i.zScale*Math.sin(n)]}function Zg(t,e=Yg){if(!Jg(e)||!Number.isFinite(t[0])||!Number.isFinite(t[1]))throw new Error("invalid isometric projection input");const i=e.rotDeg*Math.PI/180,s=e.tiltDeg*Math.PI/180,n=(t[0]-e.origin[0])/e.xyScale,o=(t[1]-e.origin[1])/(e.xyScale*Math.cos(s));return[e.origin[0]+n*Math.cos(i)+o*Math.sin(i),e.origin[1]-n*Math.sin(i)+o*Math.cos(i)]}function Qg(t=Yg){return`matrix(${function(t=Yg){if(!Jg(t))throw new Error("invalid isometric camera");const e=t.rotDeg*Math.PI/180,i=t.tiltDeg*Math.PI/180,s=t.xyScale*Math.cos(e),n=-t.xyScale*Math.sin(e),o=t.xyScale*Math.sin(e)*Math.cos(i),a=t.xyScale*Math.cos(e)*Math.cos(i);return[s,o,n,a,t.origin[0]-s*t.origin[0]-n*t.origin[1],t.origin[1]-o*t.origin[0]-a*t.origin[1]]}(t).map(t=>Number(t.toFixed(12))).join(" ")})`}function tf(t,e=Yg){const{rect:i,wallHeight:s}=t,n=t.openingHeight??s,o=t.floorDepth??0;if(!(i.w>=0)||!(i.h>=0)||!Number.isFinite(s)||!Number.isFinite(n)||!Number.isFinite(o)||s<0||n<0||o<0)throw new Error("invalid isometric frame");const a=[[i.x,i.y],[i.x+i.w,i.y],[i.x+i.w,i.y+i.h],[i.x,i.y+i.h]],r=Math.max(s,n),l=a.flatMap(t=>[Xg(t,-o,e),Xg(t,r,e)]),c=l.map(t=>t[0]),h=l.map(t=>t[1]),d=Math.min(...c),p=Math.min(...h);return{x:d,y:p,w:Math.max(...c)-d,h:Math.max(...h)-p}}const ef=t=>`${Number(t[0].toFixed(4))} ${Number(t[1].toFixed(4))}`;function sf(t){let e=0;for(let i=0;iArray.isArray(t)&&Number.isFinite(t[0])&&Number.isFinite(t[1])).map(t=>[Number(t[0]),Number(t[1])]),i=e[e.length-1];return e.length>1&&e[0][0]===i[0]&&e[0][1]===i[1]&&e.pop(),e}(t);if(i.length<3)return[];const s=!e;return sf(i)>0===s?i:[...i].reverse()}function of(t,e,i){return t.length?`M ${t.map(t=>ef(Xg(t,i,e))).join(" L ")} Z`:""}function af(t,e,i){const s=e[1]-t[1],n=-(e[0]-t[0]),o=i.rotDeg*Math.PI/180;return s*Math.sin(o)+n*Math.cos(o)}function rf(t,e,i=Yg){if(!Number.isFinite(e)||e<0)throw new Error("invalid floor edge height");const s=(t||[]).map(t=>(t||[]).map((t,e)=>function(t,e){const i=nf(t,e);if(!i.length)return i;let s=0;for(let t=1;t0)).filter(t=>t.length>=3&&Math.abs(sf(t))>=1e-9)).filter(t=>t.length&&sf(t[0])>0);s.sort((t,e)=>{const i=t[0][0],s=e[0][0];return i[0]-s[0]||i[1]-s[1]||Math.abs(sf(e[0]))-Math.abs(sf(t[0]))});const n=[],o=[];let a=0;for(let t=0;tt.depth-e.depth||t.component-e.component||t.edge-e.edge),{footprintPath:n.join(" "),sides:o,componentCount:s.length,edgeCount:a}}function lf(t,e){return t^=Math.round(64*(Number.isFinite(e)?e:0)),Math.imul(t,16777619)>>>0}const cf=t=>t.every(Number.isFinite);function hf(t,e,i,s){const n=t[0]*i,o=t[1]*s,a=e*Math.PI/180;return[n*Math.cos(a)-o*Math.sin(a),n*Math.sin(a)+o*Math.cos(a)]}function df(t,e,i,s,n,o,a){const r=t.flipH?-1:1,l="gate"===t.type?1:t.flipV?-1:1,c=(t.type,t.flipV,t.angle,t.face,{ox:0,oy:0}),h=function(t,e){return[t[0]+e[0],t[1]+e[1]]}([t.x+c.ox,t.y+c.oy],hf(i,t.angle,r,l));return{leaf:e,hinge:h,closedVector:hf(s,t.angle,r,l),quarterVector:hf([-s[1],s[0]],t.angle,r,l),turnDeg:n,bottom:o,top:a}}const pf=t=>`${Number(t[0].toFixed(4))} ${Number(t[1].toFixed(4))}`;function uf(t,e,i=Yg){const s=Math.max(0,Math.min(1,Number.isFinite(e)?e:0));return t.leaves.map(e=>{const n=function(t,e){const i=t.turnDeg*e*Math.PI/180;return[t.hinge[0]+t.closedVector[0]*Math.cos(i)+t.quarterVector[0]*Math.sin(i),t.hinge[1]+t.closedVector[1]*Math.cos(i)+t.quarterVector[1]*Math.sin(i)]}(e,s),o=Xg(e.hinge,e.bottom,i),a=Xg(n,e.bottom,i),r=Xg(n,e.top,i),l=Xg(e.hinge,e.top,i);return{id:t.id,sourceIndex:t.sourceIndex,type:t.type,leaf:e.leaf,d:`M ${pf(o)} L ${pf(a)} L ${pf(r)} L ${pf(l)} Z`,shadowD:`M ${pf(Xg(e.hinge,0,i))} L ${pf(Xg(n,0,i))}`,depth:Math.max(o[1],a[1])}})}const _f={window:120,door:90,passage:90,gate:300};function mf(t){return _f[t]}function gf(t,e){const i=[t[0],t[1]],s=[e[0],e[1]];return function(t,e){return t[0]-e[0]||t[1]-e[1]}(i,s)<=0?{a:i,b:s}:{a:s,b:i}}function ff(t){const e=new Map;return t.forEach((t,i)=>{if(!t.kind||t.open)return;const s=gf(t.a,t.b);if(Math.hypot(s.b[0]-s.a[0],s.b[1]-s.a[1])<=1e-9)return;const n=function(t,e){const i=t=>(Math.abs(t)<=5e-10?0:Math.round(1e6*t)/1e6).toFixed(6);return`${i(t[0])},${i(t[1])}>${i(e[0])},${i(e[1])}`}(s.a,s.b),o=e.get(n);if(o)return o.physicalHalfWidth=Math.max(o.physicalHalfWidth,t.half||0),o.sourceOrder=Math.min(o.sourceOrder,i),void(t.partitionHost&&(o.partitionHost&&o.partitionHost.id!==t.partitionHost.id?o.ambiguousPartitionHost=!0:o.partitionHost=t.partitionHost));e.set(n,{segmentKey:n,a:s.a,b:s.b,physicalHalfWidth:Math.max(0,t.half||0),sourceOrder:i,...t.partitionHost?{partitionHost:t.partitionHost}:{}})}),[...e.values()]}function vf(t,e){if(Math.abs(t.distance-e.distance)>1e-9)return t.distance-e.distance;if(Math.abs(t.perpendicular-e.perpendicular)>1e-9)return t.perpendicular-e.perpendicular;return(t.target.segmentKeye.target.segmentKey?1:0)||t.target.sourceOrder-e.target.sourceOrder}function yf(t){const e=ff(t.intervals).map(e=>{const i=function(t,e){const i=e.b[0]-e.a[0],s=e.b[1]-e.a[1],n=Math.hypot(i,s),o=i/n,a=s/n,r=(t[0]-e.a[0])*o+(t[1]-e.a[1])*a,l=Math.max(0,Math.min(n,r)),c=e.a[0]+l*o,h=e.a[1]+l*a;return{along:l,length:n,x:c,y:h,distance:Math.hypot(t[0]-c,t[1]-h),perpendicular:Math.abs((t[0]-e.a[0])*a-(t[1]-e.a[1])*o)}}(t.pointer,e);return{target:e,...i,envelope:Math.max(t.baseTolerance,e.physicalHalfWidth+t.bodyPointerPadding)}}).filter(t=>t.distance<=t.envelope+1e-9).filter(e=>!function(t,e,i,s,n){const o=e.b[0]-e.a[0],a=e.b[1]-e.a[1],r=Math.hypot(o,a);if(!(r>1e-9))return!1;const l=o/r,c=a/r;for(const o of i){if(!o.open&&o.kind)continue;const i=gf(o.a,o.b),a=i.b[0]-i.a[0],r=i.b[1]-i.a[1],h=Math.hypot(a,r);if(!(h>1e-9))continue;const d=a/h,p=r/h;if(Math.abs(l*p-c*d)>1e-6)continue;if(Math.abs((i.a[0]-e.a[0])*c-(i.a[1]-e.a[1])*l)>n)continue;const u=(t[0]-i.a[0])*d+(t[1]-i.a[1])*p,_=1e-9;if(!(u<=_||u>=h-_)&&Math.abs((t[0]-i.a[0])*p-(t[1]-i.a[1])*d)<=s+1e-9)return!0}return!1}(t.pointer,e.target,t.intervals,e.envelope,Math.max(1e-9,Math.min(t.baseTolerance,.04*t.gridStep)))),i=e.filter(e=>!!e.target.partitionHost&&t.renderedLength+2*e.target.physicalHalfWidth>e.length+1e-9).sort(vf),s=e.filter(e=>!e.target.partitionHost||t.renderedLength+2*e.target.physicalHalfWidth<=e.length+1e-9).sort(vf);let n=s[0];if(!n)return{candidate:null,jambBlockedTarget:i[0]?.target||null};const o=s.filter(t=>Math.abs(t.distance-n.distance)<=1e-9&&Math.abs(t.perpendicular-n.perpendicular)<=1e-9),a=o.filter(t=>t.target.partitionHost);if(a.length){if(1!==new Set(a.map(t=>t.target.partitionHost.id)).size||a.some(t=>t.target.ambiguousPartitionHost))return{candidate:null,jambBlockedTarget:null};const t=a[0],e=t.target.b[0]-t.target.a[0],i=t.target.b[1]-t.target.a[1],s=Math.hypot(e,i),r=e/s,l=i/s,c=o.every(e=>{const i=e.target.b[0]-e.target.a[0],s=e.target.b[1]-e.target.a[1],n=Math.hypot(i,s),o=i/n,a=s/n,c=Math.abs(r*a-l*o)<=1e-6,h=Math.abs((e.target.a[0]-t.target.a[0])*l-(e.target.a[1]-t.target.a[1])*r);return c&&h<=1e-9});if(!c)return{candidate:null,jambBlockedTarget:null};n=t}if(n.target.ambiguousPartitionHost)return{candidate:null,jambBlockedTarget:null};const{target:r,length:l}=n,c=r.b[0]-r.a[0],h=r.b[1]-r.a[1],d=c/l,p=h/l,u=r.partitionHost?r.physicalHalfWidth:0,_=Math.min(Math.max(0,t.renderedLength)/2+u,l/2);let m=n.along;const g=Math.max(t.gridStep,1e-9),f=l/2;m=Math.abs(m-f)<=g/2?f:Math.round(m/g)*g,m=Math.max(_,Math.min(l-_,m));const v=r.a[0]+d*m,y=r.a[1]+p*m,b=Math.max(0,t.renderedLength)/2,w=m-b,k=m+b,x=Math.max(0,w),$=Math.max(0,l-k),S=[r.a[0]+d*(w-x/2),r.a[1]+p*(w-x/2)],M=[r.a[0]+d*(k+$/2),r.a[1]+p*(k+$/2)];let C=180*Math.atan2(h,c)/Math.PI;C>=90?C-=180:C<-90&&(C+=180);const D=Math.abs(m-f)<=1e-9;return{candidate:{presetRevision:t.preset.revision,geometryRevision:t.geometryRevision,pointer:[t.pointer[0],t.pointer[1]],type:t.preset.type,lengthCm:t.preset.lengthCm,flipH:t.preset.flipH,flipV:t.preset.flipV,x:v,y:y,angle:C,renderedLength:t.renderedLength,target:r,...r.partitionHost?{host:{...r.partitionHost,t:l>0?m/l:0}}:{},measure:{labels:[{distance:x,midpoint:S},{distance:$,midpoint:M}],guide:D?{x:v,y:y,angle:C}:null}},jambBlockedTarget:null}}function bf(t,e,i,s,n=1e-6){return t.presetRevision===i&&t.geometryRevision===s&&Math.hypot(t.pointer[0]-e[0],t.pointer[1]-e[1])<=n}const wf=(t,e)=>t[0]*e[1]-t[1]*e[0],kf=(t,e)=>t[0]*e[0]+t[1]*e[1],xf=(t,e)=>[t[0]-e[0],t[1]-e[1]],$f=(t,e,i)=>[t[0]+e[0]*i,t[1]+e[1]*i];function Sf(t,e,i){return Math.abs(wf(t,e))<=i}function Mf(t,e,i){return Math.abs(wf(xf(t,e),i))}function Cf(t,e,i,s,n){const o=e[0]-t[0],a=e[1]-t[1],r=Math.hypot(o,a);if(!(r>n&&i>0))return[];const l=[o/r,a/r];return function(t,e,i){const s=e.map(([e,i])=>[Math.max(0,Math.min(e,i)),Math.min(t,Math.max(e,i))]).filter(([t,e])=>e>t+i).sort((t,e)=>t[0]-e[0]||t[1]-e[1]),n=[];for(const t of s){const e=n[n.length-1];!e||t[0]>e[1]+i?n.push([...t]):e[1]=Math.max(e[1],t[1])}const o=[];let a=0;for(const[t,e]of n)t>a+i&&o.push([a,t]),a=Math.max(a,e);return t>a+i&&o.push([a,t]),o}(r,s.flatMap(e=>{const s=e.b[0]-e.a[0],o=e.b[1]-e.a[1],a=Math.hypot(s,o);if(!(a>n&&Sf(l,[s/a,o/a],1e-6)))return[];if(Mf(e.a,t,l)>1.1*Math.max(i,n)||Mf(e.b,t,l)>1.1*Math.max(i,n))return[];return[[kf(xf(e.a,t),l),kf(xf(e.b,t),l)]]}),n).flatMap(([e,s])=>{const n=Ol({a:$f(t,l,e),b:$f(t,l,s),halfDepth:i});return n?[n]:[]})}function Df(t){const e=t.coordScale??1,i=Math.max(t.epsilon??2e-4*t.gridPitch,1e-9),s=[];for(const i of t.rooms||[]){if(!i?.id)continue;const n=hc(t.rooms,i.id,t.walls,t.openCuts,t.pitch,t.cellCm,t.gridPitch,e);if(!n||n.poly.length<3)continue;const o=Zl(n.poly,n.offsets);!o||o.length<3||s.push({roomId:i.id,profile:n,inner:o})}s.sort((t,e)=>t.roomId.localeCompare(e.roomId));const n=(t.roomOpenings||[]).map(t=>{const e=t.angle*Math.PI/180,i=[Math.cos(e),Math.sin(e)],s=Math.max(0,t.length)/2;return{a:$f([t.x,t.y],i,-s),b:$f([t.x,t.y],i,s)}}),o=[];for(const s of zc(t.rooms,t.walls,t.openCuts,t.pitch,t.cellCm,t.gridPitch,e))for(const t of Cf(s.a,s.b,s.depthUnits/2,n,i))o.push({body:t});const a=new Map;for(const e of t.partitionCuts||[]){const t=a.get(e.hostId)||[];t.push(e),a.set(e.hostId,t)}for(const e of t.partitions||[]){const s=gl(e.cm,t.cellCm,t.gridPitch)/2;for(const t of Cf(e.a,e.b,s,a.get(e.id)||[],i))o.push({body:t,partitionId:e.id})}return{rooms:s,boundaries:o,epsilon:i}}function Pf(t,e,i,s){const n=t.profile.offsets[e];if(!(n>0))return null;const o=function(t,e){const i=t[e],s=t[(e+1)%t.length],n=s[0]-i[0],o=s[1]-i[1],a=Math.hypot(n,o)||1;return function(t){let e=0;for(let i=0;i=0?[-o/a,n/a]:[o/a,-n/a]}(t.profile.poly,e),a=$f(i.center,o,n),r=[];for(let e=0;es&&Sf(i.axis,[l[0]/c,l[1]/c],1e-6)))continue;if(Mf(n,a,i.axis)>s||Mf(o,a,i.axis)>s)continue;const h=kf(xf(n,a),i.axis),d=kf(xf(o,a),i.axis);r.push([Math.min(h,d),Math.max(h,d)])}const l=function(t,e){t.sort((t,e)=>t[0]-e[0]||t[1]-e[1]);const i=[];for(const s of t){const t=i[i.length-1];!t||s[0]>t[1]+e?i.push([...s]):t[1]=Math.max(t[1],s[1])}return i}(r,s).find(([t,e])=>t<=s&&e>=-s);if(!l)return null;const[c,h]=l,d=$f(a,i.axis,-i.half),p=$f(a,i.axis,i.half),u=Math.max(0,-i.half-c),_=Math.max(0,h-i.half),m=u>0?$f(a,i.axis,c):d,g=_>0?$f(a,i.axis,h):p,f=kf(o,i.normal)>=0?1:-1,v=(e,s,n)=>({from:e,to:s,label:[(e[0]+s[0])/2,(e[1]+s[1])/2],axis:i.axis,labelNormal:o,distance:n,roomId:t.roomId,roomSide:f,source:"room-face"});return{left:v(d,m,u),right:v(p,g,_)}}function Tf(t){const e=$f(t.center,t.axis,-t.half),i=$f(t.center,t.axis,t.half),s=$f(t.center,t.axis,Math.min(-t.half,t.targetLo)),n=$f(t.center,t.axis,Math.max(t.half,t.targetHi)),o=(e,i)=>({from:e,to:i,label:[(e[0]+i[0])/2,(e[1]+i[1])/2],axis:t.axis,labelNormal:t.normal,distance:Math.hypot(i[0]-e[0],i[1]-e[1]),source:"host-end"});return[o(e,s),o(i,n)]}function Rf(t,e,i,s){const n=xf(i,e),o=kf(n,n);if(!(o>s*s))return Math.hypot(...xf(t,e))<=s;const a=kf(xf(t,e),n)/o;if(a<-s||a>1+s)return!1;const r=$f(e,n,Math.max(0,Math.min(1,a)));return Math.hypot(...xf(t,r))<=s}function If(t,e,i){let s=!1;for(let n=0,o=e.length-1;nt[1]!=c>t[1]&&t[0]<(l-a)*(t[1]-r)/(c-r)+a&&(s=!s)}return s}function Af(t,e,i,s,n,o){const a=xf(s,i),r=wf(e,a);if(Math.abs(r)<=o)return null;const l=xf(i,t),c=wf(l,a)/r,h=wf(l,e)/r;return c<-o||c>n+o||h<-o||h>1+o?null:Math.max(0,Math.min(n,c))}function zf(t,e,i){const s=Tf(i),n="partition"===t.host?.kind?t.host.id:void 0;return[{base:s[0],direction:[-i.axis[0],-i.axis[1]]},{base:s[1],direction:i.axis}].map(({base:t,direction:i})=>{const s=t.distance,o=function(t,e,i,s,n,o){let a=null;for(const r of s)if(!n||r.partitionId!==n){if(If(t,r.body,o))return 0;for(let s=0;skf(xf(t,n),i));return{center:n,axis:i,normal:s,half:Math.max(0,t.renderedLength)/2,targetLo:Math.min(...o),targetHi:Math.max(...o)}}(t),s=e.rooms.flatMap(t=>{const s=function(t,e,i){const{profile:s}=t;let n=null;for(let t=0;t0))continue;const o=s.poly[t],a=s.poly[(t+1)%s.poly.length],r=xf(a,o),l=Math.hypot(r[0],r[1]);if(!(l>i&&Sf(e.axis,[r[0]/l,r[1]/l],1e-6)))continue;if(Mf(o,e.center,e.axis)>i||Mf(a,e.center,e.axis)>i)continue;const c=kf(xf(o,e.center),e.axis),h=kf(xf(a,e.center),e.axis),d=Math.min(c,h),p=Math.max(c,h);if(d>-e.half+i||p0?d:p<0?-p:0);(!n||u2)return Tf(i);if(s.length){const t=s.map(({room:t,edge:s})=>Pf(t,s,i,e.epsilon));if(t.some(t=>!t))return Tf(i);const n=t;return[...n.map(t=>t.left),...n.map(t=>t.right)]}return zf(t,e,i)}function Ef(t){return!(!t.canEdit||t.kiosk||t.fixedFloor)&&("view"!==t.mode&&("mouse"===t.pointerType&&t.spaceCount>1))}const Nf="1.68.0",Of={badge:"display.badge",icon_ripple:"display.icon_ripple",value:"display.value",static_icon:"display.static_icon"},Lf={badge:"marker.display_hint_badge",icon_ripple:"marker.display_hint_icon_ripple",value:"marker.display_hint_value",static_icon:"marker.display_hint_static_icon"},Hf=2e3,Bf=1e3,qf=1500,Wf=t=>{const e=String(t??"").trim().replace(",",".");if(!/^[+-]?(?:\d+(?:\.\d*)?|\.\d+)$/.test(e))return null;const i=Number(e);return Number.isFinite(i)?i:null},jf=(t,e)=>{if(!t.has(e))return{hit:!1};const i=t.get(e);return t.delete(e),t.set(e,i),{hit:!0,value:i}},Uf=(t,e,i,s)=>{for(t.delete(e),t.set(e,i);t.size>s;){const e=t.keys().next().value;if(void 0===e)break;t.delete(e)}},Gf=new Map;let Vf=0;const Kf=t=>`${window.innerWidth}x${window.innerHeight}|${location.pathname}|${JSON.stringify(t??{})}`;let Yf=1e4;const Jf="houseplan_card_layout_v1",Xf="houseplan_card_cfg_v1",Zf="houseplan_card_zoom_v1",Qf="houseplan_card_nav_v1",tv="houseplan_card_kiosk_v1",ev="houseplan_card_view_v1",iv="hp-dialog, hp-help, hp-color-opacity, hp-device-preview",sv=1e3,nv=[[0,1],[45,.88],[70,.62],[86,.32],[100,0]],ov=(t,e)=>{const i=Math.min(t.x,e.x),s=Math.min(t.y,e.y);return{x:i,y:s,w:Math.max(t.x+t.w,e.x+e.w)-i,h:Math.max(t.y+t.h,e.y+e.h)-s}},av=new Set(["select","draw","column","merge","split","resize","opening","wallthick","delroom"]),rv=2e3,lv=(t,e,i)=>{const s=new Event(e,{bubbles:!0,composed:!0});s.detail=i??{},t.dispatchEvent(s)},cv=t=>{history.pushState(null,"",t),lv(window,"location-changed",{replace:!1})},hv=(t,e)=>{let i,s=null;const n=(...n)=>{clearTimeout(i),s=n,i=window.setTimeout(()=>{i=void 0;const e=s;s=null,e&&t(...e)},e)};return n.flush=()=>{if(void 0===i)return;clearTimeout(i),i=void 0;const e=s;s=null,e&&t(...e)},n.cancel=()=>{clearTimeout(i),i=void 0,s=null},n.pending=()=>void 0!==i,n},dv=t=>{try{t.target?.setPointerCapture?.(t.pointerId)}catch{}};class pv extends ht{constructor(){super(...arguments),this._space="f1",this._layout={},this._serverStorage=!1,this._loadOk=!1,this._serverCanWrite=null,this._loading=!1,this._loadTries=0,this._serverCfg=null,this._cfgRev=0,this._cfgContentFingerprint="",this._unsubCfg=null,this._unsubLayout=null,this._unsubVirtual=null,this._liveSyncAttempt=null,this._liveSyncGeneration=0,this._liveSyncConnection=null,this._layoutRev=0,this._layoutContentFingerprint="",this._virtualLights=mn(null),this._canOptimizeUndo=!1,this._undoKind=null,this._devices=[],this._regSignature="",this._defPos={},this._newSyncKey="",this._tip=null,this._hoverRoom=null,this._pointerModality=new N_(this,()=>this._syncPointerHoverTargets()),this._devicePressAnimations=new Map,this._selId=null,this._toast="",this._mode="view",this._pendingNavMode=null,this._decorTool="select",this._decorStyle={...Rr},this._decorDraft=null,this._decorMove=null,this._decorSel=null,this._decorEraseConfirm=null,this._decorTextDialog=null,this._decorShapeDialog=null,this._backdropDialog=null,this._decorTextSelection={start:0,end:0},this._furnPalette=null,this._dtBox=null,this._dtDrag=null,this._bdDrag=null,this._slide="",this._reducedMotion=!1,this._onMotionChange=t=>{this._reducedMotion=t.matches,this._cancelDevicePressFeedback(),t.matches&&this._modeTransitionPreparing?this._modeTransitionForceAtomic=!0:t.matches&&this._modeTransition.active&&this._cancelModeTransition(!0),this.requestUpdate()},this._editorChromeMode="plan",this._modeTransitionVisual=null,this._modeTransitionPreparing=!1,this._modeTransitionForceAtomic=!1,this._modeTransitionRequest=0,this._modeTransitionTargetZoom=1,this._modeTransitionEditorCamera=null,this._modeTransition=new Tg({frame:t=>this._applyModeTransitionFrame(t),settled:t=>this._settleModeTransition(t)}),this._editorSecondary=new W_({root:()=>this.renderRoot,requestUpdate:()=>this.requestUpdate(),updateComplete:()=>this.updateComplete,clearTip:()=>{this._tip=null}}),this._editorSecondaryCopy={groupActive:(t,e)=>this._t("editor.group_active",{group:t,item:e}),openGroup:t=>this._t("editor.open_group",{group:t}),disabledAction:(t,e)=>this._t("editor.disabled_action",{action:t,reason:e})},this._tool="draw",this._geometryHistory=new fg(50),this._wallDialog=null,this._drawWallField=null,this._activeDraftId=null,this._resumeDraftBySpace={},this._physicalSel=null,this._physicalDialog=null,this._partitionDeleteDialog=null,this._roomDeleteDialog=null,this._physicalDrag=null,this._physicalRotate=null,this._physicalLastTap=null,this._physicalPickCycle=null,this._wallUnionCacheValue=null,this._wallUnionPool=new Map,this._isoGeometryCache=new Map,this._isoFallback=new Set,this._openingTunnelCache=null,this._openingWallIndexCache=new Map,this._openingPlacementIntervalsCache=null,this._openingDimensionContextCache=null,this._planSnapGeometryCache=null,this._planStructuralGeometryCache=null,this._hiddenWallDiagnosticCache=null,this._physicalBodiesCache=null,this._lightPhysicalBodiesCache=null,this._cleanFloorCache=new Map,this._innerContourCache=new Map,this._glowClipCache=new Map,this._glowGeometryWarnings=new Set,this._lightBarrierCache=null,this._lightBarrierPool=new Map,this._glowFeatherUnits=null,this._glowRenderedSources=new Map,this._glowLastAppearance=new Map,this._glowEnteringSources=new Set,this._glowEnterRafs=new Map,this._glowFadeTimers=new Map,this._glowFeatherSuspendUntil=0,this._glowFeatherResumeTimer=0,this._glowSourceSeq=0,this._glowScreenBlend=!1,this._duplicateColumnId=null,this._duplicateColumnTimer=0,this._rszSel=null,this._rszDrag=null,this._rszEligibilityCache=null,this._rszPreview=null,this._rszLive=null,this._path=[],this._cursorPt=null,this._planSnapHover=null,this._mergeSel=null,this._openingPreset=null,this._openingRebindId=null,this._openingPresetRevision=0,this._openingHoverCandidate=null,this._openingJambBlockCm=null,this._openingDialog=null,this._openingInfo=null,this._opDrag=null,this._opMeasure=null,this._mergeDialog=null,this._splitSel=null,this._pendingSplit=null,this._wallFaceBatch=null,this._wallRepairDiagnostic=null,this._wallFaceGraphCache=[],this._areaSel="",this._nameSel="",this._roomDialog=!1,this._roomEditId=null,this._roomFill="",this._roomCustomFill=null,this._roomTempSrc="",this._roomHumSrc="",this._roomSrcOpen=null,this._roomSrcFilter="",this._roomNameScale=1,this._roomLabelScale=1,this._zoom=1,this._view=null,this._zoomBySpace={},this._viewModeSnap=null,this._pointers=new Map,this._panStart=null,this._panLock=null,this._pinchStart=null,this._suppressClick=!1,this._touchContacts=new Map,this._touchSequenceMultitouch=!1,this._touchClickBlockUntil=0,this._connectedPath="",this._routeDepartureHandled=!1,this._onLocationChanged=()=>{this._connectedPath&&location.pathname!==this._connectedPath?this._leaveCardRoute():location.pathname===this._connectedPath&&(this._routeDepartureHandled=!1)},this._touchGestureGuard={capture:!0,handleEvent:t=>this._guardTouchGesture(t)},this._hdrH=118,this._booting=!0,this._bootFading=!1,this._bootSettling=!1,this._bootSettleRaf=0,this._bootLastH=-1,this._bootStart=0,this._bootLastChange=0,this._bootSoft=!1,this._tapConfirm=null,this._onboardingShown=!1,this._rulesDialog=null,this._preflightClipboardFallback=null,this._haIntegrationVersion=null,this._alignDialog=null,this._settingsDialog=null,this._backupExportDialog=null,this._backupImportDialog=null,this._sunRaysCache=null,this._dayCycleTimer=0,this._dayCycleClockKey="",this._compassDrag=!1,this._importDialog=null,this._importQueue=[],this._importTotal=0,this._rulesCompiledSrc="",this._infoCard=null,this._nativeMoreInfoEntity=null,this._markerDialog=null,this._spaceDialog=null,this._keyHandler=t=>this._onKey(t),this._warmVp=null,this._warmVpArmed=!1,this._warmLongReturn=!1,this._warmRevivePending=!1,this._warmGen=++Vf,this._warmKey=null,this._warmSlot=null,this._hashApplied=!1,this._navApplied=!1,this._labs={active:Object.freeze([]),space:""},this._viewPreference={},this._renderProjection="flat",this._kioskScale={icon:1,font:1},this._kioskDialog=!1,this._activityRt=new Map,this._vacRt=new Map,this._vacViewKey="",this._vacLastView=null,this._vacRaf=0,this._vacSrvTrails={},this._vacJumpOnce=!1,this._continuity=this._newContinuityController(),this._continuityHistory=[],this._continuityEpoch=0,this._continuityDataReady=!0,this._continuityPaintToken=-1,this._continuityDisposed=!1,this._renderSnapshotAt=Date.now(),this._hassSequence=0,this._visibleDeviceSnapshot=null,this._candidateDeviceSnapshot=null,this._stagedDeviceSnapshotToken=-1,this._capturedSnapshotSequence=-1,this._capturedSnapshotDevices=null,this._capturedSnapshotLayout=null,this._capturedSnapshotActivity="",this._capturedSnapshotConfigEpoch=-1,this._capturedSnapshotVirtual="",this._lastValidStageSize=null,this._pendingRefitSize=null,this._refitRaf=0,this._pageVisibility=t=>{if(this._continuity.visibility(t),this._dayCycleVisibility(t),"hidden"===t.kind)return this._clearTransientHover(!0),this._cancelDevicePressFeedback(),void(this._modeTransitionPreparing?this._modeTransitionForceAtomic=!0:this._cancelModeTransition(!0));if(this._vacJumpOnce=!0,!t.long){const t=Date.now();let e=!1;for(const i of this._activityRt.values())!i.flashKind||(i.expiresAt||i.flashTs+I_)>t||(i.flashTs=0,i.flashKind=null,i.expiresAt=0,e=!0);return void(e&&this.requestUpdate())}Date.now()-this._renderSnapshotAt>1e3&&this._continuity.note("device-snapshot-stale"),this._continuityDataReady=!1,this._continuityPaintToken=-1,this._resumeSettling=!0,this._loading?this.requestUpdate():this._loadFromServer()},this._resumeSettling=!1,this._viewportInvalidAt=0,this._vacFit=null,this._vacAllCamerasFor=null,this._vacAllCameraCache=null,this._vacCalConfirm=null,this._kioskDots=!1,this._cyclePausedUntil=0,this._swipeStart=null,this._tabDrag=null,this._tabDragRelease=null,this._tabSuppressClick=!1,this._tabOrderWarned=!1,this._lastTap=0,this._onLabsSnapshot=t=>{const e=this._effectiveProjection();this._labs=t;const i=this._effectiveProjection();this._convertProjectionView(e,i),this.requestUpdate()},this._onHashChange=()=>{if(this._hasFixedFloor)return;const t=this._hashSpace();if(t&&this._model.find(e=>e.id===t)&&t!==this._space){if(this._wallFaceBatch&&this._roomDialogCancel(),"plan"===this._mode&&"draw"===this._tool&&!this._finishWallChain())return;this._activeDraftId&&(this._resumeDraftBySpace[this._space]=this._activeDraftId),this._commitSpace(t),this._selId=null,this._path=[],this._clearPlanSnapHover(),this._clearOpeningPlacement(!0),this._tool="draw",this._activeDraftId=null,this._draftSegmentCms=[],this._closingWallCm=null,"plan"===this._mode&&"draw"===this._tool&&this._resumeLastDraft(),this._restoreZoom(),this.requestUpdate()}},this._drag=null,this._rlResize=null,this._holdFired=!1,this._retryContinuity=()=>{this._continuityDataReady=!1,this._continuityPaintToken=-1,this._continuity.retry(this._continuity.recoveryReason||"plan"),this._loading||this._loadFromServer()},this._cfgEpoch=0,this._modelCache=null,this._emptySpaceStateActive=!1,this._decorSnapCache=null,this._markerPreviewMemo=null,this._markerPreviewDevicesMemo=null,this._showHidden=!1,this._connHooked=null,this._connectionWasLost=!1,this._haRegistryConnection=null,this._haRegistryRev=-1,this._haBindingCacheKey="",this._planHassMemo=null,this._onHaRegistryUpdate=()=>{const t=An(this.hass);t.revision===this._haRegistryRev&&this._devices.length||(this._haRegistryRev=t.revision,this._planHassMemo=null,this._regSignature="",this._maybeRebuildDevices(),this.requestUpdate())},this._onConnReady=()=>{if(this._loadTries=0,clearTimeout(this._loadRetryTimer),this._loadRetryTimer=void 0,function(t){const e=Cn(t);e&&(Tn(t,e),Rn(t,e))}(this.hass),this._saveConfigDebounced.pending()&&this._saveConfigDebounced.flush(),this._cfgWriting)return clearTimeout(this._reloadRetry),void(this._reloadRetry=window.setTimeout(this._onConnReady,400));!this._connectionWasLost&&this._continuity.hasCompleteFrame?this._beginContinuityCandidate("connection-ready",!1,"plan"):(this._continuityDataReady=!1,this._continuityPaintToken=-1),this._loading||this._loadFromServer()},this._onConnLost=()=>{this._booting&&!this._continuity.hasCompleteFrame||(this._connectionWasLost=!0,this._continuityDataReady=!1,this._continuityPaintToken=-1,this._continuity.connectionLost())},this._signer=new $d(()=>this.requestUpdate()),this._dirtyPos=new Set,this._sentPos=new Map,this._persistLayout=hv(()=>{if(this._serverStorage){const t=[...this._dirtyPos];this._dirtyPos.clear();for(const e of t){const t=ol(this._layout[e]);t&&(this._layout={...this._layout,[e]:t},this._sentPos.set(e,t),this.hass.callWS({type:"houseplan/layout/update",device_id:e,pos:t}).then(t=>this._noteLayoutRev(t)).catch(t=>this._showToast(this._t("toast.pos_save_failed",{err:this._errText(t)}))).finally(()=>{this._sentPos.get(e)===t&&this._sentPos.delete(e)}))}this._cacheSnapshot()}else this._layout=al(Gr(this._layout)),localStorage.setItem(Jf,JSON.stringify(this._layout))},600),this._frame=null,this._showFar=!1,this._writesPending=0,this._writeChain=Promise.resolve(),this._pendingPhysicalWrites=new Map,this._undoGeometry=()=>{if(this._physicalDrag||this._physicalRotate)return void this._cancelPhysicalGesture();if(this._decorDraft)return this._decorDraft=null,void this.requestUpdate();if(this._decorMove||this._dtDrag||this._bdDrag)return void this._cancelDecorGesture();if(this._rszDrag)return void this._rszCancelDrag();const t=this._geometryHistory.undo();t&&(this._applyGeometryState(t.before,!0)?this._showToast(this._t("history.undone",{name:t.name})):this._geometryHistory.clear())},this._redoGeometry=()=>{if(this._physicalDrag||this._physicalRotate)return void this._cancelPhysicalGesture();if(this._decorDraft)return this._decorDraft=null,void this.requestUpdate();if(this._decorMove||this._dtDrag||this._bdDrag)return void this._cancelDecorGesture();if(this._rszDrag)return void this._rszCancelDrag();const t=this._geometryHistory.redo();t&&(this._applyGeometryState(t.after,!0)?this._showToast(this._t("history.redone",{name:t.name})):this._geometryHistory.clear())},this._saveConfigDebounced=hv(()=>{this._serverCfg&&this._writeConfig().catch(t=>{const e=!0===t?.physicalGeometryRolledBack;"geometry-unsafe"!==t?.code&&("wall_model_client_outdated"===t?.code?this._showToast(this._t("toast.wall_model_client_outdated")):"conflict"===t?.code?(this._showToast(this._t("toast.conflict")),e||(this._cancelPath(),this._reloadConfigOnly(!0))):this._showToast(this._t("toast.cfg_save_failed",{err:this._errText(t)})),e&&this._reloadRejectedPhysicalWrite())})},500),this._draftSegmentCms=[],this._closingWallCm=null,this._savePhysicalDialog=()=>{const t=this._physicalDialog,e=this._curSpaceCfg,i=this._spaceModel();if(!t||!e||!i)return;const s=Wf(t.cm);if(null==s)return void this._showPhysicalRange("column"===t.kind?jc:100,"column"===t.kind?1:0);const n=this._imperial?2.54*s:s,o="column"===t.kind?jc:100,a="column"===t.kind?1:0;if(!Number.isFinite(n)||no)return void this._showPhysicalRange(o,a);if("column"===t.kind){const e=i.wall_columns.find(e=>e.id===t.id);if(!e)return;const s=Wf(t.angle||"0");if("circle"!==t.shape&&(null==s||s<0||s>=90))return void this._showToast(this._t("toast.physical_angle"));const o="circle"===t.shape?{id:t.id,shape:"circle",center:e.center,cm:n}:{id:t.id,shape:"square",center:e.center,cm:n,angle:s};if(i.wall_columns.some(e=>e.id!==t.id&&uh(e,o,.02*this._gridPitch)))return void this._showToast(this._t("toast.column_duplicate"))}const r=this._geometrySnapshot();if("partition"===t.kind){const i=(e.partitions||[]).find(e=>e.id===t.id);if(i&&0===n&&f_(e.openings,{kind:"partition",id:t.id}))return void this._showToast(this._t("toast.zero_wall_opening_conflict"));i&&(i.cm=n)}else if("column"===t.kind){const i=(e.wall_columns||[]).find(e=>e.id===t.id);i&&(i.cm=Gc(n),i.shape="circle"===t.shape?"circle":"square","square"===i.shape?i.angle=Wf(t.angle||"0"):delete i.angle)}else{const i=(e.room_drafts||[]).find(e=>e.id===t.id);i?.segments?.[t.segment||0]&&(i.segments[t.segment||0].cm=n)}const l=this._commitPhysicalGeometry(this._t("history.physical_edit"),r);this._physicalDialog=null,l||this.requestUpdate()},this._deletePhysicalSelection=()=>{const t=this._physicalSel,e=this._curSpaceCfg;if(!t||!e)return;if("draft"===t.kind)return void this._deleteDraftWhole();const i=this._geometrySnapshot();if("partition"===t.kind){const i=(e.openings||[]).filter(e=>"partition"===e.host?.kind&&e.host.id===t.id).sort((t,e)=>(t.host?.t||0)-(e.host?.t||0));if(i.length)return void(this._partitionDeleteDialog={id:t.id,openings:i.map(t=>JSON.parse(JSON.stringify(t)))})}const s="partition"===t.kind?"partitions":"column"===t.kind?"wall_columns":"room_drafts";e[s]=(e[s]||[]).filter(e=>e.id!==t.id),e[s].length||delete e[s],this._activeDraftId===t.id&&this._cancelPath(),this._physicalSel=null,this._physicalDialog=null,this._commitPhysicalGeometry(this._t("history.physical_delete"),i)},this._confirmPartitionDelete=()=>{const t=this._partitionDeleteDialog,e=this._curSpaceCfg;if(!t||!e)return;const i=this._geometrySnapshot();e.partitions=(e.partitions||[]).filter(e=>e.id!==t.id),e.partitions.length||delete e.partitions,e.openings=(e.openings||[]).filter(e=>"partition"!==e.host?.kind||e.host.id!==t.id),e.openings.length||delete e.openings,this._partitionDeleteDialog=null,this._physicalSel=null,this._physicalDialog=null,this._commitPhysicalGeometry(this._t("history.physical_delete"),i)},this._deleteDraftWhole=()=>{const t="draft"===this._physicalDialog?.kind?this._physicalDialog.id:"draft"===this._physicalSel?.kind?this._physicalSel.id:null,e=this._curSpaceCfg;if(!t||!e||!confirm(this._t("confirm.delete_draft")))return;const i=this._geometrySnapshot();e.room_drafts=(e.room_drafts||[]).filter(e=>e.id!==t),e.room_drafts.length||delete e.room_drafts,this._activeDraftId===t&&this._cancelPath(),this._physicalSel=null,this._physicalDialog=null,this._commitPhysicalGeometry(this._t("history.physical_delete"),i)},this._deleteDraftSegment=()=>{const t=this._physicalDialog,e=this._curSpaceCfg;if(!t||"draft"!==t.kind||!e)return;if(!confirm(this._t("confirm.delete_draft_segment")))return;const i=(e.room_drafts||[]).findIndex(e=>e.id===t.id);if(i<0)return;const s=e.room_drafts[i],n=Math.max(0,Math.min(s.segments.length-1,t.segment||0)),o=[],a=s.points.slice(0,n+1),r=s.points.slice(n+1);if(a.length>=2&&o.push({id:s.id,points:a,segments:s.segments.slice(0,n)}),r.length>=2&&o.push({id:o.length?`${s.id}-${Date.now().toString(36)}`:s.id,points:r,segments:s.segments.slice(n+1)}),2===o.length&&e.room_drafts.length>=200)return void this._showToast(this._t("toast.physical_limit"));const l=this._geometrySnapshot();e.room_drafts.splice(i,1,...o),e.room_drafts.length||delete e.room_drafts,this._activeDraftId===s.id&&this._cancelPath(),this._physicalDialog=null,this._physicalSel=o.length?{kind:"draft",id:o[0].id}:null,this._commitPhysicalGeometry(this._t("history.draft_segment_delete"),l)},this._confirmRoomDelete=t=>{const e=this._roomDeleteDialog,i=this._curSpaceCfg,s=this._spaceModel();if(!e||!i||!s)return;const n=s.rooms.find(t=>t.id===e.roomId);if(!n)return void(this._roomDeleteDialog=null);const o=this._openCuts(),a=$u(dc(s.rooms,this._spaceWalls,o,this._wallKeyPitch,this._cellCm,this._gridPitch,sv).filter(t=>t.roomId===n.id),s.partitions,this._openingsR.map(t=>({...t,x:t.rx,y:t.ry})),.02*this._gridPitch),r=new Set(a.materialize.filter(t=>!t.reusePartitionId).map(t=>t.interval.key)).size;if(t&&(i.partitions||[]).length+r>rv)return void this._showToast(this._t("toast.physical_limit"));const l=this._geometrySnapshot(),c=pc(s.rooms,this._spaceWalls,o,this._wallKeyPitch,this._cellCm,this._gridPitch,sv);if(t){i.partitions||=[];const t=new Map,e=new Map,s=t=>{const e=(i.wall_segments||[]).find(e=>{const i=[Number(e.a?.[0])*sv,Number(e.a?.[1])*sv],s=[Number(e.b?.[0])*sv,Number(e.b?.[1])*sv];return this._samePt(t.a,i)&&this._samePt(t.b,s)||this._samePt(t.a,s)&&this._samePt(t.b,i)});return"string"==typeof e?.id&&e.id?e.id:null},n=Date.now().toString(36);for(const o of a.materialize){let a=o.reusePartitionId?i.partitions.find(t=>t.id===o.reusePartitionId):e.get(o.interval.key);a||(a={id:s(o.interval)||`partition-room-${n}-${e.size}`,a:[o.interval.a[0]/sv,o.interval.a[1]/sv],b:[o.interval.b[0]/sv,o.interval.b[1]/sv],cm:o.interval.cm},i.partitions.push(a),e.set(o.interval.key,a)),t.set(o.interval.key,a)}for(const e of i.openings||[]){const i=a.openingIntervals.get(e.id),s=i?t.get(i):null,n=this._openingsR.find(t=>t.id===e.id);if(!s||!n)continue;const o={a:[s.a[0]*sv,s.a[1]*sv],b:[s.b[0]*sv,s.b[1]*sv]};e.host={kind:"partition",id:s.id,t:Su([n.rx,n.ry],o)}}}else if(a.removeOpeningIds.length){const t=new Set(a.removeOpeningIds);i.openings=(i.openings||[]).filter(e=>!t.has(e.id)),i.openings.length||delete i.openings}i.rooms=i.rooms.filter(t=>t.id!==n.id),this._cfgEpoch++;const h=this._normalizeWalls(c,this._openCuts());h.length?i.walls=h:delete i.walls,this._roomDeleteDialog=null,this._commitPhysicalGeometry(this._t(t?"history.delete_room_keep_walls":"history.delete_room_with_walls"),l),this._regSignature="",this._maybeRebuildDevices(),this.requestUpdate()},this._rebindPartitionOpening=()=>{const t=this._openingDialog;if(!t?.id)return;const e=t.id;this._activateMarkupTool("opening"),"opening"===this._tool&&(this._openingRebindId=e,this._openingPreset={type:t.type,lengthCm:t.lengthCm,flipH:t.flipH,flipV:t.flipV,revision:++this._openingPresetRevision},this._openingDialog=null,this._openingHoverCandidate=null)},this._keepClosedAsPartitions=()=>{if(this._wallFaceBatch)return void this._decideWallFace(!1);if(!this._contourClosed||this._pendingSplit||!this._curSpaceCfg)return;const t=this._curSpaceCfg,e=this._path.slice(0,-1);if((t.partitions||[]).length+e.length>rv)return void this._showToast(this._t("toast.physical_limit"));const i=this._geometrySnapshot(),s=Xp(e.length,[...this._draftSegmentCms,this._closingWallCm??void 0],this._drawWallCm,ll);t.partitions||=[];const n=Date.now().toString(36),o=this._activeDraftId?(t.room_drafts||[]).find(t=>t.id===this._activeDraftId):null,a=this._draftSegmentsForPath(this._path,o,s);for(let i=0;it.id!==this._activeDraftId),t.room_drafts.length||delete t.room_drafts),this._commitPhysicalGeometry(this._t("history.contour_to_partitions"),i),this._roomDialog=!1,this._path=[],delete this._resumeDraftBySpace[this._space],this._activeDraftId=null,this._draftSegmentCms=[],this._closingWallCm=null},this._toggleServerPlans=async()=>{const t=this._spaceDialog;if(t)if(t.pickSaved)this._spaceDialog={...t,pickSaved:!1};else{this._spaceDialog={...t,pickSaved:!0,savedBusy:!0};try{const t=await this.hass.callWS({type:"houseplan/plans/list"}),e=this._spaceDialog;e&&(this._spaceDialog={...e,saved:t?.plans||[],savedBusy:!1})}catch(t){const e=this._spaceDialog;e&&(this._spaceDialog={...e,saved:[],savedBusy:!1}),this._showToast(this._t("toast.plans_list_failed",{err:this._errText(t)}))}}},this._aspectJob=null,this._dayCycleTick=()=>{if(!this.isConnected||"hidden"===this.ownerDocument.visibilityState)return;const t=this._dayCycleState();if(!t)return this._dayCycleTimer&&(clearInterval(this._dayCycleTimer),this._dayCycleTimer=0),void(this._dayCycleClockKey="");const e=mr(t);e!==this._dayCycleClockKey&&(this._dayCycleClockKey=e,this.requestUpdate())},this._sunShown=!1,this._sunOut=!1,this._sunOutTimer=0,this._openSettingsDialog=()=>{if(!this._norm)return;const t=this._glowRadiusCm,e=this._imperial?Math.round(t/30.48*10)/10:Math.round(t)/100;this._settingsDialog={colors:JSON.parse(JSON.stringify(this._fillColors)),glowRadius:e,bgColor:hs(this._settings,{bgColor:null})||null,northDeg:$r(this._settings,{}),bgMode:Sr(this._settings,{}),sunRays:Mr(this._settings,{}),busy:!1}},this._reportedPreflightFingerprint=null,this._openAlignDialog=()=>this._previewAlignDialog(!1),this._toggleOptimizeLivePositions=()=>{const t=this._alignDialog;t&&!t.busy&&t.report.liveMissingPositions.length&&this._previewAlignDialog(!t.removeLiveMissingPositions)},this._optimizeUndoBusy=!1,this._openBackupExport=()=>{this._settingsDialog=null,this._backupExportDialog={kind:"full",planOnly:!1,busy:!1,error:""}},this._openRulesDialog=()=>{if(!this._norm)return;const t=this._settings.icon_rules,e=(t&&t.length?t:Jt).map(t=>({...t}));this._rulesDialog={rules:e,test:"",busy:!1}},this._climateCache=null,this._gearPtCache=new WeakMap}get _canEdit(){return!!this._norm&&(!0===this._serverCanWrite||!1!==this._serverCanWrite&&!0===this.hass?.user?.is_admin)}get _kiosk(){return!!this._config?.kiosk}_showKioskDots(){this._kioskDots=!0,clearTimeout(this._kioskDotsTimer),this._kioskDotsTimer=window.setTimeout(()=>this._kioskDots=!1,2500)}get _modeTransitionBusy(){return this._modeTransitionPreparing||this._modeTransition.active}_cssColor(t,e){const i=String(t||"").trim();if(!i)return e;const s=document.createElement("span");s.style.cssText=`position:absolute;visibility:hidden;color:${i}`,this.renderRoot.append(s);const n=getComputedStyle(s).color||e;return s.remove(),n}_currentModeVisual(t=this._mode){const e=this._modeTransition.presented||this._modeTransitionVisual;if(e)return{...e,viewport:{...e.viewport,viewBox:{...e.viewport.viewBox}}};const i=this._stageEl;if(!i||i.clientWidth<=0||i.clientHeight<=0)return null;const s=this.renderRoot.querySelector(".editorchrome"),n=this._viewOr(this._baseVb()),o=this.renderRoot.querySelector(".hp-paper"),a=this.renderRoot.querySelector(".hp-backdrop"),r=this.renderRoot.querySelector(".zoomwrap"),l=r?getComputedStyle(r).filter:"",c=Number(/brightness\(([^)]+)\)/.exec(l)?.[1]);return{presentedMode:t,editorChromeHeight:"view"===t?0:s?.getBoundingClientRect().height||0,stageWidth:i.clientWidth,stageHeight:i.clientHeight,viewport:Sg(n,i.clientWidth),stageColor:getComputedStyle(i).backgroundColor||"rgb(255, 255, 255)",paperColor:o?getComputedStyle(o).fill:"rgb(255, 255, 255)",sceneBrightness:Number.isFinite(c)?c:1,architectureOpacity:"decor"===t?.35:1,backdropOpacity:a&&Number(getComputedStyle(a).opacity)||1,viewWeight:"view"===t?1:0,editorWeight:"view"===t?0:1,toolbarContentOpacity:"view"===t?0:1}}_viewForModeTarget(t,e,i,s,n){const o=Ni(this._baseVb(),s/Math.max(1,n)),a=Math.min(pv.ZOOM_MAX,Math.max(pv.ZOOM_MIN,t)),r=o.w/a,l=o.h/a,c=e??o.x+o.w/2,h=i??o.y+o.h/2;return this._clampView({x:c-r/2,y:h-l/2,w:r,h:l},o)}_targetStageColor(t){return"view"!==t?"rgb(255, 255, 255)":this._cssColor(this._stageBg(this._spaceDisplayForRender()),this._cssColor("var(--ha-card-background, var(--card-background-color, #111))","rgb(17, 17, 17)"))}_targetPaperColor(t){return"view"===t&&this._spaceModel()?.bg?this._cssColor("var(--ha-card-background, var(--card-background-color, #111))","rgb(17, 17, 17)"):"rgb(255, 255, 255)"}_targetBrightness(t){return 1}_applyModeTransitionFrame(t){t.targetMode===this._mode&&(this._modeTransitionVisual=t.presented,this._view={...t.presented.viewport.viewBox},this.requestUpdate())}_settleModeTransition(t){if(t.targetMode!==this._mode)return;const e=this._modeTransitionRequest;this._view={...t.to.viewport.viewBox},this._zoom=this._modeTransitionTargetZoom,this._modeTransitionVisual=null,this._modeTransitionPreparing=!1,this._lastValidStageSize=[t.to.stageWidth,t.to.stageHeight],"view"===this._mode&&(this._saveZoom(),this._viewModeSnap=null,this._modeTransitionEditorCamera=null),this.requestUpdate(),this.updateComplete.then(()=>{if(!this.isConnected||e!==this._modeTransitionRequest||this._modeTransitionBusy||t.targetMode!==this._mode)return;const i=this._stageEl;if(i&&i.clientWidth>0&&i.clientHeight>0&&(Math.abs(i.clientWidth-t.to.stageWidth)>.5||Math.abs(i.clientHeight-t.to.stageHeight)>.5)){const t=this._view;this._lastValidStageSize=[i.clientWidth,i.clientHeight],this._applyView(this._zoom,t?t.x+t.w/2:void 0,t?t.y+t.h/2:void 0),this.requestUpdate()}const s=this.renderRoot.activeElement;(!s||!s.isConnected||!!s.closest?.(".editorchrome, .stage"))&&this.renderRoot.querySelector(".modetab.active")?.focus?.({preventScroll:!0})})}_cancelModeTransition(t=!0){const e=!!this._modeTransition.state;this._modeTransitionRequest++,this._modeTransitionPreparing=!1,this._modeTransitionForceAtomic=!1,this._modeTransition.cancel(t),t&&e||(this._modeTransitionVisual=null)}_adoptMode(t){this._cancelModeTransition(!1),this._mode=t,"view"!==t&&(this._editorChromeMode=t)}_commitViewModeAtomic(t,e,i,s){if(this._modeTransitionPreparing=!1,this._modeTransitionVisual=null,this._modeTransitionForceAtomic=!1,this._zoom=e,t){const n=this._stageEl?.clientWidth||t.stageWidth,o=Math.max(1,t.stageHeight+t.editorChromeHeight);this._view=this._viewForModeTarget(e,i,s,n,o),this._lastValidStageSize=[n,o]}else this._view=null;this._viewModeSnap=null,this._modeTransitionEditorCamera=null,this._saveZoom(),this.requestUpdate()}_prepareModeTransition(t,e,i,s,n,o){this.updateComplete.then(()=>{if(!this.isConnected||t!==this._modeTransitionRequest||this._mode!==i)return void(t===this._modeTransitionRequest&&(this._modeTransitionPreparing=!1,this._modeTransitionVisual=null,this._modeTransitionForceAtomic=!1,this.requestUpdate()));const a=this.renderRoot.querySelector(".editorchrome"),r=a?.querySelector(".editorchrome-inner"),l="view"===i?0:r?.scrollHeight||r?.getBoundingClientRect().height||0,c=Math.max(1,e.stageHeight+e.editorChromeHeight),h=Math.max(1,c-l),d=this._stageEl?.clientWidth||e.stageWidth;if(d<=0||h<=0)return this._modeTransitionPreparing=!1,this._modeTransitionVisual=null,this._applyView(s,n,o),void this.requestUpdate();const p=this._viewForModeTarget(s,n,o,d,h),u={presentedMode:i,editorChromeHeight:l,stageWidth:d,stageHeight:h,viewport:Sg(p,d),stageColor:this._targetStageColor(i),paperColor:this._targetPaperColor(i),sceneBrightness:this._targetBrightness(i),architectureOpacity:"decor"===i?.35:1,backdropOpacity:"decor"===i&&"backdrop"!==this._decorTool?.5:1,viewWeight:"view"===i?1:0,editorWeight:"view"===i?0:1,toolbarContentOpacity:"view"===i?0:1};this._modeTransitionPreparing=!1;const _=this._modeTransitionForceAtomic;this._modeTransitionForceAtomic=!1,this._modeTransition.start(e,u,i,this._reducedMotion||_?0:220)})}get _hasFixedFloor(){return!!this._config&&Object.prototype.hasOwnProperty.call(this._config,"floor")}_fixedFloorState(t=this._model,e=this._loadOk){const i=this._config?.floor,s=function(t){if(!t.hasFloor)return{kind:"absent"};const e=t.floor;if("string"==typeof e)return e.length?t.spaceIds.includes(e)?{kind:"valid",id:e,source:"id"}:{kind:"invalid",reason:"unknown-id",value:e}:{kind:"invalid",reason:"empty-id",value:e};if("number"==typeof e){if(!Number.isFinite(e))return{kind:"invalid",reason:"non-finite-index",value:e};if(!Number.isInteger(e))return{kind:"invalid",reason:"fractional-index",value:e};if(e<0)return{kind:"invalid",reason:"negative-index",value:e};const i=t.spaceIds[e];return void 0===i?{kind:"invalid",reason:"out-of-range-index",value:e}:{kind:"valid",id:i,source:"index"}}return{kind:"invalid",reason:"invalid-type",value:e}}({spaceIds:t.map(t=>t.id),hasFloor:this._hasFixedFloor,floor:i});return!this._hasFixedFloor||e?s:"number"==typeof i?"valid"===s.kind||"invalid"===s.kind&&"out-of-range-index"===s.reason?{kind:"pending",value:i}:s:"valid"===s.kind||"invalid"===s.kind&&"unknown-id"!==s.reason?s:{kind:"pending",value:i}}_canCommitSpace(t,e=!1){if(e||!this._hasFixedFloor)return!0;const i=this._fixedFloorState();return"valid"===i.kind&&i.id===t}_commitSpace(t,e=!1){return!!this._canCommitSpace(t,e)&&(t!==this._space&&(this._clearTransientHover(!0),this._cancelDevicePressFeedback()),this._space=t,!0)}_slideTo(t,e){if(t===this._space)return!0;if(!this._canCommitSpace(t))return!1;if(this._wallFaceBatch&&this._roomDialogCancel(),"plan"===this._mode&&"draw"===this._tool&&!this._finishWallChain())return!1;this._cancelModeTransition(!0);const i=window.matchMedia?.("(prefers-reduced-motion: reduce)")?.matches;return this._activeDraftId&&(this._resumeDraftBySpace[this._space]=this._activeDraftId),this._commitSpace(t),this._path=[],this._clearPlanSnapHover(),this._clearOpeningPlacement(!0),this._tool="draw",this._activeDraftId=null,this._draftSegmentCms=[],this._closingWallCm=null,this._selId=null,this._physicalSel=null,this._editorSecondary.closeForNavigation(),this._physicalDialog=null,this._physicalDrag=null,"plan"===this._mode&&"draw"===this._tool&&this._resumeLastDraft(),this._restoreZoom(),i||(this._slide=e,clearTimeout(this._slideTimer),this._slideTimer=window.setTimeout(()=>{this._slideTimer=void 0,this._slide="",this.requestUpdate()},190),this.requestUpdate()),!0}get _canReorderTabs(){return Ef({canEdit:this._canEdit,kiosk:this._kiosk,mode:this._mode,pointerType:"mouse",spaceCount:this._model.length,fixedFloor:this._hasFixedFloor})}_tabPointerDown(t,e){Ef({canEdit:this._canEdit,kiosk:this._kiosk,mode:this._mode,pointerType:t.pointerType,spaceCount:this._model.length,fixedFloor:this._hasFixedFloor})&&(dv(t),this._tabDragRelease=t=>this._tabPointerUp(t),window.addEventListener("pointerup",this._tabDragRelease),window.addEventListener("pointercancel",this._tabDragRelease),this._tabDrag={id:e,pointerId:t.pointerId,x:t.clientX,y:t.clientY,moved:!1,targetId:null,placement:null})}_tabDropTargetAt(t,e,i){const s=this._model.map(t=>t.id),n=s.indexOf(i);if(n<0)return null;const o=this.renderRoot.querySelectorAll('[data-hp="space-tab"]');for(const a of o){const o=a.dataset.id||"";if(!o||o===i)continue;const r=a.getBoundingClientRect();if(tr.right||er.bottom)continue;const l=s.indexOf(o);return l<0?null:{targetId:o,placement:l=4)))return;var i,s;const n=this._tabDropTargetAt(t.clientX,t.clientY,e.id);e.moved&&e.targetId===n?.targetId&&e.placement===n?.placement||(this._tabDrag={...e,moved:!0,targetId:n?.targetId||null,placement:n?.placement||null})}_tabPointerUp(t){const e=this._tabDrag;if(e&&e.pointerId!==t.pointerId)return;const i="pointerup"===t.type&&e?.moved?this._tabDropTargetAt(t.clientX,t.clientY,e.id):null;"pointerup"===t.type&&e?.moved&&this._suppressNextTabClick(),this._endTabDrag(),e?.moved&&i&&this._commitTabOrder(e.id,i.targetId)}_endTabDrag(){this._tabDrag=null,this._tabDragRelease&&(window.removeEventListener("pointerup",this._tabDragRelease),window.removeEventListener("pointercancel",this._tabDragRelease),this._tabDragRelease=null)}_tabClick(t){if(this._tabSuppressClick)return this._tabSuppressClick=!1,clearTimeout(this._tabSuppressClickTimer),void(this._tabSuppressClickTimer=void 0);this._pickSpace(t)}_suppressNextTabClick(){this._tabSuppressClick=!0,clearTimeout(this._tabSuppressClickTimer),this._tabSuppressClickTimer=window.setTimeout(()=>{this._tabSuppressClick=!1,this._tabSuppressClickTimer=void 0},0)}_commitTabOrder(t,e){const i=this._serverCfg;if(!i||!this._canReorderTabs)return;const s=this._model.map(t=>t.id),n=function(t,e,i){const s=t.indexOf(e),n=t.indexOf(i);if(s<0||n<0||s===n)return t;const o=t.slice();return o.splice(s,1),o.splice(n,0,e),o}(s,t,e);if(n===s)return;const o=new Map(this._devices.map(t=>[String(t.id),String(t.area||"")])),a=function(t,e,i,s=()=>""){if(!i)return[];const n=[];for(const o of t){if(!o||!0===o.removed)continue;const t="string"==typeof o.id?o.id:"";if(!t)continue;if("string"==typeof o.space&&o.space)continue;const a=("string"==typeof o.area?o.area:"")||s(t)||"";a&&e[a]||n.push({id:t,space:i})}return n}(i.markers||[],Object.fromEntries(Object.entries(this._areaToSpace).map(([t,e])=>[t,e.space])),s[0]||"",t=>o.get(t)||"");if(a.length){const t=new Map(a.map(t=>[t.id,t.space]));for(const e of i.markers||[]){const i=t.get(String(e.id));i&&(e.space=i)}}i.spaces=function(t,e){const i=new Map(e.map((t,e)=>[t,e]));return t.map((t,e)=>({space:t,index:e})).sort((t,e)=>(i.get(String(t.space?.id))??Number.MAX_SAFE_INTEGER)-(i.get(String(e.space?.id))??Number.MAX_SAFE_INTEGER)||t.index-e.index).map(t=>t.space)}(i.spaces||[],n),this._saveConfig(),this._tabOrderWarned||(this._tabOrderWarned=!0,this._showToast(this._t("toast.space_order_changed")))}_pickSpace(t){if(this._endTabDrag(),t===this._space)return;const e=this._model.map(t=>t.id),i=e.indexOf(this._space),s=e.indexOf(t);this._navApplied=!0,this._showFar=!1,this._frame=null,this._slideTo(t,i>=0&&s0&&Date.now()>=this._cyclePausedUntil&&this._model.length>1&&this._zoom<=1.001){const t=this._model.map(t=>t.id),e=t.indexOf(this._space);this._slideTo(t[(e+1)%t.length],"left"),this._showKioskDots()}}_syncCycleTimer(){clearInterval(this._cycleTimer),this._cycleTimer=void 0,this.isConnected&&!this._hasFixedFloor&&this._config?.kiosk&&Number(this._config.cycle)>0&&(this._cycleTimer=window.setInterval(()=>this._cycleTick(),1e3*Number(this._config.cycle)))}get _editing(){return"plan"===this._mode||"devices"===this._mode||"decor"===this._mode}get _markup(){return"plan"===this._mode}get _wallUnionCache(){return this._wallUnionCacheValue}set _wallUnionCache(t){this._wallUnionCacheValue=t,null===t&&this._wallUnionPool.clear()}_newContinuityController(){return new bd(()=>{this._resumeSettling="steady"!==this._continuity.state,this._continuityEpoch++,this.isConnected&&this.requestUpdate()})}get _labsIso(){return this._labs.active.includes("iso")}get _desiredProjection(){return"view"===this._mode&&this._labsIso&&"iso"===this._viewPreference[this._space]?"iso":"flat"}_saveViewPreference(){try{localStorage.setItem(ev,JSON.stringify(this._viewPreference))}catch{}}_logicalViewCenter(t){const e=this._view;if(!e)return null;const i=[e.x+e.w/2,e.y+e.h/2],s="iso"===t?Zg(i):i;return{x:s[0],y:s[1]}}_convertProjectionView(t,e){if(t===e)return;const i=this._logicalViewCenter(t);this._view=null;const s=i?"iso"===e?Xg([i.x,i.y],0):[i.x,i.y]:null;this._applyView(this._zoom,s?.[0],s?.[1]),this._warmPatch({vp:this._warmViewportState()}),this.requestUpdate()}_setProjection(t){if(!this._labsIso||"view"!==this._mode)return;const e=this._effectiveProjection();if(this._viewPreference={...this._viewPreference,[this._space]:t},"iso"===t){const t=this._isoSceneKey();t&&this._isoFallback.delete(t)}this._saveViewPreference();const i=this._effectiveProjection();this._convertProjectionView(e,i)}_hashSpace(){return Og(window.location.hash||"")}connectedCallback(){this._connectedPath=location.pathname,this._routeDepartureHandled=!1,window.addEventListener("location-changed",this._onLocationChanged),window.addEventListener("popstate",this._onLocationChanged),this._continuityDisposed&&(this._continuity=this._newContinuityController(),this._continuityDisposed=!1,this._continuityPaintToken=-1);const t=(e=this.ownerDocument,vg.get(e)?.resolved);var e;void 0!==t&&(this._glowScreenBlend=t),this._continuityUnsub?.(),this._continuityUnsub=vd(this.ownerDocument,this._pageVisibility),super.connectedCallback(),this._pointerModality.connect(this.ownerDocument.defaultView);const i=this.ownerDocument.defaultView?.MutationObserver;i&&(this._pointerHoverObserver=new i(t=>{for(const e of t)for(const t of e.addedNodes)this._syncPointerHoverSubtree(t)}),this._pointerHoverObserver.observe(this.renderRoot,{childList:!0,subtree:!0})),this._motionMedia=window.matchMedia?.("(prefers-reduced-motion: reduce)"),this._reducedMotion=!!this._motionMedia?.matches,this._motionMedia?.addEventListener?.("change",this._onMotionChange),function(t){const e=vg.get(t);if(e)return e.promise;const i={promise:Promise.resolve(!1)};return i.promise=bg(t).catch(()=>!1).then(t=>(i.resolved=t,t)),vg.set(t,i),i.promise}(this.ownerDocument).then(t=>{t!==this._glowScreenBlend&&(this._glowScreenBlend=t,this.isConnected&&this.requestUpdate())}),this.hass&&this._ensureHaRegistryAuthority(),window.addEventListener("keydown",this._keyHandler),this._signer.start(()=>this.hass,()=>Is(this._serverCfg)),this._syncCycleTimer(),window.addEventListener("hashchange",this._onHashChange),this._labsUnsub?.(),this._labsUnsub=function(t,e){Ug.add(e);const i=Kg(t);return"undefined"==typeof window&&e(i),()=>{Ug.delete(e)}}(Nf,this._onLabsSnapshot),this._booting?this._bootWatch():this._bootFading&&(clearTimeout(this._bootTimer),this._bootTimer=window.setTimeout(()=>{this._bootFading=!1},220)),this._bootSoft&&(clearTimeout(this._bootSoftTimer),this._bootSoftTimer=window.setTimeout(()=>{this._bootSoft=!1},qf)),!this._loadOk&&this._serverCfg&&this.hass&&this._scheduleLoadRetry(),!this._warmSlot&&this._config&&this._warmAdopt(),this._loadOk&&this._ensureLiveSyncSubscriptions(),this._warmVp&&!this._warmRevivePending&&void 0===this._warmReviveTimer&&(this._warmRevivePending=!0,this._warmReviveTimer=window.setTimeout(()=>this._warmReviveDialog(),0)),this._warmLongReturn&&this._beginResumeSettle(),this._warmLongReturn=!1,this.requestUpdate()}disconnectedCallback(){this._connectedPath&&location.pathname!==this._connectedPath&&this._leaveCardRoute(),window.removeEventListener("location-changed",this._onLocationChanged),window.removeEventListener("popstate",this._onLocationChanged),this._continuityUnsub?.(),this._continuityUnsub=void 0,this._motionMedia?.removeEventListener?.("change",this._onMotionChange),this._motionMedia=void 0,this._vacRaf&&(cancelAnimationFrame(this._vacRaf),this._vacRaf=0),this._refitRaf&&(cancelAnimationFrame(this._refitRaf),this._refitRaf=0),this._dayCycleTimer&&(clearInterval(this._dayCycleTimer),this._dayCycleTimer=0),this._dayCycleClockKey="",this._bootSettleRaf&&(cancelAnimationFrame(this._bootSettleRaf),this._bootSettleRaf=0),this._bootSettling=!1;for(const t of this._activityRt.values())clearTimeout(t.timer);window.removeEventListener("keydown",this._keyHandler),this._endTabDrag(),clearTimeout(this._tabSuppressClickTimer),this._tabSuppressClickTimer=void 0,this._tabSuppressClick=!1,clearInterval(this._cycleTimer),clearTimeout(this._kioskDotsTimer),clearTimeout(this._kioskHoldTimer),clearTimeout(this._reloadRetry),clearTimeout(this._loadRetryTimer),this._loadRetryTimer=void 0,this._connHooked?.removeEventListener?.("ready",this._onConnReady),this._connHooked?.removeEventListener?.("disconnected",this._onConnLost),this._connHooked?.removeEventListener?.("reconnect-error",this._onConnLost),this._connHooked=null,this._haRegistryRelease?.(),this._haRegistryRelease=void 0,this._haRegistryConnection=null,this._signer.dispose(),clearTimeout(this._toastTimer),clearTimeout(this._slideTimer),this._modeTransition.dispose(),this._modeTransitionVisual=null,this._modeTransitionPreparing=!1,this._modeTransitionForceAtomic=!1,this._modeTransitionRequest++,this._slideTimer=void 0,this._slide="",clearTimeout(this._bootTimer),this._bootTimer=void 0,clearTimeout(this._bootSoftTimer),this._saveConfigDebounced.flush(),window.removeEventListener("hashchange",this._onHashChange),this._labsUnsub?.(),this._labsUnsub=void 0,clearTimeout(this._holdTimer),this._roViewport?.disconnect(),this._roViewport=void 0,this._roHdr?.disconnect(),this._roHdr=void 0,this._onWinResize&&(window.removeEventListener("resize",this._onWinResize),this._onWinResize=void 0),this._unsubCfg&&(this._unsubCfg(),this._unsubCfg=null),this._unsubLayout&&(this._unsubLayout(),this._unsubLayout=null),this._unsubVirtual&&(this._unsubVirtual(),this._unsubVirtual=null),this._unsubTrail&&(this._unsubTrail(),this._unsubTrail=void 0),this._liveSyncGeneration++,this._liveSyncAttempt=null,this._liveSyncConnection=null,clearTimeout(this._layoutSyncTimer),clearTimeout(this._duplicateColumnTimer);for(const t of this._glowFadeTimers.values())clearTimeout(t);for(const t of this._glowEnterRafs.values())cancelAnimationFrame(t);clearTimeout(this._glowFeatherResumeTimer),this._glowFeatherResumeTimer=0,this._glowFeatherSuspendUntil=0,this._glowFadeTimers.clear(),this._glowEnterRafs.clear(),this._glowEnteringSources.clear(),this._glowRenderedSources.clear(),this._glowLastAppearance.clear(),this._glowSourceSeq=0,this._warmSnapshot(),this._warmRevivePending=!1,clearTimeout(this._warmReviveTimer),this._warmReviveTimer=void 0,this._warmRelease(),this._clearPlanSnapHover(),this._clearOpeningPlacement(!0),this._touchContacts.clear(),this._touchSequenceMultitouch=!1,this._touchClickBlockUntil=0,this._clearTransientHover(!0),this._cancelDevicePressFeedback(),this._pointerHoverObserver?.disconnect(),this._pointerHoverObserver=void 0,this._pointerModality.disconnect(),this._editorSecondary.reset(),this._resumeSettling=!1,this._continuityHistory=[...this._continuityHistory,...this._continuity.trace].slice(-80),this._continuity.dispose(),this._continuityDisposed=!0,super.disconnectedCallback()}_onKey(t){if("Escape"===t.key&&this._vacFit)return this._vacFit=null,this._showToast(this._t("vac.cal_cancelled")),void t.stopPropagation();if("Escape"===t.key){if(this._tapConfirm)return void(this._tapConfirm=null);if(this._vacCalConfirm)return void(this._vacCalConfirm=null);if(this._decorEraseConfirm)return void(this._decorEraseConfirm=null);if(this._openingInfo)return void(this._openingInfo=null);if(this._infoCard)return void this._closeInfoCard();if(this._rulesDialog)return void(this._rulesDialog=null);if(this._alignDialog)return this._alignDialog=null,void(this._preflightClipboardFallback=null);if(this._backupImportDialog)return void(this._backupImportDialog=null);if(this._backupExportDialog)return void(this._backupExportDialog=null);if(this._settingsDialog)return void(this._settingsDialog=null);if(this._markerDialog)return void(this._markerDialog=null);if(this._openingDialog)return void(this._openingDialog=null);if(this._physicalDialog)return void(this._physicalDialog=null);if(this._backdropDialog)return void(this._backdropDialog=null);if(this._decorShapeDialog)return void(this._decorShapeDialog=null);if(this._decorTextDialog)return void(this._decorTextDialog=null);if(this._spaceDialog&&!this._roomDialog)return this._spaceDialog=null,this._importQueue=[],void(this._importTotal=0);if(this._editorSecondary.hasOpenGroup)return t.preventDefault(),void this._editorSecondary.closeGroup(!0)}const e=t.composedPath?.()||[t.target],i=e.some(t=>t?.matches?.('input, textarea, select, [contenteditable="true"]')),s=e.some(t=>t?.classList?.contains?.("editor-secondary")),n=t.ctrlKey||t.metaKey,o=t.key.toLowerCase(),a=/^[a-z]$/.test(o),r="z"===o||!a&&"KeyZ"===t.code,l="y"===o||!a&&"KeyY"===t.code,c=n&&(r&&t.shiftKey||l),h=n&&r&&!t.shiftKey;if("decor"===this._mode){if((h||c)&&i)return;return c?(t.preventDefault(),void this._redoGeometry()):h?(t.preventDefault(),this._decorDraft?void(this._decorDraft=null):this._decorMove||this._dtDrag||this._bdDrag?void this._cancelDecorGesture():void this._undoGeometry()):"Delete"!==t.key&&"Backspace"!==t.key||!this._decorSel||i||s?void("Escape"===t.key&&(t.preventDefault(),this._decorDraft?this._decorDraft=null:this._decorMove||this._dtDrag||this._bdDrag?this._cancelDecorGesture():"furniture"===this._decorTool?(this._furnPalette=null,this._decorTool="select"):this._decorSel?this._decorSel=null:"select"!==this._decorTool?this._decorTool="select":this._setMode("view"))):(t.preventDefault(),void this._decorDeleteSel())}if(this._markup&&(!h&&!c||!i)){if(("Delete"===t.key||"Backspace"===t.key)&&this._physicalSel&&!i&&!s)return t.preventDefault(),void this._deletePhysicalSelection();if(c)return t.preventDefault(),void this._redoGeometry();if(h)return t.preventDefault(),this._rszDrag?void this._rszCancelDrag():this._wallFaceBatch?(this._roomDialogCancel(),void(this._activeDraftId&&this._path.length>1?this._undoActiveDraftPoint():this._undoPoint())):"draw"===this._tool&&this._path.length?void(this._activeDraftId&&this._path.length>1?this._undoActiveDraftPoint():this._undoPoint()):"split"===this._tool&&this._splitSel?.pts?.length?(this._splitSel={...this._splitSel,pts:this._splitSel.pts.slice(0,-1)},void(this._splitSel.pts.length||(this._cursorPt=null))):void this._undoGeometry();if("Escape"===t.key)return this._physicalDrag||this._physicalRotate?(t.preventDefault(),void this._cancelPhysicalGesture()):this._roomDialog?(t.preventDefault(),void this._roomDialogCancel()):"draw"===this._tool&&this._path.length?(t.preventDefault(),void this._finishWallChain()):this._physicalSel?(t.preventDefault(),void(this._physicalSel=null)):"resize"===this._tool?(t.preventDefault(),this._rszDrag?void this._rszCancelDrag():void(this._rszSel?this._rszSel=null:this._tool="draw")):"split"===this._tool?(t.preventDefault(),void(this._splitSel?.pts?.length?(this._splitSel={...this._splitSel,pts:this._splitSel.pts.slice(0,-1)},this._splitSel.pts.length||(this._cursorPt=null)):this._splitSel?this._splitSel=null:this._tool="draw")):"merge"===this._tool?(t.preventDefault(),void(this._mergeSel?this._mergeSel=null:this._tool="draw")):this._wallDialog?(t.preventDefault(),void(this._wallDialog=null)):void("opening"!==this._tool&&"wallthick"!==this._tool&&"delroom"!==this._tool&&"column"!==this._tool||(t.preventDefault(),"opening"===this._tool&&this._clearOpeningPlacement(!0),this._tool="draw"))}}_undoPoint(){if(this._path.length){if(this._contourClosed)return this._path=this._path.slice(0,-1),void(this._closingWallCm=null);if(this._activeDraftId&&this._path.length>1&&this._curSpaceCfg){const t=this._geometrySnapshot();this._path=this._path.slice(0,-1),this._draftSegmentCms=this._draftSegmentCms.slice(0,-1);const e=this._curSpaceCfg,i=(e.room_drafts||[]).findIndex(t=>t.id===this._activeDraftId);if(i>=0){const s=Array.isArray(e.room_drafts[i]?.segments)?e.room_drafts[i].segments:[];this._path.length<2?(e.room_drafts.splice(i,1),e.room_drafts.length||delete e.room_drafts,this._activeDraftId=null):e.room_drafts[i]={id:this._activeDraftId,points:this._path.map(t=>[t[0]/sv,t[1]/sv]),segments:this._draftSegmentCms.map((t,e)=>({...s[e]||{},cm:t}))},this._commitPhysicalGeometry(this._t("history.draft_segment_delete"),t)}return}this._path=this._path.slice(0,-1)}}_undoActiveDraftPoint(){const t=this._activeDraftId,e=this._path[0]?[...this._path[0]]:null,i=this._geometryHistory.undo();if(!i)return void this._undoPoint();if(!this._applyGeometryState(i.before,!0))return void this._geometryHistory.clear();const s=t?this._spaceModel()?.room_drafts.find(e=>e.id===t):null;s?(this._activeDraftId=s.id,this._path=s.points.map(t=>[...t]),this._draftSegmentCms=this._adoptDraftCms(this._path,s.segments.map(t=>t.cm),s.id),this._resumeDraftBySpace[this._space]=s.id):(this._activeDraftId=null,this._path=e?[e]:[],this._draftSegmentCms=[],t&&this._resumeDraftBySpace[this._space]===t&&delete this._resumeDraftBySpace[this._space]),this._clearPlanSnapHover(),this._showToast(this._t("history.undone",{name:i.name}))}static getConfigElement(){return document.createElement("houseplan-card-editor")}static getStubConfig(){return{type:"custom:houseplan-card"}}static _warmBootReset(t){for(const t of Gf.values())for(const e of t)clearTimeout(e.evict);Gf.clear(),Yf=t&&t>0?t:1e4}static _warmBootStats(){let t=0,e=0;const i=[];for(const s of Gf.values())for(const n of s)t++,n.dlg&&(e++,i.push(n.dlg.kind));return{keys:Gf.size,slots:t,dlgs:e,drafts:i}}setConfig(t){const e=this._config,i=!!e&&Object.prototype.hasOwnProperty.call(e,"floor");this._config={icon_size:2.5,show_temperature:!0,live_states:!0,show_signal:!0,...t};(i!==this._hasFixedFloor||e?.floor!==this._config.floor)&&(this._hashApplied=!1,this._navApplied=!1,this._warmVpArmed=!1),this._config.kiosk&&(this._booting=!1,this._bootFading=!1),!this._hasFixedFloor&&t.default_floor&&this._commitSpace(t.default_floor,!0);try{this._zoomBySpace=JSON.parse(localStorage.getItem(Zf)||"{}")||{}}catch{this._zoomBySpace={}}try{const t=JSON.parse(localStorage.getItem(ev)||"{}")||{};this._viewPreference=Object.fromEntries(Object.entries(t).filter(t=>"flat"===t[1]||"iso"===t[1]))}catch{this._viewPreference={}}this._labs=Kg(Nf);try{const t=JSON.parse(localStorage.getItem(tv)||"null");this._kioskScale={icon:Es(t?.icon),font:Es(t?.font)}}catch{}try{const t=JSON.parse(localStorage.getItem(Xf)||"null");t&&t.config&&Array.isArray(t.config.spaces)&&(this._serverCfg=t.config,this._cfgEpoch++,this._cfgRev=t.rev||0,this._cfgContentFingerprint=t.config_fingerprint||wd(t.config),this._layout=t.layout||{},this._layoutRev=t.layout_rev||0,this._layoutContentFingerprint=t.layout_fingerprint||wd(this._layout),this._virtualLights=mn(t.virtual_lights,this._cfgRev),this._serverStorage=!0)}catch{}this._adoptInitialSpace(this._model,this._loadOk),"view"!==this._mode||this._view||(this._zoom=this._zoomBySpace[this._space]||1),this.isConnected&&(this._syncCycleTimer(),this._warmAdopt(),this._warmLongReturn&&this._beginResumeSettle(),this._warmLongReturn=!1)}_warmAdopt(){if(this._config?.kiosk)return;const t=Kf(this._config);if(this._warmKey===t&&this._warmSlot)return;this._warmSlot&&this._warmRelease();const e=this.parentNode,i=this._warmIdx(e),s=Gf.get(t);if(!s||!s.length)return;const n=s.find(t=>t.owner===this._warmGen);if(n)return this._warmLongReturn=!!n.freed&&Date.now()-n.freed>=md,clearTimeout(n.evict),n.evict=0,n.freed=0,n.live=!0,this._warmSlot=n,this._warmKey=t,n.frameFingerprint&&this._continuity.adoptCompleteFrame(n.frameFingerprint),void(!this._devices.length&&n.devices?.length&&(this._devices=[...n.devices]));const{slot:o,sure:a}=((t,e,i,s)=>{const n=t=>{const e=!!i&&t.place?.deref()===i;return e&&t.idx===s?4:t.live?0:e?3:2};let o=null,a=0,r=0,l=null;for(const i of t){if(i.owner===e)continue;l=i;const t=n(i);t<=0||(t>a?(o=i,a=t,r=1):t===a&&r++)}return!o||r>1?{slot:o||l,sure:!1}:{slot:o,sure:!0}})(s,this._warmGen,e,i);o&&(this._warmLongReturn=!!o.freed&&Date.now()-o.freed>=md,this._booting=!1,this._bootFading=!1,this._hdrH=o.hdrH,this._bootSoft=!0,this.isConnected&&(clearTimeout(this._bootSoftTimer),this._bootSoftTimer=window.setTimeout(()=>{this._bootSoft=!1},qf)),this._warmKey=t,a?(clearTimeout(o.evict),o.evict=0,o.owner=this._warmGen,o.place=e?new WeakRef(e):null,o.idx=i,o.live=!0,this._warmSlot=o,this._warmVp=o.vp,o.frameFingerprint&&this._continuity.adoptCompleteFrame(o.frameFingerprint),!this._devices.length&&o.devices?.length&&(this._devices=[...o.devices]),this._warmAdoptViewport(this._config)):(this._warmSlot={owner:this._warmGen,path:location.pathname,place:e?new WeakRef(e):null,idx:i,live:!0,hdrH:o.hdrH,stageH:o.stageH,vp:null,frameFingerprint:"",devices:null,dlg:null,freed:0,evict:0},s.push(this._warmSlot),this._warmTrim(s)))}_warmIdx(t){const e=t?.children;if(!e)return-1;for(let t=0;t4;){const e=t.findIndex(t=>!t.live);if(e<0)break;clearTimeout(t[e].evict),t.splice(e,1)}}_warmScheduleEvict(t,e){if(clearTimeout(t.evict),!(t.dlg||t.vp&&"view"!==t.vp.mode))return;const i=t.freed,s=t.owner;t.evict=window.setTimeout(()=>{if(t.evict=0,t.freed!==i||t.owner!==s)return;var n;t.dlg=null,t.vp=(n=t.vp)&&"view"!==n.mode?{...n,mode:"view",zoom:n.snap?.space===n.space?n.snap.zoom:n.zoom,view:null,snap:null,tool:"draw",decorTool:"select",showHidden:!1,selId:null,rszSel:null,decorSel:null}:n,t.frameFingerprint="";const o=Gf.get(e);if(!t.live&&o&&o.length>1){const e=o.indexOf(t);e>=0&&o.splice(e,1)}},Yf+250)}_warmAdoptViewport(t){const e=this._warmVp;if(!e||this._warmSlot?.path!==location.pathname)return void(this._warmVp=null);const i=this._fixedFloorState();if(this._hashApplied||!this._model.find(t=>t.id===e.space)||"valid"===i.kind&&i.id!==e.space||this._hasFixedFloor&&"valid"!==i.kind)return void(this._warmVp=null);this._commitSpace(e.space,!0),this._navApplied=!0,this._adoptMode("view"!==e.mode&&this._canEdit&&!t.kiosk?e.mode:"view"),this._pendingNavMode="view"===e.mode||this._canEdit||t.kiosk?null:e.mode,this._zoom=e.zoom;const s=this._effectiveProjection(),n=s===e.projection&&this._labsIso===e.activeLabsIso;if(this._view=n&&e.view?{...e.view}:null,this._viewModeSnap=n&&e.snap?{...e.snap}:null,!n&&e.logicalCenter){const t="iso"===s?Xg([e.logicalCenter.x,e.logicalCenter.y],0):[e.logicalCenter.x,e.logicalCenter.y];this._applyView(e.zoom,t[0],t[1])}var o;this._tool="opening"===(o=function(t){return"partition"===t?"draw":t}(o=e.tool))?"draw":"string"==typeof o&&av.has(o)?o:"draw",this._decorTool=e.decorTool,this._showHidden=e.showHidden,this._showFar!==e.showFar&&(this._showFar=e.showFar,this._frame=null),this._selId=e.selId,this._rszSel=e.rszSel,this._decorSel=e.decorSel,this._warmVpArmed=!0}_warmPatch(t,e=!1){if(this._config?.kiosk)return;const i=Kf(this._config);if(!this._warmSlot||this._warmKey===i){if(!this._warmSlot){if(!e)return;const t=this.parentNode;this._warmKey=i,this._warmSlot={owner:this._warmGen,path:location.pathname,place:t?new WeakRef(t):null,idx:this._warmIdx(t),live:!0,hdrH:this._hdrH,stageH:0,vp:null,frameFingerprint:"",devices:null,dlg:null,freed:0,evict:0};const s=Gf.get(i)||[];for(s.push(this._warmSlot),Gf.set(i,s),this._warmTrim(s);Gf.size>8;){const t=Gf.keys().next().value;if(void 0===t||t===i)break;for(const e of Gf.get(t)||[])clearTimeout(e.evict);Gf.delete(t)}}Object.assign(this._warmSlot,t)}}_warmViewportState(){const t=this._effectiveProjection();return{space:this._space,mode:this._mode,projection:t,activeLabsIso:this._labsIso,logicalCenter:this._logicalViewCenter(t),zoom:this._zoom,view:this._view?{...this._view}:null,snap:this._viewModeSnap?{...this._viewModeSnap}:null,tool:this._tool,decorTool:this._decorTool,showHidden:this._showHidden,showFar:this._showFar,selId:this._selId,rszSel:this._rszSel,decorSel:this._decorSel}}_warmDialogState(){const t=(t,e)=>({kind:t,space:this._space,mode:this._mode,data:e});return this._tapConfirm||this._alignDialog||this._mergeDialog||this._importDialog||this._backupExportDialog||this._backupImportDialog?null:this._openingInfo?t("openingInfo",this._openingInfo.id):this._infoCard?t("info",this._infoCard.id):this._rulesDialog?this._rulesDialog.busy?null:t("rules",this._rulesDialog):this._settingsDialog?this._settingsDialog.busy?null:t("settings",this._settingsDialog):this._markerDialog?this._markerDialog.busy?null:t("marker",this._markerDialog):this._openingDialog?t("opening",this._openingDialog):this._backdropDialog?t("backdrop",this._backdropDialog):this._decorShapeDialog?t("decorShape",this._decorShapeDialog):this._decorTextDialog?t("decorText",this._decorTextDialog):this._roomDialog?t("room",{editId:this._roomEditId,fill:this._roomFill,customFill:this._roomCustomFill,tempSrc:this._roomTempSrc,humSrc:this._roomHumSrc,srcOpen:this._roomSrcOpen,srcFilter:this._roomSrcFilter,nameScale:this._roomNameScale,labelScale:this._roomLabelScale,areaSel:this._areaSel,nameSel:this._nameSel,pendingSplit:this._pendingSplit,wallFaceBatch:this._wallFaceBatch,path:this._path}):this._spaceDialog?this._spaceDialog.busy?null:t("space",this._spaceDialog):null}_warmSnapshot(){if(this._booting||this._config?.kiosk||"steady"!==this._continuity.state)return;const t={vp:this._warmViewportState(),frameFingerprint:this._continuity.frameFingerprint,devices:this._devices};if(this._warmRevivePending||(t.dlg=this._warmDialogState()),this.isConnected&&this._warmSlot?.owner===this._warmGen){const e=this.parentNode;t.place=e?new WeakRef(e):null,t.idx=this._warmIdx(e)}this._warmPatch(t)}_warmReviveDialog(){this._warmRevivePending=!1;const t=this._warmSlot;if(this._warmReviveTimer=void 0,!t||!t.dlg)return;const e=t.dlg,i=t.freed;if(t.dlg=null,t.freed=0,clearTimeout(t.evict),t.evict=0,i&&!(Date.now()-i>Yf)&&e.space===this._space&&e.mode===this._mode){switch(e.kind){case"space":this._spaceDialog={...e.data,busy:!1,savedBusy:!1};break;case"marker":this._markerDialog={...e.data,busy:!1};break;case"settings":this._settingsDialog={...e.data,busy:!1};break;case"rules":this._rulesDialog={...e.data,busy:!1};break;case"opening":this._openingDialog={...e.data};break;case"backdrop":this._backdropDialog={...e.data};break;case"decorShape":this._decorShapeDialog={...e.data};break;case"decorText":{this._decorTextDialog={...e.data};const t=String(this._decorTextDialog?.text??"").length;this._decorTextSelection={start:t,end:t};break}case"room":{const t=e.data;this._roomEditId=t.editId,this._roomFill=t.fill,this._roomCustomFill=t.customFill||null,this._roomTempSrc=t.tempSrc,this._roomHumSrc=t.humSrc,this._roomSrcOpen=t.srcOpen,this._roomSrcFilter=t.srcFilter,this._roomNameScale=t.nameScale,this._roomLabelScale=t.labelScale,this._areaSel=t.areaSel,this._nameSel=t.nameSel,this._pendingSplit=t.pendingSplit,this._wallFaceBatch=t.wallFaceBatch||null,this._path=t.path,this._wallFaceBatch&&(this._activeDraftId=this._wallFaceBatch.activeDraftId,this._draftSegmentCms=[...this._wallFaceBatch.activeCms]),this._roomDialog=!0;break}case"info":{const t=this._devices.find(t=>t.id===e.data);t&&(this._infoCard=t);break}case"openingInfo":{const t=(this._curSpaceCfg?.openings||[]).find(t=>t.id===e.data);t&&(this._openingInfo=t);break}}this.requestUpdate()}}_cacheSnapshot(){if(this._serverCfg)try{this._cfgContentFingerprint=wd(this._serverCfg),this._layoutContentFingerprint=wd(this._layout),this._virtualLights=function(t,e,i){if(t.configRev===i)return t;const s=new Set((Array.isArray(e?.markers)?e.markers:[]).filter(yn).map(t=>t.id));return{...t,configRev:i,off:new Set([...t.off].filter(t=>s.has(t)))}}(this._virtualLights,this._serverCfg,this._cfgRev),localStorage.setItem(Xf,JSON.stringify({config:this._serverCfg,rev:this._cfgRev,config_fingerprint:this._cfgContentFingerprint,layout:this._layout,layout_rev:this._layoutRev,layout_fingerprint:this._layoutContentFingerprint,virtual_lights:fn(this._virtualLights)}))}catch{}}_beginContinuityCandidate(t,e,i="plan"){return this._booting&&!this._continuity.hasCompleteFrame?this._continuity.token:(this._continuityDataReady=e,this._continuityPaintToken=-1,this._stagedDeviceSnapshotToken=-1,this._resumeSettling=!0,this._continuity.beginCandidate(t,i))}_continuityStageValid(){const t=this._stageEl;return!!t&&t.clientWidth>0&&t.clientHeight>0}_continuityAssetsReady(){if(!this._model.length)return!1;const t=this._model.length?this._spaceModel():null;return!t?.bg?.href||this._signer.isReady(this.hass,t.bg.href)}_initialSpaceSelection(t,e=this._loadOk){const i=this._fixedFloorState(t,e);return"valid"===i.kind?{id:i.id,source:"fixed"}:this._hasFixedFloor?{id:null,source:"none"}:function(t){const e=new Set(t.spaceIds.filter(t=>!!t));if(!e.size)return{id:null,source:"none"};const i=[["hash",!1===t.acceptHash?null:t.hashSpace],["current",t.preserveCurrent?t.currentSpace:null],["saved",t.savedSpace],["default",t.defaultSpace],["first",t.spaceIds[0]]];for(const[t,s]of i)if(s&&e.has(s))return{id:s,source:t};return{id:null,source:"none"}}({spaceIds:t.map(t=>t.id),hashSpace:this._hashSpace(),acceptHash:!this._hashApplied,currentSpace:this._space,preserveCurrent:this._hashApplied||this._navApplied||this._warmVpArmed,savedSpace:this._savedNav()?.space,defaultSpace:this._config?.default_floor})}_adoptInitialSpace(t,e=this._loadOk){const i=this._initialSpaceSelection(t,e);return i.id?(this._commitSpace(i.id,!0),"hash"===i.source&&(this._hashApplied=!0),"saved"===i.source&&(this._navApplied=!0),i):i}_candidateBackdrop(t,e=this._space){const i=Sh(t),s=this._fixedFloorState(i,!0);if(this._hasFixedFloor&&"valid"!==s.kind)return"";const n=this._initialSpaceSelection(i,!0).id||(i.some(t=>t.id===e)?e:i[0]?.id);return i.find(t=>t.id===n)?.bg?.href||""}_visualFrameFingerprint(){const t=this._stageEl,e=t?[t.clientWidth,t.clientHeight]:[0,0];return kd([this._cfgRev,this._cfgContentFingerprint||wd(this._serverCfg),this._layoutRev,this._layoutContentFingerprint||wd(this._layout),this._space,this._mode,this._view,e,this._glowScreenBlend?"screen":"normal",this.hass?.themes?.darkMode??this.hass?.themes?.default_theme??""])}_settleContinuityFrame(){if(this._booting||!this._continuityStageValid())return;if(!this._continuity.hasCompleteFrame&&"steady"===this._continuity.state)return void(this._continuityAssetsReady()&&(this._renderSnapshotAt=Date.now(),this._continuity.markCompleteFrame(this._visualFrameFingerprint())));if(!this._continuityDataReady)return;if(!["holding","offline-stale","overlay-pending","overlay-visible","candidate-ready"].includes(this._continuity.state))return;const t=this._continuity.token;if(this._candidateDeviceSnapshot&&this._candidateDeviceSnapshot!==this._visibleDeviceSnapshot&&this._stagedDeviceSnapshotToken!==t)return this._stagedDeviceSnapshotToken=t,void this.requestUpdate();this._continuityPaintToken!==t&&(this._continuityPaintToken=t,this._continuity.candidateReady(t)&&this._continuity.commitAfterPaint(t,{updateComplete:()=>this.updateComplete,stageValid:()=>this.isConnected&&this._continuityStageValid(),assetsReady:()=>this._continuityAssetsReady(),frameFingerprint:()=>this._visualFrameFingerprint()}).then(e=>{e&&t===this._continuity.token?(this._resumeSettling=!1,this._renderSnapshotAt=Date.now(),this._candidateDeviceSnapshot&&(this._visibleDeviceSnapshot=this._candidateDeviceSnapshot),this._candidateDeviceSnapshot=null,this._stagedDeviceSnapshotToken=-1,this._warmSnapshot()):t===this._continuity.token&&(this._continuityPaintToken=-1,this._stagedDeviceSnapshotToken=-1,this._candidateDeviceSnapshot=null,this.requestUpdate())}))}_onBackdropLoaded(t,e){this._signer.markLoaded(this.hass,t,e),this._continuity.note("asset-ready"),this._continuityPaintToken=-1,"steady"!==this._continuity.state&&this.requestUpdate()}_renderRecoveryOverlay(){if(!this._continuity.overlayVisible&&"recovery-error"!==this._continuity.state)return G;const t="connection"===this._continuity.recoveryReason;return W`
`}afterRender(){const t=this.host.root();this._blocked&&(this._openGroupId?this.closeGroup(!1):"palette"===this._currentModel?.kind&&this._currentModel.dismiss?.()),this._syncGlobalDismissListener();const e=t.querySelector(".editor-secondary"),i=this._renderedContext,s=e?.dataset.contextId||"";if(s&&i&&s!==i&&!window.matchMedia?.("(prefers-reduced-motion: reduce)")?.matches&&(this._contentAnimation?.cancel(),this._contentAnimation=e?.querySelector(".editor-secondary-content")?.animate([{opacity:.35,transform:"translateY(-4px)"},{opacity:1,transform:"translateY(0)"}],{duration:100,easing:"ease-out"})),this._renderedContext=s,i&&s!==i&&this._focusOwned){const i=s?e?.querySelector('[tabindex="0"], button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled])'):t.querySelector(".editbar-tools");i?.focus?.(),this._focusOwned=!!s}if("palette"===this._currentModel?.kind&&this._currentModel.launcherId){const e=[...t.querySelectorAll("[data-editor-palette]")].find(t=>t.dataset.editorPalette===this._currentModel?.launcherId);e&&null!==e.offsetParent||this._currentModel.dismiss?.()}if(!this._openGroupId)return;const n=[...t.querySelectorAll("[data-editor-group]")].find(t=>t.dataset.editorGroup===this._openGroupId);n&&null!==n.offsetParent||this.closeGroup(!0)}handleOutsideDismiss(t){if(q_(t,t=>t.hasAttribute("data-editor-navigation")))return"pointerdown"===t.type?this.closeForNavigation():"click"===t.type&&this._dismissPointerTarget&&this._clearDismissClick(),!1;if("click"===t.type&&this._dismissPointerTarget){return!!(t.composedPath?.()||[t.target]).includes(this._dismissPointerTarget)&&(this._clearDismissClick(),t.preventDefault(),t.stopImmediatePropagation(),!0)}const e=this._openGroupId||this._blocked||"palette"!==this._currentModel?.kind?null:this._currentModel;if("pointerdown"===t.type&&(this._openGroupId||e)){const i=q_(t,t=>t.classList.contains("editor-secondary")),s=q_(t,t=>!!t.dataset.editorGroup),n=q_(t,t=>!!t.dataset.editorPalette),o=q_(t,t=>t.classList.contains("stage"));if(!(i||s||n||"stay-open-on-canvas"===e?.dismissPolicy&&o))return t.preventDefault(),t.stopImmediatePropagation(),this._dismissPointerTarget=t.target,clearTimeout(this._dismissTimer),this._dismissTimer=window.setTimeout(()=>{this._clearDismissClick()},800),this._openGroupId?this.closeGroup(!1):e?.dismiss?.(),this._syncGlobalDismissListener(),!0}return!1}_activateGroupItem(t,e,i){if(t.id!==this._openGroupId)return;const s=t.items.find(t=>t.id===e);if(!s||s.disabled)return;const n="toggle"===s.role&&"stay-open"===s.closePolicy,o=0===i.detail;n||(this._openGroupId=null,this.host.requestUpdate(),this._syncGlobalDismissListener()),s.invoke(),!n&&o&&this.host.updateComplete().then(()=>{const e=[...this.host.root().querySelectorAll("[data-editor-group]")].find(e=>e.dataset.editorGroup===t.id&&null!==e.offsetParent);e?.focus()})}_groupKeydown(t){if(!["ArrowLeft","ArrowRight","Home","End"].includes(t.key))return;const e=[...t.currentTarget.querySelectorAll(".editor-group-item:not([disabled])")];if(!e.length)return;t.preventDefault();const i=e.indexOf(this.host.root().activeElement),s="Home"===t.key?0:"End"===t.key?e.length-1:"ArrowLeft"===t.key?i<=0?e.length-1:i-1:(i+1)%e.length;e[s]?.focus()}_clearDismissClick(){this._dismissPointerTarget=null,clearTimeout(this._dismissTimer),this._dismissTimer=void 0,this._syncGlobalDismissListener()}_syncGlobalDismissListener(){const t=!this._blocked&&"palette"===this._currentModel?.kind,e=!!this._openGroupId||t||!!this._dismissPointerTarget;e!==this._globalDismissListening&&(this._globalDismissListening=e,e?(window.addEventListener("pointerdown",this._globalDismissGuard,!0),window.addEventListener("click",this._globalDismissGuard,!0)):(window.removeEventListener("pointerdown",this._globalDismissGuard,!0),window.removeEventListener("click",this._globalDismissGuard,!0)))}}const j_=t=>t.stopPropagation(),U_=4.166666666666667e-9;function G_(t){return Number.isFinite(t)?Math.round(t/Th)*Th:t}const V_=(t,e,i,s)=>Math.hypot(i-t,s-e),K_=(t,e,i,s,n,o,a,r)=>Math.hypot(Math.max(Math.abs(n-t),Math.abs(n+a-(t+i))),Math.max(Math.abs(o-e),Math.abs(o+r-(e+s)))),Y_=(t,e,i,s,n,o,a)=>{const r=Math.max(Number(s)||0,0)/2,l=Math.PI/180,c=Math.cos(i*l)*r,h=Math.sin(i*l)*r,d=Math.cos(a*l)*r,p=Math.sin(a*l)*r,u=Math.max(V_(t+c,e+h,n+d,o+p),V_(t-c,e-h,n-d,o-p)),_=Math.max(V_(t+c,e+h,n-d,o-p),V_(t-c,e-h,n+d,o+p));return Math.min(u,_)},J_=t=>{const e=Number(t?.cell_cm);return e>0?e:5};function X_(t,e){const i=JSON.parse(JSON.stringify(t||[])),s=JSON.parse(JSON.stringify(e||{}));let n=0,o=0,a=0,r=0,l="",c=0,h=0,d=0;const p=(t,e)=>{Number.isFinite(t)&&Number.isFinite(e)&&t!==e&&Math.abs(e-t)<=U_&&h++},u=(t,e)=>{p(t[0],e[0]),p(t[1],e[1])},_={};let m=5;for(const t of i){const e=J_(t);null!=t?.id&&(_[String(t.id)]=e),e>m&&(m=e)}const g=(t,e,i,s=!1)=>{if(!(t>U_||s))return;n++,t>a&&(a=t);const o=t*Dh*e;o>r&&(r=o,l=i)};for(const t of i){const e=J_(t),i=null!=t?.id?String(t.id):"";for(const s of t.rooms||[]){o++;let t=0;if(s.poly?.length)s.poly=s.poly.map(e=>{const i=[G_(e[0]),G_(e[1])];return t=Math.max(t,V_(e[0],e[1],i[0],i[1])),u(e,i),i});else if(null!=s.x&&null!=s.y){const e=s.x,i=s.y,n=s.w||0,o=s.h||0,a=G_(e+n),r=G_(i+o),l=G_(e),c=G_(i),h=Math.max(Th,a-l),d=Math.max(Th,r-c);t=K_(e,i,n,o,l,c,h,d),s.x=l,s.y=c,s.w=h,s.h=d,p(e,l),p(i,c),p(e+n,l+h),p(i+o,c+d)}g(t,e,i)}for(const s of t.room_drafts||[]){o++;let t=0;const n=s.points||[],a=n.map(e=>{const i=[G_(e[0]),G_(e[1])];return t=Math.max(t,V_(e[0],e[1],i[0],i[1])),i}),r=a.length?[a[0]]:[],l=a.length?[[n[0],a[0]]]:[],c=[];for(let t=0;t+1=2)for(const[t,e]of l)u(t,e);g(t,e,i)}if(Array.isArray(t.room_drafts)){const e=t.room_drafts.length;t.room_drafts=t.room_drafts.filter(t=>t.points?.length>=2),d+=e-t.room_drafts.length,t.room_drafts.length||delete t.room_drafts}for(const s of t.partitions||[]){o++;const n=[s.a[0],s.a[1]],a=[s.b[0],s.b[1]],r=[G_(n[0]),G_(n[1])],l=[G_(a[0]),G_(a[1])];let c=Math.max(V_(n[0],n[1],r[0],r[1]),V_(a[0],a[1],l[0],l[1]));const h=V_(r[0],r[1],l[0],l[1]),d=(t.openings||[]).filter(t=>"partition"===t.host?.kind&&t.host.id===s.id).every(t=>{const e=Number(t.length),i=Number(t.host.t),s=i*h;return Number.isFinite(e)&&e>0&&Number.isFinite(i)&&i>=0&&i<=1&&s-e/2>=-U_&&s+e/2<=h+U_});h>U_&&d?(s.a=r,s.b=l,u(n,r),u(a,l)):c=0,g(c,e,i)}for(const s of t.wall_columns||[]){o++;const t=[s.center[0],s.center[1]],n=[G_(t[0]),G_(t[1])],a=V_(t[0],t[1],n[0],n[1]);s.center=n,u(t,n),g(a,e,i)}for(const s of t.decor||[]){o++;let t=0;if("line"===s.kind){const e=[s.x1,s.y1],i=[s.x2,s.y2],n=[G_(e[0]),G_(e[1])],o=[G_(i[0]),G_(i[1])];t=Math.max(V_(e[0],e[1],n[0],n[1]),V_(i[0],i[1],o[0],o[1])),s.x1=n[0],s.y1=n[1],s.x2=o[0],s.y2=o[1],u(e,n),u(i,o)}else{const e=s.x,i=s.y,n=s.w,o=s.h,a=G_(e),r=G_(i);if(null!=s.w&&null!=s.h){const l=G_(e+n),c=G_(i+o),h=Math.max(Th,l-a),d=Math.max(Th,c-r);t=K_(e,i,n,o,a,r,h,d),s.w=h,s.h=d,p(e+n,a+h),p(i+o,r+d)}else t=V_(e,i,a,r);s.x=a,s.y=r,p(e,a),p(i,r)}g(t,e,i)}for(const s of t.openings||[]){if(o++,"partition"===s.host?.kind){const n=(t.partitions||[]).find(t=>t.id===s.host.id),o=Number(s.host.t);if(!n||!Number.isFinite(o)||o<0||o>1)continue;const a=n.b[0]-n.a[0],r=n.b[1]-n.a[1];if(Math.hypot(a,r)<=U_)continue;const l=n.a[0]+a*o,h=n.a[1]+r*o;let d=180*Math.atan2(r,a)/Math.PI;d>=90?d-=180:d<-90&&(d+=180);const p=Number(s.angle),u=!(Number.isFinite(p)&&p===d),_=Y_(s.x,s.y,Number.isFinite(p)?p:d,Number(s.length)||0,l,h,d);s.x=l,s.y=h,s.angle=d,u&&c++,g(_,e,i,u);continue}const n=ui([s.x,s.y],t.rooms||[],.025,{step:Th,length:Number(s.length)||0});if(!n)continue;const a=Number(s.angle),r=!(Number.isFinite(a)&&a===n.angle),l=Y_(s.x,s.y,Number.isFinite(a)?a:n.angle,Number(s.length)||0,n.x,n.y,n.angle);s.x=n.x,s.y=n.y,s.angle=n.angle,r&&c++,g(l,e,i,r)}}for(const[t,e]of Object.entries(s)){if(!e||"object"!=typeof e)continue;const i=e;if("number"!=typeof i.x||"number"!=typeof i.y)continue;o++;const n=G_(i.x),a=G_(i.y),r=V_(i.x,i.y,n,a);s[t]={...i,x:n,y:a},p(i.x,n),p(i.y,a);const l="string"==typeof i.s?i.s:"";g(r,_[l]??m,l)}return{spaces:i,layout:s,report:{moved:n,coordsCanonicalized:h,total:o,maxShift:a,maxShiftCm:r,maxSpace:l,rotated:c,removedDrafts:d},changed:n>0||h>0}}function Z_(t,e){const i=e.base+t*e.span;return Math.min(1,Math.max(0,i))}const Q_=t=>Array.isArray(t)&&t.length>=2&&Number.isFinite(t[0])&&Number.isFinite(t[1]),tm=(t,e)=>Math.hypot(t[0]-e[0],t[1]-e[1]);function em(t,e,i){const s=i[0]-e[0],n=i[1]-e[1],o=s*s+n*n;if(o<=0)return tm(t,e);let a=((t[0]-e[0])*s+(t[1]-e[1])*n)/o;return a=Math.max(0,Math.min(1,a)),Math.hypot(t[0]-(e[0]+s*a),t[1]-(e[1]+n*a))}function im(t,e,i,s,n){for(const s of e)if(s&&!i.has(s.id)&&Q_(s.a)&&Q_(s.b)&&(tm(t,s.a)<=n||tm(t,s.b)<=n))return!0;for(const e of s?.roomPolygons||[])for(let i=0;i0&&r>0))return null;if(Math.abs(n[0]/a*(o[1]/r)-n[1]/a*(o[0]/r))>i)return null;for(const[i,n]of[[t.a,e.a],[t.a,e.b],[t.b,e.a],[t.b,e.b]])if(tm(i,n)<=s)return[(i[0]+n[0])/2,(i[1]+n[1])/2];return null}function nm(t,e){const i=.05*(Number(e.pitch)>0?Number(e.pitch):1),s=new Map;let n=(t||[]).filter(t=>!!t&&"string"==typeof t.id&&Q_(t.a)&&Q_(t.b));if(n.length<2)return{partitions:[...t||[]],merged:0,openingMoves:[]};const o=e.seedIds&&e.seedIds.length?new Set(e.seedIds):null;let a=0;for(let t=0;ttm(e,t.at)>i);let h=c[0]??r.a,d=c[c.length-1]??l.b;if(c.length<2&&(h=r.a,d=l.b),d[0]0?(d[0]-h[0])/u:0,m=u>0?(d[1]-h[1])/u:0,g=t=>u>0?((t[0]-h[0])*_+(t[1]-h[1])*m)/u:0;for(const t of[r,l]){const e=g(t.a),i=g(t.b)-e;for(const[n,o]of s)o.toId===t.id&&s.set(n,{fromId:o.fromId,toId:p.id,base:e+o.base*i,span:o.span*i});s.set(t.id,{fromId:t.id,toId:p.id,base:e,span:i})}o&&o.add(p.id),n=n.filter((e,i)=>i!==t.i&&i!==t.j),n.splice(t.i,0,p),a++}return{partitions:n,merged:a,openingMoves:[...s.values()]}}function om(t,e,i,s){if(!t?.length||!i.length)return 0;const n=new Map(i.map(t=>[t.fromId,t]));let o=0;for(const i of t){const t=i?.host;if(!t||"partition"!==t.kind)continue;const a=n.get(t.id);if(!a)continue;i.host={...t,id:a.toId,t:Z_(t.t,a)},o++;const r=Sp(i,e,s.coordScale,s.cellCm,s.gridPitch).resolved;r&&Object.assign(i,Ip(i,r,s.coordScale))}return o}function am(t,e){const i=e?.excludeDraftId||null;return{roomPolygons:(t?.rooms||[]).map(t=>hi(t)).filter(t=>!!t),columns:t?.wall_columns||[],draftEnds:(t?.room_drafts||[]).flatMap(t=>{if(i&&t?.id===i)return[];const e=t?.points||[];return e.length?[e[0],e[e.length-1]]:[]})}}const rm=t=>!!t&&t.length>=2&&Number.isFinite(t[0])&&Number.isFinite(t[1]),lm=(t,e)=>t[0]-e[0]||t[1]-e[1],cm=(t,e,i,s)=>[t[0]+e*s,t[1]+i*s],hm=(t,e,i,s)=>(t[0]-e[0])*i+(t[1]-e[1])*s,dm=(t,e,i,s,n)=>{const o=e[0]-t[0],a=e[1]-t[1],r=Math.hypot(o,a);if(!(r>n))return null;const l=o/r,c=a/r,h=e=>Math.abs((e[0]-t[0])*c-(e[1]-t[1])*l);if(h(i)>n||h(s)>n)return null;const d=hm(i,t,l,c),p=hm(s,t,l,c),u=Math.max(0,Math.min(d,p)),_=Math.min(r,Math.max(d,p));return _-u>n?{lo:u,hi:_}:null},pm=(t,e,i)=>Math.min(t.hi,e.hi)-Math.max(t.lo,e.lo)>i,um=t=>{const e=new Set(["id","a","b","cm"]);return Object.keys(t||{}).every(t=>e.has(t))},_m=(t,e,i,s)=>{const n=t.b[0]-t.a[0],o=t.b[1]-t.a[1],a=Math.hypot(n,o);if(!(a>s))return!0;const r=n/a,l=o/a,c=gl(t.cm,i.cellCm,i.gridPitch)/2;return e.some(e=>{const n=e?.center;if(!rm(n))return!0;const o=hm(n,t.a,r,l),h=Math.abs((n[0]-t.a[0])*l-(n[1]-t.a[1])*r),d=gl(Number(e.cm),i.cellCm,i.gridPitch)*("square"===e.shape?Math.SQRT1_2:.5);return!(Number.isFinite(d)&&d>0)||o>=-d-s&&o<=a+d+s&&h<=c+d+s})},mm=(t,e,i)=>{if(t.host){const s=Sp(t,e,i.coordScale,i.cellCm,i.gridPitch).resolved;return s?{center:s.center,angle:s.angle,length:s.length}:null}const s=Number(t.x)*i.coordScale,n=Number(t.y)*i.coordScale,o=Number(t.angle),a=Number(t.length)*i.coordScale;return[s,n,o,a].every(Number.isFinite)&&a>0?{center:[s,n],angle:o,length:a}:null},gm=(t,e,i)=>{const s=t.angle*Math.PI/180,n=Math.cos(s),o=Math.sin(s),a=e.angle*Math.PI/180,r=Math.cos(a),l=Math.sin(a);if(Math.abs(n*l-o*r)>1e-6)return!1;const c=e.center[0]-t.center[0],h=e.center[1]-t.center[1];if(Math.abs(c*o-h*n)>i)return!1;const d=c*n+h*o;return Math.max(-t.length/2,d-e.length/2)({...t,a:[t.a[0]*e,t.a[1]*e],b:[t.b[0]*e,t.b[1]*e]}),vm=(t,e,i,s)=>{const n=`~r-${(t=>{let e=2166136261;for(let i=0;i>>0;return e.toString(36)})(`${t}|${e[0].toFixed(9)},${e[1].toFixed(9)}|${i[0].toFixed(9)},${i[1].toFixed(9)}`)}`,o=`${t.slice(0,Math.max(1,64-n.length))}${n}`;let a=o;for(let t=2;s.has(a);t++){const e=`-${t}`;a=`${o.slice(0,64-e.length)}${e}`}return s.add(a),a},ym=(t,e)=>{const i=[];for(const s of t){const t=i[i.length-1];!(t&&Math.abs(t.hi-s.lo)<=e&&t.safe===s.safe)||s.safe&&t.signature!==s.signature?i.push({lo:s.lo,hi:s.hi,a:s.a,b:s.b,safe:s.safe,signature:s.signature,roomIds:s.roomIds,finalCm:s.finalCm}):(t.hi=s.hi,t.b=s.b)}return i};function bm(t,e,i,s,n){const o=i||[],a=Array.isArray(t?.partitions)?t.partitions:[],r=Array.isArray(t?.openings)?t.openings:[],l=Array.isArray(t?.room_drafts)?t.room_drafts:[],c={walls:o,partitions:a,openings:r,roomDrafts:l,partitionsReconciled:0,openingsRehosted:0,removedDrafts:0};if(!a.length&&!l.length)return c;const h=Math.max(2e-4*n.gridPitch,1e-9);let d=o,p=a,u=r;const _=dc(e.rooms,d,s,n.pitch,n.cellCm,n.gridPitch,n.coordScale),m=((t,e,i,s)=>{const n=new Map(t.map(t=>[t.id,t])),o=new Set;for(const t of e){if(!n.get(t.id)||!Array.isArray(t.points)||t.points.length<2||t.segments.length!==t.points.length-1)continue;let e=!0;for(let n=0;n+10)){e=!1;break}const l=Math.hypot(a[0]-o[0],a[1]-o[1]);if(!(l>s)){e=!1;break}const c=i.flatMap(t=>{const e=t.cm>0?t.cm:ll;if(t.open||"outer"!==t.kind&&"shared"!==t.kind||e+st.lo-e.lo||t.hi-e.hi);let h=0;for(const t of c){if(t.lo>h+s)break;if(h=Math.max(h,t.hi),h>=l-s)break}h!m.has(t.id));let f=0,v=0;const y=new Map(e.partitions.map(t=>[t.id,t]));for(const t of[...a].sort((t,e)=>t.id.localeCompare(e.id))){if(!p.some(e=>e.id===t.id))continue;if(!um(t))continue;const i=y.get(t.id);if(!(i&&rm(i.a)&&rm(i.b)&&Number.isFinite(i.cm)&&i.cm>0))continue;const[o,a]=lm(i.a,i.b)<=0?[[i.a[0],i.a[1]],[i.b[0],i.b[1]]]:[[i.b[0],i.b[1]],[i.a[0],i.a[1]]],r=a[0]-o[0],l=a[1]-o[1],c=Math.hypot(r,l);if(!(c>h))continue;const _=r/c,g=l/c,b=dc(e.rooms,d,s,n.pitch,n.cellCm,n.gridPitch,n.coordScale),w=b.flatMap(t=>{if(t.open||"outer"!==t.kind&&"shared"!==t.kind)return[];const e=dm(o,a,t.a,t.b,h);return e?[{interval:t,range:e}]:[]});if(!w.length)continue;const k=u.filter(t=>"partition"===t.host?.kind&&t.host.id===i.id).map(t=>({opening:t,resolved:Sp(t,e.partitions,n.coordScale,n.cellCm,n.gridPitch).resolved}));if(k.some(t=>!t.resolved))continue;const x=[0,c];for(const{range:t}of w)x.push(t.lo,t.hi);const $=x.slice(),S=new Map;for(const{opening:t,resolved:e}of k){const i=hm(e.center,o,_,g),s={lo:i-e.length/2,hi:i+e.length/2};S.set(t.id,s),$.push(Math.max(0,s.lo),Math.min(c,s.hi))}const M=[...new Set($.filter(t=>Number.isFinite(t)&&t>=-h&&t<=c+h).map(t=>Math.max(0,Math.min(c,t)).toFixed(9)))].map(Number).sort((t,e)=>t-e),C=p.map(t=>fm(t,n.coordScale)).filter(t=>t.id!==i.id),D=e.room_drafts.filter(t=>!m.has(t.id)),P=[];for(let t=0;t+1h))continue;const r=cm(o,_,g,s),l=cm(o,_,g,a),c=w.filter(({range:t})=>t.lo<=s+h&&t.hi>=a-h).map(({interval:t})=>t),d=new Map;for(const t of c)d.set(t.roomId,t);const p=[...d.values()],u=new Set(p.map(t=>t.kind)),m=new Set(p.map(t=>t.cm>0?t.cm:ll)),f=p[0]?.kind,v=[...d.keys()].sort(),y=1===u.size&&1===m.size&&("outer"===f&&1===v.length||"shared"===f&&2===v.length),b={id:i.id,a:r,b:l,cm:i.cm},k=C.some(t=>!!dm(r,l,t.a,t.b,h)),x=D.some(t=>t.points.some((e,i)=>i+10?p[0].cm:ll:0,T=y?Math.max(S,i.cm):i.cm;P.push({lo:s,hi:a,a:r,b:l,safe:$,signature:$?`${f}|${v.join(",")}|${T}`:"",roomIds:v,roomCm:S,finalCm:T})}if(!P.some(t=>t.safe))continue;const T=new Map;for(const{opening:t,resolved:e}of k){const s=S.get(t.id),o=x.some(t=>t>s.lo+h&&tpm(t,s,h)),r=new Set(a.filter(t=>t.safe).map(t=>t.signature));if(!o&&a.length>0&&a.every(t=>t.safe)&&1===r.size&&Rp(e,b,h)){T.set(t.id,{resolved:e,signature:[...r][0]});continue}const l=xp(i,n.cellCm,n.gridPitch),c={lo:s.lo-l,hi:s.hi+l};for(const t of P)pm(t,c,h)&&(t.safe=!1,t.signature="")}let R=!0;for(;R;){R=!1;for(const[t,e]of[...T.entries()]){const s=S.get(t),o=P.filter(t=>pm(t,s,h));if(o.length>0&&o.every(t=>t.safe)&&o.every(t=>t.signature===e.signature))continue;T.delete(t);const a=xp(i,n.cellCm,n.gridPitch),r={lo:s.lo-a,hi:s.hi+a};for(const t of P)pm(t,r,h)&&(t.safe=!1,t.signature="");R=!0}}const I=ym(P,h),A=I.filter(t=>t.safe),z=I.filter(t=>!t.safe);if(!A.length)continue;if(p.length-1+z.length>2e3)continue;let F=d;for(const t of A){const[e,s]=lm(i.a,i.b)<=0?[t.a,t.b]:[t.b,t.a];F=Fl(F,e,s,t.finalCm,n.pitch,n.coordScale)}if(F=uc(e.rooms,F,s,n.pitch,n.cellCm,n.gridPitch,n.coordScale),F.length>500)continue;const E=new Set(p.map(t=>t.id));E.delete(i.id);const N=z.map((t,e)=>{const s=[t.a[0]/n.coordScale,t.a[1]/n.coordScale],o=[t.b[0]/n.coordScale,t.b[1]/n.coordScale],a=0===e?i.id:vm(i.id,s,o,E);return E.add(a),{id:a,a:s,b:o,cm:i.cm}}),O=p.findIndex(t=>t.id===i.id),L=p.slice();L.splice(O,1,...N);const H=L.map(t=>fm(t,n.coordScale)),B=new Map;let q=!0;for(const{opening:t,resolved:e}of k){const i=T.get(t.id);if(i){const e=Ip(t,i.resolved,n.coordScale),{host:s,...o}=e;B.set(t.id,o);continue}const s=S.get(t.id),o=N[z.findIndex(t=>t.lo<=s.lo+h&&t.hi>=s.hi-h)],a=o&&H.find(t=>t.id===o.id);if(!o||!a){q=!1;break}const r=a.b[0]-a.a[0],l=a.b[1]-a.a[1],c=Math.hypot(r,l),d=hm(e.center,a.a,r/c,l/c),p={...Ip(t,e,n.coordScale),host:{kind:"partition",id:o.id,t:d/c}};if(!Mp(p,H,n.coordScale,n.cellCm,n.gridPitch).resolved){q=!1;break}B.set(t.id,p)}if(!q)continue;const W=u.map(t=>B.get(t.id)||t),j=[...T.keys()].map(t=>B.get(t)),U=j.map(t=>mm(t,H,n));if(U.some(t=>!t))continue;let G=!1;for(let t=0;tt.id));for(const t of W){if(V.has(t.id))continue;const e=mm(t,H,n);e&&U.some(t=>gm(t,e,h))&&(G=!0)}if(G)continue;const K=Ec(e.rooms,F,s,n.pitch,n.cellCm,n.gridPitch,n.coordScale);[...T.entries()].every(([t,e])=>{const i=B.get(t),s=Lc(K,{x:i.x*n.coordScale,y:i.y*n.coordScale,angle:i.angle,length:i.length*n.coordScale},!0),o=[s.negative,s.positive].filter(t=>!!t?.full),a=e.signature.split("|")[1].split(","),r=new Set(o.map(t=>t.roomId));return o.length===a.length&&r.size===a.length&&a.every(t=>r.has(t))})&&(d=F,p=L,u=W,f+=A.length,v+=T.size)}return{walls:d,partitions:p,openings:u,roomDrafts:g,partitionsReconciled:f,openingsRehosted:v,removedDrafts:m.size}}const wm=t=>JSON.parse(JSON.stringify(t)),km=(t,e)=>Object.prototype.hasOwnProperty.call(t,e),xm=(t,e)=>e.length>0&&e.length<=35&&("space"===t?/^[a-z0-9_-]+$/.test(e):/^[A-Za-z0-9_-]+$/.test(e));function $m(t,e){let i=String(e??"");const s=t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),n=new RegExp(`^${s}_(.+)_([0-9a-f]{8})$`);let o=0;for(;o<16;o++){const t=n.exec(i);if(!t)return{root:i,layers:o,bounded:!1};i=t[1]}return{root:i,layers:o,bounded:n.test(i)}}const Sm=(t,e,i)=>{const s=t.get(e)||[];s.push(i),t.set(e,s)};const Mm=1e-9;class Cm extends Error{constructor(t,e=""){super(e?`${t}: ${e}`:t),this.reason=t,this.name="WallSegmentModelError"}}const Dm=t=>JSON.parse(JSON.stringify(t)),Pm=t=>Array.isArray(t)&&t.length>=2&&Number.isFinite(Number(t[0]))&&Number.isFinite(Number(t[1])),Tm=t=>[Number(t[0]),Number(t[1])],Rm=t=>`${Number(t[0]).toFixed(12)},${Number(t[1]).toFixed(12)}`,Im=(t,e)=>{const i=Rm(t),s=Rm(e);return iRm(t)<=Rm(e)?[Tm(t),Tm(e)]:[Tm(e),Tm(t)],zm=(t,e)=>Math.hypot(e[0]-t[0],e[1]-t[1]),Fm=t=>{const e=[[Number(t.points[0][0]),Number(t.points[0][1])]],i=[];for(let s=1;s{const i=new Set,s=t=>{const e=Number(t);if(!Number.isFinite(e))return;const s=e/Th;Math.abs(s-Math.round(s))>=Ur&&i.add(e.toFixed(12))};for(const e of Array.isArray(t?.rooms)?t.rooms:[])for(const t of hi(e)||[])s(t[0]),s(t[1]);for(const e of[t?.wall_segments,t?.walls])for(const t of Array.isArray(e)?e:[])s(t?.a?.[0]),s(t?.a?.[1]),s(t?.b?.[0]),s(t?.b?.[1]);for(const t of e)s(t?.[0]),s(t?.[1]);return i.size},Nm=(t,e,i)=>{const s=i[0]-e[0],n=i[1]-e[1],o=s*s+n*n;return o>1e-18?((t[0]-e[0])*s+(t[1]-e[1])*n)/o:0},Om=(t,e,i)=>{const s=Math.max(0,Math.min(1,Nm(t,e,i)));return Math.hypot(t[0]-(e[0]+(i[0]-e[0])*s),t[1]-(e[1]+(i[1]-e[1])*s))},Lm=(t,e,i,s,n=Mm)=>{const o=e[0]-t[0],a=e[1]-t[1],r=Math.hypot(o,a);if(r<=n)return 0;const l=e=>Math.abs((e[0]-t[0])*a-(e[1]-t[1])*o)/r;if(l(i)>n||l(s)>n)return 0;const c=Nm(i,t,e),h=Nm(s,t,e);return Math.max(0,Math.min(1,Math.max(c,h))-Math.max(0,Math.min(c,h)))*r},Hm=t=>{const e=(new TextEncoder).encode(t),i=8*e.length,s=64*Math.ceil((e.length+9)/64),n=new Uint8Array(s);n.set(e),n[e.length]=128;const o=new DataView(n.buffer);o.setUint32(s-8,Math.floor(i/4294967296),!1),o.setUint32(s-4,i>>>0,!1);const a=new Uint32Array([1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298]),r=new Uint32Array([1779033703,3144134277,1013904242,2773480762,1359893119,2600822924,528734635,1541459225]),l=new Uint32Array(64),c=(t,e)=>t>>>e|t<<32-e;for(let t=0;t>>3,n=c(i,17)^c(i,19)^i>>>10;l[t]=l[t-16]+s+l[t-7]+n>>>0}let[e,i,s,n,h,d,p,u]=r;for(let t=0;t<64;t++){const o=u+(c(h,6)^c(h,11)^c(h,25))+(h&d^~h&p)+a[t]+l[t]>>>0,r=e&i^e&s^i&s;u=p,p=d,d=h,h=n+o>>>0,n=s,s=i,i=e,e=o+((c(e,2)^c(e,13)^c(e,22))+r>>>0)>>>0}r[0]=r[0]+e>>>0,r[1]=r[1]+i>>>0,r[2]=r[2]+s>>>0,r[3]=r[3]+n>>>0,r[4]=r[4]+h>>>0,r[5]=r[5]+d>>>0,r[6]=r[6]+p>>>0,r[7]=r[7]+u>>>0}const h=new Uint8Array(32),d=new DataView(h.buffer);for(let t=0;t{const e="abcdefghijklmnopqrstuvwxyz234567";let i=0,s=0,n="";for(const o of t)for(s=s<<8|o,i+=8;i>=5;)n+=e[s>>>i-5&31],i-=5;return i&&(n+=e[s<<5-i&31]),n},qm=(t,e,i,s,n="")=>{const[o,a]=Am(e,i),r=`${t}|${Rm(o)}|${Rm(a)}|${[...s].sort().join(",")}${n}`;return`wall-${Bm(Hm(r)).slice(0,20)}`};let Wm=0;const jm=t=>{for(let e=0;e<1e3;e++){const e=globalThis.crypto?.randomUUID?.(),i=`wall-${e||Bm(Hm(`${Date.now()}|${Wm++}|${Math.random()}`)).slice(0,26)}`;if(!t.has(i))return i}throw new Cm("duplicate-id","id factory exhausted")},Um=t=>{const e=new Map;for(const i of Array.isArray(t?.wall_segments)?t.wall_segments:[])if(i&&"string"==typeof i.id&&Pm(i.a)&&Pm(i.b)){if(e.has(i.id))throw new Cm("duplicate-id",i.id);e.set(i.id,i)}return e},Gm=(t,e,i)=>{const s=(i,s)=>{const n=t[0]-i[0],o=t[1]-i[1];return Math.abs(e[0]-s[0]-n)<=Mm&&Math.abs(e[1]-s[1]-o)<=Mm?[n,o]:null};return s(i.a,i.b)||s(i.b,i.a)},Vm=(t,e)=>{const i=Array.isArray(t.rooms)?t.rooms:[],s=ud(t.open_spans).map(t=>[t.a[0],t.a[1],t.b[0],t.b[1]]),n=s.length?s:_d(i,null,1,.04*Th,!0),o=[];for(const t of i){const i=hi(t),s=Array.isArray(t?.wall_ids)?t.wall_ids:[];if(i&&s.length===i.length)for(let t=0;t"partition"!==t.host?.kind&&[Number(t.x),Number(t.y)].every(Number.isFinite)&&Number.isFinite(Number(t.angle))&&Number(t.length)>0&&n.some(e=>Om([Number(t.x),Number(t.y)],[e[0],e[1]],[e[2],e[3]])<=.04*Th)):[],l=r.map(t=>{const e=Number(t.angle)*Math.PI/180,i=[Math.cos(e),Math.sin(e)],s=Number(t.length)/2,n=[Number(t.x),Number(t.y)];return{a:[n[0]-i[0]*s,n[1]-i[1]*s],b:[n[0]+i[0]*s,n[1]+i[1]*s]}}),c=(t,e)=>r.some(i=>{const s=[Number(i.x),Number(i.y)];if(!Rl(t,e,Number(i.angle)))return!1;if(Om(s,t,e)>.02*Th)return!1;const n=zm(t,e),o=Nm(s,t,e)*n,a=Number(i.length)/2;return o+a>=-Mm&&o-a<=n+Mm}),h=new Map,d=[];for(const s of i){const r=String(s?.id||""),p=hi(s);if(!r||!p||p.length<3)throw new Cm("invalid-room",r);const u=ec(i,r,a,Th,1,[...t.walls||[],...l]);if(!u||u.poly.length<3)throw new Cm("invalid-room",r);const _=Array.isArray(s.wall_ids)?s.wall_ids:[],m=_.length===p.length;let g=null,f=m;if(f)for(let t=0;tMm||Math.abs(s[1]-g[1])>Mm)){f=!1;break}g=s}const v=[];for(let t=0;t2)throw new Cm("third-owner",a);const d=m?_[u.parent[t]]:void 0;if("string"==typeof d&&d){const n=e.get(d);f||!n||Lm(i,s,n.a,n.b)>Mm?l.preferredIds.add(d):l.positionalIds.add(d),l.preferredCarriers.set(d,{a:Tm(p[u.parent[t]]),b:Tm(p[(u.parent[t]+1)%p.length])})}const g=u.parent[t];l.parentKeys.add(wl(p[g],p[(g+1)%p.length],Th));const y=[(i[0]+s[0])/2,(i[1]+s[1])/2],b=t=>t.some(t=>Om(y,[t[0],t[1]],[t[2],t[3]])<=.04*Th);l.zeroWall||=b(o)||b(n)&&!c(i,s),v.push(a)}const y={...s};delete y.wall_ids,d.push({...y,poly:u.poly.map(t=>[t[0],t[1]]),wall_ids:v})}return{atoms:[...h.values()].sort((t,e)=>t.key.localeCompare(e.key)),rooms:d}},Km=(t,e,i,s,n)=>{const o=new Map([...i.values()].map(t=>[Im(t.a,t.b),t])),a=(t=>{const e=new Map;for(const i of t)"wall"===i.host?.kind&&e.set(i.host.id,(e.get(i.host.id)||0)+1);return e})(t.openings||[]),r=new Map;for(const t of e){const e=n?.get(t.key);if(e){const s=i.get(e);if(!s)throw new Cm("duplicate-id",e);r.set(t,s);continue}if(t.preferredIds.size>1)throw new Cm("duplicate-id",[...t.preferredIds].sort().join(","));const s=[...t.preferredIds][0],l=s?i.get(s):void 0;if(l){r.set(t,l);continue}const c=s?t.preferredCarriers.get(s):void 0;if(s&&c){r.set(t,{id:s,a:c.a,b:c.b,cm:0});continue}const h=o.get(t.key);if(h){r.set(t,h);continue}const d=[...i.values()].filter(e=>Lm(t.a,t.b,e.a,e.b)>Mm),p=[...new Map(d.map(t=>[t.id,t])).values()];if(p.sort((t,e)=>(a.get(e.id)||0)-(a.get(t.id)||0)||zm(e.a,e.b)-zm(t.a,t.b)||t.id.localeCompare(e.id)),p[0])r.set(t,p[0]);else if(1===t.positionalIds.size){const e=i.get([...t.positionalIds][0]);e&&r.set(t,e)}}const l=new Map;for(const[t,e]of r){const i=l.get(e.id)||[];i.push(t),l.set(e.id,i)}for(const[t,e]of l){const s=i.get(t)||r.get(e[0]);if(!s)throw new Cm("duplicate-id",t);const n=[(s.a[0]+s.b[0])/2,(s.a[1]+s.b[1])/2];e.sort((t,e)=>{const i=Om(n,t.a,t.b)<=Mm?0:1,o=Om(n,e.a,e.b)<=Mm?0:1;if(i!==o)return i-o;return(Om(s.a,t.a,t.b)<=Mm?0:1)-(Om(s.a,e.a,e.b)<=Mm?0:1)||t.key.localeCompare(e.key)}),e[0].id=t}const c=(t=>{const e=new Set;for(const i of[t.rooms,t.openings,t.decor,t.room_drafts,t.partitions,t.wall_columns])for(const t of Array.isArray(i)?i:[])"string"==typeof t?.id&&t.id&&e.add(t.id);for(const i of Array.isArray(t.room_drafts)?t.room_drafts:[])for(const t of Array.isArray(i?.segments)?i.segments:[])"string"==typeof t?.id&&t.id&&e.add(t.id);return e})(t);for(const t of e)if(t.id){if(c.has(t.id))throw new Cm("duplicate-id",t.id);c.add(t.id)}const h=e.filter(t=>!t.id);if(s){const e=h.map(e=>{const[i,s]=Am(e.a,e.b),n=`${String(t.id||"")}|${Rm(i)}|${Rm(s)}|${[...e.owners].sort().join(",")}`,o=Bm(Hm(n));return{atom:e,seed:n,digest:o,base:`wall-${o.slice(0,20)}`}}).sort((t,e)=>t.digest.localeCompare(e.digest)||t.atom.key.localeCompare(e.atom.key)),i=new Map;for(const t of e){const e=i.get(t.digest);if(e&&e!==t.seed)throw new Cm("duplicate-id",t.digest);i.set(t.digest,t.seed);let s=1,n=t.base;for(;c.has(n);)n=`${t.base}-${++s}`;t.atom.id=n,c.add(n)}}else for(const t of h)t.id=jm(c),c.add(t.id)},Ym=(t,e)=>{if("partition"===t.host?.kind)return null;const i=[Number(t.x),Number(t.y)];if(!i.every(Number.isFinite))return null;const s=e=>{if(!(Number(e.cm)>0))return!1;const s=Nm(i,e.a,e.b),n=zm(e.a,e.b),o=Number(t.length)/2;return s>=-Mm&&s<=1+Mm&&Om(i,e.a,e.b)<=.02*Th&&Rl(e.a,e.b,Number(t.angle))&&Number.isFinite(o)&&o>=0&&s*n-o>=-Mm&&s*n+o<=n+Mm},n="wall"===t.host?.kind?e.find(e=>e.id===t.host.id):null,o=n&&s(n)?[n]:e.filter(s);if(1!==o.length)return null;const a=o[0];return{kind:"wall",id:a.id,t:Math.max(0,Math.min(1,Nm(i,a.a,a.b)))}},Jm=(t,e)=>{const i=[Number(t.x),Number(t.y)];if(!i.every(Number.isFinite))return null;const s=Number(t.length)/2,n=e.filter(e=>{if(!(Number(e.cm)>0))return!1;const n=Nm(i,e.a,e.b),o=zm(e.a,e.b);return n>=-Mm&&n<=1+Mm&&Om(i,e.a,e.b)<=.02*Th&&Rl(e.a,e.b,Number(t.angle))&&Number.isFinite(s)&&s>=0&&n*o-s>=-Mm&&n*o+s<=o+Mm}),o=(e=>{if(!e.length)return null;const s="wall"===t.host?.kind?e.find(e=>e.id===t.host.id):null;return s||[...e].sort((t,e)=>Om(i,t.a,t.b)-Om(i,e.a,e.b)||Number(e.cm)-Number(t.cm)||(t.ide.id?1:0))[0]})(n);return o?{kind:"wall",id:o.id,t:Math.max(0,Math.min(1,Nm(i,o.a,o.b)))}:null},Xm=(t,e,i)=>{const s=Um(t),{atoms:n,rooms:o}=Vm(t,s);Km(t,n,s,e,i);const a=n.map(e=>{const i=e.id?s.get(e.id):void 0,n=((t,e,i)=>{if(e.zeroWall)return 0;const s=Array.isArray(t.walls)?t.walls:[],n=wl(e.a,e.b,Th),o=s.filter(t=>Number(t.cm)>0&&(!(t.key!==n&&!e.parentKeys.has(t.key))||!(!Pm(t.a)||!Pm(t.b))&&Lm(e.a,e.b,t.a,t.b)>=zm(e.a,e.b)-Mm)).map(t=>Math.max(1,Math.min(100,Number(t.cm))));if(new Set(o.map(t=>t.toFixed(9))).size>1)throw new Cm("thickness-conflict",e.key);if(o.length)return o[0];const a=Pl(s,e.a,e.b,Th,1);return a>0?a:Number(i?.cm)>0?Number(i.cm):0})(t,e,i);return{...i||{},id:e.id,a:[...e.a],b:[...e.b],cm:n}}),r=new Map(n.map(t=>[t.key,t.id]));for(const t of o)t.wall_ids=t.wall_ids.map(t=>r.get(t));t.rooms=o,t.wall_segments=a,t.walls=a.filter(t=>t.cm>0).map(t=>({key:wl(t.a,t.b,Th),cm:t.cm,a:[...t.a],b:[...t.b]})),t.walls.length||delete t.walls,delete t.open_spans;for(const e of t.rooms)delete e.open_to;return((t,e)=>{const i=new Set;for(const e of[t.rooms,t.openings,t.decor,t.room_drafts,t.partitions,t.wall_columns,t.wall_segments])for(const t of Array.isArray(e)?e:[])"string"==typeof t?.id&&t.id&&i.add(t.id);for(const s of Array.isArray(t.room_drafts)?t.room_drafts:[]){const n=Array.isArray(s.segments)?s.segments:[];for(let o=0;o{const s=Array.isArray(t.openings)?t.openings:[];for(const t of s){if("partition"===t.host?.kind)continue;if(!t.host&&!i){const i=Ym(t,e);i&&(t.host=i);continue}const s=Ym(t,e)??(i?Jm(t,e):null);if(s)t.host=s;else{if(!i)throw new Cm("opening-host",t.id);delete t.host}}})(t,a,e),a.reduce((t,e)=>t+(s.has(e.id)?0:1),0)};function Zm(t,e={}){const i=JSON.stringify(t),s=Dm(t);rl(s);let n=0;const o=Number(s?.model_version||0)<9;for(const t of Array.isArray(s?.spaces)?s.spaces:[]){const i=e.lineageSpaceId===String(t?.id||"")?e.lineageHints:void 0;n+=Xm(t,o,i)}return s.model_version=9,rl(s),{config:s,changed:i!==JSON.stringify(s),migratedSegments:n}}const Qm=t=>!!t&&"object"==typeof t&&!Array.isArray(t);function tg(t,e){const i=(t,e)=>{if(Array.isArray(t)&&Array.isArray(e)){const s=new Map;for(const e of t)Qm(e)&&"string"==typeof e.id&&e.id&&s.set(e.id,e);const n=e.map((e,n)=>{if(Qm(e)&&"string"==typeof e.id&&e.id){const t=s.get(e.id);return t?i(t,e):Dm(e)}return n[e,e in t?i(t[e],s):Dm(s)]);for(const e of Object.keys(t))delete t[e];for(const[e,i]of s)t[e]=i;return t}return Dm(e)};return i(t,e)}const eg=(t,e)=>Object.prototype.hasOwnProperty.call(t,e),ig=(t,e,i)=>Math.min(i,Math.max(e,t)),sg=t=>Sh({spaces:[t]})[0],ng=(t,e,i)=>{const s=i>0?i:1,n=t=>`${(t[0]/s).toFixed(12)},${(t[1]/s).toFixed(12)}`,o=n(t),a=n(e);return o0?a:1,l=Math.max(s*r*.02,1e-9),c=[];for(const e of t||[])for(const t of hi(e)||[])c.push([t[0],t[1]]);const h=[];for(const t of i||[])Array.isArray(t)&&t.length>=4&&t.slice(0,4).every(Number.isFinite)&&h.push([t[0],t[1]],[t[2],t[3]]);const d=(t,e)=>e.some(e=>Math.hypot(t[0]-e[0],t[1]-e[1])<=2*l),p=new Map;for(const a of t||[]){if(!a?.id)continue;const u=hc(t,a.id,e,i,s,n,o,r);if(u)for(let t=0;t0&&_>0&&a===m&&_!==a))continue;const g=u.poly[s],f=u.poly[(s+1)%u.poly.length],v=Math.hypot(f[0]-g[0],f[1]-g[1]);if(!(v>l&&v<.5*o-1e-9*o))continue;if(d(g,h)||d(f,h))continue;if(d(g,c)&&d(f,c))continue;const y=ng(g,f,r),b=p.get(y);b?b.targets.add(a):p.set(y,{a:[g[0],g[1]],b:[f[0],f[1]],targets:new Set([a])})}}}let u=e.slice();const _=(t,e)=>Math.hypot(t[0]-e[0],t[1]-e[1])<=2*l,m=(t,e)=>{if(!Array.isArray(t.a)||!Array.isArray(t.b)||t.a.length<2||t.b.length<2)return!1;const i=[Number(t.a[0])*r,Number(t.a[1])*r],s=[Number(t.b[0])*r,Number(t.b[1])*r];return!![...i,...s].every(Number.isFinite)&&(_(i,e.a)&&_(s,e.b)||_(i,e.b)&&_(s,e.a))};for(const t of[...p.values()].filter(t=>1===t.targets.size).sort((t,e)=>ng(t.a,t.b,r).localeCompare(ng(e.a,e.b,r)))){const e=[...t.targets][0],i=u.filter(e=>m(e,t));if(new Set(i.map(t=>t.cm)).size>1)continue;let n=!1;u=u.map(i=>m(i,t)?(n=!0,i.cm===e?i:{...i,cm:e}):i),n||(u=Fl(u,t.a,t.b,e,s,r))}return u}const ag=t=>{const e=[];for(const i of t||[]){const t=hi(i);if(t?.length)for(let i=0;i"string"==typeof t?.id?t.id:"").filter(Boolean),h=new Set(c),d=new Map;for(const t of c){const e=$m("space",t);e.layers>0&&xm("space",e.root)&&Sm(d,e.root,t)}const p=new Map,u=new Map,_=new Map,m=new Map;for(const t of r){const e="string"==typeof t?.id?t.id:"";if(!e)continue;const i=new Map;for(const s of Array.isArray(t.rooms)?t.rooms:[]){const t="string"==typeof s?.id?s.id:"";if(!t)continue;const n=$m("room",t);n.layers>0&&xm("room",n.root)&&Sm(i,n.root,t),u.has(t)||u.set(t,e),_.has(t)||_.set(t,String(s.name||""));const o="string"==typeof s.area?s.area:"";if(o){const i=m.get(o)||[];i.push({spaceId:e,roomId:t}),m.set(o,i)}}p.set(e,i)}const g=new Set(u.keys()),f=new Map,v=new Map;for(const t of l)"string"==typeof t?.id&&t.id&&(!0===t.removed?v.set(t.id,t):f.set(t.id,t));const y={spaceRefsRemapped:0,roomRefsRemapped:0,positionsRemapped:0,markersDetached:0,positionsUnresolved:0,nestedRefsUnresolved:0,deadSpaceIds:[],orphanRoomLabelsRemoved:0,orphanDevicePositionsRemoved:0,orphanGroupPositionsRemoved:0,liveMissingPositionsRemoved:0,removedPositions:[],liveMissingPositions:[],unverifiedPositions:[]},b=new Set,w=t=>h.has(t)?null:(()=>{const e=$m("space",t).root;if(!xm("space",e))return null;const i=d.get(e)||[];return 1===i.length?i[0]:null})(),k=(t,e)=>{const i=$m("room",t).root;if(!xm("room",i))return null;const s=p.get(e)?.get(i)||[];return 1===s.length?s[0]:null},x=t=>{const e=i.effectiveAreaByMarker?.[t]||"",s=e&&m.get(e)||[];return 1===s.length?s[0]:null},$=(t,e,i)=>{if("string"==typeof t.room_id&&t.room_id&&!g.has(t.room_id)){const s=e?k(t.room_id,e):null;s?(t.room_id=s,y.roomRefsRemapped++):i?(t.room_id=i.roomId,y.roomRefsRemapped++):!0!==t.removed&&delete t.room_id}const s=t.vacuum?.segment_map;if(s&&"object"==typeof s&&!Array.isArray(s))for(const t of Object.keys(s)){const i=s[t];if("string"!=typeof i||!i||g.has(i))continue;const n=e?k(i,e):null;n?(s[t]=n,y.roomRefsRemapped++):y.nestedRefsUnresolved++}};for(const t of l){const e="string"==typeof t?.id?t.id:"";if(!e)continue;const i="string"==typeof t.space?t.space:"",s=i&&!h.has(i),o=n[e],a="string"==typeof o?.s?o.s:"",r=a&&!h.has(a),l=!0===t.removed;let c=i&&h.has(i)?i:null,d=null,p=!1;if(s){const s=w(i);s?(t.space=s,c=s,p=!0,y.spaceRefsRemapped++):l||"virtual"===t.binding?l||(delete t.space,c=null,y.markersDetached++):(d=x(e),d?(t.space=d.spaceId,c=d.spaceId,y.spaceRefsRemapped++):(delete t.space,c=null,y.markersDetached++))}l&&!p||$(t,c,d),r&&p&&a===i&&c&&(n[e]={...o,s:c},y.positionsRemapped++,b.add(e))}for(const t of Object.keys(n)){if(b.has(t))continue;const e=n[t],i="string"==typeof e?.s?e.s:"";if(!i||h.has(i))continue;const s=w(i);if(s){if(t.startsWith("rl_")){const i=t.slice(3),o=k(i,s);if(o){const i=`rl_${o}`;km(n,i)||(n[i]={...e,s:s}),delete n[t],y.roomRefsRemapped++,y.positionsRemapped++;continue}}n[t]={...e,s:s},y.positionsRemapped++}}const S=i.ownerRoster,M=!0===S?.authoritative,C=new Set(S?.deviceIds||[]),D=new Set(S?.entityIds||[]),P=new Set(Array.isArray(s.settings?.known_devices)?s.settings.known_devices.filter(t=>"string"==typeof t):[]),T=(t,e="")=>{const i=String(S?.names?.[t]||e||"").trim();return i&&i!==t?i:""},R=(t,e,i,s="",n)=>({id:t,spaceId:e,kind:i,name:T(t,s),...n?{reason:n}:{}}),I=t=>{"room_label"===t?y.orphanRoomLabelsRemoved++:"group"===t?y.orphanGroupPositionsRemoved++:y.orphanDevicePositionsRemoved++},A=new Set;for(const[t,e]of Object.entries(n)){const s="string"==typeof e?.s?e.s:"";if(!s||h.has(s))continue;let o,a;const r=f.get(t),l=v.get(t);if(r)o=R(t,s,"device",String(r.name||"")),a="live";else if(l)o=R(t,s,"device",String(l.name||"")),a="absent";else if(t.startsWith("rl_")){const e=t.slice(3);o=R(t,s,"room_label",_.get(e)||""),a=g.has(e)?"live":"absent"}else if(t.startsWith("lg_")){const e=t.slice(3);o=R(t,s,"group"),a=D.has(e)?"live":M?"absent":"unverified","unverified"===a&&(o.reason="registry_unavailable")}else C.has(t)?(o=R(t,s,"device"),a="live"):P.has(t)?(o=R(t,s,"device"),a=M?"absent":"unverified","unverified"===a&&(o.reason="registry_unavailable")):(o=R(t,s,"unknown","","unknown_owner"),a="unverified");if("absent"!==a){if("live"===a){if(y.liveMissingPositions.push(o),!0===i.removeLiveMissingPositions){delete n[t],y.liveMissingPositionsRemoved++,I(o.kind),y.removedPositions.push(o);continue}}else y.unverifiedPositions.push(o);y.positionsUnresolved++,A.add(s)}else delete n[t],I(o.kind),y.removedPositions.push(o)}return y.deadSpaceIds=[...A].sort((t,e)=>t.localeCompare(e)),{config:s,layout:n,report:y,changed:JSON.stringify(s)!==o||JSON.stringify(n)!==a}}(t,e,i),a=o.config,r=nl(a,o.layout);rl(a),al(o.layout);const l=JSON.stringify(t||{}),c=JSON.stringify(e||{}),h=Number.isInteger(Number(a.model_version))?Number(a.model_version):0,d=(t=>{let e=0,i=0,s=0;for(const i of t.markers||[]){if("ripple"===i.display&&(i.display="icon_ripple",e++),Array.isArray(i.controls)){const t="string"==typeof i.binding&&i.binding.startsWith("entity:")?i.binding.slice(7):"",s=t?i.controls.filter(e=>e!==t):i.controls;JSON.stringify(s)!==JSON.stringify(i.controls)&&(i.controls=s.length?s:null,e++)}const t=i.vacuum;t&&eg(t,"trail")&&(["never","cleaning","always"].includes(t.trail_mode)||(t.trail_mode=!1===t.trail?"never":"cleaning"),delete t.trail,e++)}for(const n of t.spaces||[]){const t=n.settings;"glow"===t?.fill_mode&&("boolean"!=typeof t.glow_enabled&&(t.glow_enabled=!0),t.fill_mode="none",e++,i++);for(const t of n.rooms||[]){const i=t.settings;"glow"===i?.fill_mode&&("boolean"!=typeof i.glow&&(i.glow=!0),delete i.fill_mode,e++,s++)}if(eg(n,"segments")&&(delete n.segments,e++),eg(n,"plan_scale")){const t=Number(n.plan_scale);Number.isFinite(t)&&t>=wh&&t<=kh&&(eg(n,"plan_scale_x")||(n.plan_scale_x=t),eg(n,"plan_scale_y")||(n.plan_scale_y=t),delete n.plan_scale,e++)}const o=Number(n.cell_cm);eg(n,"cell_cm")&&(!Number.isFinite(o)||o<.1||o>1e3)&&(n.cell_cm=Number.isFinite(o)&&o>0?ig(o,.1,1e3):5,e++);const a=Number(n.cell_cm),r=Number.isFinite(a)&&a>0?a:5;for(const t of n.wall_columns||[])if("circle"===t.shape)eg(t,"angle")&&(delete t.angle,e++);else if("square"===t.shape&&eg(t,"angle")){const i=((Number(t.angle)||0)%90+90)%90;t.angle!==i&&(t.angle=i,e++)}for(const t of n.decor||[]){if(eg(t,"width")){const i=Number(t.width);(eg(t,"width_cm")||Number.isFinite(i))&&(eg(t,"width_cm")||(t.width_cm=Number(ig(i/Ph*r,.1,100).toFixed(6))),delete t.width,e++)}if("rect"!==t?.kind&&"ellipse"!==t?.kind||!0!==t.fill||(eg(t,"fill_color")||(t.fill_color=t.color||"#607d8b",e++),eg(t,"fill_opacity")||(t.fill_opacity=.25,e++)),"text"!==t?.kind)continue;void 0===t.size_cm?(t.size_cm=Number(ig(es*is(t)/Ph*r,.1,2e3).toFixed(6)),delete t.scale,delete t.size,e++):(eg(t,"scale")||eg(t,"size"))&&(delete t.scale,delete t.size,e++);let i=String(t.text??"");const s=[...i.matchAll(/\{([^{}\r\n]+)\}/g)].some(t=>!!Yi(t[1]));if(!(eg(t,"entity")||eg(t,"attr")||eg(t,"unit")))continue;const n=String(t.unit??"").trim(),o="state"===String(t.attr??"").trim().toLowerCase()?null:t.attr,a=s||n?"":Ji(t.entity,o);if(s||a){if(a){const e=i.indexOf("{}");i=e>=0?i.slice(0,e)+a+i.slice(e+2):`${i}${i?" ":""}${a}`,t.text=i}delete t.entity,delete t.attr,delete t.unit,e++}}}return{total:e,glowSpaces:i,glowRooms:s}})(a);let p=d.total;const u=(_=a.spaces||[],JSON.parse(JSON.stringify(_)));var _;const m=X_(a.spaces||[],o.layout);let g=0,f=0,v=0,y="";const b=m.spaces.map(t=>{const e=function(t){const e=JSON.parse(JSON.stringify(t||{}));let i=Array.isArray(e.rooms)?e.rooms:[];const s=new Map;for(const t of i){const e=hi(t);if(e)for(let t=0;tt.key.localeCompare(e.key))){let e=null;for(const s of $a(t,i)){const t=r.get(_a(s.from));if(t&&t!==_a(s.to))continue;const n=wa(i,s);if(ka(i,n,s)){e=s,i=n;break}}e?(r.set(_a(e.from),_a(e.to)),n++,a=Math.max(a,Math.hypot(e.to[0]-e.from[0],e.to[1]-e.from[1]))):o++}e.rooms=i;for(const t of e.room_drafts||[]){if(!Array.isArray(t?.points)||t.points.length<2)continue;const e=t.points.map(t=>[...t]),i=e.slice(0,-1).flatMap((i,s)=>{const n=e[s+1],o=pa(i,n);return o?[{key:`${String(t.id||"")}:${s}`,a:[...i],b:[...n],axis:o.axis}]:[]});let s=e;for(const t of i){let e=null;for(const i of $a(t,[{poly:s}])){const t=s.map(t=>ba(t,i)),n=t.length>=4&&ma(t[0],t[t.length-1]),o=n?t.slice(0,-1):t;if(n?va(o):ya(o)){e=i,s=t;break}}e?(n++,a=Math.max(a,Math.hypot(e.to[0]-e.from[0],e.to[1]-e.from[1]))):o++}t.points=s}for(const t of e.partitions||[]){if(!Array.isArray(t?.a)||!Array.isArray(t?.b))continue;const i=pa(t.a,t.b);if(!i)continue;const s={key:String(t.id||ga(t.a,t.b)),a:[...t.a],b:[...t.b],axis:i.axis};let r=null;for(const i of $a(s,[{poly:[t.a,t.b]}])){const s=ba(t.a,i),n=ba(t.b,i),o=Math.hypot(n[0]-s[0],n[1]-s[1]);if(!(o>0))continue;const a=(e.openings||[]).filter(e=>"partition"===e?.host?.kind&&e.host.id===t.id).every(t=>{const e=Number(t.host.t),i=Number(t.length);return Number.isFinite(e)&&e>=0&&e<=1&&Number.isFinite(i)&&i>0&&e*o-i/2>=-1e-12&&e*o+i/2<=o+1e-12});if(a){r=i,t.a=s,t.b=n;break}}r?(n++,a=Math.max(a,Math.hypot(r.to[0]-r.from[0],r.to[1]-r.from[1]))):o++}return{space:e,report:{wallsStraightened:n,wallsStraightenSkipped:o,maxStraightenShift:a},changed:n>0}}(t);g+=e.report.wallsStraightened,f+=e.report.wallsStraightenSkipped;const i=Number(t?.cell_cm)>0?Number(t.cell_cm):5,s=e.report.maxStraightenShift/Th*i;return s>v&&(v=s,y=String(t?.id||"")),e.space}),w=g?X_(b,m.layout):{...m,spaces:b};a.spaces=w.spaces;const k=g?{...m.report,moved:m.report.moved+w.report.moved,coordsCanonicalized:m.report.coordsCanonicalized+w.report.coordsCanonicalized,maxShift:Math.max(m.report.maxShift,w.report.maxShift),maxShiftCm:Math.max(m.report.maxShiftCm,w.report.maxShiftCm),maxSpace:w.report.maxShiftCm>m.report.maxShiftCm?w.report.maxSpace:m.report.maxSpace,rotated:m.report.rotated+w.report.rotated,removedDrafts:m.report.removedDrafts+w.report.removedDrafts}:{...m.report};let x=0,$=0,S=0,M=0,C=0,D=0,P=0,T=0;for(let t=0;t0===Number(t.cm)),walls:e.walls||[]}),o=sg(e),r=sg(i);if(!o||!r)continue;const l=ag(o.rooms),c=ag(r.rooms),h=.02*Ph,d=(e.wall_segments||[]).filter(t=>0===Number(t.cm)).map(t=>({...t,key:wl(t.a,t.b,Th),cm:0})),p=new Set(d.map(t=>t.key)),_=m_(e,o.rooms,yh,h);$+=_.length;for(const t of _){const e=[t[0]/yh,t[1]/yh],i=[t[2]/yh,t[3]/yh],s=wl(e,i,Th);p.has(s)||(p.add(s),d.push({key:s,a:e,b:i,cm:0}))}const m=d.length,g=Al(d,l,c,Th,yh),f=(t,e,i)=>{const s=i[0]-e[0],n=i[1]-e[1],o=s*s+n*n;if(!(o>0))return Math.hypot(t[0]-e[0],t[1]-e[1]);const a=Math.max(0,Math.min(1,((t[0]-e[0])*s+(t[1]-e[1])*n)/o));return Math.hypot(t[0]-(e[0]+s*a),t[1]-(e[1]+n*a))},v=g.filter(t=>{if(!Array.isArray(t.a)||!Array.isArray(t.b))return!1;const e=t.a.map(t=>t*yh),i=t.b.map(t=>t*yh);return c.some(([t,s])=>f(e,t,s)<=4*h&&f(i,t,s)<=4*h)});S+=Math.max(0,m-v.length);const y=(i.wall_segments||[]).filter(t=>Number(t.cm)>0);i.wall_segments=[...y,...v.map(({key:t,...e})=>e)];const b=v.map(t=>[t.a[0]*yh,t.a[1]*yh,t.b[0]*yh,t.b[1]*yh]),w=Array.isArray(e.walls)?e.walls.length:0;let k=Al(e.walls,l,c,Th,yh);k=og(r.rooms,k,b,Th,Number(i.cell_cm)>0?Number(i.cell_cm):5,Ph,yh),k=uc(r.rooms,k,b,Th,Number(i.cell_cm)>0?Number(i.cell_cm):5,Ph,yh),k=Tl(k,i.rooms||[],Th,1,b.map(t=>[t[0]/yh,t[1]/yh,t[2]/yh,t[3]/yh])),x+=Math.max(0,w-k.length),k.length?i.walls=k:delete i.walls;const R=nm(i.partitions||[],{pitch:Th,geometry:am(i)});R.merged&&(M+=R.merged,i.partitions=R.partitions,om(i.openings,i.partitions,R.openingMoves,{coordScale:yh,cellCm:Number(i.cell_cm)>0?Number(i.cell_cm):5,gridPitch:Ph}));const I=sg(i);if(I){const t=n(i,I,i.walls||[],b,{pitch:Th,cellCm:Number(i.cell_cm)>0?Number(i.cell_cm):5,gridPitch:Ph,coordScale:yh});t.partitionsReconciled&&(C+=t.partitionsReconciled,D+=t.openingsRehosted,t.partitions.length?i.partitions=t.partitions:delete i.partitions,t.openings.length?i.openings=t.openings:delete i.openings,t.walls.length?i.walls=t.walls:delete i.walls),t.removedDrafts&&(P+=t.removedDrafts,t.roomDrafts.length?i.room_drafts=t.roomDrafts:delete i.room_drafts)}JSON.stringify({zero:(i.wall_segments||[]).filter(t=>0===Number(t.cm)),walls:i.walls||[]})!==s&&T++}let R=0;h<=9&&(R=function(t){const e=Zm(t);return tg(t,e.config),{...e,config:t}}(a).migratedSegments);const I=rl(a),A=al(w.layout),z=JSON.stringify(I)!==l||JSON.stringify(A)!==c;h<9&&z&&(I.model_version=9);const F=JSON.stringify(I)!==l||JSON.stringify(A)!==c,E=Number.isInteger(Number(I.model_version))?Number(I.model_version):h,N=F?k:{...k,moved:0,coordsCanonicalized:0,maxShift:0,maxShiftCm:0,maxSpace:"",rotated:0,removedDrafts:0},O=F?o.report:{...o.report,spaceRefsRemapped:0,roomRefsRemapped:0,positionsRemapped:0,markersDetached:0,orphanRoomLabelsRemoved:0,orphanDevicePositionsRemoved:0,orphanGroupPositionsRemoved:0,liveMissingPositionsRemoved:0};return{config:I,layout:A,report:{...N,modelFrom:h,modelTo:E,migrated:F?p:0,glowSpacesMigrated:F?d.glowSpaces:0,glowRoomsMigrated:F?d.glowRooms:0,canonicalized:F?T:0,wallSegmentsMigrated:F?R:0,legacyZeroWallsMigrated:F?$:0,wallsMerged:F?x:0,spansMerged:F?S:0,partitionsMerged:F?M:0,partitionsReconciled:F?C:0,openingsRehosted:F?D:0,redundantDraftsRemoved:F?P:0,wallsStraightened:F?g:0,wallsStraightenSkipped:f,maxStraightenShiftCm:F?v:0,maxStraightenSpace:F?y:"",latticeCoordinatesCanonicalized:F?r.canonicalized:0,latticeCoordinatesFar:F?r.far:0,latticeMaxShift:F?r.maxShift:0,latticeMaxShiftCm:F?r.maxShiftCm:0,latticeSpaces:F?r.spaces:[],...O},changed:F}}function lg(t,e,i){const s=(t?.spaces||[]).find(t=>t?.id===i),n=new Set((s?.rooms||[]).map(t=>String(t?.id||"")).filter(Boolean)),o=[...new Set((t?.markers||[]).filter(t=>!0!==t?.removed&&"string"==typeof t?.id).filter(t=>t.space===i||"string"==typeof t.room_id&&n.has(t.room_id)||e?.[t.id]?.s===i).map(t=>t.id))].sort((t,e)=>t.localeCompare(e));return{markerIds:o,count:o.length}}function cg(t){return t instanceof Error?t.name||"Error":typeof t}function hg(t){return wd({id:t?.id??"",cell_cm:t?.cell_cm,rooms:t?.rooms||[],walls:t?.walls||[],wall_segments:t?.wall_segments||[],open_spans:t?.open_spans||[],openings:t?.openings||[],partitions:t?.partitions||[],room_drafts:t?.room_drafts||[],wall_columns:t?.wall_columns||[]})}function dg(t,e,i,s=Ph,n=1e3){return(Array.isArray(t?.openings)?t.openings:[]).flatMap(t=>{const o={...t,rx:Number(t.x)*n,ry:Number(t.y)*n,rlen:Number(t.length)*n};if(!t.host||"wall"===t.host.kind)return[o];const a=Sp(t,e.partitions,n,i,s);return a.resolved?[{...t,rx:a.resolved.center[0],ry:a.resolved.center[1],rlen:a.resolved.length,angle:a.resolved.angle,partitionHost:a.resolved}]:[]})}function pg(t,e=()=>!0){return t.flatMap(t=>t.host&&t.partitionHost&&e(t)?[Dp(t.partitionHost)]:[])}function ug(t,e,i,s,n,o,a=Ph,r=1e3){const l=dc(e.rooms,[...i],s,n,o,a,r);return t.flatMap(t=>{const e={x:t.rx,y:t.ry,angle:Number(t.angle)||0,length:t.rlen};return t.host&&"wall"!==t.host.kind?t.partitionHost&&Rp(t.partitionHost,l,2e-4*a)?[e]:[]:[e]})}function _g(t,e){const i=Th,s=Ph,n=yh,o=Number.isFinite(Number(e.cellCm))&&Number(e.cellCm)>0?Number(e.cellCm):5,a=Array.isArray(t?.walls)?t.walls:[],r=function(t,e,i=Ph,s=1e3){return _d(e.rooms,t?.open_spans,s,.02*i)}(t,e,s,n),l=function(t,e,i=Ph){if(!e.length)return[];const s=t.filter(t=>t?.id),n=.02*i,o=[];for(let t=0;t{const e=[(t[0]+t[2])/2,(t[1]+t[3])/2];return h.some(t=>Ls(e,t)<4*n)}).map(t=>[...t]);d.length&&o.push({a:a,b:r,segs:d})}return o}(e.rooms,r,s).flatMap(t=>t.segs),c=dg(t,e,o,s,n),h=pg(c),d=ih(e,o,s,2e-4*s,h).all;return{space:e,walls:a,openCuts:l,openings:c,roomOpenings:ug(c,e,a,l,i,o,s,n),partitionCuts:h,physicalBodies:d,wallKeyPitch:i,cellCm:o,gridPitch:s,coordScale:n}}function mg(t,e,i){const s="string"==typeof t?.title?t.title.trim():"",n=null==t?.id?"":String(t.id).trim();return{spaceId:n,displayName:s||n||i(e+1)}}function gg(t,e={}){const i=(e.fingerprint||wd)(t),s=Array.isArray(t?.spaces)?t.spaces:[],n=e.fallbackSpaceName||(t=>`Space ${t}`),o=e.prepareSpace||_g,a=e.wallPass||Rc,r=e.floorPass||Pc,l=[];for(let i=0;i0||d.physicalBodies.length>0;if(!d.space.rooms.length&&!p){l.push({...h,status:"not-applicable"});continue}let u=null;if(p){try{u=a(d.space.rooms,d.walls,d.openCuts,d.roomOpenings,d.wallKeyPitch,d.cellCm,d.gridPitch,d.coordScale,d.physicalBodies)}catch(t){l.push({...h,status:"failed",reason:"wall-exception",detail:cg(t)});continue}if(null==u){l.push({...h,status:"failed",reason:"wall-null"});continue}if("degraded-extra"===u.status){l.push({...h,status:"failed",reason:"wall-degraded-extra"});continue}if("failed-core"===u.status){l.push({...h,status:"failed",reason:"wall-failed-core"});continue}e.captureWallGeometry?.(d,u)}if(d.space.rooms.length&&null==u?.paperGeom){let t;try{t=r(d.space.rooms,d.walls,d.openCuts,d.wallKeyPitch,d.cellCm,d.gridPitch,d.coordScale)}catch(t){l.push({...h,status:"failed",reason:"floor-exception",detail:cg(t)});continue}if(null==t){l.push({...h,status:"failed",reason:"floor-null"});continue}}l.push({...h,status:"ok"})}const c=l.filter(t=>"failed"===t.status);return{fingerprint:i,spaces:l,failures:c,ok:0===c.length}}class fg{constructor(t=50){this._undo=[],this._redo=[],this._limit=Math.max(30,Math.floor(t))}get canUndo(){return this._undo.length>0}get canRedo(){return this._redo.length>0}get undoName(){return this._undo[this._undo.length-1]?.name??null}get redoName(){return this._redo[this._redo.length-1]?.name??null}get size(){return this._undo.length}push(t){this._undo.push(t),this._undo.length>this._limit&&this._undo.splice(0,this._undo.length-this._limit),this._redo=[]}undo(){const t=this._undo.pop()??null;return t&&this._redo.push(t),t}redo(){const t=this._redo.pop()??null;return t&&this._undo.push(t),t}clear(){this._undo=[],this._redo=[]}}const vg=new WeakMap;const yg=(t,e,i)=>255===t[i+3]&&e.every((e,s)=>Math.abs(t[i+s]-e)<=2);async function bg(t){const e=t.defaultView;if(!e||!e.CSS?.supports?.("mix-blend-mode","screen"))return!1;const i=[128,32,16],s=[16,64,128],n=[9,19,29],o=`\n \n \n \n \n \n `,a=e.URL.createObjectURL(new Blob([o],{type:"image/svg+xml"}));try{const o=await new Promise((t,i)=>{const s=new e.Image,n=e.setTimeout(()=>i(new Error("SVG blend probe timeout")),1e3);s.onload=()=>{e.clearTimeout(n),t(s)},s.onerror=()=>{e.clearTimeout(n),i(new Error("SVG blend probe failed"))},s.src=a}),r=t.createElement("canvas");r.width=4,r.height=1;const l=r.getContext("2d",{willReadFrequently:!0});if(!l)return!1;l.drawImage(o,0,0,4,1);const c=l.getImageData(0,0,4,1).data;return yg(c,i,0)&&yg(c,function(t,e){return[0,1,2].map(i=>Math.round(255-(255-t[i])*(255-e[i])/255))}(i,s),4)&&yg(c,s,8)&&yg(c,n,12)}catch{return!1}finally{e.URL.revokeObjectURL(a)}}const wg={now:()=>performance.now(),requestFrame:t=>requestAnimationFrame(t),cancelFrame:t=>cancelAnimationFrame(t)},kg=t=>Math.max(0,Math.min(1,t)),xg=(t,e,i)=>t+(e-t)*i,$g=(t,e,i)=>{const s=1-t;return 3*s*s*t*e+3*s*t*t*i+t*t*t};function Sg(t,e){return{centerX:t.x+t.w/2,centerY:t.y+t.h/2,pixelsPerUnit:e>0&&t.w>0?e/t.w:1,viewBox:{...t}}}function Mg(t,e,i){const s=Math.max(1e-9,t.pixelsPerUnit),n=Math.max(1e-9,e/s),o=Math.max(1e-9,i/s);return{x:t.centerX-n/2,y:t.centerY-o/2,w:n,h:o}}function Cg(t){const e=t.trim(),i=/^rgba?\(\s*([\d.]+)[, ]+([\d.]+)[, ]+([\d.]+)(?:\s*[,/]\s*([\d.]+))?\s*\)$/i.exec(e);if(i)return[Number(i[1]),Number(i[2]),Number(i[3]),null==i[4]?1:Number(i[4])];const s=/^#([0-9a-f]{6}|[0-9a-f]{8})$/i.exec(e)?.[1];return s?[parseInt(s.slice(0,2),16),parseInt(s.slice(2,4),16),parseInt(s.slice(4,6),16),8===s.length?parseInt(s.slice(6,8),16)/255:1]:null}function Dg(t,e,i){const s=Cg(t),n=Cg(e);if(!s||!n)return i<.5?t:e;const o=kg(i);return`rgba(${Math.round(xg(s[0],n[0],o))}, ${Math.round(xg(s[1],n[1],o))}, ${Math.round(xg(s[2],n[2],o))}, ${xg(s[3],n[3],o).toFixed(3)})`}function Pg(t,e,i){const s=(t=>{const e=kg(t);if(0===e||1===e)return e;let i=0,s=1,n=e;for(let t=0;t<12;t++)n=(i+s)/2,$g(n,.2,.2){const e=this._state;if(!e||e.token!==n)return;const i=kg((t-e.startedAt)/e.duration);e.presented=i>=1?e.to:Pg(e.from,e.to,i),e.phase=i>=1?"settling":"running",this._hooks.frame(e),i<1?this._raf=this._clock.requestFrame(a):(this._raf=0,this._hooks.settled(e),this._state?.token===n&&(this._state=null))};return this._raf=this._clock.requestFrame(a),n}cancel(t=!0){this._raf&&this._clock.cancelFrame(this._raf),this._raf=0;const e=this._state;this._state=null,this._token++,e&&t&&(e.phase="settling",e.presented=e.to,this._hooks.frame(e),this._hooks.settled(e))}dispose(){this.cancel(!1)}}const Rg="houseplan_card_labs_v1",Ig=Object.freeze([Object.freeze({id:"iso",issue:89,since:"1.62.0",expires:"1.65.0",summary:"Volumetric plan renderer"})]);function Ag(t){const e=/^(\d+)\.(\d+)\.(\d+)(?:-[0-9A-Za-z.-]+)?$/.exec(String(t||"").trim());if(!e)return null;const i=e.slice(1).map(Number);return i.every(t=>Number.isSafeInteger(t))?i:null}function zg(t,e){for(let i=0;i<3;i++)if(t[i]!==e[i])return t[i]t.split(",")).map(t=>t.trim()).filter(Boolean)}function Hg(t,e,i,s=Ig){const n=function(t,e=Ig){const i=Ag(t),s=new Map;if(!i||!Eg(e))return s;for(const t of e){const e=Ag(t.since),n=Ag(t.expires);zg(i,e)>=0&&zg(i,n)<0&&s.set(t.id,t)}return s}(i,s),o=new Set(Eg(s)?s.map(t=>t.id):[]),a=new Set(function(t){if(!t)return[];try{const e=JSON.parse(t);return Array.isArray(e)?e.filter(t=>"string"==typeof t):[]}catch{return[]}}(e).filter(t=>n.has(t)));let r=!1;const l=t=>{if("off"===t)return a.clear(),void(r=!0);const e=t.startsWith("-"),i=e?t.slice(1):t;o.has(i)&&(r=!0,e||!n.has(i)?a.delete(i):a.add(i))};for(const e of Lg(new URLSearchParams(String(t.search||"").replace(/^\?/,""))))l(e);for(const e of Lg(Ng(t.hash)))l(e);const c=Object.freeze([...a].sort());return{active:c,space:Og(t.hash),persist:r?JSON.stringify(c):void 0,knownUrlOperation:r}}let Bg={active:Object.freeze([]),space:""},qg="",Wg=!1,jg="";const Ug=new Set;function Gg(){if("undefined"==typeof window)return Bg;const t=Hg(window.location,function(){try{return window.localStorage.getItem(Rg)}catch{return null}}(),qg);void 0!==t.persist&&function(t){try{window.localStorage.setItem(Rg,t)}catch{}}(t.persist),Bg={active:t.active,space:t.space},window.__hpLabs=t.active;for(const t of Ug)t(Bg);return Bg}function Vg(){Gg()}function Kg(t){return qg=t,"undefined"==typeof window?Bg:(Wg||(Wg=!0,window.addEventListener("hashchange",Vg),window.addEventListener("popstate",Vg)),Gg())}const Yg=Object.freeze({rotDeg:0,tiltDeg:20,xyScale:1,zScale:1,origin:Object.freeze([500,500])});function Jg(t){return[t.rotDeg,t.tiltDeg,t.xyScale,t.zScale,t.origin[0],t.origin[1]].every(Number.isFinite)&&Math.abs(t.xyScale)>1e-12&&Math.abs(Math.cos(t.tiltDeg*Math.PI/180))>1e-12}function Xg(t,e,i=Yg){if(!(Jg(i)&&Number.isFinite(t[0])&&Number.isFinite(t[1])&&Number.isFinite(e)))throw new Error("invalid isometric projection input");const s=i.rotDeg*Math.PI/180,n=i.tiltDeg*Math.PI/180,o=t[0]-i.origin[0],a=t[1]-i.origin[1],r=(o*Math.cos(s)-a*Math.sin(s))*i.xyScale,l=(o*Math.sin(s)+a*Math.cos(s))*i.xyScale;return[i.origin[0]+r,i.origin[1]+l*Math.cos(n)-e*i.zScale*Math.sin(n)]}function Zg(t,e=Yg){if(!Jg(e)||!Number.isFinite(t[0])||!Number.isFinite(t[1]))throw new Error("invalid isometric projection input");const i=e.rotDeg*Math.PI/180,s=e.tiltDeg*Math.PI/180,n=(t[0]-e.origin[0])/e.xyScale,o=(t[1]-e.origin[1])/(e.xyScale*Math.cos(s));return[e.origin[0]+n*Math.cos(i)+o*Math.sin(i),e.origin[1]-n*Math.sin(i)+o*Math.cos(i)]}function Qg(t=Yg){return`matrix(${function(t=Yg){if(!Jg(t))throw new Error("invalid isometric camera");const e=t.rotDeg*Math.PI/180,i=t.tiltDeg*Math.PI/180,s=t.xyScale*Math.cos(e),n=-t.xyScale*Math.sin(e),o=t.xyScale*Math.sin(e)*Math.cos(i),a=t.xyScale*Math.cos(e)*Math.cos(i);return[s,o,n,a,t.origin[0]-s*t.origin[0]-n*t.origin[1],t.origin[1]-o*t.origin[0]-a*t.origin[1]]}(t).map(t=>Number(t.toFixed(12))).join(" ")})`}function tf(t,e=Yg){const{rect:i,wallHeight:s}=t,n=t.openingHeight??s,o=t.floorDepth??0;if(!(i.w>=0)||!(i.h>=0)||!Number.isFinite(s)||!Number.isFinite(n)||!Number.isFinite(o)||s<0||n<0||o<0)throw new Error("invalid isometric frame");const a=[[i.x,i.y],[i.x+i.w,i.y],[i.x+i.w,i.y+i.h],[i.x,i.y+i.h]],r=Math.max(s,n),l=a.flatMap(t=>[Xg(t,-o,e),Xg(t,r,e)]),c=l.map(t=>t[0]),h=l.map(t=>t[1]),d=Math.min(...c),p=Math.min(...h);return{x:d,y:p,w:Math.max(...c)-d,h:Math.max(...h)-p}}const ef=t=>`${Number(t[0].toFixed(4))} ${Number(t[1].toFixed(4))}`;function sf(t){let e=0;for(let i=0;iArray.isArray(t)&&Number.isFinite(t[0])&&Number.isFinite(t[1])).map(t=>[Number(t[0]),Number(t[1])]),i=e[e.length-1];return e.length>1&&e[0][0]===i[0]&&e[0][1]===i[1]&&e.pop(),e}(t);if(i.length<3)return[];const s=!e;return sf(i)>0===s?i:[...i].reverse()}function of(t,e,i){return t.length?`M ${t.map(t=>ef(Xg(t,i,e))).join(" L ")} Z`:""}function af(t,e,i){const s=e[1]-t[1],n=-(e[0]-t[0]),o=i.rotDeg*Math.PI/180;return s*Math.sin(o)+n*Math.cos(o)}function rf(t,e,i=Yg){if(!Number.isFinite(e)||e<0)throw new Error("invalid floor edge height");const s=(t||[]).map(t=>(t||[]).map((t,e)=>function(t,e){const i=nf(t,e);if(!i.length)return i;let s=0;for(let t=1;t0)).filter(t=>t.length>=3&&Math.abs(sf(t))>=1e-9)).filter(t=>t.length&&sf(t[0])>0);s.sort((t,e)=>{const i=t[0][0],s=e[0][0];return i[0]-s[0]||i[1]-s[1]||Math.abs(sf(e[0]))-Math.abs(sf(t[0]))});const n=[],o=[];let a=0;for(let t=0;tt.depth-e.depth||t.component-e.component||t.edge-e.edge),{footprintPath:n.join(" "),sides:o,componentCount:s.length,edgeCount:a}}function lf(t,e){return t^=Math.round(64*(Number.isFinite(e)?e:0)),Math.imul(t,16777619)>>>0}const cf=t=>t.every(Number.isFinite);function hf(t,e,i,s){const n=t[0]*i,o=t[1]*s,a=e*Math.PI/180;return[n*Math.cos(a)-o*Math.sin(a),n*Math.sin(a)+o*Math.cos(a)]}function df(t,e,i,s,n,o,a){const r=t.flipH?-1:1,l="gate"===t.type?1:t.flipV?-1:1,c=(t.type,t.flipV,t.angle,t.face,{ox:0,oy:0}),h=function(t,e){return[t[0]+e[0],t[1]+e[1]]}([t.x+c.ox,t.y+c.oy],hf(i,t.angle,r,l));return{leaf:e,hinge:h,closedVector:hf(s,t.angle,r,l),quarterVector:hf([-s[1],s[0]],t.angle,r,l),turnDeg:n,bottom:o,top:a}}const pf=t=>`${Number(t[0].toFixed(4))} ${Number(t[1].toFixed(4))}`;function uf(t,e,i=Yg){const s=Math.max(0,Math.min(1,Number.isFinite(e)?e:0));return t.leaves.map(e=>{const n=function(t,e){const i=t.turnDeg*e*Math.PI/180;return[t.hinge[0]+t.closedVector[0]*Math.cos(i)+t.quarterVector[0]*Math.sin(i),t.hinge[1]+t.closedVector[1]*Math.cos(i)+t.quarterVector[1]*Math.sin(i)]}(e,s),o=Xg(e.hinge,e.bottom,i),a=Xg(n,e.bottom,i),r=Xg(n,e.top,i),l=Xg(e.hinge,e.top,i);return{id:t.id,sourceIndex:t.sourceIndex,type:t.type,leaf:e.leaf,d:`M ${pf(o)} L ${pf(a)} L ${pf(r)} L ${pf(l)} Z`,shadowD:`M ${pf(Xg(e.hinge,0,i))} L ${pf(Xg(n,0,i))}`,depth:Math.max(o[1],a[1])}})}const _f={window:120,door:90,passage:90,gate:300};function mf(t){return _f[t]}function gf(t,e){const i=[t[0],t[1]],s=[e[0],e[1]];return function(t,e){return t[0]-e[0]||t[1]-e[1]}(i,s)<=0?{a:i,b:s}:{a:s,b:i}}function ff(t){const e=new Map;return t.forEach((t,i)=>{if(!t.kind||t.open)return;const s=gf(t.a,t.b);if(Math.hypot(s.b[0]-s.a[0],s.b[1]-s.a[1])<=1e-9)return;const n=function(t,e){const i=t=>(Math.abs(t)<=5e-10?0:Math.round(1e6*t)/1e6).toFixed(6);return`${i(t[0])},${i(t[1])}>${i(e[0])},${i(e[1])}`}(s.a,s.b),o=e.get(n);if(o)return o.physicalHalfWidth=Math.max(o.physicalHalfWidth,t.half||0),o.sourceOrder=Math.min(o.sourceOrder,i),void(t.partitionHost&&(o.partitionHost&&o.partitionHost.id!==t.partitionHost.id?o.ambiguousPartitionHost=!0:o.partitionHost=t.partitionHost));e.set(n,{segmentKey:n,a:s.a,b:s.b,physicalHalfWidth:Math.max(0,t.half||0),sourceOrder:i,...t.partitionHost?{partitionHost:t.partitionHost}:{}})}),[...e.values()]}function vf(t,e){if(Math.abs(t.distance-e.distance)>1e-9)return t.distance-e.distance;if(Math.abs(t.perpendicular-e.perpendicular)>1e-9)return t.perpendicular-e.perpendicular;return(t.target.segmentKeye.target.segmentKey?1:0)||t.target.sourceOrder-e.target.sourceOrder}function yf(t){const e=ff(t.intervals).map(e=>{const i=function(t,e){const i=e.b[0]-e.a[0],s=e.b[1]-e.a[1],n=Math.hypot(i,s),o=i/n,a=s/n,r=(t[0]-e.a[0])*o+(t[1]-e.a[1])*a,l=Math.max(0,Math.min(n,r)),c=e.a[0]+l*o,h=e.a[1]+l*a;return{along:l,length:n,x:c,y:h,distance:Math.hypot(t[0]-c,t[1]-h),perpendicular:Math.abs((t[0]-e.a[0])*a-(t[1]-e.a[1])*o)}}(t.pointer,e);return{target:e,...i,envelope:Math.max(t.baseTolerance,e.physicalHalfWidth+t.bodyPointerPadding)}}).filter(t=>t.distance<=t.envelope+1e-9).filter(e=>!function(t,e,i,s,n){const o=e.b[0]-e.a[0],a=e.b[1]-e.a[1],r=Math.hypot(o,a);if(!(r>1e-9))return!1;const l=o/r,c=a/r;for(const o of i){if(!o.open&&o.kind)continue;const i=gf(o.a,o.b),a=i.b[0]-i.a[0],r=i.b[1]-i.a[1],h=Math.hypot(a,r);if(!(h>1e-9))continue;const d=a/h,p=r/h;if(Math.abs(l*p-c*d)>1e-6)continue;if(Math.abs((i.a[0]-e.a[0])*c-(i.a[1]-e.a[1])*l)>n)continue;const u=(t[0]-i.a[0])*d+(t[1]-i.a[1])*p,_=1e-9;if(!(u<=_||u>=h-_)&&Math.abs((t[0]-i.a[0])*p-(t[1]-i.a[1])*d)<=s+1e-9)return!0}return!1}(t.pointer,e.target,t.intervals,e.envelope,Math.max(1e-9,Math.min(t.baseTolerance,.04*t.gridStep)))),i=e.filter(e=>!!e.target.partitionHost&&t.renderedLength+2*e.target.physicalHalfWidth>e.length+1e-9).sort(vf),s=e.filter(e=>!e.target.partitionHost||t.renderedLength+2*e.target.physicalHalfWidth<=e.length+1e-9).sort(vf);let n=s[0];if(!n)return{candidate:null,jambBlockedTarget:i[0]?.target||null};const o=s.filter(t=>Math.abs(t.distance-n.distance)<=1e-9&&Math.abs(t.perpendicular-n.perpendicular)<=1e-9),a=o.filter(t=>t.target.partitionHost);if(a.length){if(1!==new Set(a.map(t=>t.target.partitionHost.id)).size||a.some(t=>t.target.ambiguousPartitionHost))return{candidate:null,jambBlockedTarget:null};const t=a[0],e=t.target.b[0]-t.target.a[0],i=t.target.b[1]-t.target.a[1],s=Math.hypot(e,i),r=e/s,l=i/s,c=o.every(e=>{const i=e.target.b[0]-e.target.a[0],s=e.target.b[1]-e.target.a[1],n=Math.hypot(i,s),o=i/n,a=s/n,c=Math.abs(r*a-l*o)<=1e-6,h=Math.abs((e.target.a[0]-t.target.a[0])*l-(e.target.a[1]-t.target.a[1])*r);return c&&h<=1e-9});if(!c)return{candidate:null,jambBlockedTarget:null};n=t}if(n.target.ambiguousPartitionHost)return{candidate:null,jambBlockedTarget:null};const{target:r,length:l}=n,c=r.b[0]-r.a[0],h=r.b[1]-r.a[1],d=c/l,p=h/l,u=r.partitionHost?r.physicalHalfWidth:0,_=Math.min(Math.max(0,t.renderedLength)/2+u,l/2);let m=n.along;const g=Math.max(t.gridStep,1e-9),f=l/2;m=Math.abs(m-f)<=g/2?f:Math.round(m/g)*g,m=Math.max(_,Math.min(l-_,m));const v=r.a[0]+d*m,y=r.a[1]+p*m,b=Math.max(0,t.renderedLength)/2,w=m-b,k=m+b,x=Math.max(0,w),$=Math.max(0,l-k),S=[r.a[0]+d*(w-x/2),r.a[1]+p*(w-x/2)],M=[r.a[0]+d*(k+$/2),r.a[1]+p*(k+$/2)];let C=180*Math.atan2(h,c)/Math.PI;C>=90?C-=180:C<-90&&(C+=180);const D=Math.abs(m-f)<=1e-9;return{candidate:{presetRevision:t.preset.revision,geometryRevision:t.geometryRevision,pointer:[t.pointer[0],t.pointer[1]],type:t.preset.type,lengthCm:t.preset.lengthCm,flipH:t.preset.flipH,flipV:t.preset.flipV,x:v,y:y,angle:C,renderedLength:t.renderedLength,target:r,...r.partitionHost?{host:{...r.partitionHost,t:l>0?m/l:0}}:{},measure:{labels:[{distance:x,midpoint:S},{distance:$,midpoint:M}],guide:D?{x:v,y:y,angle:C}:null}},jambBlockedTarget:null}}function bf(t,e,i,s,n=1e-6){return t.presetRevision===i&&t.geometryRevision===s&&Math.hypot(t.pointer[0]-e[0],t.pointer[1]-e[1])<=n}const wf=(t,e)=>t[0]*e[1]-t[1]*e[0],kf=(t,e)=>t[0]*e[0]+t[1]*e[1],xf=(t,e)=>[t[0]-e[0],t[1]-e[1]],$f=(t,e,i)=>[t[0]+e[0]*i,t[1]+e[1]*i];function Sf(t,e,i){return Math.abs(wf(t,e))<=i}function Mf(t,e,i){return Math.abs(wf(xf(t,e),i))}function Cf(t,e,i,s,n){const o=e[0]-t[0],a=e[1]-t[1],r=Math.hypot(o,a);if(!(r>n&&i>0))return[];const l=[o/r,a/r];return function(t,e,i){const s=e.map(([e,i])=>[Math.max(0,Math.min(e,i)),Math.min(t,Math.max(e,i))]).filter(([t,e])=>e>t+i).sort((t,e)=>t[0]-e[0]||t[1]-e[1]),n=[];for(const t of s){const e=n[n.length-1];!e||t[0]>e[1]+i?n.push([...t]):e[1]=Math.max(e[1],t[1])}const o=[];let a=0;for(const[t,e]of n)t>a+i&&o.push([a,t]),a=Math.max(a,e);return t>a+i&&o.push([a,t]),o}(r,s.flatMap(e=>{const s=e.b[0]-e.a[0],o=e.b[1]-e.a[1],a=Math.hypot(s,o);if(!(a>n&&Sf(l,[s/a,o/a],1e-6)))return[];if(Mf(e.a,t,l)>1.1*Math.max(i,n)||Mf(e.b,t,l)>1.1*Math.max(i,n))return[];return[[kf(xf(e.a,t),l),kf(xf(e.b,t),l)]]}),n).flatMap(([e,s])=>{const n=Ol({a:$f(t,l,e),b:$f(t,l,s),halfDepth:i});return n?[n]:[]})}function Df(t){const e=t.coordScale??1,i=Math.max(t.epsilon??2e-4*t.gridPitch,1e-9),s=[];for(const i of t.rooms||[]){if(!i?.id)continue;const n=hc(t.rooms,i.id,t.walls,t.openCuts,t.pitch,t.cellCm,t.gridPitch,e);if(!n||n.poly.length<3)continue;const o=Zl(n.poly,n.offsets);!o||o.length<3||s.push({roomId:i.id,profile:n,inner:o})}s.sort((t,e)=>t.roomId.localeCompare(e.roomId));const n=(t.roomOpenings||[]).map(t=>{const e=t.angle*Math.PI/180,i=[Math.cos(e),Math.sin(e)],s=Math.max(0,t.length)/2;return{a:$f([t.x,t.y],i,-s),b:$f([t.x,t.y],i,s)}}),o=[];for(const s of zc(t.rooms,t.walls,t.openCuts,t.pitch,t.cellCm,t.gridPitch,e))for(const t of Cf(s.a,s.b,s.depthUnits/2,n,i))o.push({body:t});const a=new Map;for(const e of t.partitionCuts||[]){const t=a.get(e.hostId)||[];t.push(e),a.set(e.hostId,t)}for(const e of t.partitions||[]){const s=gl(e.cm,t.cellCm,t.gridPitch)/2;for(const t of Cf(e.a,e.b,s,a.get(e.id)||[],i))o.push({body:t,partitionId:e.id})}return{rooms:s,boundaries:o,epsilon:i}}function Pf(t,e,i,s){const n=t.profile.offsets[e];if(!(n>0))return null;const o=function(t,e){const i=t[e],s=t[(e+1)%t.length],n=s[0]-i[0],o=s[1]-i[1],a=Math.hypot(n,o)||1;return function(t){let e=0;for(let i=0;i=0?[-o/a,n/a]:[o/a,-n/a]}(t.profile.poly,e),a=$f(i.center,o,n),r=[];for(let e=0;es&&Sf(i.axis,[l[0]/c,l[1]/c],1e-6)))continue;if(Mf(n,a,i.axis)>s||Mf(o,a,i.axis)>s)continue;const h=kf(xf(n,a),i.axis),d=kf(xf(o,a),i.axis);r.push([Math.min(h,d),Math.max(h,d)])}const l=function(t,e){t.sort((t,e)=>t[0]-e[0]||t[1]-e[1]);const i=[];for(const s of t){const t=i[i.length-1];!t||s[0]>t[1]+e?i.push([...s]):t[1]=Math.max(t[1],s[1])}return i}(r,s).find(([t,e])=>t<=s&&e>=-s);if(!l)return null;const[c,h]=l,d=$f(a,i.axis,-i.half),p=$f(a,i.axis,i.half),u=Math.max(0,-i.half-c),_=Math.max(0,h-i.half),m=u>0?$f(a,i.axis,c):d,g=_>0?$f(a,i.axis,h):p,f=kf(o,i.normal)>=0?1:-1,v=(e,s,n)=>({from:e,to:s,label:[(e[0]+s[0])/2,(e[1]+s[1])/2],axis:i.axis,labelNormal:o,distance:n,roomId:t.roomId,roomSide:f,source:"room-face"});return{left:v(d,m,u),right:v(p,g,_)}}function Tf(t){const e=$f(t.center,t.axis,-t.half),i=$f(t.center,t.axis,t.half),s=$f(t.center,t.axis,Math.min(-t.half,t.targetLo)),n=$f(t.center,t.axis,Math.max(t.half,t.targetHi)),o=(e,i)=>({from:e,to:i,label:[(e[0]+i[0])/2,(e[1]+i[1])/2],axis:t.axis,labelNormal:t.normal,distance:Math.hypot(i[0]-e[0],i[1]-e[1]),source:"host-end"});return[o(e,s),o(i,n)]}function Rf(t,e,i,s){const n=xf(i,e),o=kf(n,n);if(!(o>s*s))return Math.hypot(...xf(t,e))<=s;const a=kf(xf(t,e),n)/o;if(a<-s||a>1+s)return!1;const r=$f(e,n,Math.max(0,Math.min(1,a)));return Math.hypot(...xf(t,r))<=s}function If(t,e,i){let s=!1;for(let n=0,o=e.length-1;nt[1]!=c>t[1]&&t[0]<(l-a)*(t[1]-r)/(c-r)+a&&(s=!s)}return s}function Af(t,e,i,s,n,o){const a=xf(s,i),r=wf(e,a);if(Math.abs(r)<=o)return null;const l=xf(i,t),c=wf(l,a)/r,h=wf(l,e)/r;return c<-o||c>n+o||h<-o||h>1+o?null:Math.max(0,Math.min(n,c))}function zf(t,e,i){const s=Tf(i),n="partition"===t.host?.kind?t.host.id:void 0;return[{base:s[0],direction:[-i.axis[0],-i.axis[1]]},{base:s[1],direction:i.axis}].map(({base:t,direction:i})=>{const s=t.distance,o=function(t,e,i,s,n,o){let a=null;for(const r of s)if(!n||r.partitionId!==n){if(If(t,r.body,o))return 0;for(let s=0;skf(xf(t,n),i));return{center:n,axis:i,normal:s,half:Math.max(0,t.renderedLength)/2,targetLo:Math.min(...o),targetHi:Math.max(...o)}}(t),s=e.rooms.flatMap(t=>{const s=function(t,e,i){const{profile:s}=t;let n=null;for(let t=0;t0))continue;const o=s.poly[t],a=s.poly[(t+1)%s.poly.length],r=xf(a,o),l=Math.hypot(r[0],r[1]);if(!(l>i&&Sf(e.axis,[r[0]/l,r[1]/l],1e-6)))continue;if(Mf(o,e.center,e.axis)>i||Mf(a,e.center,e.axis)>i)continue;const c=kf(xf(o,e.center),e.axis),h=kf(xf(a,e.center),e.axis),d=Math.min(c,h),p=Math.max(c,h);if(d>-e.half+i||p0?d:p<0?-p:0);(!n||u2)return Tf(i);if(s.length){const t=s.map(({room:t,edge:s})=>Pf(t,s,i,e.epsilon));if(t.some(t=>!t))return Tf(i);const n=t;return[...n.map(t=>t.left),...n.map(t=>t.right)]}return zf(t,e,i)}function Ef(t){return!(!t.canEdit||t.kiosk||t.fixedFloor)&&("view"!==t.mode&&("mouse"===t.pointerType&&t.spaceCount>1))}const Nf="1.68.1",Of={badge:"display.badge",icon_ripple:"display.icon_ripple",value:"display.value",static_icon:"display.static_icon"},Lf={badge:"marker.display_hint_badge",icon_ripple:"marker.display_hint_icon_ripple",value:"marker.display_hint_value",static_icon:"marker.display_hint_static_icon"},Hf=2e3,Bf=1e3,qf=1500,Wf=t=>{const e=String(t??"").trim().replace(",",".");if(!/^[+-]?(?:\d+(?:\.\d*)?|\.\d+)$/.test(e))return null;const i=Number(e);return Number.isFinite(i)?i:null},jf=(t,e)=>{if(!t.has(e))return{hit:!1};const i=t.get(e);return t.delete(e),t.set(e,i),{hit:!0,value:i}},Uf=(t,e,i,s)=>{for(t.delete(e),t.set(e,i);t.size>s;){const e=t.keys().next().value;if(void 0===e)break;t.delete(e)}},Gf=new Map;let Vf=0;const Kf=t=>`${window.innerWidth}x${window.innerHeight}|${location.pathname}|${JSON.stringify(t??{})}`;let Yf=1e4;const Jf="houseplan_card_layout_v1",Xf="houseplan_card_cfg_v1",Zf="houseplan_card_zoom_v1",Qf="houseplan_card_nav_v1",tv="houseplan_card_kiosk_v1",ev="houseplan_card_view_v1",iv="hp-dialog, hp-help, hp-color-opacity, hp-device-preview",sv=1e3,nv=[[0,1],[45,.88],[70,.62],[86,.32],[100,0]],ov=(t,e)=>{const i=Math.min(t.x,e.x),s=Math.min(t.y,e.y);return{x:i,y:s,w:Math.max(t.x+t.w,e.x+e.w)-i,h:Math.max(t.y+t.h,e.y+e.h)-s}},av=new Set(["select","draw","column","merge","split","resize","opening","wallthick","delroom"]),rv=2e3,lv=(t,e,i)=>{const s=new Event(e,{bubbles:!0,composed:!0});s.detail=i??{},t.dispatchEvent(s)},cv=t=>{history.pushState(null,"",t),lv(window,"location-changed",{replace:!1})},hv=(t,e)=>{let i,s=null;const n=(...n)=>{clearTimeout(i),s=n,i=window.setTimeout(()=>{i=void 0;const e=s;s=null,e&&t(...e)},e)};return n.flush=()=>{if(void 0===i)return;clearTimeout(i),i=void 0;const e=s;s=null,e&&t(...e)},n.cancel=()=>{clearTimeout(i),i=void 0,s=null},n.pending=()=>void 0!==i,n},dv=t=>{try{t.target?.setPointerCapture?.(t.pointerId)}catch{}};class pv extends ht{constructor(){super(...arguments),this._space="f1",this._layout={},this._serverStorage=!1,this._loadOk=!1,this._serverCanWrite=null,this._loading=!1,this._loadTries=0,this._serverCfg=null,this._cfgRev=0,this._cfgContentFingerprint="",this._unsubCfg=null,this._unsubLayout=null,this._unsubVirtual=null,this._liveSyncAttempt=null,this._liveSyncGeneration=0,this._liveSyncConnection=null,this._layoutRev=0,this._layoutContentFingerprint="",this._virtualLights=mn(null),this._canOptimizeUndo=!1,this._undoKind=null,this._devices=[],this._regSignature="",this._defPos={},this._newSyncKey="",this._tip=null,this._hoverRoom=null,this._pointerModality=new N_(this,()=>this._syncPointerHoverTargets()),this._devicePressAnimations=new Map,this._selId=null,this._toast="",this._mode="view",this._pendingNavMode=null,this._decorTool="select",this._decorStyle={...Rr},this._decorDraft=null,this._decorMove=null,this._decorSel=null,this._decorEraseConfirm=null,this._decorTextDialog=null,this._decorShapeDialog=null,this._backdropDialog=null,this._decorTextSelection={start:0,end:0},this._furnPalette=null,this._dtBox=null,this._dtDrag=null,this._bdDrag=null,this._slide="",this._reducedMotion=!1,this._onMotionChange=t=>{this._reducedMotion=t.matches,this._cancelDevicePressFeedback(),t.matches&&this._modeTransitionPreparing?this._modeTransitionForceAtomic=!0:t.matches&&this._modeTransition.active&&this._cancelModeTransition(!0),this.requestUpdate()},this._editorChromeMode="plan",this._modeTransitionVisual=null,this._modeTransitionPreparing=!1,this._modeTransitionForceAtomic=!1,this._modeTransitionRequest=0,this._modeTransitionTargetZoom=1,this._modeTransitionEditorCamera=null,this._modeTransition=new Tg({frame:t=>this._applyModeTransitionFrame(t),settled:t=>this._settleModeTransition(t)}),this._editorSecondary=new W_({root:()=>this.renderRoot,requestUpdate:()=>this.requestUpdate(),updateComplete:()=>this.updateComplete,clearTip:()=>{this._tip=null}}),this._editorSecondaryCopy={groupActive:(t,e)=>this._t("editor.group_active",{group:t,item:e}),openGroup:t=>this._t("editor.open_group",{group:t}),disabledAction:(t,e)=>this._t("editor.disabled_action",{action:t,reason:e})},this._tool="draw",this._geometryHistory=new fg(50),this._wallDialog=null,this._drawWallField=null,this._activeDraftId=null,this._resumeDraftBySpace={},this._physicalSel=null,this._physicalDialog=null,this._partitionDeleteDialog=null,this._roomDeleteDialog=null,this._physicalDrag=null,this._physicalRotate=null,this._physicalLastTap=null,this._physicalPickCycle=null,this._wallUnionCacheValue=null,this._wallUnionPool=new Map,this._isoGeometryCache=new Map,this._isoFallback=new Set,this._openingTunnelCache=null,this._openingWallIndexCache=new Map,this._openingPlacementIntervalsCache=null,this._openingDimensionContextCache=null,this._planSnapGeometryCache=null,this._planStructuralGeometryCache=null,this._hiddenWallDiagnosticCache=null,this._physicalBodiesCache=null,this._lightPhysicalBodiesCache=null,this._cleanFloorCache=new Map,this._innerContourCache=new Map,this._glowClipCache=new Map,this._glowGeometryWarnings=new Set,this._lightBarrierCache=null,this._lightBarrierPool=new Map,this._glowFeatherUnits=null,this._glowRenderedSources=new Map,this._glowLastAppearance=new Map,this._glowEnteringSources=new Set,this._glowEnterRafs=new Map,this._glowFadeTimers=new Map,this._glowFeatherSuspendUntil=0,this._glowFeatherResumeTimer=0,this._glowSourceSeq=0,this._glowScreenBlend=!1,this._duplicateColumnId=null,this._duplicateColumnTimer=0,this._rszSel=null,this._rszDrag=null,this._rszEligibilityCache=null,this._rszPreview=null,this._rszLive=null,this._path=[],this._cursorPt=null,this._planSnapHover=null,this._mergeSel=null,this._openingPreset=null,this._openingRebindId=null,this._openingPresetRevision=0,this._openingHoverCandidate=null,this._openingJambBlockCm=null,this._openingDialog=null,this._openingInfo=null,this._opDrag=null,this._opMeasure=null,this._mergeDialog=null,this._splitSel=null,this._pendingSplit=null,this._wallFaceBatch=null,this._wallRepairDiagnostic=null,this._wallFaceGraphCache=[],this._areaSel="",this._nameSel="",this._roomDialog=!1,this._roomEditId=null,this._roomFill="",this._roomCustomFill=null,this._roomTempSrc="",this._roomHumSrc="",this._roomSrcOpen=null,this._roomSrcFilter="",this._roomNameScale=1,this._roomLabelScale=1,this._zoom=1,this._view=null,this._zoomBySpace={},this._viewModeSnap=null,this._pointers=new Map,this._panStart=null,this._panLock=null,this._pinchStart=null,this._suppressClick=!1,this._touchContacts=new Map,this._touchSequenceMultitouch=!1,this._touchClickBlockUntil=0,this._connectedPath="",this._routeDepartureHandled=!1,this._onLocationChanged=()=>{this._connectedPath&&location.pathname!==this._connectedPath?this._leaveCardRoute():location.pathname===this._connectedPath&&(this._routeDepartureHandled=!1)},this._touchGestureGuard={capture:!0,handleEvent:t=>this._guardTouchGesture(t)},this._hdrH=118,this._booting=!0,this._bootFading=!1,this._bootSettling=!1,this._bootSettleRaf=0,this._bootLastH=-1,this._bootStart=0,this._bootLastChange=0,this._bootSoft=!1,this._tapConfirm=null,this._onboardingShown=!1,this._rulesDialog=null,this._preflightClipboardFallback=null,this._haIntegrationVersion=null,this._alignDialog=null,this._settingsDialog=null,this._backupExportDialog=null,this._backupImportDialog=null,this._sunRaysCache=null,this._dayCycleTimer=0,this._dayCycleClockKey="",this._compassDrag=!1,this._importDialog=null,this._importQueue=[],this._importTotal=0,this._rulesCompiledSrc="",this._infoCard=null,this._nativeMoreInfoEntity=null,this._markerDialog=null,this._spaceDialog=null,this._keyHandler=t=>this._onKey(t),this._warmVp=null,this._warmVpArmed=!1,this._warmLongReturn=!1,this._warmRevivePending=!1,this._warmGen=++Vf,this._warmKey=null,this._warmSlot=null,this._hashApplied=!1,this._navApplied=!1,this._labs={active:Object.freeze([]),space:""},this._viewPreference={},this._renderProjection="flat",this._kioskScale={icon:1,font:1},this._kioskDialog=!1,this._activityRt=new Map,this._vacRt=new Map,this._vacViewKey="",this._vacLastView=null,this._vacRaf=0,this._vacSrvTrails={},this._vacJumpOnce=!1,this._continuity=this._newContinuityController(),this._continuityHistory=[],this._continuityEpoch=0,this._continuityDataReady=!0,this._continuityPaintToken=-1,this._continuityDisposed=!1,this._renderSnapshotAt=Date.now(),this._hassSequence=0,this._visibleDeviceSnapshot=null,this._candidateDeviceSnapshot=null,this._stagedDeviceSnapshotToken=-1,this._capturedSnapshotSequence=-1,this._capturedSnapshotDevices=null,this._capturedSnapshotLayout=null,this._capturedSnapshotActivity="",this._capturedSnapshotConfigEpoch=-1,this._capturedSnapshotVirtual="",this._lastValidStageSize=null,this._pendingRefitSize=null,this._refitRaf=0,this._pageVisibility=t=>{if(this._continuity.visibility(t),this._dayCycleVisibility(t),"hidden"===t.kind)return this._clearTransientHover(!0),this._cancelDevicePressFeedback(),void(this._modeTransitionPreparing?this._modeTransitionForceAtomic=!0:this._cancelModeTransition(!0));if(this._vacJumpOnce=!0,!t.long){const t=Date.now();let e=!1;for(const i of this._activityRt.values())!i.flashKind||(i.expiresAt||i.flashTs+I_)>t||(i.flashTs=0,i.flashKind=null,i.expiresAt=0,e=!0);return void(e&&this.requestUpdate())}Date.now()-this._renderSnapshotAt>1e3&&this._continuity.note("device-snapshot-stale"),this._continuityDataReady=!1,this._continuityPaintToken=-1,this._resumeSettling=!0,this._loading?this.requestUpdate():this._loadFromServer()},this._resumeSettling=!1,this._viewportInvalidAt=0,this._vacFit=null,this._vacAllCamerasFor=null,this._vacAllCameraCache=null,this._vacCalConfirm=null,this._kioskDots=!1,this._cyclePausedUntil=0,this._swipeStart=null,this._tabDrag=null,this._tabDragRelease=null,this._tabSuppressClick=!1,this._tabOrderWarned=!1,this._lastTap=0,this._onLabsSnapshot=t=>{const e=this._effectiveProjection();this._labs=t;const i=this._effectiveProjection();this._convertProjectionView(e,i),this.requestUpdate()},this._onHashChange=()=>{if(this._hasFixedFloor)return;const t=this._hashSpace();if(t&&this._model.find(e=>e.id===t)&&t!==this._space){if(this._wallFaceBatch&&this._roomDialogCancel(),"plan"===this._mode&&"draw"===this._tool&&!this._finishWallChain())return;this._activeDraftId&&(this._resumeDraftBySpace[this._space]=this._activeDraftId),this._commitSpace(t),this._selId=null,this._path=[],this._clearPlanSnapHover(),this._clearOpeningPlacement(!0),this._tool="draw",this._activeDraftId=null,this._draftSegmentCms=[],this._closingWallCm=null,"plan"===this._mode&&"draw"===this._tool&&this._resumeLastDraft(),this._restoreZoom(),this.requestUpdate()}},this._drag=null,this._rlResize=null,this._holdFired=!1,this._retryContinuity=()=>{this._continuityDataReady=!1,this._continuityPaintToken=-1,this._continuity.retry(this._continuity.recoveryReason||"plan"),this._loading||this._loadFromServer()},this._cfgEpoch=0,this._modelCache=null,this._emptySpaceStateActive=!1,this._decorSnapCache=null,this._markerPreviewMemo=null,this._markerPreviewDevicesMemo=null,this._showHidden=!1,this._connHooked=null,this._connectionWasLost=!1,this._haRegistryConnection=null,this._haRegistryRev=-1,this._haBindingCacheKey="",this._planHassMemo=null,this._onHaRegistryUpdate=()=>{const t=An(this.hass);t.revision===this._haRegistryRev&&this._devices.length||(this._haRegistryRev=t.revision,this._planHassMemo=null,this._regSignature="",this._maybeRebuildDevices(),this.requestUpdate())},this._onConnReady=()=>{if(this._loadTries=0,clearTimeout(this._loadRetryTimer),this._loadRetryTimer=void 0,function(t){const e=Cn(t);e&&(Tn(t,e),Rn(t,e))}(this.hass),this._saveConfigDebounced.pending()&&this._saveConfigDebounced.flush(),this._cfgWriting)return clearTimeout(this._reloadRetry),void(this._reloadRetry=window.setTimeout(this._onConnReady,400));!this._connectionWasLost&&this._continuity.hasCompleteFrame?this._beginContinuityCandidate("connection-ready",!1,"plan"):(this._continuityDataReady=!1,this._continuityPaintToken=-1),this._loading||this._loadFromServer()},this._onConnLost=()=>{this._booting&&!this._continuity.hasCompleteFrame||(this._connectionWasLost=!0,this._continuityDataReady=!1,this._continuityPaintToken=-1,this._continuity.connectionLost())},this._signer=new $d(()=>this.requestUpdate()),this._dirtyPos=new Set,this._sentPos=new Map,this._persistLayout=hv(()=>{if(this._serverStorage){const t=[...this._dirtyPos];this._dirtyPos.clear();for(const e of t){const t=ol(this._layout[e]);t&&(this._layout={...this._layout,[e]:t},this._sentPos.set(e,t),this.hass.callWS({type:"houseplan/layout/update",device_id:e,pos:t}).then(t=>this._noteLayoutRev(t)).catch(t=>this._showToast(this._t("toast.pos_save_failed",{err:this._errText(t)}))).finally(()=>{this._sentPos.get(e)===t&&this._sentPos.delete(e)}))}this._cacheSnapshot()}else this._layout=al(Gr(this._layout)),localStorage.setItem(Jf,JSON.stringify(this._layout))},600),this._frame=null,this._showFar=!1,this._writesPending=0,this._writeChain=Promise.resolve(),this._pendingPhysicalWrites=new Map,this._undoGeometry=()=>{if(this._physicalDrag||this._physicalRotate)return void this._cancelPhysicalGesture();if(this._decorDraft)return this._decorDraft=null,void this.requestUpdate();if(this._decorMove||this._dtDrag||this._bdDrag)return void this._cancelDecorGesture();if(this._rszDrag)return void this._rszCancelDrag();const t=this._geometryHistory.undo();t&&(this._applyGeometryState(t.before,!0)?this._showToast(this._t("history.undone",{name:t.name})):this._geometryHistory.clear())},this._redoGeometry=()=>{if(this._physicalDrag||this._physicalRotate)return void this._cancelPhysicalGesture();if(this._decorDraft)return this._decorDraft=null,void this.requestUpdate();if(this._decorMove||this._dtDrag||this._bdDrag)return void this._cancelDecorGesture();if(this._rszDrag)return void this._rszCancelDrag();const t=this._geometryHistory.redo();t&&(this._applyGeometryState(t.after,!0)?this._showToast(this._t("history.redone",{name:t.name})):this._geometryHistory.clear())},this._saveConfigDebounced=hv(()=>{this._serverCfg&&this._writeConfig().catch(t=>{const e=!0===t?.physicalGeometryRolledBack;"geometry-unsafe"!==t?.code&&("wall_model_client_outdated"===t?.code?this._showToast(this._t("toast.wall_model_client_outdated")):"conflict"===t?.code?(this._showToast(this._t("toast.conflict")),e||(this._cancelPath(),this._reloadConfigOnly(!0))):this._showToast(this._t("toast.cfg_save_failed",{err:this._errText(t)})),e&&this._reloadRejectedPhysicalWrite())})},500),this._draftSegmentCms=[],this._closingWallCm=null,this._savePhysicalDialog=()=>{const t=this._physicalDialog,e=this._curSpaceCfg,i=this._spaceModel();if(!t||!e||!i)return;const s=Wf(t.cm);if(null==s)return void this._showPhysicalRange("column"===t.kind?jc:100,"column"===t.kind?1:0);const n=this._imperial?2.54*s:s,o="column"===t.kind?jc:100,a="column"===t.kind?1:0;if(!Number.isFinite(n)||no)return void this._showPhysicalRange(o,a);if("column"===t.kind){const e=i.wall_columns.find(e=>e.id===t.id);if(!e)return;const s=Wf(t.angle||"0");if("circle"!==t.shape&&(null==s||s<0||s>=90))return void this._showToast(this._t("toast.physical_angle"));const o="circle"===t.shape?{id:t.id,shape:"circle",center:e.center,cm:n}:{id:t.id,shape:"square",center:e.center,cm:n,angle:s};if(i.wall_columns.some(e=>e.id!==t.id&&uh(e,o,.02*this._gridPitch)))return void this._showToast(this._t("toast.column_duplicate"))}const r=this._geometrySnapshot();if("partition"===t.kind){const i=(e.partitions||[]).find(e=>e.id===t.id);if(i&&0===n&&f_(e.openings,{kind:"partition",id:t.id}))return void this._showToast(this._t("toast.zero_wall_opening_conflict"));i&&(i.cm=n)}else if("column"===t.kind){const i=(e.wall_columns||[]).find(e=>e.id===t.id);i&&(i.cm=Gc(n),i.shape="circle"===t.shape?"circle":"square","square"===i.shape?i.angle=Wf(t.angle||"0"):delete i.angle)}else{const i=(e.room_drafts||[]).find(e=>e.id===t.id);i?.segments?.[t.segment||0]&&(i.segments[t.segment||0].cm=n)}const l=this._commitPhysicalGeometry(this._t("history.physical_edit"),r);this._physicalDialog=null,l||this.requestUpdate()},this._deletePhysicalSelection=()=>{const t=this._physicalSel,e=this._curSpaceCfg;if(!t||!e)return;if("draft"===t.kind)return void this._deleteDraftWhole();const i=this._geometrySnapshot();if("partition"===t.kind){const i=(e.openings||[]).filter(e=>"partition"===e.host?.kind&&e.host.id===t.id).sort((t,e)=>(t.host?.t||0)-(e.host?.t||0));if(i.length)return void(this._partitionDeleteDialog={id:t.id,openings:i.map(t=>JSON.parse(JSON.stringify(t)))})}const s="partition"===t.kind?"partitions":"column"===t.kind?"wall_columns":"room_drafts";e[s]=(e[s]||[]).filter(e=>e.id!==t.id),e[s].length||delete e[s],this._activeDraftId===t.id&&this._cancelPath(),this._physicalSel=null,this._physicalDialog=null,this._commitPhysicalGeometry(this._t("history.physical_delete"),i)},this._confirmPartitionDelete=()=>{const t=this._partitionDeleteDialog,e=this._curSpaceCfg;if(!t||!e)return;const i=this._geometrySnapshot();e.partitions=(e.partitions||[]).filter(e=>e.id!==t.id),e.partitions.length||delete e.partitions,e.openings=(e.openings||[]).filter(e=>"partition"!==e.host?.kind||e.host.id!==t.id),e.openings.length||delete e.openings,this._partitionDeleteDialog=null,this._physicalSel=null,this._physicalDialog=null,this._commitPhysicalGeometry(this._t("history.physical_delete"),i)},this._deleteDraftWhole=()=>{const t="draft"===this._physicalDialog?.kind?this._physicalDialog.id:"draft"===this._physicalSel?.kind?this._physicalSel.id:null,e=this._curSpaceCfg;if(!t||!e||!confirm(this._t("confirm.delete_draft")))return;const i=this._geometrySnapshot();e.room_drafts=(e.room_drafts||[]).filter(e=>e.id!==t),e.room_drafts.length||delete e.room_drafts,this._activeDraftId===t&&this._cancelPath(),this._physicalSel=null,this._physicalDialog=null,this._commitPhysicalGeometry(this._t("history.physical_delete"),i)},this._deleteDraftSegment=()=>{const t=this._physicalDialog,e=this._curSpaceCfg;if(!t||"draft"!==t.kind||!e)return;if(!confirm(this._t("confirm.delete_draft_segment")))return;const i=(e.room_drafts||[]).findIndex(e=>e.id===t.id);if(i<0)return;const s=e.room_drafts[i],n=Math.max(0,Math.min(s.segments.length-1,t.segment||0)),o=[],a=s.points.slice(0,n+1),r=s.points.slice(n+1);if(a.length>=2&&o.push({id:s.id,points:a,segments:s.segments.slice(0,n)}),r.length>=2&&o.push({id:o.length?`${s.id}-${Date.now().toString(36)}`:s.id,points:r,segments:s.segments.slice(n+1)}),2===o.length&&e.room_drafts.length>=200)return void this._showToast(this._t("toast.physical_limit"));const l=this._geometrySnapshot();e.room_drafts.splice(i,1,...o),e.room_drafts.length||delete e.room_drafts,this._activeDraftId===s.id&&this._cancelPath(),this._physicalDialog=null,this._physicalSel=o.length?{kind:"draft",id:o[0].id}:null,this._commitPhysicalGeometry(this._t("history.draft_segment_delete"),l)},this._confirmRoomDelete=t=>{const e=this._roomDeleteDialog,i=this._curSpaceCfg,s=this._spaceModel();if(!e||!i||!s)return;const n=s.rooms.find(t=>t.id===e.roomId);if(!n)return void(this._roomDeleteDialog=null);const o=this._openCuts(),a=$u(dc(s.rooms,this._spaceWalls,o,this._wallKeyPitch,this._cellCm,this._gridPitch,sv).filter(t=>t.roomId===n.id),s.partitions,this._openingsR.map(t=>({...t,x:t.rx,y:t.ry})),.02*this._gridPitch),r=new Set(a.materialize.filter(t=>!t.reusePartitionId).map(t=>t.interval.key)).size;if(t&&(i.partitions||[]).length+r>rv)return void this._showToast(this._t("toast.physical_limit"));const l=this._geometrySnapshot(),c=pc(s.rooms,this._spaceWalls,o,this._wallKeyPitch,this._cellCm,this._gridPitch,sv);if(t){i.partitions||=[];const t=new Map,e=new Map,s=t=>{const e=(i.wall_segments||[]).find(e=>{const i=[Number(e.a?.[0])*sv,Number(e.a?.[1])*sv],s=[Number(e.b?.[0])*sv,Number(e.b?.[1])*sv];return this._samePt(t.a,i)&&this._samePt(t.b,s)||this._samePt(t.a,s)&&this._samePt(t.b,i)});return"string"==typeof e?.id&&e.id?e.id:null},n=Date.now().toString(36);for(const o of a.materialize){let a=o.reusePartitionId?i.partitions.find(t=>t.id===o.reusePartitionId):e.get(o.interval.key);a||(a={id:s(o.interval)||`partition-room-${n}-${e.size}`,a:[o.interval.a[0]/sv,o.interval.a[1]/sv],b:[o.interval.b[0]/sv,o.interval.b[1]/sv],cm:o.interval.cm},i.partitions.push(a),e.set(o.interval.key,a)),t.set(o.interval.key,a)}for(const e of i.openings||[]){const i=a.openingIntervals.get(e.id),s=i?t.get(i):null,n=this._openingsR.find(t=>t.id===e.id);if(!s||!n)continue;const o={a:[s.a[0]*sv,s.a[1]*sv],b:[s.b[0]*sv,s.b[1]*sv]};e.host={kind:"partition",id:s.id,t:Su([n.rx,n.ry],o)}}}else if(a.removeOpeningIds.length){const t=new Set(a.removeOpeningIds);i.openings=(i.openings||[]).filter(e=>!t.has(e.id)),i.openings.length||delete i.openings}i.rooms=i.rooms.filter(t=>t.id!==n.id),this._cfgEpoch++;const h=this._normalizeWalls(c,this._openCuts());h.length?i.walls=h:delete i.walls,this._roomDeleteDialog=null,this._commitPhysicalGeometry(this._t(t?"history.delete_room_keep_walls":"history.delete_room_with_walls"),l),this._regSignature="",this._maybeRebuildDevices(),this.requestUpdate()},this._rebindPartitionOpening=()=>{const t=this._openingDialog;if(!t?.id)return;const e=t.id;this._activateMarkupTool("opening"),"opening"===this._tool&&(this._openingRebindId=e,this._openingPreset={type:t.type,lengthCm:t.lengthCm,flipH:t.flipH,flipV:t.flipV,revision:++this._openingPresetRevision},this._openingDialog=null,this._openingHoverCandidate=null)},this._keepClosedAsPartitions=()=>{if(this._wallFaceBatch)return void this._decideWallFace(!1);if(!this._contourClosed||this._pendingSplit||!this._curSpaceCfg)return;const t=this._curSpaceCfg,e=this._path.slice(0,-1);if((t.partitions||[]).length+e.length>rv)return void this._showToast(this._t("toast.physical_limit"));const i=this._geometrySnapshot(),s=Xp(e.length,[...this._draftSegmentCms,this._closingWallCm??void 0],this._drawWallCm,ll);t.partitions||=[];const n=Date.now().toString(36),o=this._activeDraftId?(t.room_drafts||[]).find(t=>t.id===this._activeDraftId):null,a=this._draftSegmentsForPath(this._path,o,s);for(let i=0;it.id!==this._activeDraftId),t.room_drafts.length||delete t.room_drafts),this._commitPhysicalGeometry(this._t("history.contour_to_partitions"),i),this._roomDialog=!1,this._path=[],delete this._resumeDraftBySpace[this._space],this._activeDraftId=null,this._draftSegmentCms=[],this._closingWallCm=null},this._toggleServerPlans=async()=>{const t=this._spaceDialog;if(t)if(t.pickSaved)this._spaceDialog={...t,pickSaved:!1};else{this._spaceDialog={...t,pickSaved:!0,savedBusy:!0};try{const t=await this.hass.callWS({type:"houseplan/plans/list"}),e=this._spaceDialog;e&&(this._spaceDialog={...e,saved:t?.plans||[],savedBusy:!1})}catch(t){const e=this._spaceDialog;e&&(this._spaceDialog={...e,saved:[],savedBusy:!1}),this._showToast(this._t("toast.plans_list_failed",{err:this._errText(t)}))}}},this._aspectJob=null,this._dayCycleTick=()=>{if(!this.isConnected||"hidden"===this.ownerDocument.visibilityState)return;const t=this._dayCycleState();if(!t)return this._dayCycleTimer&&(clearInterval(this._dayCycleTimer),this._dayCycleTimer=0),void(this._dayCycleClockKey="");const e=mr(t);e!==this._dayCycleClockKey&&(this._dayCycleClockKey=e,this.requestUpdate())},this._sunShown=!1,this._sunOut=!1,this._sunOutTimer=0,this._openSettingsDialog=()=>{if(!this._norm)return;const t=this._glowRadiusCm,e=this._imperial?Math.round(t/30.48*10)/10:Math.round(t)/100;this._settingsDialog={colors:JSON.parse(JSON.stringify(this._fillColors)),glowRadius:e,bgColor:hs(this._settings,{bgColor:null})||null,northDeg:$r(this._settings,{}),bgMode:Sr(this._settings,{}),sunRays:Mr(this._settings,{}),busy:!1}},this._reportedPreflightFingerprint=null,this._openAlignDialog=()=>this._previewAlignDialog(!1),this._toggleOptimizeLivePositions=()=>{const t=this._alignDialog;t&&!t.busy&&t.report.liveMissingPositions.length&&this._previewAlignDialog(!t.removeLiveMissingPositions)},this._optimizeUndoBusy=!1,this._openBackupExport=()=>{this._settingsDialog=null,this._backupExportDialog={kind:"full",planOnly:!1,busy:!1,error:""}},this._openRulesDialog=()=>{if(!this._norm)return;const t=this._settings.icon_rules,e=(t&&t.length?t:Jt).map(t=>({...t}));this._rulesDialog={rules:e,test:"",busy:!1}},this._climateCache=null,this._gearPtCache=new WeakMap}get _canEdit(){return!!this._norm&&(!0===this._serverCanWrite||!1!==this._serverCanWrite&&!0===this.hass?.user?.is_admin)}get _kiosk(){return!!this._config?.kiosk}_showKioskDots(){this._kioskDots=!0,clearTimeout(this._kioskDotsTimer),this._kioskDotsTimer=window.setTimeout(()=>this._kioskDots=!1,2500)}get _modeTransitionBusy(){return this._modeTransitionPreparing||this._modeTransition.active}_cssColor(t,e){const i=String(t||"").trim();if(!i)return e;const s=document.createElement("span");s.style.cssText=`position:absolute;visibility:hidden;color:${i}`,this.renderRoot.append(s);const n=getComputedStyle(s).color||e;return s.remove(),n}_currentModeVisual(t=this._mode){const e=this._modeTransition.presented||this._modeTransitionVisual;if(e)return{...e,viewport:{...e.viewport,viewBox:{...e.viewport.viewBox}}};const i=this._stageEl;if(!i||i.clientWidth<=0||i.clientHeight<=0)return null;const s=this.renderRoot.querySelector(".editorchrome"),n=this._viewOr(this._baseVb()),o=this.renderRoot.querySelector(".hp-paper"),a=this.renderRoot.querySelector(".hp-backdrop"),r=this.renderRoot.querySelector(".zoomwrap"),l=r?getComputedStyle(r).filter:"",c=Number(/brightness\(([^)]+)\)/.exec(l)?.[1]);return{presentedMode:t,editorChromeHeight:"view"===t?0:s?.getBoundingClientRect().height||0,stageWidth:i.clientWidth,stageHeight:i.clientHeight,viewport:Sg(n,i.clientWidth),stageColor:getComputedStyle(i).backgroundColor||"rgb(255, 255, 255)",paperColor:o?getComputedStyle(o).fill:"rgb(255, 255, 255)",sceneBrightness:Number.isFinite(c)?c:1,architectureOpacity:"decor"===t?.35:1,backdropOpacity:a&&Number(getComputedStyle(a).opacity)||1,viewWeight:"view"===t?1:0,editorWeight:"view"===t?0:1,toolbarContentOpacity:"view"===t?0:1}}_viewForModeTarget(t,e,i,s,n){const o=Ni(this._baseVb(),s/Math.max(1,n)),a=Math.min(pv.ZOOM_MAX,Math.max(pv.ZOOM_MIN,t)),r=o.w/a,l=o.h/a,c=e??o.x+o.w/2,h=i??o.y+o.h/2;return this._clampView({x:c-r/2,y:h-l/2,w:r,h:l},o)}_targetStageColor(t){return"view"!==t?"rgb(255, 255, 255)":this._cssColor(this._stageBg(this._spaceDisplayForRender()),this._cssColor("var(--ha-card-background, var(--card-background-color, #111))","rgb(17, 17, 17)"))}_targetPaperColor(t){return"view"===t&&this._spaceModel()?.bg?this._cssColor("var(--ha-card-background, var(--card-background-color, #111))","rgb(17, 17, 17)"):"rgb(255, 255, 255)"}_targetBrightness(t){return 1}_applyModeTransitionFrame(t){t.targetMode===this._mode&&(this._modeTransitionVisual=t.presented,this._view={...t.presented.viewport.viewBox},this.requestUpdate())}_settleModeTransition(t){if(t.targetMode!==this._mode)return;const e=this._modeTransitionRequest;this._view={...t.to.viewport.viewBox},this._zoom=this._modeTransitionTargetZoom,this._modeTransitionVisual=null,this._modeTransitionPreparing=!1,this._lastValidStageSize=[t.to.stageWidth,t.to.stageHeight],"view"===this._mode&&(this._saveZoom(),this._viewModeSnap=null,this._modeTransitionEditorCamera=null),this.requestUpdate(),this.updateComplete.then(()=>{if(!this.isConnected||e!==this._modeTransitionRequest||this._modeTransitionBusy||t.targetMode!==this._mode)return;const i=this._stageEl;if(i&&i.clientWidth>0&&i.clientHeight>0&&(Math.abs(i.clientWidth-t.to.stageWidth)>.5||Math.abs(i.clientHeight-t.to.stageHeight)>.5)){const t=this._view;this._lastValidStageSize=[i.clientWidth,i.clientHeight],this._applyView(this._zoom,t?t.x+t.w/2:void 0,t?t.y+t.h/2:void 0),this.requestUpdate()}const s=this.renderRoot.activeElement;(!s||!s.isConnected||!!s.closest?.(".editorchrome, .stage"))&&this.renderRoot.querySelector(".modetab.active")?.focus?.({preventScroll:!0})})}_cancelModeTransition(t=!0){const e=!!this._modeTransition.state;this._modeTransitionRequest++,this._modeTransitionPreparing=!1,this._modeTransitionForceAtomic=!1,this._modeTransition.cancel(t),t&&e||(this._modeTransitionVisual=null)}_adoptMode(t){this._cancelModeTransition(!1),this._mode=t,"view"!==t&&(this._editorChromeMode=t)}_commitViewModeAtomic(t,e,i,s){if(this._modeTransitionPreparing=!1,this._modeTransitionVisual=null,this._modeTransitionForceAtomic=!1,this._zoom=e,t){const n=this._stageEl?.clientWidth||t.stageWidth,o=Math.max(1,t.stageHeight+t.editorChromeHeight);this._view=this._viewForModeTarget(e,i,s,n,o),this._lastValidStageSize=[n,o]}else this._view=null;this._viewModeSnap=null,this._modeTransitionEditorCamera=null,this._saveZoom(),this.requestUpdate()}_prepareModeTransition(t,e,i,s,n,o){this.updateComplete.then(()=>{if(!this.isConnected||t!==this._modeTransitionRequest||this._mode!==i)return void(t===this._modeTransitionRequest&&(this._modeTransitionPreparing=!1,this._modeTransitionVisual=null,this._modeTransitionForceAtomic=!1,this.requestUpdate()));const a=this.renderRoot.querySelector(".editorchrome"),r=a?.querySelector(".editorchrome-inner"),l="view"===i?0:r?.scrollHeight||r?.getBoundingClientRect().height||0,c=Math.max(1,e.stageHeight+e.editorChromeHeight),h=Math.max(1,c-l),d=this._stageEl?.clientWidth||e.stageWidth;if(d<=0||h<=0)return this._modeTransitionPreparing=!1,this._modeTransitionVisual=null,this._applyView(s,n,o),void this.requestUpdate();const p=this._viewForModeTarget(s,n,o,d,h),u={presentedMode:i,editorChromeHeight:l,stageWidth:d,stageHeight:h,viewport:Sg(p,d),stageColor:this._targetStageColor(i),paperColor:this._targetPaperColor(i),sceneBrightness:this._targetBrightness(i),architectureOpacity:"decor"===i?.35:1,backdropOpacity:"decor"===i&&"backdrop"!==this._decorTool?.5:1,viewWeight:"view"===i?1:0,editorWeight:"view"===i?0:1,toolbarContentOpacity:"view"===i?0:1};this._modeTransitionPreparing=!1;const _=this._modeTransitionForceAtomic;this._modeTransitionForceAtomic=!1,this._modeTransition.start(e,u,i,this._reducedMotion||_?0:220)})}get _hasFixedFloor(){return!!this._config&&Object.prototype.hasOwnProperty.call(this._config,"floor")}_fixedFloorState(t=this._model,e=this._loadOk){const i=this._config?.floor,s=function(t){if(!t.hasFloor)return{kind:"absent"};const e=t.floor;if("string"==typeof e)return e.length?t.spaceIds.includes(e)?{kind:"valid",id:e,source:"id"}:{kind:"invalid",reason:"unknown-id",value:e}:{kind:"invalid",reason:"empty-id",value:e};if("number"==typeof e){if(!Number.isFinite(e))return{kind:"invalid",reason:"non-finite-index",value:e};if(!Number.isInteger(e))return{kind:"invalid",reason:"fractional-index",value:e};if(e<0)return{kind:"invalid",reason:"negative-index",value:e};const i=t.spaceIds[e];return void 0===i?{kind:"invalid",reason:"out-of-range-index",value:e}:{kind:"valid",id:i,source:"index"}}return{kind:"invalid",reason:"invalid-type",value:e}}({spaceIds:t.map(t=>t.id),hasFloor:this._hasFixedFloor,floor:i});return!this._hasFixedFloor||e?s:"number"==typeof i?"valid"===s.kind||"invalid"===s.kind&&"out-of-range-index"===s.reason?{kind:"pending",value:i}:s:"valid"===s.kind||"invalid"===s.kind&&"unknown-id"!==s.reason?s:{kind:"pending",value:i}}_canCommitSpace(t,e=!1){if(e||!this._hasFixedFloor)return!0;const i=this._fixedFloorState();return"valid"===i.kind&&i.id===t}_commitSpace(t,e=!1){return!!this._canCommitSpace(t,e)&&(t!==this._space&&(this._clearTransientHover(!0),this._cancelDevicePressFeedback()),this._space=t,!0)}_slideTo(t,e){if(t===this._space)return!0;if(!this._canCommitSpace(t))return!1;if(this._wallFaceBatch&&this._roomDialogCancel(),"plan"===this._mode&&"draw"===this._tool&&!this._finishWallChain())return!1;this._cancelModeTransition(!0);const i=window.matchMedia?.("(prefers-reduced-motion: reduce)")?.matches;return this._activeDraftId&&(this._resumeDraftBySpace[this._space]=this._activeDraftId),this._commitSpace(t),this._path=[],this._clearPlanSnapHover(),this._clearOpeningPlacement(!0),this._tool="draw",this._activeDraftId=null,this._draftSegmentCms=[],this._closingWallCm=null,this._selId=null,this._physicalSel=null,this._editorSecondary.closeForNavigation(),this._physicalDialog=null,this._physicalDrag=null,"plan"===this._mode&&"draw"===this._tool&&this._resumeLastDraft(),this._restoreZoom(),i||(this._slide=e,clearTimeout(this._slideTimer),this._slideTimer=window.setTimeout(()=>{this._slideTimer=void 0,this._slide="",this.requestUpdate()},190),this.requestUpdate()),!0}get _canReorderTabs(){return Ef({canEdit:this._canEdit,kiosk:this._kiosk,mode:this._mode,pointerType:"mouse",spaceCount:this._model.length,fixedFloor:this._hasFixedFloor})}_tabPointerDown(t,e){Ef({canEdit:this._canEdit,kiosk:this._kiosk,mode:this._mode,pointerType:t.pointerType,spaceCount:this._model.length,fixedFloor:this._hasFixedFloor})&&(dv(t),this._tabDragRelease=t=>this._tabPointerUp(t),window.addEventListener("pointerup",this._tabDragRelease),window.addEventListener("pointercancel",this._tabDragRelease),this._tabDrag={id:e,pointerId:t.pointerId,x:t.clientX,y:t.clientY,moved:!1,targetId:null,placement:null})}_tabDropTargetAt(t,e,i){const s=this._model.map(t=>t.id),n=s.indexOf(i);if(n<0)return null;const o=this.renderRoot.querySelectorAll('[data-hp="space-tab"]');for(const a of o){const o=a.dataset.id||"";if(!o||o===i)continue;const r=a.getBoundingClientRect();if(tr.right||er.bottom)continue;const l=s.indexOf(o);return l<0?null:{targetId:o,placement:l=4)))return;var i,s;const n=this._tabDropTargetAt(t.clientX,t.clientY,e.id);e.moved&&e.targetId===n?.targetId&&e.placement===n?.placement||(this._tabDrag={...e,moved:!0,targetId:n?.targetId||null,placement:n?.placement||null})}_tabPointerUp(t){const e=this._tabDrag;if(e&&e.pointerId!==t.pointerId)return;const i="pointerup"===t.type&&e?.moved?this._tabDropTargetAt(t.clientX,t.clientY,e.id):null;"pointerup"===t.type&&e?.moved&&this._suppressNextTabClick(),this._endTabDrag(),e?.moved&&i&&this._commitTabOrder(e.id,i.targetId)}_endTabDrag(){this._tabDrag=null,this._tabDragRelease&&(window.removeEventListener("pointerup",this._tabDragRelease),window.removeEventListener("pointercancel",this._tabDragRelease),this._tabDragRelease=null)}_tabClick(t){if(this._tabSuppressClick)return this._tabSuppressClick=!1,clearTimeout(this._tabSuppressClickTimer),void(this._tabSuppressClickTimer=void 0);this._pickSpace(t)}_suppressNextTabClick(){this._tabSuppressClick=!0,clearTimeout(this._tabSuppressClickTimer),this._tabSuppressClickTimer=window.setTimeout(()=>{this._tabSuppressClick=!1,this._tabSuppressClickTimer=void 0},0)}_commitTabOrder(t,e){const i=this._serverCfg;if(!i||!this._canReorderTabs)return;const s=this._model.map(t=>t.id),n=function(t,e,i){const s=t.indexOf(e),n=t.indexOf(i);if(s<0||n<0||s===n)return t;const o=t.slice();return o.splice(s,1),o.splice(n,0,e),o}(s,t,e);if(n===s)return;const o=new Map(this._devices.map(t=>[String(t.id),String(t.area||"")])),a=function(t,e,i,s=()=>""){if(!i)return[];const n=[];for(const o of t){if(!o||!0===o.removed)continue;const t="string"==typeof o.id?o.id:"";if(!t)continue;if("string"==typeof o.space&&o.space)continue;const a=("string"==typeof o.area?o.area:"")||s(t)||"";a&&e[a]||n.push({id:t,space:i})}return n}(i.markers||[],Object.fromEntries(Object.entries(this._areaToSpace).map(([t,e])=>[t,e.space])),s[0]||"",t=>o.get(t)||"");if(a.length){const t=new Map(a.map(t=>[t.id,t.space]));for(const e of i.markers||[]){const i=t.get(String(e.id));i&&(e.space=i)}}i.spaces=function(t,e){const i=new Map(e.map((t,e)=>[t,e]));return t.map((t,e)=>({space:t,index:e})).sort((t,e)=>(i.get(String(t.space?.id))??Number.MAX_SAFE_INTEGER)-(i.get(String(e.space?.id))??Number.MAX_SAFE_INTEGER)||t.index-e.index).map(t=>t.space)}(i.spaces||[],n),this._saveConfig(),this._tabOrderWarned||(this._tabOrderWarned=!0,this._showToast(this._t("toast.space_order_changed")))}_pickSpace(t){if(this._endTabDrag(),t===this._space)return;const e=this._model.map(t=>t.id),i=e.indexOf(this._space),s=e.indexOf(t);this._navApplied=!0,this._showFar=!1,this._frame=null,this._slideTo(t,i>=0&&s0&&Date.now()>=this._cyclePausedUntil&&this._model.length>1&&this._zoom<=1.001){const t=this._model.map(t=>t.id),e=t.indexOf(this._space);this._slideTo(t[(e+1)%t.length],"left"),this._showKioskDots()}}_syncCycleTimer(){clearInterval(this._cycleTimer),this._cycleTimer=void 0,this.isConnected&&!this._hasFixedFloor&&this._config?.kiosk&&Number(this._config.cycle)>0&&(this._cycleTimer=window.setInterval(()=>this._cycleTick(),1e3*Number(this._config.cycle)))}get _editing(){return"plan"===this._mode||"devices"===this._mode||"decor"===this._mode}get _markup(){return"plan"===this._mode}get _wallUnionCache(){return this._wallUnionCacheValue}set _wallUnionCache(t){this._wallUnionCacheValue=t,null===t&&this._wallUnionPool.clear()}_newContinuityController(){return new bd(()=>{this._resumeSettling="steady"!==this._continuity.state,this._continuityEpoch++,this.isConnected&&this.requestUpdate()})}get _labsIso(){return this._labs.active.includes("iso")}get _desiredProjection(){return"view"===this._mode&&this._labsIso&&"iso"===this._viewPreference[this._space]?"iso":"flat"}_saveViewPreference(){try{localStorage.setItem(ev,JSON.stringify(this._viewPreference))}catch{}}_logicalViewCenter(t){const e=this._view;if(!e)return null;const i=[e.x+e.w/2,e.y+e.h/2],s="iso"===t?Zg(i):i;return{x:s[0],y:s[1]}}_convertProjectionView(t,e){if(t===e)return;const i=this._logicalViewCenter(t);this._view=null;const s=i?"iso"===e?Xg([i.x,i.y],0):[i.x,i.y]:null;this._applyView(this._zoom,s?.[0],s?.[1]),this._warmPatch({vp:this._warmViewportState()}),this.requestUpdate()}_setProjection(t){if(!this._labsIso||"view"!==this._mode)return;const e=this._effectiveProjection();if(this._viewPreference={...this._viewPreference,[this._space]:t},"iso"===t){const t=this._isoSceneKey();t&&this._isoFallback.delete(t)}this._saveViewPreference();const i=this._effectiveProjection();this._convertProjectionView(e,i)}_hashSpace(){return Og(window.location.hash||"")}connectedCallback(){this._connectedPath=location.pathname,this._routeDepartureHandled=!1,window.addEventListener("location-changed",this._onLocationChanged),window.addEventListener("popstate",this._onLocationChanged),this._continuityDisposed&&(this._continuity=this._newContinuityController(),this._continuityDisposed=!1,this._continuityPaintToken=-1);const t=(e=this.ownerDocument,vg.get(e)?.resolved);var e;void 0!==t&&(this._glowScreenBlend=t),this._continuityUnsub?.(),this._continuityUnsub=vd(this.ownerDocument,this._pageVisibility),super.connectedCallback(),this._pointerModality.connect(this.ownerDocument.defaultView);const i=this.ownerDocument.defaultView?.MutationObserver;i&&(this._pointerHoverObserver=new i(t=>{for(const e of t)for(const t of e.addedNodes)this._syncPointerHoverSubtree(t)}),this._pointerHoverObserver.observe(this.renderRoot,{childList:!0,subtree:!0})),this._motionMedia=window.matchMedia?.("(prefers-reduced-motion: reduce)"),this._reducedMotion=!!this._motionMedia?.matches,this._motionMedia?.addEventListener?.("change",this._onMotionChange),function(t){const e=vg.get(t);if(e)return e.promise;const i={promise:Promise.resolve(!1)};return i.promise=bg(t).catch(()=>!1).then(t=>(i.resolved=t,t)),vg.set(t,i),i.promise}(this.ownerDocument).then(t=>{t!==this._glowScreenBlend&&(this._glowScreenBlend=t,this.isConnected&&this.requestUpdate())}),this.hass&&this._ensureHaRegistryAuthority(),window.addEventListener("keydown",this._keyHandler),this._signer.start(()=>this.hass,()=>Is(this._serverCfg)),this._syncCycleTimer(),window.addEventListener("hashchange",this._onHashChange),this._labsUnsub?.(),this._labsUnsub=function(t,e){Ug.add(e);const i=Kg(t);return"undefined"==typeof window&&e(i),()=>{Ug.delete(e)}}(Nf,this._onLabsSnapshot),this._booting?this._bootWatch():this._bootFading&&(clearTimeout(this._bootTimer),this._bootTimer=window.setTimeout(()=>{this._bootFading=!1},220)),this._bootSoft&&(clearTimeout(this._bootSoftTimer),this._bootSoftTimer=window.setTimeout(()=>{this._bootSoft=!1},qf)),!this._loadOk&&this._serverCfg&&this.hass&&this._scheduleLoadRetry(),!this._warmSlot&&this._config&&this._warmAdopt(),this._loadOk&&this._ensureLiveSyncSubscriptions(),this._warmVp&&!this._warmRevivePending&&void 0===this._warmReviveTimer&&(this._warmRevivePending=!0,this._warmReviveTimer=window.setTimeout(()=>this._warmReviveDialog(),0)),this._warmLongReturn&&this._beginResumeSettle(),this._warmLongReturn=!1,this.requestUpdate()}disconnectedCallback(){this._connectedPath&&location.pathname!==this._connectedPath&&this._leaveCardRoute(),window.removeEventListener("location-changed",this._onLocationChanged),window.removeEventListener("popstate",this._onLocationChanged),this._continuityUnsub?.(),this._continuityUnsub=void 0,this._motionMedia?.removeEventListener?.("change",this._onMotionChange),this._motionMedia=void 0,this._vacRaf&&(cancelAnimationFrame(this._vacRaf),this._vacRaf=0),this._refitRaf&&(cancelAnimationFrame(this._refitRaf),this._refitRaf=0),this._dayCycleTimer&&(clearInterval(this._dayCycleTimer),this._dayCycleTimer=0),this._dayCycleClockKey="",this._bootSettleRaf&&(cancelAnimationFrame(this._bootSettleRaf),this._bootSettleRaf=0),this._bootSettling=!1;for(const t of this._activityRt.values())clearTimeout(t.timer);window.removeEventListener("keydown",this._keyHandler),this._endTabDrag(),clearTimeout(this._tabSuppressClickTimer),this._tabSuppressClickTimer=void 0,this._tabSuppressClick=!1,clearInterval(this._cycleTimer),clearTimeout(this._kioskDotsTimer),clearTimeout(this._kioskHoldTimer),clearTimeout(this._reloadRetry),clearTimeout(this._loadRetryTimer),this._loadRetryTimer=void 0,this._connHooked?.removeEventListener?.("ready",this._onConnReady),this._connHooked?.removeEventListener?.("disconnected",this._onConnLost),this._connHooked?.removeEventListener?.("reconnect-error",this._onConnLost),this._connHooked=null,this._haRegistryRelease?.(),this._haRegistryRelease=void 0,this._haRegistryConnection=null,this._signer.dispose(),clearTimeout(this._toastTimer),clearTimeout(this._slideTimer),this._modeTransition.dispose(),this._modeTransitionVisual=null,this._modeTransitionPreparing=!1,this._modeTransitionForceAtomic=!1,this._modeTransitionRequest++,this._slideTimer=void 0,this._slide="",clearTimeout(this._bootTimer),this._bootTimer=void 0,clearTimeout(this._bootSoftTimer),this._saveConfigDebounced.flush(),window.removeEventListener("hashchange",this._onHashChange),this._labsUnsub?.(),this._labsUnsub=void 0,clearTimeout(this._holdTimer),this._roViewport?.disconnect(),this._roViewport=void 0,this._roHdr?.disconnect(),this._roHdr=void 0,this._onWinResize&&(window.removeEventListener("resize",this._onWinResize),this._onWinResize=void 0),this._unsubCfg&&(this._unsubCfg(),this._unsubCfg=null),this._unsubLayout&&(this._unsubLayout(),this._unsubLayout=null),this._unsubVirtual&&(this._unsubVirtual(),this._unsubVirtual=null),this._unsubTrail&&(this._unsubTrail(),this._unsubTrail=void 0),this._liveSyncGeneration++,this._liveSyncAttempt=null,this._liveSyncConnection=null,clearTimeout(this._layoutSyncTimer),clearTimeout(this._duplicateColumnTimer);for(const t of this._glowFadeTimers.values())clearTimeout(t);for(const t of this._glowEnterRafs.values())cancelAnimationFrame(t);clearTimeout(this._glowFeatherResumeTimer),this._glowFeatherResumeTimer=0,this._glowFeatherSuspendUntil=0,this._glowFadeTimers.clear(),this._glowEnterRafs.clear(),this._glowEnteringSources.clear(),this._glowRenderedSources.clear(),this._glowLastAppearance.clear(),this._glowSourceSeq=0,this._warmSnapshot(),this._warmRevivePending=!1,clearTimeout(this._warmReviveTimer),this._warmReviveTimer=void 0,this._warmRelease(),this._clearPlanSnapHover(),this._clearOpeningPlacement(!0),this._touchContacts.clear(),this._touchSequenceMultitouch=!1,this._touchClickBlockUntil=0,this._clearTransientHover(!0),this._cancelDevicePressFeedback(),this._pointerHoverObserver?.disconnect(),this._pointerHoverObserver=void 0,this._pointerModality.disconnect(),this._editorSecondary.reset(),this._resumeSettling=!1,this._continuityHistory=[...this._continuityHistory,...this._continuity.trace].slice(-80),this._continuity.dispose(),this._continuityDisposed=!0,super.disconnectedCallback()}_onKey(t){if("Escape"===t.key&&this._vacFit)return this._vacFit=null,this._showToast(this._t("vac.cal_cancelled")),void t.stopPropagation();if("Escape"===t.key){if(this._tapConfirm)return void(this._tapConfirm=null);if(this._vacCalConfirm)return void(this._vacCalConfirm=null);if(this._decorEraseConfirm)return void(this._decorEraseConfirm=null);if(this._openingInfo)return void(this._openingInfo=null);if(this._infoCard)return void this._closeInfoCard();if(this._rulesDialog)return void(this._rulesDialog=null);if(this._alignDialog)return this._alignDialog=null,void(this._preflightClipboardFallback=null);if(this._backupImportDialog)return void(this._backupImportDialog=null);if(this._backupExportDialog)return void(this._backupExportDialog=null);if(this._settingsDialog)return void(this._settingsDialog=null);if(this._markerDialog)return void(this._markerDialog=null);if(this._openingDialog)return void(this._openingDialog=null);if(this._physicalDialog)return void(this._physicalDialog=null);if(this._backdropDialog)return void(this._backdropDialog=null);if(this._decorShapeDialog)return void(this._decorShapeDialog=null);if(this._decorTextDialog)return void(this._decorTextDialog=null);if(this._spaceDialog&&!this._roomDialog)return this._spaceDialog=null,this._importQueue=[],void(this._importTotal=0);if(this._editorSecondary.hasOpenGroup)return t.preventDefault(),void this._editorSecondary.closeGroup(!0)}const e=t.composedPath?.()||[t.target],i=e.some(t=>t?.matches?.('input, textarea, select, [contenteditable="true"]')),s=e.some(t=>t?.classList?.contains?.("editor-secondary")),n=t.ctrlKey||t.metaKey,o=t.key.toLowerCase(),a=/^[a-z]$/.test(o),r="z"===o||!a&&"KeyZ"===t.code,l="y"===o||!a&&"KeyY"===t.code,c=n&&(r&&t.shiftKey||l),h=n&&r&&!t.shiftKey;if("decor"===this._mode){if((h||c)&&i)return;return c?(t.preventDefault(),void this._redoGeometry()):h?(t.preventDefault(),this._decorDraft?void(this._decorDraft=null):this._decorMove||this._dtDrag||this._bdDrag?void this._cancelDecorGesture():void this._undoGeometry()):"Delete"!==t.key&&"Backspace"!==t.key||!this._decorSel||i||s?void("Escape"===t.key&&(t.preventDefault(),this._decorDraft?this._decorDraft=null:this._decorMove||this._dtDrag||this._bdDrag?this._cancelDecorGesture():"furniture"===this._decorTool?(this._furnPalette=null,this._decorTool="select"):this._decorSel?this._decorSel=null:"select"!==this._decorTool?this._decorTool="select":this._setMode("view"))):(t.preventDefault(),void this._decorDeleteSel())}if(this._markup&&(!h&&!c||!i)){if(("Delete"===t.key||"Backspace"===t.key)&&this._physicalSel&&!i&&!s)return t.preventDefault(),void this._deletePhysicalSelection();if(c)return t.preventDefault(),void this._redoGeometry();if(h)return t.preventDefault(),this._rszDrag?void this._rszCancelDrag():this._wallFaceBatch?(this._roomDialogCancel(),void(this._activeDraftId&&this._path.length>1?this._undoActiveDraftPoint():this._undoPoint())):"draw"===this._tool&&this._path.length?void(this._activeDraftId&&this._path.length>1?this._undoActiveDraftPoint():this._undoPoint()):"split"===this._tool&&this._splitSel?.pts?.length?(this._splitSel={...this._splitSel,pts:this._splitSel.pts.slice(0,-1)},void(this._splitSel.pts.length||(this._cursorPt=null))):void this._undoGeometry();if("Escape"===t.key)return this._physicalDrag||this._physicalRotate?(t.preventDefault(),void this._cancelPhysicalGesture()):this._roomDialog?(t.preventDefault(),void this._roomDialogCancel()):"draw"===this._tool&&this._path.length?(t.preventDefault(),void this._finishWallChain()):this._physicalSel?(t.preventDefault(),void(this._physicalSel=null)):"resize"===this._tool?(t.preventDefault(),this._rszDrag?void this._rszCancelDrag():void(this._rszSel?this._rszSel=null:this._tool="draw")):"split"===this._tool?(t.preventDefault(),void(this._splitSel?.pts?.length?(this._splitSel={...this._splitSel,pts:this._splitSel.pts.slice(0,-1)},this._splitSel.pts.length||(this._cursorPt=null)):this._splitSel?this._splitSel=null:this._tool="draw")):"merge"===this._tool?(t.preventDefault(),void(this._mergeSel?this._mergeSel=null:this._tool="draw")):this._wallDialog?(t.preventDefault(),void(this._wallDialog=null)):void("opening"!==this._tool&&"wallthick"!==this._tool&&"delroom"!==this._tool&&"column"!==this._tool||(t.preventDefault(),"opening"===this._tool&&this._clearOpeningPlacement(!0),this._tool="draw"))}}_undoPoint(){if(this._path.length){if(this._contourClosed)return this._path=this._path.slice(0,-1),void(this._closingWallCm=null);if(this._activeDraftId&&this._path.length>1&&this._curSpaceCfg){const t=this._geometrySnapshot();this._path=this._path.slice(0,-1),this._draftSegmentCms=this._draftSegmentCms.slice(0,-1);const e=this._curSpaceCfg,i=(e.room_drafts||[]).findIndex(t=>t.id===this._activeDraftId);if(i>=0){const s=Array.isArray(e.room_drafts[i]?.segments)?e.room_drafts[i].segments:[];this._path.length<2?(e.room_drafts.splice(i,1),e.room_drafts.length||delete e.room_drafts,this._activeDraftId=null):e.room_drafts[i]={id:this._activeDraftId,points:this._path.map(t=>[t[0]/sv,t[1]/sv]),segments:this._draftSegmentCms.map((t,e)=>({...s[e]||{},cm:t}))},this._commitPhysicalGeometry(this._t("history.draft_segment_delete"),t)}return}this._path=this._path.slice(0,-1)}}_undoActiveDraftPoint(){const t=this._activeDraftId,e=this._path[0]?[...this._path[0]]:null,i=this._geometryHistory.undo();if(!i)return void this._undoPoint();if(!this._applyGeometryState(i.before,!0))return void this._geometryHistory.clear();const s=t?this._spaceModel()?.room_drafts.find(e=>e.id===t):null;s?(this._activeDraftId=s.id,this._path=s.points.map(t=>[...t]),this._draftSegmentCms=this._adoptDraftCms(this._path,s.segments.map(t=>t.cm),s.id),this._resumeDraftBySpace[this._space]=s.id):(this._activeDraftId=null,this._path=e?[e]:[],this._draftSegmentCms=[],t&&this._resumeDraftBySpace[this._space]===t&&delete this._resumeDraftBySpace[this._space]),this._clearPlanSnapHover(),this._showToast(this._t("history.undone",{name:i.name}))}static getConfigElement(){return document.createElement("houseplan-card-editor")}static getStubConfig(){return{type:"custom:houseplan-card"}}static _warmBootReset(t){for(const t of Gf.values())for(const e of t)clearTimeout(e.evict);Gf.clear(),Yf=t&&t>0?t:1e4}static _warmBootStats(){let t=0,e=0;const i=[];for(const s of Gf.values())for(const n of s)t++,n.dlg&&(e++,i.push(n.dlg.kind));return{keys:Gf.size,slots:t,dlgs:e,drafts:i}}setConfig(t){const e=this._config,i=!!e&&Object.prototype.hasOwnProperty.call(e,"floor");this._config={icon_size:2.5,show_temperature:!0,live_states:!0,show_signal:!0,...t};(i!==this._hasFixedFloor||e?.floor!==this._config.floor)&&(this._hashApplied=!1,this._navApplied=!1,this._warmVpArmed=!1),this._config.kiosk&&(this._booting=!1,this._bootFading=!1),!this._hasFixedFloor&&t.default_floor&&this._commitSpace(t.default_floor,!0);try{this._zoomBySpace=JSON.parse(localStorage.getItem(Zf)||"{}")||{}}catch{this._zoomBySpace={}}try{const t=JSON.parse(localStorage.getItem(ev)||"{}")||{};this._viewPreference=Object.fromEntries(Object.entries(t).filter(t=>"flat"===t[1]||"iso"===t[1]))}catch{this._viewPreference={}}this._labs=Kg(Nf);try{const t=JSON.parse(localStorage.getItem(tv)||"null");this._kioskScale={icon:Es(t?.icon),font:Es(t?.font)}}catch{}try{const t=JSON.parse(localStorage.getItem(Xf)||"null");t&&t.config&&Array.isArray(t.config.spaces)&&(this._serverCfg=t.config,this._cfgEpoch++,this._cfgRev=t.rev||0,this._cfgContentFingerprint=t.config_fingerprint||wd(t.config),this._layout=t.layout||{},this._layoutRev=t.layout_rev||0,this._layoutContentFingerprint=t.layout_fingerprint||wd(this._layout),this._virtualLights=mn(t.virtual_lights,this._cfgRev),this._serverStorage=!0)}catch{}this._adoptInitialSpace(this._model,this._loadOk),"view"!==this._mode||this._view||(this._zoom=this._zoomBySpace[this._space]||1),this.isConnected&&(this._syncCycleTimer(),this._warmAdopt(),this._warmLongReturn&&this._beginResumeSettle(),this._warmLongReturn=!1)}_warmAdopt(){if(this._config?.kiosk)return;const t=Kf(this._config);if(this._warmKey===t&&this._warmSlot)return;this._warmSlot&&this._warmRelease();const e=this.parentNode,i=this._warmIdx(e),s=Gf.get(t);if(!s||!s.length)return;const n=s.find(t=>t.owner===this._warmGen);if(n)return this._warmLongReturn=!!n.freed&&Date.now()-n.freed>=md,clearTimeout(n.evict),n.evict=0,n.freed=0,n.live=!0,this._warmSlot=n,this._warmKey=t,n.frameFingerprint&&this._continuity.adoptCompleteFrame(n.frameFingerprint),void(!this._devices.length&&n.devices?.length&&(this._devices=[...n.devices]));const{slot:o,sure:a}=((t,e,i,s)=>{const n=t=>{const e=!!i&&t.place?.deref()===i;return e&&t.idx===s?4:t.live?0:e?3:2};let o=null,a=0,r=0,l=null;for(const i of t){if(i.owner===e)continue;l=i;const t=n(i);t<=0||(t>a?(o=i,a=t,r=1):t===a&&r++)}return!o||r>1?{slot:o||l,sure:!1}:{slot:o,sure:!0}})(s,this._warmGen,e,i);o&&(this._warmLongReturn=!!o.freed&&Date.now()-o.freed>=md,this._booting=!1,this._bootFading=!1,this._hdrH=o.hdrH,this._bootSoft=!0,this.isConnected&&(clearTimeout(this._bootSoftTimer),this._bootSoftTimer=window.setTimeout(()=>{this._bootSoft=!1},qf)),this._warmKey=t,a?(clearTimeout(o.evict),o.evict=0,o.owner=this._warmGen,o.place=e?new WeakRef(e):null,o.idx=i,o.live=!0,this._warmSlot=o,this._warmVp=o.vp,o.frameFingerprint&&this._continuity.adoptCompleteFrame(o.frameFingerprint),!this._devices.length&&o.devices?.length&&(this._devices=[...o.devices]),this._warmAdoptViewport(this._config)):(this._warmSlot={owner:this._warmGen,path:location.pathname,place:e?new WeakRef(e):null,idx:i,live:!0,hdrH:o.hdrH,stageH:o.stageH,vp:null,frameFingerprint:"",devices:null,dlg:null,freed:0,evict:0},s.push(this._warmSlot),this._warmTrim(s)))}_warmIdx(t){const e=t?.children;if(!e)return-1;for(let t=0;t4;){const e=t.findIndex(t=>!t.live);if(e<0)break;clearTimeout(t[e].evict),t.splice(e,1)}}_warmScheduleEvict(t,e){if(clearTimeout(t.evict),!(t.dlg||t.vp&&"view"!==t.vp.mode))return;const i=t.freed,s=t.owner;t.evict=window.setTimeout(()=>{if(t.evict=0,t.freed!==i||t.owner!==s)return;var n;t.dlg=null,t.vp=(n=t.vp)&&"view"!==n.mode?{...n,mode:"view",zoom:n.snap?.space===n.space?n.snap.zoom:n.zoom,view:null,snap:null,tool:"draw",decorTool:"select",showHidden:!1,selId:null,rszSel:null,decorSel:null}:n,t.frameFingerprint="";const o=Gf.get(e);if(!t.live&&o&&o.length>1){const e=o.indexOf(t);e>=0&&o.splice(e,1)}},Yf+250)}_warmAdoptViewport(t){const e=this._warmVp;if(!e||this._warmSlot?.path!==location.pathname)return void(this._warmVp=null);const i=this._fixedFloorState();if(this._hashApplied||!this._model.find(t=>t.id===e.space)||"valid"===i.kind&&i.id!==e.space||this._hasFixedFloor&&"valid"!==i.kind)return void(this._warmVp=null);this._commitSpace(e.space,!0),this._navApplied=!0,this._adoptMode("view"!==e.mode&&this._canEdit&&!t.kiosk?e.mode:"view"),this._pendingNavMode="view"===e.mode||this._canEdit||t.kiosk?null:e.mode,this._zoom=e.zoom;const s=this._effectiveProjection(),n=s===e.projection&&this._labsIso===e.activeLabsIso;if(this._view=n&&e.view?{...e.view}:null,this._viewModeSnap=n&&e.snap?{...e.snap}:null,!n&&e.logicalCenter){const t="iso"===s?Xg([e.logicalCenter.x,e.logicalCenter.y],0):[e.logicalCenter.x,e.logicalCenter.y];this._applyView(e.zoom,t[0],t[1])}var o;this._tool="opening"===(o=function(t){return"partition"===t?"draw":t}(o=e.tool))?"draw":"string"==typeof o&&av.has(o)?o:"draw",this._decorTool=e.decorTool,this._showHidden=e.showHidden,this._showFar!==e.showFar&&(this._showFar=e.showFar,this._frame=null),this._selId=e.selId,this._rszSel=e.rszSel,this._decorSel=e.decorSel,this._warmVpArmed=!0}_warmPatch(t,e=!1){if(this._config?.kiosk)return;const i=Kf(this._config);if(!this._warmSlot||this._warmKey===i){if(!this._warmSlot){if(!e)return;const t=this.parentNode;this._warmKey=i,this._warmSlot={owner:this._warmGen,path:location.pathname,place:t?new WeakRef(t):null,idx:this._warmIdx(t),live:!0,hdrH:this._hdrH,stageH:0,vp:null,frameFingerprint:"",devices:null,dlg:null,freed:0,evict:0};const s=Gf.get(i)||[];for(s.push(this._warmSlot),Gf.set(i,s),this._warmTrim(s);Gf.size>8;){const t=Gf.keys().next().value;if(void 0===t||t===i)break;for(const e of Gf.get(t)||[])clearTimeout(e.evict);Gf.delete(t)}}Object.assign(this._warmSlot,t)}}_warmViewportState(){const t=this._effectiveProjection();return{space:this._space,mode:this._mode,projection:t,activeLabsIso:this._labsIso,logicalCenter:this._logicalViewCenter(t),zoom:this._zoom,view:this._view?{...this._view}:null,snap:this._viewModeSnap?{...this._viewModeSnap}:null,tool:this._tool,decorTool:this._decorTool,showHidden:this._showHidden,showFar:this._showFar,selId:this._selId,rszSel:this._rszSel,decorSel:this._decorSel}}_warmDialogState(){const t=(t,e)=>({kind:t,space:this._space,mode:this._mode,data:e});return this._tapConfirm||this._alignDialog||this._mergeDialog||this._importDialog||this._backupExportDialog||this._backupImportDialog?null:this._openingInfo?t("openingInfo",this._openingInfo.id):this._infoCard?t("info",this._infoCard.id):this._rulesDialog?this._rulesDialog.busy?null:t("rules",this._rulesDialog):this._settingsDialog?this._settingsDialog.busy?null:t("settings",this._settingsDialog):this._markerDialog?this._markerDialog.busy?null:t("marker",this._markerDialog):this._openingDialog?t("opening",this._openingDialog):this._backdropDialog?t("backdrop",this._backdropDialog):this._decorShapeDialog?t("decorShape",this._decorShapeDialog):this._decorTextDialog?t("decorText",this._decorTextDialog):this._roomDialog?t("room",{editId:this._roomEditId,fill:this._roomFill,customFill:this._roomCustomFill,tempSrc:this._roomTempSrc,humSrc:this._roomHumSrc,srcOpen:this._roomSrcOpen,srcFilter:this._roomSrcFilter,nameScale:this._roomNameScale,labelScale:this._roomLabelScale,areaSel:this._areaSel,nameSel:this._nameSel,pendingSplit:this._pendingSplit,wallFaceBatch:this._wallFaceBatch,path:this._path}):this._spaceDialog?this._spaceDialog.busy?null:t("space",this._spaceDialog):null}_warmSnapshot(){if(this._booting||this._config?.kiosk||"steady"!==this._continuity.state)return;const t={vp:this._warmViewportState(),frameFingerprint:this._continuity.frameFingerprint,devices:this._devices};if(this._warmRevivePending||(t.dlg=this._warmDialogState()),this.isConnected&&this._warmSlot?.owner===this._warmGen){const e=this.parentNode;t.place=e?new WeakRef(e):null,t.idx=this._warmIdx(e)}this._warmPatch(t)}_warmReviveDialog(){this._warmRevivePending=!1;const t=this._warmSlot;if(this._warmReviveTimer=void 0,!t||!t.dlg)return;const e=t.dlg,i=t.freed;if(t.dlg=null,t.freed=0,clearTimeout(t.evict),t.evict=0,i&&!(Date.now()-i>Yf)&&e.space===this._space&&e.mode===this._mode){switch(e.kind){case"space":this._spaceDialog={...e.data,busy:!1,savedBusy:!1};break;case"marker":this._markerDialog={...e.data,busy:!1};break;case"settings":this._settingsDialog={...e.data,busy:!1};break;case"rules":this._rulesDialog={...e.data,busy:!1};break;case"opening":this._openingDialog={...e.data};break;case"backdrop":this._backdropDialog={...e.data};break;case"decorShape":this._decorShapeDialog={...e.data};break;case"decorText":{this._decorTextDialog={...e.data};const t=String(this._decorTextDialog?.text??"").length;this._decorTextSelection={start:t,end:t};break}case"room":{const t=e.data;this._roomEditId=t.editId,this._roomFill=t.fill,this._roomCustomFill=t.customFill||null,this._roomTempSrc=t.tempSrc,this._roomHumSrc=t.humSrc,this._roomSrcOpen=t.srcOpen,this._roomSrcFilter=t.srcFilter,this._roomNameScale=t.nameScale,this._roomLabelScale=t.labelScale,this._areaSel=t.areaSel,this._nameSel=t.nameSel,this._pendingSplit=t.pendingSplit,this._wallFaceBatch=t.wallFaceBatch||null,this._path=t.path,this._wallFaceBatch&&(this._activeDraftId=this._wallFaceBatch.activeDraftId,this._draftSegmentCms=[...this._wallFaceBatch.activeCms]),this._roomDialog=!0;break}case"info":{const t=this._devices.find(t=>t.id===e.data);t&&(this._infoCard=t);break}case"openingInfo":{const t=(this._curSpaceCfg?.openings||[]).find(t=>t.id===e.data);t&&(this._openingInfo=t);break}}this.requestUpdate()}}_cacheSnapshot(){if(this._serverCfg)try{this._cfgContentFingerprint=wd(this._serverCfg),this._layoutContentFingerprint=wd(this._layout),this._virtualLights=function(t,e,i){if(t.configRev===i)return t;const s=new Set((Array.isArray(e?.markers)?e.markers:[]).filter(yn).map(t=>t.id));return{...t,configRev:i,off:new Set([...t.off].filter(t=>s.has(t)))}}(this._virtualLights,this._serverCfg,this._cfgRev),localStorage.setItem(Xf,JSON.stringify({config:this._serverCfg,rev:this._cfgRev,config_fingerprint:this._cfgContentFingerprint,layout:this._layout,layout_rev:this._layoutRev,layout_fingerprint:this._layoutContentFingerprint,virtual_lights:fn(this._virtualLights)}))}catch{}}_beginContinuityCandidate(t,e,i="plan"){return this._booting&&!this._continuity.hasCompleteFrame?this._continuity.token:(this._continuityDataReady=e,this._continuityPaintToken=-1,this._stagedDeviceSnapshotToken=-1,this._resumeSettling=!0,this._continuity.beginCandidate(t,i))}_continuityStageValid(){const t=this._stageEl;return!!t&&t.clientWidth>0&&t.clientHeight>0}_continuityAssetsReady(){if(!this._model.length)return!1;const t=this._model.length?this._spaceModel():null;return!t?.bg?.href||this._signer.isReady(this.hass,t.bg.href)}_initialSpaceSelection(t,e=this._loadOk){const i=this._fixedFloorState(t,e);return"valid"===i.kind?{id:i.id,source:"fixed"}:this._hasFixedFloor?{id:null,source:"none"}:function(t){const e=new Set(t.spaceIds.filter(t=>!!t));if(!e.size)return{id:null,source:"none"};const i=[["hash",!1===t.acceptHash?null:t.hashSpace],["current",t.preserveCurrent?t.currentSpace:null],["saved",t.savedSpace],["default",t.defaultSpace],["first",t.spaceIds[0]]];for(const[t,s]of i)if(s&&e.has(s))return{id:s,source:t};return{id:null,source:"none"}}({spaceIds:t.map(t=>t.id),hashSpace:this._hashSpace(),acceptHash:!this._hashApplied,currentSpace:this._space,preserveCurrent:this._hashApplied||this._navApplied||this._warmVpArmed,savedSpace:this._savedNav()?.space,defaultSpace:this._config?.default_floor})}_adoptInitialSpace(t,e=this._loadOk){const i=this._initialSpaceSelection(t,e);return i.id?(this._commitSpace(i.id,!0),"hash"===i.source&&(this._hashApplied=!0),"saved"===i.source&&(this._navApplied=!0),i):i}_candidateBackdrop(t,e=this._space){const i=Sh(t),s=this._fixedFloorState(i,!0);if(this._hasFixedFloor&&"valid"!==s.kind)return"";const n=this._initialSpaceSelection(i,!0).id||(i.some(t=>t.id===e)?e:i[0]?.id);return i.find(t=>t.id===n)?.bg?.href||""}_visualFrameFingerprint(){const t=this._stageEl,e=t?[t.clientWidth,t.clientHeight]:[0,0];return kd([this._cfgRev,this._cfgContentFingerprint||wd(this._serverCfg),this._layoutRev,this._layoutContentFingerprint||wd(this._layout),this._space,this._mode,this._view,e,this._glowScreenBlend?"screen":"normal",this.hass?.themes?.darkMode??this.hass?.themes?.default_theme??""])}_settleContinuityFrame(){if(this._booting||!this._continuityStageValid())return;if(!this._continuity.hasCompleteFrame&&"steady"===this._continuity.state)return void(this._continuityAssetsReady()&&(this._renderSnapshotAt=Date.now(),this._continuity.markCompleteFrame(this._visualFrameFingerprint())));if(!this._continuityDataReady)return;if(!["holding","offline-stale","overlay-pending","overlay-visible","candidate-ready"].includes(this._continuity.state))return;const t=this._continuity.token;if(this._candidateDeviceSnapshot&&this._candidateDeviceSnapshot!==this._visibleDeviceSnapshot&&this._stagedDeviceSnapshotToken!==t)return this._stagedDeviceSnapshotToken=t,void this.requestUpdate();this._continuityPaintToken!==t&&(this._continuityPaintToken=t,this._continuity.candidateReady(t)&&this._continuity.commitAfterPaint(t,{updateComplete:()=>this.updateComplete,stageValid:()=>this.isConnected&&this._continuityStageValid(),assetsReady:()=>this._continuityAssetsReady(),frameFingerprint:()=>this._visualFrameFingerprint()}).then(e=>{e&&t===this._continuity.token?(this._resumeSettling=!1,this._renderSnapshotAt=Date.now(),this._candidateDeviceSnapshot&&(this._visibleDeviceSnapshot=this._candidateDeviceSnapshot),this._candidateDeviceSnapshot=null,this._stagedDeviceSnapshotToken=-1,this._warmSnapshot()):t===this._continuity.token&&(this._continuityPaintToken=-1,this._stagedDeviceSnapshotToken=-1,this._candidateDeviceSnapshot=null,this.requestUpdate())}))}_onBackdropLoaded(t,e){this._signer.markLoaded(this.hass,t,e),this._continuity.note("asset-ready"),this._continuityPaintToken=-1,"steady"!==this._continuity.state&&this.requestUpdate()}_renderRecoveryOverlay(){if(!this._continuity.overlayVisible&&"recovery-error"!==this._continuity.state)return G;const t="connection"===this._continuity.recoveryReason;return W`
t.stopPropagation()} @click=${t=>t.stopPropagation()} diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index f58656e8..81e54dc3 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +## v1.68.1 — 2026-08-27 + - Creating a space no longer reports `v8+ space requires wall_segments` while leaving an unsaved ghost space on screen; a failed space save now restores the server-backed state before another create or delete diff --git a/docs/CHANGELOG.ru.md b/docs/CHANGELOG.ru.md index 6d482bc0..92ead00a 100755 --- a/docs/CHANGELOG.ru.md +++ b/docs/CHANGELOG.ru.md @@ -8,6 +8,8 @@ ## Не выпущено +## v1.68.1 — 2026-08-27 + - Создание пространства больше не выдаёт ошибку `v8+ space requires wall_segments` и не оставляет на экране несохранённое пространство-призрак; после неудачного сохранения состояние возвращается к diff --git a/docs/RELEASE-NOTES.md b/docs/RELEASE-NOTES.md index 05746369..f9ad9e77 100644 --- a/docs/RELEASE-NOTES.md +++ b/docs/RELEASE-NOTES.md @@ -1,18 +1,14 @@ - + ## Основное -- Стены получили стабильные ID: Resize, Undo/Redo, импорт, оптимизация и повторные правки сохраняют толщину и проёмы; переход на новую модель выполняется атомарно и сам разрешает конфликты старых границ с проёмами. -- Виртуальные стены заменены обычными стенами толщиной 0 см. Пунктирный вид пропускает Glow и солнце, сплошной работает как световой барьер. -- Перед первым структурным сохранением или «Оптимизировать планы» рекомендуется экспортировать резервную копию: старые версии не понимают новую модель стен. +- Исправлено создание и удаление пространств: новый план больше не получает ошибку `v8+ space requires wall_segments`, а неудачная запись не оставляет несохранённое пространство. - Мелкие исправления и улучшения. ## Highlights -- Walls now have stable IDs: Resize, Undo/Redo, import, optimization and repeated edits preserve thickness and openings; the new model upgrades atomically and resolves legacy boundary/opening conflicts by itself. -- Virtual walls are replaced by ordinary 0 cm walls. Dashed walls transmit Glow and sunlight, while solid ones act as light barriers. -- Exporting a backup before the first structural save or Optimize plans run is recommended because older versions do not understand the new wall model. +- Fixed space creation and deletion: a new plan no longer reports `v8+ space requires wall_segments`, and a rejected save no longer leaves an unsaved space behind. - Small fixes and improvements. -[Полный список изменений на русском](https://github.com/Matysh/houseplan-card/blob/v1.68.0/docs/CHANGELOG.ru.md) -· [Full changelog in English](https://github.com/Matysh/houseplan-card/blob/v1.68.0/docs/CHANGELOG.md) +[Полный список изменений на русском](https://github.com/Matysh/houseplan-card/blob/v1.68.1/docs/CHANGELOG.ru.md) +· [Full changelog in English](https://github.com/Matysh/houseplan-card/blob/v1.68.1/docs/CHANGELOG.md) diff --git a/docs/STATUS.md b/docs/STATUS.md index 07979e13..b0c6b378 100644 --- a/docs/STATUS.md +++ b/docs/STATUS.md @@ -21,8 +21,8 @@ metadata). Only an explicit owner-approved emergency hotfix may skip this gate. | Item | State | |---|---| -| Version | **v1.68.0** everywhere (manifest, const.py, package.json, CARD_VERSION) — stable promotion of the published v1.68.0-beta.4 product line | -| Current local cycle | v1.68.0 promotes the exact product behaviour already published through beta.4: stable wall-segment identity and atomic model-v9 migration, unified zero-thickness walls, repaired junction rendering and reliable plan editing. The complete local suite and exact-tree Validate are green. Stable-gate diagnostics exposed infrastructure-only defects: legacy v1.66.0 lacked the current bundle materializer, five full 7-sample profile pairs could not fit a 60-minute serial job, and the comparative launcher initially validated an old served bundle against the candidate tree. Old baselines now use an equivalent fresh-bundle fallback, each target is freshness-checked against its own exact tree, and independent profile pairs run in parallel while retaining same-runner sequential base/candidate comparison. These repairs change no shipped bundle or product behaviour; their exact-SHA Validate and Full Performance remain the publication gates. | +| Version | **v1.68.1** everywhere (manifest, const.py, package.json, CARD_VERSION) — owner-approved emergency patch release for space creation and deletion (#324) | +| Current local cycle | v1.68.1 is a promotion-only emergency hotfix over v1.68.0: canonical empty spaces now include the required v8/v9 wall catalogue, and rejected space writes restore server-backed state before another create or delete. No other product behaviour is added in the release commit. The complete local suite plus exact-SHA Validate and Full Performance remain the publication gates. | | Hidden Labs Stage | #89 Stage 1 ships in v1.63.0-beta.1. #122 Stage 2 ships in v1.64.0 and evolves the same hidden, expiring `iso` experiment with matte walls, a low exterior floor edge, restrained shared shadows and live vertical door/window/gate panels. Flat remains default; editors and `houseplan-space-card` remain flat; live floor effects and HA actions remain unchanged. Public activation remains a separate task. | | Workflow | Superseded 2026-08-12: the pre-1.62 rule of "local edits without tests or commits" is **dead** — since release 1.62 every product change follows `PROCESS.md` (issue in `S5-ready`+, branch `issue/-slug`, trailers on every commit, review pipeline; `AGENTS.md` is the summary). Release mechanics below remain current. A requested pre-release gets a production build plus the smallest targeted unit/smoke set covering the changed surfaces, one tested `dev` commit/tag and a GitHub Release with `prerelease=true`; `main` stays untouched. The complete local frontend/backend/smoke gate runs only before a stable release, after which `main` is fast-forwarded to the exact tested `dev` SHA and the GitHub Release uses `prerelease=false`. Release bodies are short and bilingual (Russian first): only significant user changes get individual bullets, while minor/code-only work is grouped as `Мелкие исправления и улучшения` / `Small fixes and improvements`; every body ends with separate links to the Russian and English changelogs. Detailed RU/EN changelog bullets may link the corresponding closed GitHub Issues; open or partially delivered issues are never presented as shipped. Telegram announcements are sent only for stable releases; beta and RC publication is silent. `docs/RELEASE-NOTES.md` is the current canonical body instance; `npm run release:prerelease -- --issues=… --yes` is the primary local publication path and the manual `Publish prerelease` workflow is its GitHub-only equivalent once present on `main`. Nothing is copied to the home instance by hand | | GitHub | https://github.com/Matysh/houseplan-card — [Issues](https://github.com/Matysh/houseplan-card/issues) are the canonical task records; their labels carry priority and workflow status (`PROCESS.md` §9). GitHub Projects is no longer used. `main` carries stable releases; pre-release tags may point directly at `dev`. Work lands on `dev` and is merged into `main` for a stable release, so `dev` is normally equal to or ahead of `main`, never behind. Push via SSH key `ha_jb` (remote git@github.com:…); API releases via the fine-grained PAT in `~/.git-credentials` (Contents R/W, issued 2026-07-23) | diff --git a/package-lock.json b/package-lock.json index 1056624b..60be977e 100755 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "houseplan-card", - "version": "1.68.0", + "version": "1.68.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "houseplan-card", - "version": "1.68.0", + "version": "1.68.1", "license": "MIT", "dependencies": { "lit": "^3.1.3", diff --git a/package.json b/package.json index 163340c4..4b7054da 100755 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "houseplan-card", - "version": "1.68.0", + "version": "1.68.1", "description": "Interactive house plan Lovelace card for Home Assistant", "license": "MIT", "type": "module", diff --git a/src/houseplan-card.ts b/src/houseplan-card.ts index 0586e3d0..9b67f9a5 100755 --- a/src/houseplan-card.ts +++ b/src/houseplan-card.ts @@ -318,7 +318,7 @@ import { } from './space-order'; import { applyOpeningMoves, mergeCollinearPartitions, spaceMergeGeometry } from './wall-merge'; -const CARD_VERSION = '1.68.0'; +const CARD_VERSION = '1.68.1'; type ResizeLiveLabel = { kind: 'length';