svg{position:absolute;inset:0;width:100%;height:100%;display:block;z-index:1;}.hp-static-stage>.hp-paper-outline-svg{z-index:0;overflow:visible;}.hp-paper{fill:var(--ha-card-background,var(--card-background-color,#111));stroke:none;}.wallbody-fill{fill:var(--wall-fill,#ffffff);fill-opacity:var(--wall-fill-op,1);fill-rule:evenodd;stroke:none;pointer-events:none;}.wallbody{fill:url(#hp-wall-hatch);fill-rule:evenodd;stroke:var(--room-stroke,var(--hp-muted,#607d8b));stroke-width:calc(0.6px * var(--hp-cell-visual-scale,1));pointer-events:none;}.wallbody.solid{fill:none;}.hp-static-stage .devlayer{position:absolute;inset:0;z-index:2;}.hp-static-foot{padding:8px 12px 12px;pointer-events:auto;}.hp-static-btn{width:100%;padding:9px 14px;border:none;border-radius:10px;background:var(--primary-color,#3ea6ff);color:var(--text-primary-color,#fff);font-size:14px;font-weight:600;cursor:pointer;}:host([data-pointer-hover]) .hp-static-btn:hover{filter:brightness(1.08);}.hp-static-error{padding:24px;text-align:center;color:var(--secondary-text-color,#9aa4ad);}`],customElements.get("houseplan-space-card")||customElements.define("houseplan-space-card",_g),window.customCards=window.customCards||[],window.customCards.find(e=>"houseplan-space-card"===e.type)||window.customCards.push({type:"houseplan-space-card",name:"House Plan — Space (static)",description:"Read-only live schematic of a single houseplan space, with a deep-link button.",preview:!1,documentation:"https://github.com/Matysh/houseplan-card"});const mg=o`:host{--hp-editor-tray-bg-fallback:color-mix(in srgb,var(--card-background-color,var(--hp-bg)) 94%,var(--hp-line));--hp-editor-tray-bg:color-mix(in srgb,var(--card-background-color,var(--hp-bg)) 86%,transparent);--hp-editor-tray-border:color-mix(in srgb,var(--hp-line) 82%,var(--hp-accent));--hp-editor-tray-blur:8px;--hp-editor-tray-shadow:var(--shadow-2);}.editor-secondary-host{position:absolute;inset:var(--sp-2) var(--sp-4) auto;z-index:70;display:flex;justify-content:flex-end;pointer-events:none;}.editor-secondary-host.kind-palette,.editor-secondary-host.kind-group{justify-content:flex-start;}.editor-secondary{pointer-events:none;max-width:100%;display:flex;align-items:center;gap:var(--sp-3);padding:var(--sp-3) var(--sp-4);color:var(--hp-txt);background:var(--card-background-color,var(--hp-bg));background:var(--hp-editor-tray-bg-fallback);border:1px solid var(--hp-line);border-color:var(--hp-editor-tray-border);border-radius:var(--rad-l);box-shadow:var(--hp-editor-tray-shadow);opacity:0;visibility:hidden;transform:translateY(-4px);transition:opacity 0.1s ease,transform 0.1s cubic-bezier(0.2,0.7,0.2,1),visibility 0s linear 0.1s;touch-action:auto;}.editor-secondary-host.open .editor-secondary{pointer-events:auto;opacity:1;visibility:visible;transform:translateY(0);transition-duration:0.14s,0.14s,0s;transition-delay:0s;}.editor-secondary-host.blocked .editor-secondary{pointer-events:none;}@supports ((backdrop-filter:blur(1px)) or (-webkit-backdrop-filter:blur(1px))){.editor-secondary{background:var(--hp-editor-tray-bg);-webkit-backdrop-filter:blur(var(--hp-editor-tray-blur));backdrop-filter:blur(var(--hp-editor-tray-blur));}}.editor-secondary-content,.editor-group-items{display:flex;align-items:center;gap:var(--sp-3);min-width:0;}.editor-context-label{max-width:14rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;padding-inline-end:var(--sp-4);border-inline-end:1px solid var(--hp-line);color:var(--hp-muted);font-size:var(--fs-s);}.editor-secondary.kind-palette{width:min(760px,100%);align-items:stretch;padding:0;overflow:hidden;}.editor-secondary.kind-palette .editor-secondary-content,.editor-secondary.kind-palette .furnpalette{width:100%;}.editor-secondary.kind-palette .furnpalette{max-height:38vh;border:0;background:transparent;}.editor-group-launcher .group-chevron{--mdc-icon-size:16px;transition:transform 0.14s ease;}.editor-group-launcher[aria-expanded="true"] .group-chevron{transform:rotate(180deg);}.editor-secondary .bdhint{font-size:var(--fs-s);color:var(--hp-muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}.editor-secondary .dfill{display:inline-flex;align-items:center;gap:var(--sp-2);font-size:var(--fs-s);cursor:pointer;}.editor-secondary .dfill input[type="checkbox"]{width:16px;height:16px;flex:none;margin:0;padding:0;}.editor-secondary hp-color-opacity{flex:0 0 auto;}.editor-secondary input{width:74px;background:transparent;border:1px solid var(--hp-line);color:var(--hp-txt);border-radius:var(--rad-s);padding:var(--sp-3) var(--sp-4);font-size:var(--fs-m);}.editor-secondary label,.editor-secondary .hint{color:var(--hp-muted);font-size:var(--fs-s);}.editor-secondary .drawwall{display:inline-flex;align-items:center;gap:var(--sp-3);white-space:nowrap;}.editor-secondary .drawwall input{width:4.2em;}.editor-secondary .drawwall .opl{color:var(--hp-muted);font-size:var(--fs-s);}@container (min-width:560px) and (max-width:899px){.editor-secondary-content,.editor-group-items{flex-wrap:wrap;justify-content:flex-end;}}@container (max-width:559px){.editor-secondary-host{inset-inline:var(--sp-4);}.editor-secondary{max-width:100%;}.editor-secondary-content,.editor-group-items{overflow-x:auto;scrollbar-width:thin;}.editor-secondary-content>*,.editor-group-items>*{flex:none;}.editor-context-label{display:none;}}@media (prefers-reduced-motion:reduce){.editor-secondary{transition:none;}.editor-group-launcher .group-chevron{transition:none;}}`;class gg{constructor(e=50){this._undo=[],this._redo=[],this._limit=Math.max(30,Math.floor(e))}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(e){this._undo.push(e),this._undo.length>this._limit&&this._undo.splice(0,this._undo.length-this._limit),this._redo=[]}undo(){const e=this._undo.pop()??null;return e&&this._redo.push(e),e}redo(){const e=this._redo.pop()??null;return e&&this._undo.push(e),e}removeWhere(e){const t=this._undo.length,i=this._redo.length;return this._undo=this._undo.filter(t=>!e(t)),this._redo=this._redo.filter(t=>!e(t)),t+i-this._undo.length-this._redo.length}clear(){this._undo=[],this._redo=[]}}function fg(e,t){const i=e[t];return i&&Number.isFinite(i.x)&&Number.isFinite(i.y)?{x:i.x,y:i.y,..."string"==typeof i.s?{s:i.s}:{}}:null}function vg(e,t,i){if(null===i){if(!(t in e))return e;const i={...e};return delete i[t],i}const n={...e[t]||{}};delete n.x,delete n.y,delete n.s;const r={...n,x:i.x,y:i.y,...void 0!==i.s?{s:i.s}:{}};return{...e,[t]:r}}const yg="houseplan-card:version-reload-target:v1";function bg(e){if("string"!=typeof e)return null;return e.trim()||null}class wg{constructor(e){this.hooks=e,this._input={frontendVersion:null,backendVersion:null,kiosk:!1,reducedMotion:!1},this._relation={kind:"unknown"},this._banner=null,this._connected=!1,this._attemptTarget=null,this._attemptState=null,this._noticeToken=0}get relation(){return this._relation}get banner(){return this._banner}get hasCurrentMismatchNotice(){return"mismatch"===this._relation.kind&&"visible"===this._banner?.phase}connect(){this._connected||(this._connected=!0,this._attemptTarget=null,this._attemptState=null,this._reconcile())}disconnect(){(this._connected||this._banner)&&(this._connected=!1,this._cancelTimer(),this._banner&&(this._banner=null,this.hooks.changed()))}update(e){const t={frontendVersion:bg(e.frontendVersion),backendVersion:bg(e.backendVersion),kiosk:!0===e.kiosk,reducedMotion:!0===e.reducedMotion},i=function(e,t){const i=bg(e),n=bg(t);return i&&n?i===n?{kind:"equal",frontend:i,backend:n}:{kind:"mismatch",frontend:i,backend:n}:{kind:"unknown"}}(t.frontendVersion,t.backendVersion),n=!((e,t)=>e.frontendVersion===t.frontendVersion&&e.backendVersion===t.backendVersion&&e.kiosk===t.kiosk&&e.reducedMotion===t.reducedMotion)(this._input,t)||!((e,t)=>e.kind===t.kind&&("unknown"===e.kind||"unknown"!==t.kind&&e.frontend===t.frontend&&e.backend===t.backend))(this._relation,i);this._input=t,this._relation=i,n&&this._reconcile()}finishBannerExit(e){this._banner&&"leaving"===this._banner.phase&&this._banner.token===e&&(this._banner=null,this.hooks.changed())}_reconcile(){if(this._cancelTimer(),!this._connected||"mismatch"!==this._relation.kind)return this._attemptTarget=null,this._attemptState=null,void this._hideBanner();if(!this._input.kiosk)return this._attemptTarget=null,this._attemptState=null,void this._showBanner(this._relation.frontend,this._relation.backend);const e=this._relation.backend;if(this._attemptTarget===e&&null!==this._attemptState||(this._attemptTarget=e,this._attemptState=function(e,t){try{const i=e();return i?i.getItem(yg)===t?"attempted":"fresh":"unavailable"}catch{return"unavailable"}}(this.hooks.storage,e)),"fresh"===this._attemptState)return this._hideBanner(),void this._armTimer();this._showBanner(this._relation.frontend,e)}_armTimer(){this._connected&&void 0===this._timer&&"mismatch"===this._relation.kind&&this._input.kiosk&&"fresh"===this._attemptState&&(this._timer=this.hooks.clock.setTimeout(()=>{this._timer=void 0,this._tick()},250))}_cancelTimer(){void 0!==this._timer&&(this.hooks.clock.clearTimeout(this._timer),this._timer=void 0)}_tick(){if(!this._connected||"mismatch"!==this._relation.kind||!this._input.kiosk||"fresh"!==this._attemptState)return;if(!function(e){return e.connected&&e.initialFrameSettled&&e.viewOnly&&e.surfacesIdle&&e.configWritesIdle&&e.physicalWritesIdle&&e.layoutWritesIdle&&e.gesturesIdle&&e.interactionPauseElapsed&&e.baseZoom}(this.hooks.safety()))return void this._armTimer();const e=this._relation.backend,t=function(e,t){try{const i=e();return i?i.getItem(yg)===t?"attempted":(i.setItem(yg,t),"claimed"):"unavailable"}catch{return"unavailable"}}(this.hooks.storage,e);if(this._attemptTarget=e,this._attemptState="claimed"===t?"attempted":t,"claimed"===t){this._showBanner(this._relation.frontend,e);try{this.hooks.reload()}catch{}}else this._showBanner(this._relation.frontend,e)}_showBanner(e,t){"visible"===this._banner?.phase&&this._banner.frontend===e&&this._banner.backend===t||(this._banner={frontend:e,backend:t,phase:"visible",token:++this._noticeToken},this.hooks.changed())}_hideBanner(){if(this._banner)return this._input.reducedMotion?(this._banner=null,void this.hooks.changed()):void("leaving"!==this._banner.phase&&(this._banner={...this._banner,phase:"leaving",token:++this._noticeToken},this.hooks.changed()))}}const kg=1;function xg(e,t){const i=t&&"object"==typeof t?t:{};e._haIntegrationVersion=bg(i.integration_version);const n=i.support_api;e._haSupportApi="number"==typeof n&&Number.isSafeInteger(n)?n:null,e._haDecorAssetsApi=1===i.decor_assets_api?1:null,e._haSummaryPanelApi=1===i.summary_panel_api?1:null,e._haRadarStage1Api=1===i.radar_stage1_api?1:null,e._syncVersionRecovery()}function Sg(e){const t=e._stageEl,i=e._loadOk&&!e._loading&&e._continuityDataReady&&!e._resumeSettling&&!e._connectionWasLost&&!e._booting&&!e._bootFading&&!e._bootSettling&&!e._bootSoft&&e._continuity.hasCompleteFrame&&"steady"===e._continuity.state&&!e._continuity.overlayBlocksInteraction&&!!t&&t.clientWidth>0&&t.clientHeight>0,n=!(0!==e._pointers.size||0!==e._touchContacts.size||e._touchSequenceMultitouch||e._roomPointer||e._panStart||e._panLock||e._pinchStart||e._swipeStart||e._tabDrag||e._tabDragRelease||e._drag||e._deviceDrag||e._rlResize||e._resize?.dragging||e._physicalDrag||e._physicalRotate||e._opDrag||e._decorDraft||e._decorMove||e._dtDrag||e._bdDrag||e._furnTouchPending||e._compassDrag||e._viewportGestureDirty||e._devicePositionBusy||e._modeTransitionBusy||e._cameraTransition.active||e._slide||0!==e._warmModeRequest),r=!(e._editorSecondaryDialogBlocked||e._partitionDeleteDialog||e._roomDeleteDialog||e._backdropGuard||e._vacFit||e._editorSecondary?.hasOpenGroup||e._furnPalette||e._decorImagePalette);return{connected:e.isConnected,initialFrameSettled:i,viewOnly:!0===e._config?.kiosk&&"view"===e._mode&&!e._editing,surfacesIdle:r,configWritesIdle:0===e._writesPending&&!e._saveConfigDebounced.pending(),physicalWritesIdle:0===e._pendingPhysicalWrites.size,layoutWritesIdle:!e._persistLayout.pending()&&0===e._dirtyPos.size&&0===e._sentPos.size&&!e._devicePositionBusy,gesturesIdle:n,interactionPauseElapsed:Date.now()>=e._cyclePausedUntil,baseZoom:e._zoom<=1.001}}class $g{constructor(){this.seen=null,this.diagnosticsCache=null}observe(e,t,i,n){this.invalidateDiagnosticsForHass(e,t,i),this.intake(t,n)}intake(e,t){e&&this.seen!==e&&(this.seen=e,t())}invalidate(){this.diagnosticsCache=null}invalidateDiagnosticsForHass(e,t,i){this.diagnosticsCache&&(e?.entities!==t?.entities||e?.devices!==t?.devices||[...i?.entityIds||[]].some(i=>!!e?.states?.[i]!=!!t?.states?.[i]))&&this.invalidate()}diagnostics(e,t,i){if(this.diagnosticsCache)return this.diagnosticsCache;const n={active:0,ha_disabled:0,orphaned:0,unverified:0};for(const e of t)e.removed||"virtual"===e.binding||n[i(e.binding).kind]++;return this.diagnosticsCache={registry:ud(e),bindings:n},this.diagnosticsCache}}function Mg(e){const t=e;t._hassSequence++,t._renderSnapshotAt=Date.now(),t._continuity.note("hass-snapshot"),t._ensureHaRegistryAuthority(),t._planHassMemo=null,t._hookConnection(),!t._loadOk&&!t._loading&&t._loadTries<8&&t._loadFromServer(),t._maybeRebuildDevices(),t._vacTick(),t._activityTick()}function Rg(e){return!!e&&"object"==typeof e&&1===e.version}function Cg(e,t){const i=e.radar;return e.space===t&&!0!==e.hidden&&!0!==e.removed&&Rg(i)&&!0===i.enabled&&!1!==i.show_live}const Tg={ok:"radar.health_ok",off:"radar.health_off",stale:"radar.health_stale",partial:"radar.health_partial",restricted:"radar.health_restricted",incomplete:"radar.health_incomplete",position_unavailable:"radar.health_position_unavailable",unavailable:"radar.health_unavailable",needs_setup:"radar.health_needs_setup",inconsistent:"radar.health_inconsistent",unknown:"radar.health_unknown"};const Dg=e=>"number"==typeof e&&Number.isFinite(e);class Ag{constructor(e){this.host=e,this.frames=new Map,this.connection=null,this.space="",this.generation=0,this.expiryTimer=0,this.deadlines=new Map}sync(e,t){const i=this.host.hass?.connection;if(!t||!i||!this.host.isConnected)return void this.stop();if(this.unsubscribe&&this.connection===i&&this.space===e)return;this.stop(),this.connection=i,this.space=e;const n=++this.generation,r=i.subscribeMessage?.bind(i);"function"==typeof r&&Promise.resolve(r(e=>{if(n!==this.generation||!this.host.isConnected)return;const t=function(e){if(!e||"object"!=typeof e)return null;const t=e;if("string"!=typeof t.marker_id||"string"!=typeof t.server_session_id||!Number.isSafeInteger(t.seq)||"string"!=typeof t.health)return null;const i=Array.isArray(t.targets)?t.targets.slice(0,256).flatMap(e=>{if(!e||"object"!=typeof e)return[];const t=e;return"string"==typeof t.slot&&Dg(t.x)&&Dg(t.y)&&Dg(t.expires_at)&&Dg(t.reported_at)&&("bounded_latest"===t.pair_quality||"coherent"===t.pair_quality)?[{...t,included:!0===t.included,smooth:!0===t.smooth}]:[]}):[],n=Array.isArray(t.ranges)?t.ranges.slice(0,64).flatMap(e=>{if(!e||"object"!=typeof e)return[];const t=e;if(!("string"==typeof t.id&&Dg(t.x)&&Dg(t.y)&&Dg(t.radius)&&Dg(t.expires_at)&&Dg(t.reported_at)))return[];const i=Array.isArray(t.segments)?t.segments.slice(0,64).flatMap(e=>{if(!Array.isArray(e))return[];const t=e.slice(0,181).flatMap(e=>Array.isArray(e)&&2===e.length&&Dg(e[0])&&Dg(e[1])?[[e[0],e[1]]]:[]);return t.length>=2?[t]:[]}):void 0;return[{...t,...i?{segments:i}:{}}]}):[],r=Array.isArray(t.zones)?t.zones.slice(0,64).flatMap(e=>{if(!e||"object"!=typeof e)return[];const t=e;if("string"!=typeof t.id)return[];const i=t.state;if(null!==i&&"boolean"!=typeof i&&!Dg(i))return[];const n=Array.isArray(t.polygon)?t.polygon.slice(0,64).flatMap(e=>Array.isArray(e)&&2===e.length&&Dg(e[0])&&Dg(e[1])?[[e[0],e[1]]]:[]):[];return[{id:t.id,state:i,...n.length>=3?{polygon:n}:{}}]}):[];return{server_session_id:t.server_session_id,marker_id:t.marker_id,source_generation:"string"==typeof t.source_generation?t.source_generation:void 0,calibration_revision:"string"==typeof t.calibration_revision?t.calibration_revision:void 0,seq:t.seq,reported_at:Dg(t.reported_at)?t.reported_at:void 0,expires_at:Dg(t.expires_at)?t.expires_at:void 0,health:t.health,reported_presence:"boolean"==typeof t.reported_presence?t.reported_presence:null,complete:!0===t.complete,targets:i,ranges:n,zones:r}}(e);if(!t)return;if(!function(e,t){return!e||t.server_session_id!==e.server_session_id||t.source_generation!==e.source_generation||t.calibration_revision!==e.calibration_revision||t.seq>e.seq}(this.frames.get(t.marker_id),t))return;const i=function(e,t=Date.now()){if(!Dg(e.expires_at))return null;if(!Dg(e.reported_at))return Math.max(0,1e3*e.expires_at-t);const i=Math.max(0,1e3*(e.expires_at-e.reported_at)),n=Math.max(0,t-1e3*e.reported_at);return Math.max(0,i-n)}(t);"restricted"===t.health||"disabled"===t.health||0===i?(this.frames.delete(t.marker_id),this.deadlines.delete(t.marker_id)):(this.frames.set(t.marker_id,t),null==i?this.deadlines.delete(t.marker_id):this.deadlines.set(t.marker_id,this.monotonicNow()+i)),this.armExpiry(),this.host.requestUpdate()},{type:"houseplan/radar/subscribe",space_id:e})).then(e=>{n===this.generation&&this.host.isConnected?"function"==typeof e&&(this.unsubscribe=e):"function"==typeof e&&e()}).catch(()=>{n===this.generation&&this.stop()})}stop(){this.generation++,this.unsubscribe?.(),this.unsubscribe=void 0,this.connection=null,this.space="",clearTimeout(this.expiryTimer),this.expiryTimer=0,this.frames.size&&(this.frames.clear(),this.host.isConnected&&this.host.requestUpdate()),this.deadlines.clear()}armExpiry(){clearTimeout(this.expiryTimer);const e=this.monotonicNow(),t=[...this.deadlines.values()].filter(t=>t>e);if(!t.length)return;const i=Math.max(20,Math.min(...t)-e+10);this.expiryTimer=window.setTimeout(()=>{this.expiryTimer=0;let e=!1;const t=this.monotonicNow();for(const[i,n]of this.deadlines)n>t||(this.deadlines.delete(i),this.frames.delete(i),e=!0);this.armExpiry(),e&&this.host.isConnected&&this.host.requestUpdate()},i)}monotonicNow(){return globalThis.performance?.now?.()??Date.now()}}const Pg=Object.freeze({enabled:!1,z2mBaseTopics:Object.freeze([])});function Fg(e){if("string"!=typeof e)return null;const t=e.trim().replace(/^\/+|\/+$/g,"").replace(/\/{2,}/g,"/");return!t||t.length>180||/[#+\u0000-\u001f\u007f]/.test(t)?null:t}function zg(e){const t=e?.zigbee_topology;if(!t||"object"!=typeof t)return Pg;const i=t,n=Array.isArray(i.z2m_base_topics)?i.z2m_base_topics:Array.isArray(i.z2mBaseTopics)?i.z2mBaseTopics:[],r=new Set,o=[];for(const e of n){const t=Fg(e);if(t&&!r.has(t)&&(r.add(t),o.push(t),8===o.length))break}return{enabled:!0===i.enabled,z2mBaseTopics:o}}function Ig(e,t){const i={...e},n=t.z2mBaseTopics.map(Fg).filter(Boolean);return t.enabled||n.length?i.zigbee_topology={enabled:!0===t.enabled,z2m_base_topics:[...new Set(n)].slice(0,8)}:delete i.zigbee_topology,i}const Og={now:()=>performance.now(),requestFrame:e=>requestAnimationFrame(e),cancelFrame:e=>cancelAnimationFrame(e)},Eg=e=>Math.max(0,Math.min(1,e)),Ng=(e,t,i)=>e+(t-e)*i,Hg=(e,t,i)=>{const n=1-e;return 3*n*n*e*t+3*n*e*e*i+e*e*e},Lg=e=>{const t=Eg(e);if(0===t||1===t)return t;let i=0,n=1,r=t;for(let e=0;e<12;e++)r=(i+n)/2,Hg(r,.2,.2)
0&&e.w>0?t/e.w:1,viewBox:{...e}}}function qg(e,t,i){const n=Math.max(1e-9,e.pixelsPerUnit),r=Math.max(1e-9,t/n),o=Math.max(1e-9,i/n);return{x:e.centerX-r/2,y:e.centerY-o/2,w:r,h:o}}function jg(e){const t=e.trim(),i=/^rgba?\(\s*([\d.]+)[, ]+([\d.]+)[, ]+([\d.]+)(?:\s*[,/]\s*([\d.]+))?\s*\)$/i.exec(t);if(i)return[Number(i[1]),Number(i[2]),Number(i[3]),null==i[4]?1:Number(i[4])];const n=/^#([0-9a-f]{6}|[0-9a-f]{8})$/i.exec(t)?.[1];return n?[parseInt(n.slice(0,2),16),parseInt(n.slice(2,4),16),parseInt(n.slice(4,6),16),8===n.length?parseInt(n.slice(6,8),16)/255:1]:null}function Wg(e,t,i){const n=jg(e),r=jg(t);if(!n||!r)return i<.5?e:t;const o=Eg(i);return`rgba(${Math.round(Ng(n[0],r[0],o))}, ${Math.round(Ng(n[1],r[1],o))}, ${Math.round(Ng(n[2],r[2],o))}, ${Ng(n[3],r[3],o).toFixed(3)})`}class Ug{constructor(e,t=Og){this._hooks=e,this._clock=t,this._token=0,this._raf=0,this._state=null}get state(){return this._state}get active(){return"running"===this._state?.phase||"preparing"===this._state?.phase}get presented(){return this._state?.presented||null}start(e,t,i,n=220){this.cancel(!1);const r=++this._token,o=this._clock.now();if(this._state={token:r,phase:n<=0?"settling":"running",from:e,to:t,presented:n<=0?t:e,startedAt:o,duration:Math.max(0,n),targetMode:i},n<=0)return this._hooks.frame(this._state),this._hooks.settled(this._state),this._state=null,r;this._hooks.frame(this._state);const s=e=>{const t=this._state;if(!t||t.token!==r)return;const i=Eg((e-t.startedAt)/t.duration);t.presented=i>=1?t.to:function(e,t,i){const n=Lg(i),r=Ng(e.stageWidth,t.stageWidth,n),o=Ng(e.stageHeight,t.stageHeight,n),s=Math.max(1e-9,e.viewport.pixelsPerUnit),a=Math.max(1e-9,t.viewport.pixelsPerUnit),l={centerX:Ng(e.viewport.centerX,t.viewport.centerX,n),centerY:Ng(e.viewport.centerY,t.viewport.centerY,n),pixelsPerUnit:Math.exp(Ng(Math.log(s),Math.log(a),n))};return{presentedMode:n<.5?e.presentedMode:t.presentedMode,editorChromeHeight:Ng(e.editorChromeHeight,t.editorChromeHeight,n),stageWidth:r,stageHeight:o,viewport:{...l,viewBox:qg(l,r,o)},stageColor:Wg(e.stageColor,t.stageColor,n),paperColor:Wg(e.paperColor,t.paperColor,n),sceneBrightness:Ng(e.sceneBrightness,t.sceneBrightness,n),architectureOpacity:Ng(e.architectureOpacity,t.architectureOpacity,n),backdropOpacity:Ng(e.backdropOpacity,t.backdropOpacity,n),viewWeight:Ng(e.viewWeight,t.viewWeight,n),editorWeight:Ng(e.editorWeight,t.editorWeight,n),toolbarContentOpacity:Ng(e.toolbarContentOpacity,t.toolbarContentOpacity,n)}}(t.from,t.to,i),t.phase=i>=1?"settling":"running",this._hooks.frame(t),i<1?this._raf=this._clock.requestFrame(s):(this._raf=0,this._hooks.settled(t),this._state?.token===r&&(this._state=null))};return this._raf=this._clock.requestFrame(s),r}cancel(e=!0){this._raf&&this._clock.cancelFrame(this._raf),this._raf=0;const t=this._state;this._state=null,this._token++,t&&e&&(t.phase="settling",t.presented=t.to,this._hooks.frame(t),this._hooks.settled(t))}dispose(){this.cancel(!1)}}const Gg={now:()=>"undefined"!=typeof performance?performance.now():Date.now(),requestFrame:e=>"function"==typeof requestAnimationFrame?requestAnimationFrame(e):null,cancelFrame:e=>{"function"==typeof cancelAnimationFrame&&cancelAnimationFrame(e)}},Vg=e=>Number.isFinite(e);function Kg(e){return!!e&&Vg(e.zoom)&&e.zoom>0&&Vg(e.viewBox.x)&&Vg(e.viewBox.y)&&Vg(e.viewBox.w)&&e.viewBox.w>0&&Vg(e.viewBox.h)&&e.viewBox.h>0}function Yg(e){return{zoom:e.zoom,viewBox:{...e.viewBox}}}function Xg(e,t){return Math.abs(e.zoom-t.zoom)<1e-9&&Math.abs(e.viewBox.x-t.viewBox.x)<1e-6&&Math.abs(e.viewBox.y-t.viewBox.y)<1e-6&&Math.abs(e.viewBox.w-t.viewBox.w)<1e-6&&Math.abs(e.viewBox.h-t.viewBox.h)<1e-6}const Zg=(e,t,i)=>e+(t-e)*i,Jg=(e,t,i)=>Math.exp(Zg(Math.log(e),Math.log(t),i));class Qg{constructor(e,t=Gg){this._hooks=e,this._clock=t,this._token=0,this._raf=null,this._state=null}get state(){return this._state}get active(){return"running"===this._state?.phase}get presented(){return this._state?.presented||null}get target(){return this._state?.to||null}start(e,t,i,n){this.cancel(!1);const r=++this._token,o=Yg(e),s=Yg(t),a=n>0&&Kg(o)&&Kg(s),l=this._clock.now(),c={token:r,phase:a?"running":"settling",from:o,to:s,presented:Yg(a?o:s),startedAt:l,duration:a?n:0,reason:i};if(this._state=c,this._hooks.frame(c),!a)return this._settle(r),r;const h=e=>{const t=this._state;if(!t||t.token!==r)return;const i=Math.max(0,Math.min(1,(e-t.startedAt)/t.duration));if(t.presented=i>=1?Yg(t.to):function(e,t,i){if(!Kg(e))return Yg(t);if(!Kg(t))return Yg(e);const n=Lg(i);if(n<=0)return Yg(e);if(n>=1)return Yg(t);const r=e.viewBox.x+e.viewBox.w/2,o=e.viewBox.y+e.viewBox.h/2,s=t.viewBox.x+t.viewBox.w/2,a=t.viewBox.y+t.viewBox.h/2,l=Jg(e.viewBox.w,t.viewBox.w,n),c=Jg(e.viewBox.h,t.viewBox.h,n),h=Zg(r,s,n),d=Zg(o,a,n);return{zoom:Jg(e.zoom,t.zoom,n),viewBox:{x:h-l/2,y:d-c/2,w:l,h:c}}}(t.from,t.to,i),t.phase=i>=1?"settling":"running",this._hooks.frame(t),i>=1)return this._raf=null,void this._settle(r);this._raf=this._clock.requestFrame(h),null===this._raf&&this._settle(r)};return this._raf=this._clock.requestFrame(h),null===this._raf&&(c.phase="settling",c.presented=Yg(s),this._hooks.frame(c),this._settle(r)),r}cancel(e=!0){null!==this._raf&&this._clock.cancelFrame(this._raf),this._raf=null;const t=this._state;this._state=null,this._token++,t&&e&&(t.phase="settling",t.presented=Yg(t.to),this._hooks.frame(t),this._hooks.settled(t))}dispose(){this.cancel(!1)}_settle(e){const t=this._state;t&&t.token===e&&(t.phase="settling",t.presented=Yg(t.to),this._hooks.settled(t),this._state?.token===e&&(this._state=null))}}function ef(e,t,i){const n=e.querySelector("ha-card");if(!n)return null;const r=n.getBoundingClientRect(),o=t.getBoundingClientRect().top-r.top,s=i?0:Math.min(Math.max(r.top,0),120),a=Math.round(o+s);return a>=0?a:null}const tf=Object.freeze({rotDeg:0,tiltDeg:20,xyScale:1,zScale:1,origin:Object.freeze([500,500])}),nf=84,rf=10,of=4,sf=4;function af(e){return[e.rotDeg,e.tiltDeg,e.xyScale,e.zScale,e.origin[0],e.origin[1]].every(Number.isFinite)&&Math.abs(e.xyScale)>1e-12&&Math.abs(Math.cos(e.tiltDeg*Math.PI/180))>1e-12}function lf(e,t,i=tf){if(!Number.isFinite(e[0])||!Number.isFinite(e[1]))throw new Error("invalid isometric projection input");return function(e,t){if(!Number.isFinite(e[0])||!Number.isFinite(e[1])||!t.every(Number.isFinite))throw new Error("invalid isometric affine input");const[i,n,r,o,s,a]=t;return[i*e[0]+r*e[1]+s,n*e[0]+o*e[1]+a]}(e,hf(t,i))}function cf(e,t=tf){if(!af(t)||!Number.isFinite(e[0])||!Number.isFinite(e[1]))throw new Error("invalid isometric projection input");const i=t.rotDeg*Math.PI/180,n=t.tiltDeg*Math.PI/180,r=(e[0]-t.origin[0])/t.xyScale,o=(e[1]-t.origin[1])/(t.xyScale*Math.cos(n));return[t.origin[0]+r*Math.cos(i)+o*Math.sin(i),t.origin[1]-r*Math.sin(i)+o*Math.cos(i)]}function hf(e=0,t=tf){if(!af(t)||!Number.isFinite(e))throw new Error("invalid isometric camera");const i=t.rotDeg*Math.PI/180,n=t.tiltDeg*Math.PI/180,r=t.xyScale*Math.cos(i),o=-t.xyScale*Math.sin(i),s=t.xyScale*Math.sin(i)*Math.cos(n),a=t.xyScale*Math.cos(i)*Math.cos(n);return[r,s,o,a,t.origin[0]-r*t.origin[0]-o*t.origin[1],t.origin[1]-s*t.origin[0]-a*t.origin[1]-e*t.zScale*Math.sin(n)]}function df(e=tf){return function(e=0,t=tf){return`matrix(${hf(e,t).map(e=>Number(e.toFixed(12))).join(" ")})`}(0,e)}function uf(e,t=tf){const{rect:i,wallHeight:n}=e,r=e.openingHeight??n,o=e.floorDepth??0,s=e.raisedHeight??n;if(!(i.w>=0)||!(i.h>=0)||!Number.isFinite(n)||!Number.isFinite(r)||!Number.isFinite(o)||!Number.isFinite(s)||n<0||r<0||o<0||s<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]],l=Math.max(n,r,s),c=a.flatMap(e=>[lf(e,-o,t),lf(e,l,t)]),h=c.map(e=>e[0]),d=c.map(e=>e[1]),u=Math.min(...h),p=Math.min(...d);return{x:u,y:p,w:Math.max(...h)-u,h:Math.max(...d)-p}}const pf=[".dev",".vacpuck",".oplock",".op-hit",".opening",".rlgo","a","button","input","select","textarea",'[contenteditable]:not([contenteditable="false"])',"[data-room-fit-block]",'[role="link"]','[role="button"]'].join(","),_f=(e,t)=>{try{return"function"==typeof e?.matches&&e.matches(t)}catch{return!1}};function mf(e){for(const t of e){const e=t;if(_f(e,".roomlabel[data-id]")){const t=e.getAttribute?.("data-id");return t?{kind:"room",roomId:t}:{kind:"interactive"}}if(_f(e,pf))return{kind:"interactive"};if(_f(e,'[data-hp="room"][data-id]')){const t=e.getAttribute?.("data-id");return t?{kind:"room",roomId:t}:{kind:"interactive"}}if(_f(e,".stage"))return{kind:"background"}}return{kind:"outside"}}function gf(e){const t=mf(e);return"room"===t.kind?t.roomId:null}class ff{constructor(){this.pointer=null,this.sequence=null}clear(){this.pointer=null,this.sequence=null}clearOutside(e){let t={kind:"outside"};try{t=mf(e.composedPath())}catch{}"outside"===t.kind&&this.clear()}pointerDown(e,t,i){let n={kind:"outside"};try{n=mf(e.composedPath())}catch{}this.pointer=function(e){const t="mouse"===(i=e.pointerType)||"touch"===i||"pen"===i?i:null;var i;return t&&"view"===e.mode&&"background"===e.owner.kind&&!e.blocked&&e.isPrimary&&0===e.button&&Number.isFinite(e.x)&&Number.isFinite(e.y)?{pointerId:e.pointerId,spaceId:e.spaceId,modality:t,x:e.x,y:e.y}:null}({pointerId:e.pointerId,pointerType:e.pointerType,isPrimary:e.isPrimary,button:e.button,spaceId:t,mode:i?"view":"blocked",owner:n,blocked:!i,x:e.clientX,y:e.clientY}),this.pointer||(this.sequence=null)}pointerUp(e,t,i,n,r=Date.now()){let o={kind:"outside"};try{o=mf(e.composedPath())}catch{}const s=function(e,t,i){if(!t||"view"!==i.mode||"background"!==i.owner.kind||i.blocked||t.pointerId!==i.pointerId||t.spaceId!==i.spaceId||!Number.isFinite(i.x)||!Number.isFinite(i.y)||!Number.isFinite(i.now)||Math.abs(i.x-t.x)+Math.abs(i.y-t.y)>=8)return{sequence:null,trigger:!1};const n=e?i.now-e.at:Number.POSITIVE_INFINITY;return e&&e.spaceId===i.spaceId&&e.modality===t.modality&&n>=0&&n<=350?{sequence:null,trigger:!0}:{sequence:{at:i.now,spaceId:i.spaceId,modality:t.modality},trigger:!1}}(this.sequence,this.pointer,{pointerId:e.pointerId,spaceId:t,mode:i?"view":"blocked",owner:o,blocked:n||!i,x:e.clientX,y:e.clientY,now:r});return this.pointer=null,this.sequence=s.sequence,s.trigger}}const vf=e=>e.length>=2&&Number.isFinite(e[0])&&Number.isFinite(e[1]);function yf(e){return!!e&&Number.isFinite(e.x)&&Number.isFinite(e.y)&&Number.isFinite(e.w)&&e.w>0&&Number.isFinite(e.h)&&e.h>0}function bf(e,t=0){if(!e.length||!Number.isFinite(t)||t<0||!e.every(vf))return null;let i=1/0,n=1/0,r=-1/0,o=-1/0;for(const t of e)i=Math.min(i,t[0]),n=Math.min(n,t[1]),r=Math.max(r,t[0]),o=Math.max(o,t[1]);const s=r-i,a=o-n;return s>0&&a>0?{x:i-t,y:n-t,w:s+2*t,h:a+2*t}:null}function wf(e,t,i){const n="string"!=typeof t||"invalid"!==t&&"no-borders"!==t&&"unverified"!==t&&!/^[a-z0-9]{1,8}$/i.test(t)?"redacted":t;return Object.freeze({kind:e,fingerprint:n,terminal:!!i})}function kf(e,t){return`${e("editor.load_failed")} ${e(t.terminal?"editor.refresh_advice":"editor.retry_advice")}`}class xf extends Error{}class Sf{constructor(e){this.options=e,this._state="idle",this._inFlight=null}get state(){return this._state}ensure(){return"ready"===this._state?Promise.resolve(!0):"failed"===this._state?Promise.resolve(!1):(this._inFlight||(this._setState("loading"),this._inFlight=this._loadWithRetry().finally(()=>{this._inFlight=null})),this._inFlight)}async _loadWithRetry(){let e=new Error("Editor runtime did not load"),t=!1;for(const i of[0,1])try{const e=await this.options.load(i);if(e.fingerprint!==this.options.expectedFingerprint)throw new xf(`Editor runtime fingerprint mismatch: expected ${this.options.expectedFingerprint}, got ${e.fingerprint}`);const t=e.create();return this.options.install(t),this._setState("ready"),!0}catch(i){e=i,i instanceof xf&&(t=!0)}return this._setState(t?"failed":"idle"),this.options.failed?.(e,{terminal:t}),!1}_setState(e){e!==this._state&&(this._state=e,this.options.stateChanged?.(e))}}const $f=(e,t)=>{if(!e.has(t))return{hit:!1};const i=e.get(t);return e.delete(t),e.set(t,i),{hit:!0,value:i}},Mf=(e,t,i,n)=>{for(e.delete(t),e.set(t,i);e.size>n;){const t=e.keys().next().value;if(void 0===t)break;e.delete(t)}},Rf=new Set(["select","draw","column","merge","split","resize","opening","wallthick","delroom"]),Cf=e=>`${window.innerWidth}x${window.innerHeight}|${location.pathname}|${JSON.stringify(e??{})}`,Tf="houseplan_card_alpha_v1",Df=Object.freeze([Object.freeze({id:"iso",issue:89,summary:"Volumetric plan renderer"})]);function Af(e){return/^[a-z][a-z0-9-]*$/.test(e.id)&&Number.isInteger(e.issue)&&e.issue>0&&!!e.summary.trim()}function Pf(e){const t=String(e||"").replace(/^#/,"");return new URLSearchParams(t)}function Ff(e){return Pf(e).get("space")||""}function zf(e,t,i=Df){const n=function(e){const t=new Set;for(const i of e){if(!Af(i)||t.has(i.id))return!1;t.add(i.id)}return!0}(i),r=function(e){let t,i=!1;const n=e=>{for(const n of e.getAll("hp_alpha"))i=!0,"1"===n?t=!0:"0"===n&&(t=!1)};return n(new URLSearchParams(String(e.search||"").replace(/^\?/,""))),n(Pf(e.hash)),{present:i,value:t}}(e),o=void 0!==r.value,s="1"===t,a=o?!0===r.value:!r.present&&s,l=n&&a;return{alpha:l,active:Object.freeze(l?i.map(e=>e.id).sort():[]),space:Ff(e.hash),persist:n&&o?l?"1":"0":void 0,knownUrlOperation:o}}let If={alpha:!1,active:Object.freeze([]),space:""},Of=!1,Ef="";const Nf=new Set;function Hf(){if("undefined"==typeof window)return If;const e=zf(window.location,function(){try{return window.localStorage.getItem(Tf)}catch{return null}}());void 0!==e.persist&&function(e){try{window.localStorage.setItem(Tf,e)}catch{}}(e.persist),If={alpha:e.alpha,active:e.active,space:e.space},window.__hpAlpha=e.alpha,window.__hpLabs=e.active;for(const e of Nf)e(If);return If}function Lf(){Hf()}function Bf(){if("undefined"==typeof window)return If;if(!Of){Of=!0,window.__hpLabsListenerCleanup?.(),window.addEventListener("hashchange",Lf),window.addEventListener("popstate",Lf);const e=()=>{window.removeEventListener("hashchange",Lf),window.removeEventListener("popstate",Lf),window.__hpLabsListenerCleanup===e&&delete window.__hpLabsListenerCleanup};window.__hpLabsListenerCleanup=e}return Hf()}const qf={window:120,door:90,passage:90,gate:300};function jf(e){return qf[e]}function Wf(e,t){return{type:e,lengthCm:jf(e),flipH:!1,flipV:!1,revision:t}}function Uf(e,t){const i=Math.max(0,e.renderedLength)/2,n=Math.max(0,e.target.physicalHalfWidth),r=n+.18*Math.max(0,t),o=e=>({x1:e,y1:-r,x2:e,y2:r});return{rect:{x:-i,y:n?-n:0,width:2*i,height:2*n},boundaries:[o(-i),o(i)]}}function Gf(e,t){const i=[e[0],e[1]],n=[t[0],t[1]];return function(e,t){return e[0]-t[0]||e[1]-t[1]}(i,n)<=0?{a:i,b:n}:{a:n,b:i}}function Vf(e){const t=new Map;return e.forEach((e,i)=>{if(!e.kind||e.open)return;const n=Gf(e.a,e.b);if(Math.hypot(n.b[0]-n.a[0],n.b[1]-n.a[1])<=1e-9)return;const r=function(e,t){const i=e=>(Math.abs(e)<=5e-10?0:Math.round(1e6*e)/1e6).toFixed(6);return`${i(e[0])},${i(e[1])}>${i(t[0])},${i(t[1])}`}(n.a,n.b),o=t.get(r);if(o)return o.physicalHalfWidth=Math.max(o.physicalHalfWidth,e.half||0),o.sourceOrder=Math.min(o.sourceOrder,i),void(e.partitionHost&&(o.partitionHost&&o.partitionHost.id!==e.partitionHost.id?o.ambiguousPartitionHost=!0:o.partitionHost=e.partitionHost));t.set(r,{segmentKey:r,a:n.a,b:n.b,physicalHalfWidth:Math.max(0,e.half||0),sourceOrder:i,...e.partitionHost?{partitionHost:e.partitionHost}:{}})}),[...t.values()]}function Kf(e,t){if(Math.abs(e.distance-t.distance)>1e-9)return e.distance-t.distance;if(Math.abs(e.perpendicular-t.perpendicular)>1e-9)return e.perpendicular-t.perpendicular;return(e.target.segmentKeyt.target.segmentKey?1:0)||e.target.sourceOrder-t.target.sourceOrder}function Yf(e){const t=Vf(e.intervals).map(t=>{const i=function(e,t){const i=t.b[0]-t.a[0],n=t.b[1]-t.a[1],r=Math.hypot(i,n),o=i/r,s=n/r,a=(e[0]-t.a[0])*o+(e[1]-t.a[1])*s,l=Math.max(0,Math.min(r,a)),c=t.a[0]+l*o,h=t.a[1]+l*s;return{along:l,length:r,x:c,y:h,distance:Math.hypot(e[0]-c,e[1]-h),perpendicular:Math.abs((e[0]-t.a[0])*s-(e[1]-t.a[1])*o)}}(e.pointer,t);return{target:t,...i,envelope:Math.max(e.baseTolerance,t.physicalHalfWidth+e.bodyPointerPadding)}}).filter(e=>e.distance<=e.envelope+1e-9).filter(t=>!function(e,t,i,n,r){const o=t.b[0]-t.a[0],s=t.b[1]-t.a[1],a=Math.hypot(o,s);if(!(a>1e-9))return!1;const l=o/a,c=s/a;for(const o of i){if(!o.open&&o.kind)continue;const i=Gf(o.a,o.b),s=i.b[0]-i.a[0],a=i.b[1]-i.a[1],h=Math.hypot(s,a);if(!(h>1e-9))continue;const d=s/h,u=a/h;if(Math.abs(l*u-c*d)>1e-6)continue;if(Math.abs((i.a[0]-t.a[0])*c-(i.a[1]-t.a[1])*l)>r)continue;const p=(e[0]-i.a[0])*d+(e[1]-i.a[1])*u,_=1e-9;if(!(p<=_||p>=h-_)&&Math.abs((e[0]-i.a[0])*u-(e[1]-i.a[1])*d)<=n+1e-9)return!0}return!1}(e.pointer,t.target,e.intervals,t.envelope,Math.max(1e-9,Math.min(e.baseTolerance,.04*e.gridStep)))),i=t.filter(t=>!!t.target.partitionHost&&e.renderedLength+2*t.target.physicalHalfWidth>t.length+1e-9).sort(Kf),n=t.filter(t=>!t.target.partitionHost||e.renderedLength+2*t.target.physicalHalfWidth<=t.length+1e-9).sort(Kf);let r=n[0];if(!r)return{candidate:null,jambBlockedTarget:i[0]?.target||null};const o=n.filter(e=>Math.abs(e.distance-r.distance)<=1e-9&&Math.abs(e.perpendicular-r.perpendicular)<=1e-9),s=o.filter(e=>e.target.partitionHost);if(s.length){if(1!==new Set(s.map(e=>e.target.partitionHost.id)).size||s.some(e=>e.target.ambiguousPartitionHost))return{candidate:null,jambBlockedTarget:null};const e=s[0],t=e.target.b[0]-e.target.a[0],i=e.target.b[1]-e.target.a[1],n=Math.hypot(t,i),a=t/n,l=i/n;if(!o.every(t=>{const i=t.target.b[0]-t.target.a[0],n=t.target.b[1]-t.target.a[1],r=Math.hypot(i,n),o=i/r,s=n/r,c=Math.abs(a*s-l*o)<=1e-6,h=Math.abs((t.target.a[0]-e.target.a[0])*l-(t.target.a[1]-e.target.a[1])*a);return c&&h<=1e-9}))return{candidate:null,jambBlockedTarget:null};r=e}if(r.target.ambiguousPartitionHost)return{candidate:null,jambBlockedTarget:null};const{target:a,length:l}=r,c=a.b[0]-a.a[0],h=a.b[1]-a.a[1],d=c/l,u=h/l,p=a.partitionHost?a.physicalHalfWidth:0,_=Math.min(Math.max(0,e.renderedLength)/2+p,l/2);let m=r.along;const g=Math.max(e.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=a.a[0]+d*m,y=a.a[1]+u*m,b=Math.max(0,e.renderedLength)/2,w=m-b,k=m+b,x=Math.max(0,w),S=Math.max(0,l-k),$=[a.a[0]+d*(w-x/2),a.a[1]+u*(w-x/2)],M=[a.a[0]+d*(k+S/2),a.a[1]+u*(k+S/2)];let R=180*Math.atan2(h,c)/Math.PI;R>=90?R-=180:R<-90&&(R+=180);const C=Math.abs(m-f)<=1e-9;return{candidate:{presetRevision:e.preset.revision,geometryRevision:e.geometryRevision,pointer:[e.pointer[0],e.pointer[1]],type:e.preset.type,lengthCm:e.preset.lengthCm,flipH:e.preset.flipH,flipV:e.preset.flipV,x:v,y:y,angle:R,renderedLength:e.renderedLength,target:a,...a.partitionHost?{host:{...a.partitionHost,t:l>0?m/l:0}}:{},measure:{labels:[{distance:x,midpoint:$},{distance:S,midpoint:M}],guide:C?{x:v,y:y,angle:R}:null}},jambBlockedTarget:null}}function Xf(e,t,i,n,r=1e-6){return e.presetRevision===i&&e.geometryRevision===n&&Math.hypot(e.pointer[0]-t[0],e.pointer[1]-t[1])<=r}function Zf(e){return!(!e.canEdit||e.kiosk||e.fixedFloor)&&("view"!==e.mode&&("mouse"===e.pointerType&&e.spaceCount>1))}class Jf{constructor(e,t,i){this.loader=e,this.host=t,this.adopted=i,this.attachment=null}connect(){if(this.runtime)return void this.runtime.connect();this.attachment?.cancel();const e=this.loader.attach(this.host,e=>this.adopt(e));this.runtime||(this.attachment=e)}disconnect(){this.attachment?.cancel(),this.attachment=null,this.runtime?.disconnect()}adopt(e){this.attachment=null,this.runtime||(this.runtime=e,this.adopted(e))}}const Qf=new class{constructor(e){this.load=e,this.factory=null,this.pending=null}get warm(){return null!==this.factory}create(e){return this.factory?this.factory(e):null}attach(e,t){let i=!0;const n={cancel:()=>{i=!1}},r=this.create(e);return r?(t(r),n):(this.ensure().then(n=>{i&&t(n(e))},()=>{}),n)}ensure(){return this.factory?Promise.resolve(this.factory):(this.pending||(this.pending=this.load().then(e=>(this.factory=e,this.pending=null,e),e=>{throw this.pending=null,e})),this.pending)}reset(){this.factory=null,this.pending=null}}(()=>import("./summary-panel-runtime-loaded-D3ySFavc.js").then(function(e){return e.e}).then(({LoadedSummaryPanelRuntime:e})=>t=>new e(t)));function ev(e){const t=globalThis.__HP_VERSION_OVERRIDE__;return"string"==typeof t&&t.length>0?t:e}let tv=0;const iv="1.77.0-beta.4",nv="44c8db0207714f5476f58cdacdfaae63754967422e492b7fadf3551ecaee4380",rv=1500,ov=new Map;let sv=0,av=1e4;const lv="houseplan_card_layout_v1",cv="houseplan_card_cfg_v1",hv="houseplan_card_zoom_v1",dv="houseplan_card_nav_v1",uv="houseplan_card_view_v1",pv="hp-dialog, hp-help, hp-color-opacity, hp-device-preview",_v=1e3,mv=(e,t)=>{const i=Math.min(e.x,t.x),n=Math.min(e.y,t.y);return{x:i,y:n,w:Math.max(e.x+e.w,t.x+t.w)-i,h:Math.max(e.y+e.h,t.y+t.h)-n}},gv=(e,t,i)=>{const n=new Event(t,{bubbles:!0,composed:!0});n.detail=i??{},e.dispatchEvent(n)},fv=e=>{history.pushState(null,"",e),gv(window,"location-changed",{replace:!1})},vv=(e,t)=>{let i,n=null;const r=(...r)=>{clearTimeout(i),n=r,i=window.setTimeout(()=>{i=void 0;const t=n;n=null,t&&e(...t)},t)};return r.flush=()=>{if(void 0===i)return;clearTimeout(i),i=void 0;const t=n;n=null,t&&e(...t)},r.cancel=()=>{clearTimeout(i),i=void 0,n=null},r.pending=()=>void 0!==i,r},yv=e=>{try{e.target?.setPointerCapture?.(e.pointerId)}catch{}},bv=["edges","corners"];class wv extends he{constructor(){var e;super(...arguments),this._editorRuntime=null,this._liveRt=null,this._onboardingRuntime=null,this._editorRuntimeLoadingVisible=!1,this._backdropGuard=null,this._editorModeRequest=0,this._warmModeRequest=0,this._editorRuntimeLoader=new Sf({expectedFingerprint:nv,load:async e=>{const t=0===e?await import("./houseplan-editor-runtime-BXjfKYAx.js"):await import((()=>{const e=new URL("./houseplan-editor-runtime-BXjfKYAx.js",import.meta.url);return e.searchParams.set("hp_retry",`${iv}-${++tv}`),e.href})());return{fingerprint:t.EDITOR_RUNTIME_FINGERPRINT,create:()=>new t.HouseplanEditorRuntime(this)}},install:e=>{this._editorRuntime=e},stateChanged:e=>this._editorRuntimeStateChanged(e),failed:(e,t)=>{console.error("[houseplan] unable to load editor runtime",e),t.terminal&&this._versionRecovery.hasCurrentMismatchNotice||this._showToast(kf(e=>this._t(e),t))}}),this._onboardingRuntimeLoader=new Sf({expectedFingerprint:nv,load:async e=>{const t=0===e?await import("./houseplan-onboarding-runtime-CNBlGqTW.js"):await import((()=>{const e=new URL("./houseplan-onboarding-runtime-CNBlGqTW.js",import.meta.url);return e.searchParams.set("hp_retry",`${iv}-${++tv}`),e.href})());return{fingerprint:t.ONBOARDING_RUNTIME_FINGERPRINT,create:()=>new t.HouseplanOnboardingRuntime(this)}},install:e=>{this._onboardingRuntime=e},failed:(e,t)=>{console.error("[houseplan] unable to load onboarding runtime",e),t.terminal&&this._versionRecovery.hasCurrentMismatchNotice||this._showToast(kf(e=>this._t(e),t))}}),this._isoSceneRuntime=null,this._isoSceneRuntimeLoader=new Sf({expectedFingerprint:nv,load:async e=>{const t=0===e?await import("./iso-scene-render-sNAJFXBj.js"):await import((()=>{const e=new URL("./iso-scene-render-sNAJFXBj.js",import.meta.url);return e.searchParams.set("hp_retry",`${iv}-${++tv}`),e.href})());return{fingerprint:t.ISO_SCENE_RUNTIME_FINGERPRINT,create:()=>t}},install:e=>{const t=this._effectiveProjection();this._isoSceneRuntime=e,this._isoProjectionSnapshot=null;const i=this._effectiveProjection();this._convertProjectionView(t,i),this.isConnected&&this.requestUpdate()},failed:(e,t)=>{console.warn("[houseplan] hidden isometric runtime diagnostic",wf("runtime-load","unverified",t.terminal)),this.isConnected&&this.requestUpdate()}}),this._pdfRuntime=null,this._pdfRuntimeLoader=new Sf({expectedFingerprint:nv,load:async e=>{const t=0===e?await import("./pdf-export-DO9ua2us.js"):await import((()=>{const e=new URL("./pdf-export-DO9ua2us.js",import.meta.url);return e.searchParams.set("hp_retry",`${iv}-${++tv}`),e.href})());return{fingerprint:t.PDF_EXPORT_FINGERPRINT,create:()=>new t.PdfExportRuntime}},install:e=>{this._pdfRuntime=e,this.isConnected&&this.requestUpdate()},failed:(e,t)=>{if(console.error("[houseplan] unable to load PDF export runtime",e),!t.terminal||!this._versionRecovery.hasCurrentMismatchNotice){const e=kf(e=>this._t(e),t),i=this._t("editor.load_failed"),n=e.startsWith(i)?e.slice(i.length).trim():e;this._showToast(`${this._t("pdf.failed")} ${n}`.trim())}}}),this.panelHost=!1,this.narrow=null,this._space="f1",this._adoption=new qu((e,t)=>this.requestUpdate(e,t)),this._serverStorage=!1,this._loadOk=!1,this._serverCanWrite=null,this._loading=!1,this._loadTries=0,this._unsubCfg=null,this._unsubLayout=null,this._unsubVirtual=null,this._liveSyncAttempt=null,this._liveSyncGeneration=0,this._liveSyncConnection=null,this._configReloadAuthority=new Gu,this._virtualLights=Hh(null),this._canOptimizeUndo=!1,this._undoKind=null,this._devices=[],this._regSignature="",this._defPos={},this._newSyncKey="",this._areaRelocationIds=new Set,this._areaSnapshotCleanupCandidates=new Map,this._areaRelocationSyncKey="",this._areaRelocationWrite=Promise.resolve(),this._tip=null,this._hoverRoom=null,this._pointerModality=new sg(this,()=>this._syncPointerHoverTargets()),this._devicePressAnimations=new Map,this._selId=null,this._toast="",this._mode="view",this._pendingNavMode=null,this._decorTool="select",this._decorStyle={...Cr},this._decorStyleSeeded=!1,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._decorImagePalette=null,this._decorAssetCatalog=[],this._decorAssets=new Map,this._decorAssetBusy=!1,this._furnCategory=null,this._furnPreviewInput=null,this._furnTouchPending=null,this._dtBox=null,this._dtDrag=null,this._bdDrag=null,this._slide="",this._reducedMotion=!1,this._onMotionChange=e=>{this._reducedMotion=e.matches,this._cancelDevicePressFeedback(),e.matches&&this._cancelCameraTransition(!0),e.matches&&this._modeTransitionPreparing?this._modeTransitionForceAtomic=!0:e.matches&&this._modeTransition.active&&this._cancelModeTransition(!0),this._syncVersionRecovery(),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 Ug({frame:e=>this._applyModeTransitionFrame(e),settled:e=>this._settleModeTransition(e)}),this._cameraTransitionFit=null,this._cameraTransition=new Qg({frame:e=>this._applyCameraTransitionFrame(e),settled:e=>this._settleCameraTransition(e)}),this._editorSecondaryCopy={groupActive:(e,t)=>this._t("editor.group_active",{group:e,item:t}),openGroup:e=>this._t("editor.open_group",{group:e}),disabledAction:(e,t)=>this._t("editor.disabled_action",{action:e,reason:t})},this._tool="draw",this._geometryHistory=new gg(50),this._devicePositionHistory=new gg(50),this._devicePositionBusy=!1,this._wallDialog=null,this._drawWallField=null,this._activeWallChainId=null,this._activeWallChainPartitionIds=[],this._wallChainRedo=[],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._renderIsoScene=null,this._isoProjectionSnapshot=null,this._isoStructuralBuildCount=0,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._glowRuntimeState=bm(),this._glowRuntimeHost={window:()=>this.ownerDocument.defaultView||window,isConnected:()=>this.isConnected,requestUpdate:()=>this.requestUpdate(),reducedMotion:()=>this._reducedMotion},this._lightBarrierCache=null,this._lightBarrierPool=new Map,this._glowScreenBlend=!1,this._duplicateColumnId=null,this._duplicateColumnTimer=0,this._rszLimitViolation=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._roomTempMin="",this._roomTempMax="",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._roomFocus=null,this._roomPointer=null,this._doubleFit=new ff,this._deviceHits=new wc,this._pointers=new Map,this._panStart=null,this._panLock=null,this._pinchStart=null,this._safeDayCycleOutline=!1,this._suppressClick=!1,this._viewportGestureDirty=!1,this._touchContacts=new Map,this._touchClickGuard=new pc,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:e=>this._guardTouchGesture(e)},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._dangerConfirm=null,this._dangerConfirmController=new ze(e=>{this._dangerConfirm=e}),this._confirmDanger=e=>this._config&&this.hass?"warm"===this._syncDangerConfirmLocaleGate()||this._dangerConfirmMissingSpace()?Promise.resolve(!1):this._dangerConfirmController.confirm(e):Promise.resolve(!1),this._cancelDangerConfirm=()=>{this._dangerConfirmController.cancel()},this._onDangerConfirmDecision=e=>{this._dangerConfirmController.resolve(e.detail.token,e.detail.accepted)},this._onboardingShown=!1,this._rulesDialog=null,this._preflightClipboardFallback=null,this._haIntegrationVersion=null,this._versionRecovery=(e=this,new wg({clock:{setTimeout:(e,t)=>window.setTimeout(e,t),clearTimeout:e=>window.clearTimeout(e)},storage:()=>e.ownerDocument.defaultView?.sessionStorage??null,safety:()=>Sg(e),reload:()=>e._reloadDocument(),changed:()=>{e.requestUpdate()}})),this._haSupportApi=null,this._haDecorAssetsApi=null,this._haSummaryPanelApi=null,this._haRadarStage1Api=null,this._radarLive=new Ag(this),this._decorAssetSyncToken=0,this._alignDialog=null,this._settingsDialog=null,this._pdfDialog=!1,this._supportDialog=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._deviceInbox=null,this._deviceInboxReturn=null,this._deviceInboxMemo=null,this._markerDialog=null,this._spaceDialog=null,this._keyHandler=e=>this._onKey(e),this._warmVp=null,this._warmVpArmed=!1,this._warmLongReturn=!1,this._warmRevivePending=!1,this._warmGen=++sv,this._warmKey=null,this._warmSlot=null,this._hashApplied=!1,this._navApplied=!1,this._labs={alpha:!1,active:Object.freeze([]),space:""},this._viewPreference={},this._renderProjection="flat",this._kioskScale={icon:1,font:1},this._kioskDialog=!1,this._summarySlot=new Jf(Qf,this,e=>{this._summary=e,this._capturedSnapshotSequence=-1,this.isConnected&&(e.connect(),this.hasUpdated&&this.requestUpdate())}),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=e=>{if(this._continuity.visibility(e),this._dayCycleVisibility(e),this._summary?.visibility(e.kind),"hidden"===e.kind)return this._radarLive.stop(),this._editorRuntime?._cancelRadarSetup(),this._clearRoomFocus(!0),this._clearTransientHover(!0),this._cancelDevicePressFeedback(),this._cancelCameraTransition(!0),void(this._modeTransitionPreparing?this._modeTransitionForceAtomic=!0:this._cancelModeTransition(!0));if(this._vacJumpOnce=!0,this._syncRadarLive(),!e.long){const e=Date.now();let t=!1;for(const i of this._activityRt.values())!i.flashKind||(i.expiresAt||i.flashTs+tg)>e||(i.flashTs=0,i.flashKind=null,i.expiresAt=0,t=!0);return void(t&&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._onLabsSnapshot=e=>{const t=this._effectiveProjection();this._labs=e,this._isoProjectionSnapshot=null,this._labsIso&&this._ensureIsoSceneRuntime();const i=this._effectiveProjection();this._convertProjectionView(t,i),this.requestUpdate()},this._onHashChange=()=>{if(this._hasFixedFloor)return;const e=this._hashSpace();if(e&&this._model.find(t=>t.id===e)&&e!==this._space){if(this._wallFaceBatch&&this._roomDialogCancel(),"plan"===this._mode&&"draw"===this._tool&&!this._finishWallChain())return;this._commitSpace(e),this._selId=null,this._path=[],this._clearPlanSnapHover(),this._clearOpeningPlacement(!0),this._tool="draw",this._activeWallChainId=null,this._activeWallChainPartitionIds=[],this._wallChainSegmentCms=[],this._closingWallCm=null,this._restoreZoom(),this.requestUpdate()}},this._drag=null,this._deviceDrag=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._cfgEpochPreservedConfig=null,this._terminalFrame=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._renderLife=new $g,this._liveEditorPaintCount=0,this._onHaRegistryUpdate=()=>{const e=nd(this.hass);e.revision===this._haRegistryRev&&this._devices.length||(this._haRegistryRev=e.revision,this._renderLife.invalidate(),this._planHassMemo=null,this._regSignature="",this._maybeRebuildDevices(),this.requestUpdate())},this._onConnReady=()=>{if(this._loadTries=0,clearTimeout(this._loadRetryTimer),this._loadRetryTimer=void 0,id(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 uc(()=>this.requestUpdate()),this._dirtyPos=new Set,this._sentPos=new Map,this._persistLayout=vv(()=>{if(this._serverStorage){const e=[...this._dirtyPos];this._dirtyPos.clear();for(const t of e){const e=xo(this._layout[t]);e&&(this._layout={...this._layout,[t]:e},this._sentPos.set(t,e),this.hass.callWS({type:"houseplan/layout/update",device_id:t,pos:e}).then(e=>this._noteLayoutRev(e)).catch(e=>this._showToast(this._t("toast.pos_save_failed",{err:this._errText(e)}))).finally(()=>{this._sentPos.get(t)===e&&this._sentPos.delete(t)}))}this._cacheSnapshot()}else this._persistLocalLayout()},600),this._frame=null,this._showFar=!1,this._writesPending=0,this._writeChain=Promise.resolve(),this._pendingPhysicalWrites=new Map,this._undoGeometry=()=>this._editorRuntimeOrThrow()._undoGeometry(),this._redoGeometry=()=>this._editorRuntimeOrThrow()._redoGeometry(),this._saveConfigDebounced=vv(()=>{this._serverCfg&&this._writeConfig().catch(e=>{const t=!0===e?.physicalGeometryRolledBack;"geometry-unsafe"!==e?.code&&("wall_model_client_outdated"===e?.code?this._showToast(this._t("toast.wall_model_client_outdated")):"conflict"===e?.code?(this._showToast(this._t("toast.conflict")),t||(this._cancelPath(),this._reloadConfigOnly(!0))):this._showToast(this._t("toast.cfg_save_failed",{err:this._errText(e)})),t&&this._reloadRejectedPhysicalWrite())})},500),this._wallChainSegmentCms=[],this._closingWallCm=null,this._savePhysicalDialog=()=>this._editorRuntimeOrThrow()._savePhysicalDialog(),this._deletePhysicalSelection=()=>this._editorRuntimeOrThrow()._deletePhysicalSelection(),this._confirmPartitionDelete=()=>this._editorRuntimeOrThrow()._confirmPartitionDelete(),this._confirmRoomDelete=e=>this._editorRuntimeOrThrow()._confirmRoomDelete(e),this._rebindPartitionOpening=()=>this._editorRuntimeOrThrow()._rebindPartitionOpening(),this._keepClosedAsPartitions=()=>this._editorRuntimeOrThrow()._keepClosedAsPartitions(),this._toggleServerPlans=async()=>this._onboardingRuntime&&this._spaceDialogUsesOnboardingRuntime("create")?this._onboardingRuntime._toggleServerPlans():this._editorRuntimeOrThrow()._toggleServerPlans(),this._aspectJob=null,this._dayCycleTick=()=>{if(!this.isConnected||"hidden"===this.ownerDocument.visibilityState)return;const e=this._dayCycleState();if(!e)return this._dayCycleTimer&&(clearInterval(this._dayCycleTimer),this._dayCycleTimer=0),void(this._dayCycleClockKey="");const t=cr(e);t!==this._dayCycleClockKey&&(this._dayCycleClockKey=t,this.requestUpdate())},this._sunShown=!1,this._sunOut=!1,this._sunOutTimer=0,this._openSettingsDialog=()=>{if(this._editorRuntime)return this._editorRuntime._openSettingsDialog();this._ensureEditorRuntime().then(e=>{e&&this._openSettingsDialog()})},this._openSupportDialog=()=>{this._editorRuntime?this._editorRuntime._openSupportDialog():this._ensureEditorRuntime().then(e=>{e&&this._openSupportDialog()})},this._openPdfDialog=()=>{this._pdfRuntimeLoader.ensure().then(e=>{e&&(this._pdfDialog=!0,this.requestUpdate())})},this._reportedPreflightFingerprint=null,this._openAlignDialog=()=>this._editorRuntimeOrThrow()._openAlignDialog(),this._toggleOptimizeLivePositions=()=>this._editorRuntimeOrThrow()._toggleOptimizeLivePositions(),this._optimizeUndoBusy=!1,this._openBackupExport=()=>this._editorRuntimeOrThrow()._openBackupExport(),this._openRulesDialog=()=>this._editorRuntimeOrThrow()._openRulesDialog(),this._climateCache=null,this._gearPtCache=new WeakMap}requestUpdate(e,t,i){if("hass"===e&&this.hass&&this._liveRt){const e=this._visibleDeviceSnapshot||this._candidateDeviceSnapshot;if(!this._liveRt.hass(t,this.hass,e?{entityIds:e.entityIds}:null,()=>Mg(this))&&!this._summary?.observeHassComposition())return}void 0!==e&&(this._terminalFrame=0),this._editorRuntime?._routeLiveEditorUpdate(e,t)||(this._liveRt?.clear(),super.requestUpdate(e,t,i))}_editorRuntimeOrThrow(){if(!this._editorRuntime)throw new Error("Houseplan editor runtime is not loaded");return this._editorRuntime}async _ensureEditorRuntime(){return this._editorRuntimeLoader.ensure()}async _ensureOnboardingRuntime(){return this._onboardingRuntimeLoader.ensure()}async _ensureIsoSceneRuntime(){return this._isoSceneRuntimeLoader.ensure()}_editorRuntimeStateChanged(e){clearTimeout(this._editorRuntimeLoadingTimer),this._editorRuntimeLoadingTimer=void 0,"loading"!==e?(this._editorRuntimeLoadingVisible=!1,this.requestUpdate()):this._editorRuntimeLoadingTimer=window.setTimeout(()=>{this._editorRuntimeLoadingVisible=!0,this.requestUpdate()},150)}async _requestMode(e,t=!0,i=!1){const n=++this._editorModeRequest;if(i&&(this._warmModeRequest=n,this._refitRaf&&(cancelAnimationFrame(this._refitRaf),this._refitRaf=0),this._pendingRefitSize=null),"view"===e||await this._ensureEditorRuntime()){if(n===this._editorModeRequest&&this.isConnected)return i?(this._adoptMode(e),this._warmRevivePending&&(clearTimeout(this._warmReviveTimer),this._warmReviveTimer=void 0,this._warmReviveDialog()),this.requestUpdate(),void this.updateComplete.then(()=>requestAnimationFrame(()=>requestAnimationFrame(()=>{if(this._warmModeRequest!==n||n!==this._editorModeRequest)return;const e=this._stageEl;this._lastValidStageSize=e&&e.clientWidth>0&&e.clientHeight>0?[e.clientWidth,e.clientHeight]:null,this._pendingRefitSize=null,this._warmModeRequest=0})))):void this._setMode(e,t);this._warmModeRequest===n&&(this._warmModeRequest=0)}else this._warmModeRequest===n&&(this._warmModeRequest=0)}get _layout(){return this._adoption.layout}set _layout(e){this._adoption.stageLocalLayout(e)}get _layoutRev(){return this._adoption.layoutRev}set _layoutRev(e){this._adoption.seedIdentity({layoutRev:e})}get _layoutContentFingerprint(){return this._adoption.layoutFingerprint}set _layoutContentFingerprint(e){this._adoption.seedIdentity({layoutFingerprint:e})}get _serverCfg(){return this._adoption.config}set _serverCfg(e){this._adoption.stageLocalConfig(e)}get _cfgRev(){return this._adoption.configRev}set _cfgRev(e){this._adoption.seedIdentity({configRev:e})}get _cfgContentFingerprint(){return this._adoption.configFingerprint}set _cfgContentFingerprint(e){this._adoption.seedIdentity({configFingerprint:e})}_seedDecorStyle(e){var t,i;if(t=Ol,i=this,Fl(e,Bl)&&"pending"===t.state()&&(t.art("",i),t.ensure()),this._decorStyleSeeded||!e)return;this._decorStyleSeeded=!0;const n=e.settings?.decor_default_style;n&&(this._decorStyle=function(e,t){if(!e||"object"!=typeof e)return{...t};const i=e,n="string"==typeof i.color&&i.color?i.color:t.color,r="string"==typeof i.fill_color&&i.fill_color?i.fill_color:t.fillColor,o=Number(i.width_cm);return{color:n,opacity:Tr(i.opacity,t.opacity),widthCm:Number.isFinite(o)&&o>0?Math.max(.1,Math.min(100,o)):t.widthCm,fill:"boolean"==typeof i.fill?i.fill:t.fill,fillColor:r,fillOpacity:Tr(i.fill_opacity,t.fillOpacity)}}(n,Cr))}get _canManageConfiguration(){return null!==this._serverCanWrite?this._serverCanWrite:!0===this.hass?.user?.is_admin}get _canEdit(){return this._norm&&this._canManageConfiguration}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}get _doubleFitEnabled(){return!("view"!==this._mode||this._vacFit||this._modeTransitionBusy||this._touchSequenceMultitouch||"steady"!==this._continuity.state||this._continuity.overlayBlocksInteraction)}_cameraState(){const e=this._viewOr(this._baseVb());return{zoom:this._zoom,viewBox:{...e}}}_normalizeCameraState(e){const t=this._cameraTransitionFit||Oi(this._baseVb(),this._stageAspect());return{zoom:Math.min(wv.ZOOM_MAX,Math.max(wv.ZOOM_MIN,e.zoom)),viewBox:this._clampView({...e.viewBox},t)}}_applyCameraTransitionFrame(e){const t=this._normalizeCameraState(e.presented);e.presented=t,this._zoom=t.zoom,this._view={...t.viewBox},this._liveVp(!0)}_settleCameraTransition(e){const t=this._normalizeCameraState(e.to);this._zoom=t.zoom,this._view={...t.viewBox},this._cameraTransitionFit=null,"room"!==e.reason&&this._saveZoom(),this.requestUpdate()}_cancelCameraTransition(e=!1,t=!1){const i=this._cameraTransition.state?.reason,n=t&&this._cameraTransition.active?this._cameraTransition.presented?.zoom:void 0;this._cameraTransition.cancel(e),this._cameraTransitionFit=null,void 0!==n&&"room"!==i&&this._saveZoom()}_prepareCameraCommand(){this._bootSoftCancel(),this._modeTransitionBusy&&this._cancelModeTransition(!0),"opening"===this._tool&&(this._cursorPt=null,this._clearOpeningPlacement(!1))}_startCameraTransition(e,t,i,n){const r=this._cameraState(),o=this._cameraTransition.target;return(!o||!Xg(o,e))&&(Xg(r,e)?(this._cancelCameraTransition(!1),!1):(this._activateSafeDayCycleOutline(),this._cameraTransitionFit={...t},this._cameraTransition.start(r,e,i,this._reducedMotion?0:n),!0))}_cssColor(e,t){const i=String(e||"").trim();if(!i)return t;const n=document.createElement("span");n.style.cssText=`position:absolute;visibility:hidden;color:${i}`,this.renderRoot.append(n);const r=getComputedStyle(n).color||t;return n.remove(),r}_currentModeVisual(e=this._mode){const t=this._modeTransition.presented||this._modeTransitionVisual;if(t)return{...t,viewport:{...t.viewport,viewBox:{...t.viewport.viewBox}}};const i=this._stageEl;if(!i||i.clientWidth<=0||i.clientHeight<=0)return null;const n=this.renderRoot.querySelector(".editorchrome"),r=this._viewOr(this._baseVb()),o=this.renderRoot.querySelector(".hp-paper"),s=this.renderRoot.querySelector(".hp-backdrop"),a=this.renderRoot.querySelector(".zoomwrap"),l=a?getComputedStyle(a).filter:"",c=Number(/brightness\(([^)]+)\)/.exec(l)?.[1]);return{presentedMode:e,editorChromeHeight:"view"===e?0:n?.getBoundingClientRect().height||0,stageWidth:i.clientWidth,stageHeight:i.clientHeight,viewport:Bg(r,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"===e?.35:1,backdropOpacity:s&&Number(getComputedStyle(s).opacity)||1,viewWeight:"view"===e?1:0,editorWeight:"view"===e?0:1,toolbarContentOpacity:"view"===e?0:1}}_viewForModeTarget(e,t,i,n,r){const o=Oi(this._baseVb(),n/r),s=Math.min(wv.ZOOM_MAX,Math.max(wv.ZOOM_MIN,e)),a=o.w/s,l=o.h/s,c=t??o.x+o.w/2,h=i??o.y+o.h/2;return this._clampView({x:c-a/2,y:h-l/2,w:a,h:l},o)}_targetStageColor(e){return"view"!==e?"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(e){return"view"===e&&this._spaceModel()?.bg?this._cssColor("var(--ha-card-background, var(--card-background-color, #111))","rgb(17, 17, 17)"):"rgb(255, 255, 255)"}_targetBrightness(e){return 1}_applyModeTransitionFrame(e){e.targetMode===this._mode&&(this._modeTransitionVisual=e.presented,this._view={...e.presented.viewport.viewBox},this.requestUpdate())}_settleModeTransition(e){if(e.targetMode!==this._mode)return;const t=this._modeTransitionRequest;this._view={...e.to.viewport.viewBox},this._zoom=this._modeTransitionTargetZoom,this._modeTransitionVisual=null,this._modeTransitionPreparing=!1,this._lastValidStageSize=[e.to.stageWidth,e.to.stageHeight],"view"===this._mode&&(this._saveZoom(),this._viewModeSnap=null,this._modeTransitionEditorCamera=null),this.requestUpdate(),this.updateComplete.then(()=>{if(!this.isConnected||t!==this._modeTransitionRequest||this._modeTransitionBusy||e.targetMode!==this._mode)return;const i=this._stageEl;if(i&&i.clientWidth>0&&i.clientHeight>0&&(Math.abs(i.clientWidth-e.to.stageWidth)>.5||Math.abs(i.clientHeight-e.to.stageHeight)>.5)){const e=this._view;this._lastValidStageSize=[i.clientWidth,i.clientHeight],this._applyView(this._zoom,e?e.x+e.w/2:void 0,e?e.y+e.h/2:void 0),this.requestUpdate()}const n=this.renderRoot.activeElement;(!n||!n.isConnected||!!n.closest?.(".editorchrome, .stage"))&&this.renderRoot.querySelector(".modetab.active")?.focus?.({preventScroll:!0})})}_cancelModeTransition(e=!0){this._cancelCameraTransition(!1);const t=!!this._modeTransition.state;this._modeTransitionRequest++,this._modeTransitionPreparing=!1,this._modeTransitionForceAtomic=!1,this._modeTransition.cancel(e),e&&t||(this._modeTransitionVisual=null)}_adoptMode(e){e!==this._mode&&(this._clearRoomFocus(!0),this._resetDeviceHitState()),this._cancelModeTransition(!1),this._mode=e,this._isoProjectionSnapshot=null,"view"!==e&&(this._editorChromeMode=e)}_commitViewModeAtomic(e,t,i,n){if(this._modeTransitionPreparing=!1,this._modeTransitionVisual=null,this._modeTransitionForceAtomic=!1,this._zoom=t,e){const r=this._stageEl?.clientWidth||e.stageWidth,o=Math.max(1,e.stageHeight+e.editorChromeHeight);this._view=this._viewForModeTarget(t,i,n,r,o),this._lastValidStageSize=[r,o]}else this._view=null;this._viewModeSnap=null,this._modeTransitionEditorCamera=null,this._saveZoom(),this.requestUpdate()}_prepareModeTransition(e,t,i,n,r,o){this.updateComplete.then(()=>{if(!this.isConnected||e!==this._modeTransitionRequest||this._mode!==i)return void(e===this._modeTransitionRequest&&(this._modeTransitionPreparing=!1,this._modeTransitionVisual=null,this._modeTransitionForceAtomic=!1,this.requestUpdate()));const s=this.renderRoot.querySelector(".editorchrome-inner"),a="view"===i?0:s?.scrollHeight||0,l=Math.max(1,(this.panelHost?this.clientHeight:innerHeight)-ef(this.renderRoot,this._stageEl,this.panelHost)),c=this._stageEl?.clientWidth||t.stageWidth,h=this._viewForModeTarget(n,r,o,c,l),d={presentedMode:i,editorChromeHeight:a,stageWidth:c,stageHeight:l,viewport:Bg(h,c),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 u=this._modeTransitionForceAtomic;this._modeTransitionForceAtomic=!1,this._modeTransition.start(t,d,i,this._reducedMotion||u?0:220)})}get _hasFixedFloor(){return!!this._config&&Object.prototype.hasOwnProperty.call(this._config,"floor")}_fixedFloorState(e=this._model,t=this._loadOk){const i=this._config?.floor,n=function(e){if(!e.hasFloor)return{kind:"absent"};const t=e.floor;if("string"==typeof t)return t.length?e.spaceIds.includes(t)?{kind:"valid",id:t,source:"id"}:{kind:"invalid",reason:"unknown-id",value:t}:{kind:"invalid",reason:"empty-id",value:t};if("number"==typeof t){if(!Number.isFinite(t))return{kind:"invalid",reason:"non-finite-index",value:t};if(!Number.isInteger(t))return{kind:"invalid",reason:"fractional-index",value:t};if(t<0)return{kind:"invalid",reason:"negative-index",value:t};const i=e.spaceIds[t];return void 0===i?{kind:"invalid",reason:"out-of-range-index",value:t}:{kind:"valid",id:i,source:"index"}}return{kind:"invalid",reason:"invalid-type",value:t}}({spaceIds:e.map(e=>e.id),hasFloor:this._hasFixedFloor,floor:i});return!this._hasFixedFloor||t?n:"number"==typeof i?"valid"===n.kind||"invalid"===n.kind&&"out-of-range-index"===n.reason?{kind:"pending",value:i}:n:"valid"===n.kind||"invalid"===n.kind&&"unknown-id"!==n.reason?n:{kind:"pending",value:i}}_canCommitSpace(e,t=!1){if(t||!this._hasFixedFloor)return!0;const i=this._fixedFloorState();return"valid"===i.kind&&i.id===e}_commitSpace(e,t=!1){return!!this._canCommitSpace(e,t)&&(e!==this._space&&(this._clearRoomFocus(!0),this._resetDeviceHitState(),this._cancelDangerConfirm(),this._cancelCameraTransition(!1),this._clearTransientHover(!0),this._cancelDevicePressFeedback(),this._editorRuntime?._clearFurniturePreview()),this._space=e,this._isoProjectionSnapshot=null,!0)}_slideTo(e,t){if(e===this._space)return!0;if(!this._canCommitSpace(e))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._commitSpace(e),this._path=[],this._clearPlanSnapHover(),this._clearOpeningPlacement(!0),this._tool="draw",this._activeWallChainId=null,this._activeWallChainPartitionIds=[],this._wallChainSegmentCms=[],this._closingWallCm=null,this._selId=null,this._physicalSel=null,this._editorSecondary?.closeForNavigation(),this._physicalDialog=null,this._physicalDrag=null,this._restoreZoom(),i||(this._slide=t,clearTimeout(this._slideTimer),this._slideTimer=window.setTimeout(()=>{this._slideTimer=void 0,this._slide="",this.requestUpdate()},190),this.requestUpdate()),!0}get _canReorderTabs(){return Zf({canEdit:this._canEdit,kiosk:this._kiosk,mode:this._mode,pointerType:"mouse",spaceCount:this._model.length,fixedFloor:this._hasFixedFloor})}_tabPointerDown(e,t){Zf({canEdit:this._canEdit,kiosk:this._kiosk,mode:this._mode,pointerType:e.pointerType,spaceCount:this._model.length,fixedFloor:this._hasFixedFloor})&&(yv(e),this._tabDragRelease=e=>this._tabPointerUp(e),window.addEventListener("pointerup",this._tabDragRelease),window.addEventListener("pointercancel",this._tabDragRelease),this._tabDrag={id:t,pointerId:e.pointerId,x:e.clientX,y:e.clientY,moved:!1,targetId:null,placement:null})}_tabDropTargetAt(e,t,i){const n=this._model.map(e=>e.id),r=n.indexOf(i);if(r<0)return null;const o=this.renderRoot.querySelectorAll('[data-hp="space-tab"]');for(const s of o){const o=s.dataset.id||"";if(!o||o===i)continue;const a=s.getBoundingClientRect();if(ea.right||ta.bottom)continue;const l=n.indexOf(o);return l<0?null:{targetId:o,placement:l=4)))return;var i,n;const r=this._tabDropTargetAt(e.clientX,e.clientY,t.id);t.moved&&t.targetId===r?.targetId&&t.placement===r?.placement||(this._tabDrag={...t,moved:!0,targetId:r?.targetId||null,placement:r?.placement||null})}_tabPointerUp(e){const t=this._tabDrag;if(t&&t.pointerId!==e.pointerId)return;const i="pointerup"===e.type&&t?.moved?this._tabDropTargetAt(e.clientX,e.clientY,t.id):null;"pointerup"===e.type&&t?.moved&&this._suppressNextTabClick(),this._endTabDrag(),t?.moved&&i&&this._commitTabOrder(t.id,i.targetId)}_endTabDrag(){this._tabDrag=null,this._tabDragRelease&&(window.removeEventListener("pointerup",this._tabDragRelease),window.removeEventListener("pointercancel",this._tabDragRelease),this._tabDragRelease=null)}_tabClick(e){if(this._tabSuppressClick)return this._tabSuppressClick=!1,clearTimeout(this._tabSuppressClickTimer),void(this._tabSuppressClickTimer=void 0);this._pickSpace(e)}_suppressNextTabClick(){this._tabSuppressClick=!0,clearTimeout(this._tabSuppressClickTimer),this._tabSuppressClickTimer=window.setTimeout(()=>{this._tabSuppressClick=!1,this._tabSuppressClickTimer=void 0},0)}_commitTabOrder(e,t){const i=this._serverCfg;if(!i||!this._canReorderTabs)return;const n=this._model.map(e=>e.id),r=function(e,t,i){const n=e.indexOf(t),r=e.indexOf(i);if(n<0||r<0||n===r)return e;const o=e.slice();return o.splice(n,1),o.splice(r,0,t),o}(n,e,t);if(r===n)return;const o=new Map(this._devices.map(e=>[String(e.id),String(e.area||"")])),s=function(e,t,i,n=()=>""){if(!i)return[];const r=[];for(const o of e){if(!o||!0===o.removed)continue;const e="string"==typeof o.id?o.id:"";if(!e)continue;if("string"==typeof o.space&&o.space)continue;const s=("string"==typeof o.area?o.area:"")||n(e)||"";s&&t[s]||r.push({id:e,space:i})}return r}(i.markers||[],Object.fromEntries(Object.entries(this._areaToSpace).map(([e,t])=>[e,t.space])),n[0]||"",e=>o.get(e)||"");if(s.length){const e=new Map(s.map(e=>[e.id,e.space]));for(const t of i.markers||[]){const i=e.get(String(t.id));i&&(t.space=i)}}i.spaces=function(e,t){const i=new Map(t.map((e,t)=>[e,t]));return e.map((e,t)=>({space:e,index:t})).sort((e,t)=>(i.get(String(e.space?.id))??Number.MAX_SAFE_INTEGER)-(i.get(String(t.space?.id))??Number.MAX_SAFE_INTEGER)||e.index-t.index).map(e=>e.space)}(i.spaces||[],r),this._saveConfig(),this._tabOrderWarned||(this._tabOrderWarned=!0,this._showToast(this._t("toast.space_order_changed")))}_pickSpace(e){if(this._endTabDrag(),e===this._space)return;const t=this._model.map(e=>e.id),i=t.indexOf(this._space),n=t.indexOf(e);this._navApplied=!0,this._showFar=!1,this._frame=null,this._slideTo(e,i>=0&&n0&&Date.now()>=this._cyclePausedUntil&&this._model.length>1&&this._zoom<=1.001){const e=this._model.map(e=>e.id),t=e.indexOf(this._space);this._slideTo(e[(t+1)%e.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(e){this._wallUnionCacheValue=e,null===e&&this._wallUnionPool.clear()}get _glowClipCache(){return this._glowRuntimeState.clipCache}get _glowGeometryWarnings(){return this._glowRuntimeState.geometryWarnings}get _glowFeatherUnits(){return this._glowRuntimeState.featherUnits}set _glowFeatherUnits(e){this._glowRuntimeState.featherUnits=e}get _glowRenderedSources(){return this._glowRuntimeState.renderedSources}get _glowLastAppearance(){return this._glowRuntimeState.lastAppearance}get _glowFeatherSuspendUntil(){return this._glowRuntimeState.featherSuspendUntil}set _glowFeatherSuspendUntil(e){this._glowRuntimeState.featherSuspendUntil=e}get _glowFeatherResumeTimer(){return this._glowRuntimeState.featherResumeTimer}set _glowFeatherResumeTimer(e){this._glowRuntimeState.featherResumeTimer=e}get _glowSourceSeq(){return this._glowRuntimeState.sourceSeq}set _glowSourceSeq(e){this._glowRuntimeState.sourceSeq=e}_activateSafeDayCycleOutline(){this._safeDayCycleOutline=!0,this._stageEl?.classList.add("hp-safe-daycycle-outline")}get _touchSequenceMultitouch(){return this._touchClickGuard.sequenceMultitouch}_syncDangerConfirmLocaleGate(){return this._config&&this.hass?dp(this,gp,kp(this.hass,this._config.language)):"ready"}_dangerConfirmMissingSpace(){const e=this._model;if(!e.length)return!1;const t=this._fixedFloorState(e);return"pending"!==t.kind&&"invalid"!==t.kind&&!this._spaceModel()}_syncVersionRecovery(){this._versionRecovery.update({frontendVersion:ev(iv),backendVersion:this._haIntegrationVersion,kiosk:!0===this._config?.kiosk,reducedMotion:this._reducedMotion})}_newContinuityController(){return new lc(()=>{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(uv,JSON.stringify(this._viewPreference))}catch{}}_logicalViewCenter(e){const t=this._view;if(!t)return null;const i=[t.x+t.w/2,t.y+t.h/2],n="iso"===e?cf(i):i;return{x:n[0],y:n[1]}}_convertProjectionView(e,t){if(e===t)return;this._clearRoomFocus(!0);const i=this._logicalViewCenter(e);this._view=null;const n=i?"iso"===t?lf([i.x,i.y],0):[i.x,i.y]:null;this._applyView(this._zoom,n?.[0],n?.[1]),this._warmPatch({vp:this._warmViewportState()}),this.requestUpdate()}_setProjection(e){if(!this._labsIso||"view"!==this._mode)return;const t=this._effectiveProjection();if(this._viewPreference={...this._viewPreference,[this._space]:e},"iso"===e){this._ensureIsoSceneRuntime();const e=this._isoSceneKey();e&&this._isoFallback.delete(e),this._isoFallback.delete(`${this._space}|no-borders`),this._clearIsoInvalidFallback()}this._saveViewPreference(),this._isoProjectionSnapshot=null;const i=this._effectiveProjection();this._convertProjectionView(t,i)}_hashSpace(){return Ff(window.location.hash||"")}connectedCallback(){this._connectedPath=location.pathname,this._routeDepartureHandled=!1,this._configReloadAuthority.observeContext(Vu(this)),window.addEventListener("location-changed",this._onLocationChanged),window.addEventListener("popstate",this._onLocationChanged),this._continuityDisposed&&(this._continuity=this._newContinuityController(),this._continuityDisposed=!1,this._continuityPaintToken=-1);const e=dg(this.ownerDocument);var t;void 0!==e&&(this._glowScreenBlend=e),this._continuityUnsub?.(),this._continuityUnsub=sc(this.ownerDocument,this._pageVisibility),this._languageFailureUnsub?.(),this._languageFailureUnsub=function(...e){return()=>{for(const t of e)t()}}((t=()=>{this._showToast(this._t("toast.locale_load_failed"))},mp.add(t),()=>mp.delete(t)),function(e){return Il.add(e),()=>{Il.delete(e)}}(()=>this._showToast(this._t("toast.furniture_art_load_failed")))),super.connectedCallback(),this._summarySlot.connect(),this._ensureLiveRuntime().catch(()=>this.requestUpdate()),this._pointerModality.connect(this.ownerDocument.defaultView);const i=this.ownerDocument.defaultView?.MutationObserver;i&&(this._pointerHoverObserver=new i(e=>{let t=!1;for(const i of e){for(const e of i.addedNodes)this._syncPointerHoverSubtree(e);const e=e=>{if(e.nodeType!==Node.ELEMENT_NODE)return!1;const t=e;return t.matches(".devlayer, .devlayer *")||!!t.querySelector?.(".devlayer")};(e(i.target)||[...i.addedNodes,...i.removedNodes].some(e))&&(t=!0)}t&&this._invalidateDeviceHitGeometry()}),this._pointerHoverObserver.observe(this.renderRoot,{childList:!0,subtree:!0,attributes:!0,attributeFilter:["class","style","data-id"]})),this._motionMedia=window.matchMedia?.("(prefers-reduced-motion: reduce)"),this._reducedMotion=!!this._motionMedia?.matches,this._motionMedia?.addEventListener?.("change",this._onMotionChange),this._syncVersionRecovery(),this._versionRecovery.connect(),hg(this.ownerDocument).then(e=>{e!==this._glowScreenBlend&&(this._glowScreenBlend=e,this.isConnected&&this.requestUpdate())}),this.hass&&this._ensureHaRegistryAuthority(),window.addEventListener("keydown",this._keyHandler),this._signer.start(()=>this.hass,()=>this._referencedContentUrls()),this._syncCycleTimer(),window.addEventListener("hashchange",this._onHashChange),this._labsUnsub?.(),this._labsUnsub=function(e){Nf.add(e);const t=Bf();return"undefined"==typeof window&&e(t),()=>{Nf.delete(e)}}(this._onLabsSnapshot),this._labsIso&&this._ensureIsoSceneRuntime(),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},rv)),!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._versionRecovery.disconnect(),this._configReloadAuthority.invalidateLifecycle(),this._liveRt?.dispose(),this._radarLive.stop(),this._editorRuntime?._disposeLiveEditor(),this._clearRoomFocus(!0),this._cancelDangerConfirm(),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._languageFailureUnsub?.(),this._languageFailureUnsub=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._warmModeRequest=0,this._dayCycleTimer&&(clearInterval(this._dayCycleTimer),this._dayCycleTimer=0),this._summarySlot.disconnect(),this._dayCycleClockKey="",this._bootSettleRaf&&(cancelAnimationFrame(this._bootSettleRaf),this._bootSettleRaf=0),this._bootSettling=!1;for(const e of this._activityRt.values())clearTimeout(e.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),clearTimeout(this._editorRuntimeLoadingTimer),this._editorRuntimeLoadingTimer=void 0,this._editorRuntimeLoadingVisible=!1,this._modeTransition.dispose(),this._cameraTransition.dispose(),this._cameraTransitionFit=null,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(),this._cancelDeviceDrag(),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),Fm(this._glowRuntimeState,this._glowRuntimeHost),this._warmSnapshot(),this._warmRevivePending=!1,clearTimeout(this._warmReviveTimer),this._warmReviveTimer=void 0,this._warmRelease(),this._clearPlanSnapHover(),this._clearOpeningPlacement(!0),this._editorRuntime?._clearFurniturePreview(),this._editorRuntime?._furnShiftDetach(),this._touchContacts.clear(),this._touchClickGuard.reset(),this._resetDeviceHitState(),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(e){if("Escape"===e.key&&this._vacFit){if(this._vacFit.busy)return;return this._vacFit=null,this._showToast(this._t("vac.cal_cancelled")),void e.stopPropagation()}if("Escape"===e.key){if(this._tapConfirm)return void(this._tapConfirm=null);if(this._vacCalConfirm)return void(this._vacCalConfirm.busy||(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._pdfDialog)return void(this._pdfDialog=!1);if(this._supportDialog)return void this._editorRuntime?._closeSupportDialog();if(this._settingsDialog)return void(this._settingsDialog=null);if(this._summary?.closeDialogIfIdle())return;if(this._markerDialog)return void this._closeMarkerDialog();if(this._deviceInbox)return void(this._deviceInbox=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 e.preventDefault(),void this._editorSecondary?.closeGroup(!0)}const t=e.composedPath?.()||[e.target],i=t.some(e=>e?.matches?.('input, textarea, select, [contenteditable="true"]')),n=t.some(e=>e?.classList?.contains?.("editor-secondary")),r=e.ctrlKey||e.metaKey,o=e.key.toLowerCase(),s=/^[a-z]$/.test(o),a="z"===o||!s&&"KeyZ"===e.code,l="y"===o||!s&&"KeyY"===e.code,c=r&&(a&&e.shiftKey||l),h=r&&a&&!e.shiftKey;if("decor"===this._mode){if((h||c)&&i)return;if(c)return e.preventDefault(),void this._redoGeometry();if(h)return e.preventDefault(),this._decorDraft?void(this._decorDraft=null):this._decorMove||this._dtDrag||this._bdDrag?void this._cancelDecorGesture():void this._undoGeometry();if(("Delete"===e.key||"Backspace"===e.key)&&this._decorSel&&!i&&!n)return e.preventDefault(),void this._decorDeleteSel();const t="ArrowLeft"===e.key?[-this._gridPitch,0]:"ArrowRight"===e.key?[this._gridPitch,0]:"ArrowUp"===e.key?[0,-this._gridPitch]:"ArrowDown"===e.key?[0,this._gridPitch]:null;return!t||r||e.altKey||"select"!==this._decorTool||!this._decorSel||!this._decorList.some(e=>e.id===this._decorSel)||this._decorDraft||this._decorMove||this._dtDrag||this._bdDrag||i||n||this._editorSecondaryDialogBlocked?void("Escape"===e.key&&(e.preventDefault(),this._decorDraft?this._decorDraft=null:this._decorMove||this._dtDrag||this._bdDrag?this._cancelDecorGesture():"furniture"===this._decorTool?(this._editorRuntime?._clearFurniturePreview(),this._editorRuntime?._furnShiftDetach(),this._furnPalette=null,this._furnCategory=null,this._decorTool="select"):this._decorSel?this._decorSel=null:"select"!==this._decorTool?this._decorTool="select":this._setMode("view"))):(e.preventDefault(),void this._decorNudge(t[0],t[1]))}if("devices"===this._mode){if((h||c)&&i)return;return c?(e.preventDefault(),void this._redoDevicePosition()):h?(e.preventDefault(),void this._undoDevicePosition()):void("Escape"===e.key&&this._deviceDrag&&(e.preventDefault(),this._cancelDeviceDrag()))}if(this._markup&&(!h&&!c||!i)){if(("Delete"===e.key||"Backspace"===e.key)&&this._physicalSel&&!i&&!n)return e.preventDefault(),void this._deletePhysicalSelection();if(c)return e.preventDefault(),void this._redoGeometry();if(h)return e.preventDefault(),this._resize?.dragging?void this._rszCancelDrag():this._wallFaceBatch?(this._roomDialogCancel(),void(this._activeWallChainId&&this._path.length>1?this._undoActiveWallPoint():this._undoPoint())):"draw"===this._tool&&this._path.length?void(this._activeWallChainId&&this._path.length>1?this._undoActiveWallPoint():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"===e.key)return this._physicalDrag||this._physicalRotate?(e.preventDefault(),void this._cancelPhysicalGesture()):this._roomDialog?(e.preventDefault(),void this._roomDialogCancel()):"draw"===this._tool&&this._path.length?(e.preventDefault(),void this._finishWallChain()):this._physicalSel?(e.preventDefault(),void(this._physicalSel=null)):"resize"===this._tool?(e.preventDefault(),this._resize?.dragging?void this._rszCancelDrag():("exit-tool"===this._resize?.escapeIdle()&&(this._tool="draw"),void this.requestUpdate())):"split"===this._tool?(e.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?(e.preventDefault(),void(this._mergeSel?this._mergeSel=null:this._tool="draw")):this._wallDialog?(e.preventDefault(),void(this._wallDialog=null)):void("opening"!==this._tool&&"wallthick"!==this._tool&&"delroom"!==this._tool&&"column"!==this._tool||(e.preventDefault(),"opening"===this._tool&&this._clearOpeningPlacement(!0),this._tool="draw"))}}_undoPoint(){if(this._path.length)return this._contourClosed?(this._path=this._path.slice(0,-1),void(this._closingWallCm=null)):void(this._activeWallChainPartitionIds.length&&this._path.length>1?this._undoActiveWallPoint():this._path=this._path.slice(0,-1))}_undoActiveWallPoint(){const e=[...this._activeWallChainPartitionIds],t=e[e.length-1],i=this._spaceModel()?.partitions.find(e=>e.id===t),n=this._path[0]?[...this._path[0]]:null,r=this._path.slice(0,-1).map(e=>[...e]),o=this._wallChainSegmentCms.slice(0,-1),s=this._geometryHistory.undo();if(!s)return this._activeWallChainPartitionIds=[],this._wallChainSegmentCms=[],this._wallChainRedo=[],void(this._path=n?[n]:[]);this._applyGeometryState(s.before,!0)?(this._activeWallChainId||=`chain-${Date.now().toString(36)}`,this._activeWallChainPartitionIds=e.slice(0,-1),this._path=r.length?r:n?[n]:[],this._wallChainSegmentCms=o,i&&this._wallChainRedo.push({id:i.id,point:[...i.b],cm:i.cm}),this._clearPlanSnapHover(),this._showToast(this._t("history.undone",{name:s.name}))):this._geometryHistory.clear()}static async getConfigElement(){return await import("./editor-BIdm6L_k.js"),document.createElement("houseplan-card-editor")}static getStubConfig(){return{type:"custom:houseplan-card"}}static _warmBootReset(e){for(const e of ov.values())for(const t of e)clearTimeout(t.evict);ov.clear(),av=e&&e>0?e:1e4}static _warmBootStats(){let e=0,t=0;const i=[];for(const n of ov.values())for(const r of n)e++,r.dlg&&(t++,i.push(r.dlg.kind));return{keys:ov.size,slots:e,dlgs:t,drafts:i}}setConfig(e){const t=this._config,i=!!t&&Object.prototype.hasOwnProperty.call(t,"floor");this._config={icon_size:2.5,show_temperature:!0,live_states:!0,show_signal:!0,...e};(i!==this._hasFixedFloor||t?.floor!==this._config.floor)&&(this._hashApplied=!1,this._navApplied=!1,this._warmVpArmed=!1),this._config.kiosk&&(this._booting=!1,this._bootFading=!1),!this._hasFixedFloor&&e.default_floor&&this._commitSpace(e.default_floor,!0);try{this._zoomBySpace=JSON.parse(localStorage.getItem(hv)||"{}")||{}}catch{this._zoomBySpace={}}try{const e=JSON.parse(localStorage.getItem(uv)||"{}")||{};this._viewPreference=Object.fromEntries(Object.entries(e).filter(e=>"flat"===e[1]||"iso"===e[1]))}catch{this._viewPreference={}}if(this._labs=Bf(),this.isConnected&&this._labsIso&&this._ensureIsoSceneRuntime(),!this._summary?.applyLocalScaleForCurrentIdentity())try{const e=JSON.parse(localStorage.getItem("houseplan_card_kiosk_v1")||"null");this._kioskScale={icon:jn(e?.icon),font:jn(e?.font)}}catch{}try{const e=JSON.parse(localStorage.getItem(cv)||"null");this._adoption.restoreCached(e)&&(this._seedDecorStyle(this._serverCfg),this._cfgEpoch++,this._virtualLights=Hh(e.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),this._syncVersionRecovery()}_warmAdopt(){if(this._config?.kiosk)return;const e=Cf(this._config);if(this._warmKey===e&&this._warmSlot)return;this._warmSlot&&this._warmRelease();const t=this.parentNode,i=this._warmIdx(t),n=ov.get(e);if(!n||!n.length)return;const r=n.find(e=>e.owner===this._warmGen);if(r)return this._warmLongReturn=!!r.freed&&Date.now()-r.freed>=nc,clearTimeout(r.evict),r.evict=0,r.freed=0,r.live=!0,this._warmSlot=r,this._warmKey=e,r.frameFingerprint&&this._continuity.adoptCompleteFrame(r.frameFingerprint),void(!this._devices.length&&r.devices?.length&&(this._devices=[...r.devices]));const{slot:o,sure:s}=((e,t,i,n)=>{const r=e=>{const t=!!i&&e.place?.deref()===i;return t&&e.idx===n?4:e.live?0:t?3:2};let o=null,s=0,a=0,l=null;for(const i of e){if(i.owner===t)continue;l=i;const e=r(i);e<=0||(e>s?(o=i,s=e,a=1):e===s&&a++)}return!o||a>1?{slot:o||l,sure:!1}:{slot:o,sure:!0}})(n,this._warmGen,t,i);o&&(this._warmLongReturn=!!o.freed&&Date.now()-o.freed>=nc,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},rv)),this._warmKey=e,s?(clearTimeout(o.evict),o.evict=0,o.owner=this._warmGen,o.place=t?new WeakRef(t):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:t?new WeakRef(t):null,idx:i,live:!0,hdrH:o.hdrH,stageH:o.stageH,vp:null,frameFingerprint:"",devices:null,dlg:null,freed:0,evict:0},n.push(this._warmSlot),this._warmTrim(n)))}_warmIdx(e){const t=e?.children;if(!t)return-1;for(let e=0;e4;){const t=e.findIndex(e=>!e.live);if(t<0)break;clearTimeout(e[t].evict),e.splice(t,1)}}_warmScheduleEvict(e,t){if(clearTimeout(e.evict),!(e.dlg||e.vp&&"view"!==e.vp.mode))return;const i=e.freed,n=e.owner;e.evict=window.setTimeout(()=>{if(e.evict=0,e.freed!==i||e.owner!==n)return;var r;e.dlg=null,e.vp=(r=e.vp)&&"view"!==r.mode?{...r,mode:"view",zoom:r.snap?.space===r.space?r.snap.zoom:r.zoom,view:null,snap:null,tool:"draw",decorTool:"select",showHidden:!1,selId:null,rszSel:null,decorSel:null}:r,e.frameFingerprint="";const o=ov.get(t);if(!e.live&&o&&o.length>1){const t=o.indexOf(e);t>=0&&o.splice(t,1)}},av+250)}_warmAdoptViewport(e){const t=this._warmVp;if(!t||this._warmSlot?.path!==location.pathname)return void(this._warmVp=null);const i=this._fixedFloorState();if(this._hashApplied||!this._model.find(e=>e.id===t.space)||"valid"===i.kind&&i.id!==t.space||this._hasFixedFloor&&"valid"!==i.kind)return void(this._warmVp=null);this._commitSpace(t.space,!0),this._navApplied=!0;const n="view"!==t.mode&&this._canEdit&&!e.kiosk?t.mode:"view";this._adoptMode("view"),this._pendingNavMode="view"===t.mode||this._canEdit||e.kiosk?null:t.mode,this._zoom=t.zoom;const r=this._effectiveProjection(),o=r===t.projection&&this._labsIso===t.activeLabsIso;if(this._view=o&&t.view?{...t.view}:null,this._viewModeSnap=o&&t.snap?{...t.snap}:null,!o&&t.logicalCenter){const e="iso"===r?lf([t.logicalCenter.x,t.logicalCenter.y],0):[t.logicalCenter.x,t.logicalCenter.y];this._applyView(t.zoom,e[0],e[1])}var s;this._tool="opening"===(s=function(e){return"partition"===e?"draw":e}(s=t.tool))?"draw":"string"==typeof s&&Rf.has(s)?s:"draw",this._decorTool=t.decorTool,this._showHidden=t.showHidden,this._showFar!==t.showFar&&(this._showFar=t.showFar,this._frame=null),this._selId=t.selId,this._resize?.restoreSelection(t.rszSel),this._decorSel=t.decorSel,this._warmVpArmed=!0,"view"!==n&&this._requestMode(n,!1,!0)}_warmPatch(e,t=!1){if(this._config?.kiosk)return;const i=Cf(this._config);if(!this._warmSlot||this._warmKey===i){if(!this._warmSlot){if(!t)return;const e=this.parentNode;this._warmKey=i,this._warmSlot={owner:this._warmGen,path:location.pathname,place:e?new WeakRef(e):null,idx:this._warmIdx(e),live:!0,hdrH:this._hdrH,stageH:0,vp:null,frameFingerprint:"",devices:null,dlg:null,freed:0,evict:0};const n=ov.get(i)||[];for(n.push(this._warmSlot),ov.set(i,n),this._warmTrim(n);ov.size>8;){const e=ov.keys().next().value;if(void 0===e||e===i)break;for(const t of ov.get(e)||[])clearTimeout(t.evict);ov.delete(e)}}Object.assign(this._warmSlot,e)}}_warmViewportState(){const e=this._effectiveProjection();return{space:this._space,mode:this._mode,projection:e,activeLabsIso:this._labsIso,logicalCenter:this._logicalViewCenter(e),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._resize?.selectedRoomId,decorSel:this._decorSel}}_warmDialogState(){const e=(e,t)=>({kind:e,space:this._space,mode:this._mode,data:t});return this._tapConfirm||this._alignDialog||this._mergeDialog||this._importDialog||this._backupExportDialog||this._backupImportDialog?null:this._openingInfo?e("openingInfo",this._openingInfo.id):this._infoCard?e("info",this._infoCard.id):this._rulesDialog?this._rulesDialog.busy?null:e("rules",this._rulesDialog):this._settingsDialog?this._settingsDialog.busy?null:e("settings",this._settingsDialog):this._markerDialog?this._markerDialog.busy?null:e("marker",this._markerDialog):this._openingDialog?e("opening",this._openingDialog):this._backdropDialog?e("backdrop",this._backdropDialog):this._decorShapeDialog?e("decorShape",this._decorShapeDialog):this._decorTextDialog?e("decorText",this._decorTextDialog):this._roomDialog?e("room",{editId:this._roomEditId,fill:this._roomFill,customFill:this._roomCustomFill,tempMin:this._roomTempMin,tempMax:this._roomTempMax,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:e("space",this._spaceDialog):null}_warmSnapshot(){if(this._booting||this._config?.kiosk||"steady"!==this._continuity.state)return;const e={vp:this._warmViewportState(),frameFingerprint:this._continuity.frameFingerprint,devices:this._devices,hdrH:this._hdrH};if(this._warmRevivePending||(e.dlg=this._warmDialogState()),this.isConnected&&this._warmSlot?.owner===this._warmGen){const t=this.parentNode;e.place=t?new WeakRef(t):null,e.idx=this._warmIdx(t)}this._warmPatch(e)}_warmReviveDialog(){const e=this._warmSlot;if(this._warmReviveTimer=void 0,!e||!e.dlg)return void(this._warmRevivePending=!1);const t=e.dlg,i=e.freed;if(t.mode===this._mode||"view"===t.mode||this._warmVp?.mode!==t.mode||this._editorRuntime){if(this._warmRevivePending=!1,e.dlg=null,e.freed=0,clearTimeout(e.evict),e.evict=0,i&&!(Date.now()-i>av)&&t.space===this._space&&t.mode===this._mode){switch(t.kind){case"space":this._spaceDialog={...t.data,busy:!1,savedBusy:!1};break;case"marker":this._markerDialog={...t.data,busy:!1};break;case"settings":this._settingsDialog={...t.data,busy:!1};break;case"rules":this._rulesDialog={...t.data,busy:!1};break;case"opening":this._openingDialog={...t.data};break;case"backdrop":this._backdropDialog={...t.data};break;case"decorShape":this._decorShapeDialog={...t.data};break;case"decorText":{this._decorTextDialog={...t.data};const e=String(this._decorTextDialog?.text??"").length;this._decorTextSelection={start:e,end:e};break}case"room":{const e=t.data;this._roomEditId=e.editId,this._roomFill=e.fill,this._roomCustomFill=e.customFill||null,this._roomTempMin=e.tempMin||"",this._roomTempMax=e.tempMax||"",this._roomTempSrc=e.tempSrc,this._roomHumSrc=e.humSrc,this._roomSrcOpen=e.srcOpen,this._roomSrcFilter=e.srcFilter,this._roomNameScale=e.nameScale,this._roomLabelScale=e.labelScale,this._areaSel=e.areaSel,this._nameSel=e.nameSel,this._pendingSplit=e.pendingSplit,this._wallFaceBatch=e.wallFaceBatch||null,this._path=e.path,this._wallFaceBatch&&(this._activeWallChainId=`chain-${Date.now().toString(36)}`,this._activeWallChainPartitionIds=[...this._wallFaceBatch.activePartitionIds],this._wallChainSegmentCms=[...this._wallFaceBatch.activeCms]),this._roomDialog=!0;break}case"info":{const e=this._devices.find(e=>e.id===t.data);e&&(this._infoCard=e);break}case"openingInfo":{const e=(this._curSpaceCfg?.openings||[]).find(e=>e.id===t.data);e&&(this._openingInfo=e);break}}this.requestUpdate()}}else this._warmRevivePending=!0}_cacheSnapshot(){if(this._serverCfg)try{this._virtualLights=function(e,t,i){if(e.configRev===i)return e;const n=new Set((Array.isArray(t?.markers)?t.markers:[]).filter(qh).map(e=>e.id));return{...e,configRev:i,off:new Set([...e.off].filter(e=>n.has(e)))}}(this._virtualLights,this._serverCfg,this._cfgRev);const e=this._adoption.snapshot(function(e){return{rev:e.rev,config_rev:e.configRev,off:[...e.off].sort()}}(this._virtualLights));e&&localStorage.setItem(cv,JSON.stringify(e))}catch{}}_beginContinuityCandidate(e,t,i="plan"){return this._booting&&!this._continuity.hasCompleteFrame?this._continuity.token:(this._continuityDataReady=t,this._continuityPaintToken=-1,this._stagedDeviceSnapshotToken=-1,this._resumeSettling=!0,this._continuity.beginCandidate(e,i))}_continuityStageValid(){const e=this._stageEl;return!!e&&e.clientWidth>0&&e.clientHeight>0}_versionReloadSafetySnapshot(){return Sg(this)}_continuityAssetsReady(){if(!this._model.length)return!1;const e=this._model.length?this._spaceModel():null;return!e?.bg?.href||this._signer.isReady(this.hass,e.bg.href)}_initialSpaceSelection(e,t=this._loadOk){const i=this._fixedFloorState(e,t);return"valid"===i.kind?{id:i.id,source:"fixed"}:this._hasFixedFloor?{id:null,source:"none"}:function(e){const t=new Set(e.spaceIds.filter(e=>!!e));if(!t.size)return{id:null,source:"none"};const i=[["hash",!1===e.acceptHash?null:e.hashSpace],["current",e.preserveCurrent?e.currentSpace:null],["saved",e.savedSpace],["default",e.defaultSpace],["first",e.spaceIds[0]]];for(const[e,n]of i)if(n&&t.has(n))return{id:n,source:e};return{id:null,source:"none"}}({spaceIds:e.map(e=>e.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(e,t=this._loadOk){const i=this._initialSpaceSelection(e,t);return i.id?(this._commitSpace(i.id,!0),"hash"===i.source&&(this._hashApplied=!0),"saved"===i.source&&(this._navApplied=!0),i):i}_candidateBackdrop(e,t=this._space){const i=el(e),n=this._fixedFloorState(i,!0);if(this._hasFixedFloor&&"valid"!==n.kind)return"";const r=this._initialSpaceSelection(i,!0).id||(i.some(e=>e.id===t)?t:i[0]?.id);return i.find(e=>e.id===r)?.bg?.href||""}_visualFrameFingerprint(){const e=this._stageEl,t=e?[e.clientWidth,e.clientHeight]:[0,0];return hc([this._cfgRev,this._adoption.currentConfigFingerprint(),this._layoutRev,this._adoption.currentLayoutFingerprint(),this._space,this._mode,this._view,t,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 e=this._continuity.token;if(this._candidateDeviceSnapshot&&this._candidateDeviceSnapshot!==this._visibleDeviceSnapshot&&this._stagedDeviceSnapshotToken!==e)return this._stagedDeviceSnapshotToken=e,void this.requestUpdate();this._continuityPaintToken!==e&&(this._continuityPaintToken=e,this._continuity.candidateReady(e)&&this._continuity.commitAfterPaint(e,{updateComplete:()=>this.updateComplete,stageValid:()=>this.isConnected&&this._continuityStageValid(),assetsReady:()=>this._continuityAssetsReady(),frameFingerprint:()=>this._visualFrameFingerprint()}).then(t=>{t&&e===this._continuity.token?(this._resumeSettling=!1,this._renderSnapshotAt=Date.now(),this._candidateDeviceSnapshot&&(this._visibleDeviceSnapshot=this._candidateDeviceSnapshot),this._candidateDeviceSnapshot=null,this._stagedDeviceSnapshotToken=-1,this._warmSnapshot()):e===this._continuity.token&&(this._continuityPaintToken=-1,this._stagedDeviceSnapshotToken=-1,this._candidateDeviceSnapshot=null,this.requestUpdate())}))}_onBackdropLoaded(e,t){this._signer.markLoaded(this.hass,e,t),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 e="connection"===this._continuity.recoveryReason;return j`e.stopPropagation()}
@click=${e=>e.stopPropagation()}
@@ -364,7 +364,7 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="33e3bf530b13e01b6cc86d437770676c1644
aria-label=${this._t("editor.loading_aria")}>
${this._t("editor.loading")}
-
`:G}houseplanContinuityTrace(){return[...this._continuityHistory,...this._continuity.trace].slice(-80).map(e=>({...e,...e.stage?{stage:[...e.stage]}:{}}))}getCardSize(){return 12}getGridOptions(){return{columns:"full"}}get _norm(){return!(!this._serverCfg||!this._serverCfg.spaces.length)}_cfgFingerprint(){const e=this._serverCfg?.spaces||[];let t=e.length+":";for(const i of e){t+=(i.id||"")+","+(i.plan_aspect||"")+","+(i.plan_url||"").length+","+(i.plan_x??"")+","+(i.plan_y??"")+","+(i.plan_scale??"")+","+(i.plan_scale_x??"")+","+(i.plan_scale_y??"")+","+(i.plan_angle??"")+","+(i.rooms?.length||0)+","+(i.openings?.length||0)+","+(i.decor?.length||0)+";";for(const e of i.rooms||[]){const i=e.poly?.[0],n=e.poly?.[e.poly.length-1];t+=(e.poly?.length||0)+"."+(e.id||"")+"."+(e.open_to||[]).join("+")+"."+(e.area||"")+"."+JSON.stringify(e.settings||0)+"."+(e.x??"")+","+(e.y??"")+","+(e.w??"")+","+(e.h??"")+","+(i?i[0]+"/"+i[1]:"")+","+(n?n[0]+"/"+n[1]:"")+";"}}return t}get _model(){if(!this._serverCfg)return[];const e=this._cfgEpoch+"|"+this._cfgFingerprint();if(this._modelCache&&this._modelCache.key===e)return this._modelCache.model;const t=this._buildModel();return this._modelCache={key:e,model:t},t}_buildModel(){if(!this._serverCfg)return[];const e=this._renderCfg;return el(e).map((t,i)=>{const n=e.spaces[i]?.plan_url;return t.bg&&n?{...t,bg:{...t.bg,href:n}}:t})}_spaceModel(){return this._hasFixedFloor?kc(this._model,this._space):(e=this._model,t=this._space,e.find(e=>e.id===t)??e[0]);var e,t}_spaceModelById(e){return kc(this._model,e)}_syncEmptySpaceState(){if(!!this._serverCfg&&0===this._serverCfg.spaces.length){if(!this._emptySpaceStateActive){this._emptySpaceStateActive=!0,this._clearRoomFocus(!0);for(const e of this._pointers.keys())for(const t of this.renderRoot.querySelectorAll("*"))try{t.hasPointerCapture?.(e)&&t.releasePointerCapture(e)}catch{}this._pointers.clear(),this._panStart=null,this._panLock=null,this._pinchStart=null,this._swipeStart=null,this._drag=null,this._deviceDrag=null,this._resetDeviceHitState(),this._rlResize=null,this._vacFit=null,this._compassDrag=!1,this._cancelModeTransition(!1),this._mode="view",this._clearGeometryGesture(),this._geometryHistory.clear(),this._devicePositionHistory.clear(),this._tip=null,this._hoverRoom=null,this._openingInfo=null,this._closeInfoCard(),this._deviceInbox=null,this._deviceInboxReturn=null,this._markerDialog=null,this._physicalDialog=null,this._backdropDialog=null,this._decorShapeDialog=null,this._decorTextDialog=null,this._roomDialog=!1,"edit"===this._spaceDialog?.mode&&(this._spaceDialog=null),this._editorSecondary?.closeForNavigation(),this._saveConfigDebounced.cancel(),this._frame=null,this._planSnapGeometryCache=null,this._hiddenWallDiagnosticCache=null,this._decorSnapCache=null,this._commitSpace("",!0)}}else this._emptySpaceStateActive=!1}get _areaToSpace(){const e={};for(const t of this._model)for(const i of t.rooms)i.area&&(e[i.area]={space:t.id,room:i});return e}get _settings(){return this._serverCfg?.settings||{}}get _showAll(){return this._showHidden||!this._settings.filter_seeded&&!!this._settings.show_all}_seedHiddenDevices(){if(!(this._loadOk&&this._serverCfg&&this._norm&&this._canEdit))return;const e=this._serverCfg,t=eu({hass:this.hass,registry:this._haRegistry,areaToSpace:Object.fromEntries(Object.entries(this._areaToSpace).map(([e,t])=>[e,t.space])),markers:this._markers,settings:this._settings,excluded:this._excluded,firstSpaceId:this._model[0]?.id||"",iconRules:this._iconRules});if(!t.length&&e.settings?.filter_seeded)return;e.markers=e.markers||[];const i=[];for(const n of t){const t="h"+n.slice(n.indexOf(":")+1);e.markers.push({id:t,binding:n,hidden:!0}),i.push(n.slice(n.indexOf(":")+1))}const n={...e.settings||{},filter_seeded:!0};delete n.show_all,i.length&&Array.isArray(n.new_device_ids)&&(n.new_device_ids=n.new_device_ids.filter(e=>!i.includes(e))),e.settings=n,this._regSignature="",this._maybeRebuildDevices(),this._saveConfig(),this.requestUpdate()}get _iconRules(){const e=this._settings.icon_rules;if(!e||!Array.isArray(e)||!e.length)return;const t=JSON.stringify(e);return t!==this._rulesCompiledSrc&&(this._rulesCompiledSrc=t,this._rulesCompiled=Ee(e)),this._rulesCompiled}get _fillColors(){return vn(this._settings)}get _excluded(){return lu(this._settings)}_setAreaLifecycleConfig(e){this._cfgEpochPreservedConfig=e,this._serverCfg=e}willUpdate(e){if(this._isoProjectionSnapshot=null,this._summary?.willUpdate(),e.has("hass")&&this._configReloadAuthority.observeContext(Vu(this)),e.has("_serverCfg")){const e=this._cfgEpochPreservedConfig===this._serverCfg;this._cfgEpochPreservedConfig=null,e||this._cfgEpoch++,this._renderLife.invalidate()}if(this._syncEmptySpaceState(),this._dangerConfirm&&(this._dangerConfirmMissingSpace()||"warm"===this._syncDangerConfirmLocaleGate())&&this._cancelDangerConfirm(),e.has("hass")&&this.hass){const t=this._visibleDeviceSnapshot||this._candidateDeviceSnapshot;this._renderLife.observe(e.get("hass"),this.hass,t?{entityIds:t.entityIds}:null,()=>Mg(this))}this._continuity.hasCompleteFrame&&"steady"===this._continuity.state&&this._continuity.refreshCompleteFrame(this._visualFrameFingerprint()),this._captureRenderDeviceSnapshot()}updated(){this._summary?.updated(),this._liveRt?.commit(),this._editorRuntime?._commitLiveEditor(),this._pruneDevicePressFeedback(),this._syncDayCycleClock(),this._syncRadarLive(),this._warmSnapshot(),this._editorRuntime&&this._dtMeasure();const e=this._stageEl;e&&!this._roViewport&&(this._roViewport=new ResizeObserver(()=>{this._invalidateDeviceHitGeometry(),this._refitView(),requestAnimationFrame(()=>this._summary?.resized())}),this._roViewport.observe(e)),e&&this._booting&&!this._bootTimer&&this._bootWatch();const t=this.renderRoot.querySelector(".hdr");if(t&&e&&!this._roHdr){const i=()=>{const t=ef(this.renderRoot,e,this.panelHost);null!==t&&(t>=0&&t!==this._hdrH&&(this._hdrH=t),t>=0&&!this._booting&&!this._config?.kiosk&&e.clientHeight>0&&this._warmPatch({hdrH:t,stageH:e.clientHeight}))};this._roHdr=new ResizeObserver(()=>requestAnimationFrame(i)),this._roHdr.observe(t),this._onWinResize=()=>requestAnimationFrame(i),window.addEventListener("resize",this._onWinResize),i()}if(e&&!this._view&&this._refitView(),this._editorSecondary?.afterRender(),this._settleContinuityFrame(),this._serverStorage&&this._loadOk&&this._canManageConfiguration&&0===this._model.length&&!this._spaceDialog&&!this._importDialog&&!this._onboardingShown){this._onboardingShown=!0;const e=function(e){const t=e?.floors;if(!t||"object"!=typeof t)return[];const i=[];for(const e of Object.values(t))e&&e.floor_id&&i.push({id:e.floor_id,name:e.name||e.floor_id,level:e.level??null});return i.sort((e,t)=>{const i=e.level??1e9,n=t.level??1e9;return i!==n?i-n:e.name.localeCompare(t.name)}),i}(this.hass);e.length?this._importDialog={floors:e.map(e=>({...e,checked:!0}))}:this._openSpaceDialog("create")}}_adoptConfigCapabilities(e){xg(this,e)}_syncRadarLive(){const e=this._serverCfg?.settings?.radar,t=(this._serverCfg?.markers||[]).some(e=>Cg(e,this._space));this._radarLive.sync(this._space,1===this._haRadarStage1Api&&"view"===this._mode&&!1!==e?.show_live&&t&&"hidden"!==this.ownerDocument.visibilityState)}async _syncDecorAssets(e){const t=++this._decorAssetSyncToken;if(1!==this._haDecorAssetsApi||!this.hass)return void(this._decorAssets=new Map);const i=await um(this.hass,cm(e),this._cfgRev);t===this._decorAssetSyncToken&&(this._decorAssets=i,this._resign(),this.requestUpdate())}_adoptAuthoritative(e){return ju(this,e)}_rollbackOptimistic(e){const t=this._adoption.rollbackOptimistic(e);return t&&this.requestUpdate(),t}_resumePendingNavMode(){if(!this._pendingNavMode||!this._canEdit||this._config?.kiosk)return!1;const e=this._pendingNavMode;return this._pendingNavMode=null,this._setMode(e,!1),!0}_getAuthoritativeConfig(){return e=this,async function(e,t){const i=await e();return t(i),i}(()=>e.hass.callWS({type:"houseplan/config/get"}),t=>xg(e,t));var e}async _loadFromServer(){this._loading=!0,this._loadTries++;const e=this._space,t=!!this._view;let i=!1;const n=()=>{i=!0,this._regSignature="",this._maybeRebuildDevices()};try{const[i,r]=await Promise.all([this._getAuthoritativeConfig(),this.hass.callWS({type:"houseplan/layout/get"})]);if("adopted"!==(await this._adoptAuthoritative({cfgResp:i,layResp:r,reason:"structural-response",profile:"reload",beforeAdopt:()=>{this._connectionWasLost=!1,this._serverStorage=!0},afterAdopt:()=>{this._warmVpArmed&&this._space===this._warmVp?.space?this._warmVpArmed=!1:t&&this._space===e||this._restoreZoom(),this._loadOk=!0,n()}})).status)return;this.hass.callWS({type:"houseplan/trail/get"}).then(e=>{this._vacSrvTrails=e?.trails||{},this.requestUpdate()}).catch(()=>{}),this._ensureLiveSyncSubscriptions()}catch(e){if(this._serverCfg)this._scheduleLoadRetry(!0);else if(this._loadTries>=8){this._serverStorage=!1;try{this._layout=JSON.parse(localStorage.getItem(lv)||"{}")||{}}catch{this._layout={}}}}finally{this._loading=!1,this._continuityDataReady=!0,i||n(),this.requestUpdate()}}_ensureLiveSyncSubscriptions(){const e=this.hass?.connection;if(!e)return;if(e!==this._liveSyncConnection&&(this._unsubCfg?.(),this._unsubCfg=null,this._unsubLayout?.(),this._unsubLayout=null,this._unsubTrail?.(),this._unsubTrail=void 0,this._unsubVirtual?.(),this._unsubVirtual=null,this._liveSyncGeneration++,this._liveSyncAttempt=null,this._liveSyncConnection=e),this._liveSyncAttempt)return;const t=this._liveSyncGeneration,i=[],n=(n,r,o,s)=>{n()||i.push(async()=>{const i=await e.subscribeEvents(s,o);t===this._liveSyncGeneration&&this.isConnected&&this.hass?.connection===e&&!n()?r(i):i?.()})};if(n(()=>this._unsubCfg,e=>{this._unsubCfg=e},"houseplan_config_updated",e=>{const t=Number(e?.data?.rev??-1);t!==this._cfgRev&&this._reloadConfigOnly(!1,t)}),n(()=>this._unsubTrail,e=>{this._unsubTrail=e},"houseplan_trail_updated",async()=>{try{const e=await this.hass.callWS({type:"houseplan/trail/get"});this._vacSrvTrails=e?.trails||{},this.requestUpdate()}catch{}}),n(()=>this._unsubLayout,e=>{this._unsubLayout=e},"houseplan_layout_updated",e=>this._onLayoutEvent(Number(e?.data?.rev??-1))),n(()=>this._unsubVirtual,e=>{this._unsubVirtual=e},"houseplan_virtual_light_updated",e=>{const t=Wh(this._virtualLights,e?.data);t!==this._virtualLights&&(this._virtualLights=t,this._capturedSnapshotVirtual="",this._cacheSnapshot(),this.requestUpdate())}),!i.length)return;const r=function(e){return Promise.allSettled(e.map(e=>Promise.resolve().then(e)))}(i).then(()=>{});this._liveSyncAttempt=r,r.finally(()=>{this._liveSyncAttempt===r&&(this._liveSyncAttempt=null)})}async _reloadConfigOnly(e=!1,t){return Ku(this,e,t)}_scheduleLoadRetry(e=!1){if(void 0!==this._loadRetryTimer)return;const t=Math.min(8e3,500*2**Math.min(4,Math.max(1,this._loadTries-7)));this._loadRetryTimer=window.setTimeout(()=>{this._loadRetryTimer=void 0,!e&&this._loadOk||this._loading||!this.hass||this._loadFromServer()},t)}async _ensureLiveRuntime(){if(this._liveRt)return;const e=await import("./live-interaction-runtime-B_hYV9lk.js");this._liveRt=new e.LiveRuntime(this),this.isConnected&&this.requestUpdate()}_liveVp(e=!1){this._liveRt?this._liveRt.viewport(e):this.requestUpdate()}_syncLiveHover(){this._liveRt?this._liveRt.hover():this.requestUpdate()}_flushHa(){this._liveRt?.take()&&(this._terminalFrame=2,super.requestUpdate())}_ensureHaRegistryAuthority(){const e=this.hass?.connection||null;e&&e!==this._haRegistryConnection&&(this._haRegistryRelease?.(),this._haRegistryConnection=e,this._haRegistryRev=-1,this._haBindingCacheKey="",this._renderLife.invalidate(),this._areaSnapshotCleanupCandidates.clear(),this._planHassMemo=null,this._haRegistryRelease=td(this.hass,this._onHaRegistryUpdate),this._onHaRegistryUpdate())}get _haRegistry(){return nd(this.hass)}get _planHass(){const e=this._haRegistry,t=od(this.hass,e),i=this._planHassMemo;if(i&&i.hass===this.hass&&i.sig===t)return i.active;const n=ad(this.hass,e),r=ld(this.hass,e);return this._planHassMemo={hass:this.hass,sig:t,active:n,full:r},n}_captureRenderDeviceSnapshot(){if(!this.hass)return;const e=Date.now(),t=[...this._activityRt.entries()].map(([t,i])=>`${t}:${i.gen}:${i.flashTs}:`+(i.flashKind&&(i.expiresAt||i.flashTs+tg)>e?1:0)).join("|"),i=Bh(this._virtualLights);if(this._capturedSnapshotSequence===this._hassSequence&&this._capturedSnapshotDevices===this._devices&&this._capturedSnapshotLayout===this._layout&&this._capturedSnapshotConfigEpoch===this._cfgEpoch&&this._capturedSnapshotVirtual===i&&this._capturedSnapshotActivity===t)return;const n=this._planHass,r=new Map,o=new Map,s=new Set(["sun.sun"]);for(const e of this._summary?.entityIds()||[])s.add(e);this._vacFit?.source&&s.add(this._vacFit.source);const a=new Set,l=new Set,c=e=>{if(!e)return;const t=e.indexOf(":");if(t<0)return void s.add(e);const i=e.slice(0,t),n=e.slice(t+1);"device"===i?a.add(n):"entity"===i&&s.add(n)};for(const e of this._model)for(const t of e.rooms)t.area&&l.add(t.area),c(t.settings?.temp_source),c(t.settings?.hum_source);for(const e of this._serverCfg?.spaces||[])for(const t of e.openings||[])for(const e of ui(t))s.add(e);for(const e of this._serverCfg?.spaces||[])for(const t of e.decor||[])if("text"===t.kind){for(const e of String(t.text||"").matchAll(/\{([^{}\r\n]+)\}/g)){const t=Xi(e[1]);t?.entity&&s.add(t.entity)}t.entity&&s.add(t.entity),o.set(`decor:${e.id}:${t.id}`,tn(t.text,t,n,e=>!!n.entities?.[e]&&!!n.states?.[e]&&!Jd(n,e,Zd(this._markers))))}const h=Ed(n,this._devices,null,this._virtualLights);for(const e of this._devices){for(const t of[!1,!0])r.set(f_(e.id,t),p_(n,e,{liveStates:!1!==this._config?.live_states,showTemperature:!1!==this._config?.show_temperature,showSignal:t,activityRuntime:this._activityRt.get(e.id),sourceDetails:!1,lightDevices:this._devices,lightSources:h,registryHass:this._fullRegistryHass,reducedMotion:this._reducedMotion}));if(this._isVacDev(e)){const t=this._vacSource(e,n),i=t?Wc(n?.states?.[t]?.attributes):null,r=this._vacRt.get(e.id),s=lh(e.id,e.marker?.vacuum??null,e.space,t),a=hh({routes:s,observed:dh(s,[t],t=>this._vacObservedMapId(e,t,n)),spaceIds:new Set(this._model.map(e=>e.id))});o.set(`vacuum:${e.id}`,{source:t,telemetry:i,routes:s,resolution:a,mapId:i?this._vacMapId(e,i,n):null,runtime:r?{trail:r.trail,lastTs:r.lastTs,moving:r.moving,jump:r.jump}:null,server:this._vacSrvTrails[e.id]||null})}}const d=g_({sourceSequence:this._hassSequence,hass:n,devices:this._devices,presentations:r,positions:(u=this._model.length>0,p=this._devices,_=e=>this._livePos(e),u?new Map(p.map(e=>[e.id,_(e)])):new Map),facts:o,entityIds:s,deviceIds:a,areaIds:l});var u,p,_;this._capturedSnapshotSequence=this._hassSequence,this._capturedSnapshotDevices=this._devices,this._capturedSnapshotLayout=this._layout,this._capturedSnapshotActivity=t,this._capturedSnapshotConfigEpoch=this._cfgEpoch,this._capturedSnapshotVirtual=i,this._visibleDeviceSnapshot&&"steady"!==this._continuity.state?this._candidateDeviceSnapshot=d:(this._visibleDeviceSnapshot=d,this._candidateDeviceSnapshot=null)}get _renderDeviceSnapshot(){return this._stagedDeviceSnapshotToken===this._continuity.token?this._candidateDeviceSnapshot||this._visibleDeviceSnapshot:this._visibleDeviceSnapshot||this._candidateDeviceSnapshot}get _renderPlanHass(){return this._renderDeviceSnapshot?.hass||this._planHass}get _renderDevices(){return this._renderDeviceSnapshot?.devices||this._devices}get _renderVacuumDevices(){return this._renderDeviceSnapshot?.vacuumDevices||this._devices}get _fullRegistryHass(){return this._planHass,this._planHassMemo?.full||this.hass}_bindingStatus(e){return dd(this.hass,e,this._haRegistry)}houseplanDiagnostics(){const{registry:e,bindings:t}=this._renderLife.diagnostics(this.hass,this._markers,e=>this._bindingStatus(e));return{registry:{...e,lastSuccessAgeMs:e.lastSuccess?Math.max(0,Date.now()-e.lastSuccess):null},bindings:t}}_openBindingInHa(e){const[t,i]=e.split(":");if(i)if("device"!==t){if("entity"===t){const e=this._fullRegistryHass.entities?.[i];e?.device_id&&fv("/config/devices/device/"+encodeURIComponent(e.device_id))}}else fv("/config/devices/device/"+encodeURIComponent(i))}_bindingHasHaPage(e){const[t,i]=e.split(":");return!!i&&("device"===t||"entity"===t&&!!this._fullRegistryHass.entities?.[i]?.device_id)}_toggleMarkerDialogVisibility(){const e=this._markerDialog;if(!e)return;const t="ha"===e.bindingMode?this._bindingStatus(e.binding):null,i=e.hideFromPlan||"ha_disabled"===t?.kind;i&&"ha_disabled"===t?.kind?this._showToast(this._t("entity"===t.reason?"toast.ha_disabled_show_entity":"toast.ha_disabled_show_device")):i&&"unverified"===t?.kind?this._showToast(this._t("toast.ha_binding_unverified")):this._markerDialog={...e,hideFromPlan:!i}}_hookConnection(){const e=this.hass?.connection;e&&e!==this._connHooked&&(this._connHooked?.removeEventListener?.("ready",this._onConnReady),this._connHooked?.removeEventListener?.("disconnected",this._onConnLost),this._connHooked?.removeEventListener?.("reconnect-error",this._onConnLost),e.addEventListener?.("ready",this._onConnReady),e.addEventListener?.("disconnected",this._onConnLost),e.addEventListener?.("reconnect-error",this._onConnLost),this._connHooked=e)}_display(e){return this._signer.display(this.hass,e)}_referencedContentUrls(){const e=Nn(this._serverCfg);for(const t of this._decorAssets.values())e.add(t.url);return e}_resign(){this._signer.resign(this.hass,this._referencedContentUrls())}_onLayoutEvent(e){e<=this._layoutRev||(clearTimeout(this._layoutSyncTimer),this._layoutSyncTimer=window.setTimeout(()=>{e<=this._layoutRev||this._reloadLayoutOnly()},200))}_noteLayoutRev(e){this._adoption.noteLayoutRevision(e?.rev)}async _reloadLayoutOnly(){if(!this._serverStorage||!this.hass?.callWS)return;this._beginContinuityCandidate("layout-reload",!1);const e=new Map;for(const t of this._dirtyPos)this._layout[t]&&e.set(t,this._layout[t]);this._persistLayout.pending()&&this._persistLayout.flush();for(const[t,i]of this._sentPos)e.set(t,i);try{const t=await this.hass.callWS({type:"houseplan/layout/get"}),i={...t?.layout||{}};for(const[t,n]of e)null===n?delete i[t]:i[t]=n;this._adoption.adoptMergedLayout(i,t,()=>{this._cancelDeviceDrag(),this._devicePositionHistory.clear()}),this._canOptimizeUndo=!!t?.can_optimize_undo,this._undoKind=t?.undo_kind||null,this._cacheSnapshot(),this.requestUpdate()}catch{}finally{this._continuityDataReady=!0,this.requestUpdate()}}_persistLocalLayout(){this._layout=So(lo(this._layout)),localStorage.setItem(lv,JSON.stringify(this._layout))}_maybeRebuildDevices(){const e=this.hass;if(!e?.devices||!e?.entities||!e?.areas)return;const t=this._haRegistry,i=od(e,t)+":"+Object.keys(e.areas).length+":"+(this._norm?"n":"l")+":"+kp(e,this._config?.language);if(i===this._regSignature&&this._devices.length)return;this._regSignature=i;const n=new Map(this._devices.map(e=>[e.id,e.bindingStatus?.kind||"active"]));this._devices=iu({hass:e,registry:t,areaToSpace:Object.fromEntries(Object.entries(this._areaToSpace).map(([e,t])=>[e,t.space])),markers:this._markers,settings:this._settings,excluded:this._excluded,showAll:this._showAll,firstSpaceId:this._model[0]?.id||"",loc:e=>this._t(e),iconRules:this._iconRules});const r=this._markers.filter(e=>!e.removed&&"virtual"!==e.binding).map(e=>e.binding).sort(),o=t.revision+":"+r.join("|");if(t.authoritative&&o!==this._haBindingCacheKey){const i=new Map;for(const n of r)i.set(n,dd(e,n,t));!function(e){if("undefined"==typeof localStorage||!e.size)return;const t=hd(),i=Date.now();for(const[n,r]of e)"active"===r.kind?t[n]={kind:"active",ts:i}:"ha_disabled"===r.kind&&(t[n]={kind:"ha_disabled",reason:r.reason,ts:i});const n=Object.fromEntries(Object.entries(t).sort((e,t)=>t[1].ts-e[1].ts).slice(0,1500));Yh=n;try{localStorage.setItem(Kh,JSON.stringify(n))}catch{}}(i),this._haBindingCacheKey=o}let s=null;if(t.authoritative&&(s=this._resolveAreaRelocations(t),this._areaRelocationIds=new Set(s.relocateIds),this._areaRelocationIds.size)){this._cancelDeviceDrag();const e=this._areaRelocationIds;this._devicePositionHistory.removeWhere(({before:t,after:i})=>e.has(t.deviceId)||e.has(i.deviceId));const t=this._markerDialog;if(t?.devId&&!t.roomTouched&&this._areaRelocationIds.has(t.devId)){const e=this._devices.find(e=>e.id===t.devId);e&&(this._markerDialog={...t,room:e.marker?.room_id?`${e.space}#@${e.marker.room_id}`:e.space&&e.area?`${e.space}#${e.area}`:""})}}this._defPos=this._defaultPositions(),this._syncNewDevices(),this._seedHiddenDevices(),s&&this._syncAreaRelocations(s),this._syncActivityRuntime();const a=new Set(this._devices.filter(e=>!e.hidden).map(e=>e.id));for(const e of this._vacRt.keys())a.has(e)||this._vacRt.delete(e);if(this._infoCard){const e=this._devices.find(e=>e.id===this._infoCard.id);this._infoCard=e&&"ha_disabled"!==e.bindingStatus?.kind?e:null}const l=this._devices.some(e=>"ha_disabled"===e.bindingStatus?.kind&&"ha_disabled"!==n.get(e.id));l&&("ha_disabled"!==this._infoCard?.bindingStatus?.kind&&"ha_disabled"!==this._devices.find(e=>e.id===this._infoCard?.id)?.bindingStatus?.kind||this._closeInfoCard(),this._deviceDrag&&"ha_disabled"===this._devices.find(e=>e.id===this._deviceDrag.id)?.bindingStatus?.kind&&(this._cancelDeviceDrag(),this._devicePositionHistory.clear()),clearTimeout(this._holdTimer),this._holdFired=!1,this._tip=null,this._tapConfirm=null),this._nativeMoreInfoEntity&&!this._planEntityAvailable(this._nativeMoreInfoEntity)&&(gv(this,"hass-more-info",{entityId:null}),this._nativeMoreInfoEntity=null)}_resolveAreaRelocations(e=this._haRegistry){const t=function(e){const t=Q_(e.snapshot),i=new Set(Object.values(t).map(e=>e.binding)),n=new Map;for(const[t,r]of e.previousCandidates||[])J_(t)&&Number.isFinite(r)&&i.has(t)&&n.set(t,r);const r=new Set,o=new Set;for(const t of e.markers||[])t.removed||(Z_(t.id)&&r.add(t.id),J_(t.binding)&&o.add(t.binding));const s=new Set(Object.keys(e.registryDevices||{})),a=new Set(Object.keys(e.registryEntities||{})),l=new Set(Object.keys(e.liveStates||{})),c=new Map;for(const[e,i]of Object.entries(t)){const t=c.get(i.binding)||[];t.push(e),c.set(i.binding,t)}const h=new Set;let d=!1;for(const[t,i]of c){const[c,u]=rm(t);if(o.has(t)||i.some(e=>r.has(e))||("device"===c?s.has(u):a.has(u)||l.has(u))){n.delete(t);continue}const p="device"===c?s.size>0:a.size>0;if(!e.authoritative||!p)continue;const _=n.get(t);if(void 0!==_){if(_!==e.revision)for(const e of i)h.add(e)}else n.set(t,e.revision),d=!0}return{removeIds:h,candidates:n,needsConfirmationRefresh:d}}({snapshot:this._settings.marker_area_snapshot,authoritative:e.authoritative,revision:e.revision,registryDevices:e.devices,registryEntities:e.entities,liveStates:this.hass?.states,markers:this._markers,previousCandidates:this._areaSnapshotCleanupCandidates});return this._areaSnapshotCleanupCandidates=t.candidates,t.needsConfirmationRefresh&&this._canEdit&&id(this.hass),om({devices:this._devices,model:this._model,layout:this._layout,snapshot:this._settings.marker_area_snapshot,authoritative:e.authoritative,cleanupSnapshotIds:t.removeIds,coordinateScale:_v})}_syncNewDevices(){if(!this._norm||!this._loadOk||!this._serverCfg)return;const e=this._devices.filter(e=>!e.marker&&!e.virtual).map(e=>e.id).sort(),t=e.join(",");if(t===this._newSyncKey)return;this._newSyncKey=t;const i=this._settings,{fresh:n,known:r}=function(e,t){if(!Array.isArray(t))return{fresh:[],known:[...e]};const i=new Set(t),n=e.filter(e=>!i.has(e));return{fresh:n,known:n.length?[...t,...n]:t}}(e,i.known_devices);if(!Array.isArray(i.known_devices)||n.length){const e=[...new Set([...i.new_device_ids||[],...n])];this._serverCfg={...this._serverCfg,settings:{...i,known_devices:r,new_device_ids:e}},this._saveConfig()}}_syncAreaRelocations(e){if(!(this._loadOk&&this._serverCfg&&this._norm&&this._canEdit&&this._haRegistry.authoritative))return;const t=e.decisions.filter(e=>e.updateSnapshot||e.removeSnapshot);if(!t.length)return;const i=cc({snapshot:Q_(this._settings.marker_area_snapshot),decisions:t});i!==this._areaRelocationSyncKey&&(this._areaRelocationSyncKey=i,this._areaRelocationWrite=this._areaRelocationWrite.catch(()=>{}).then(async()=>{if(!this._serverCfg||!this._haRegistry.authoritative)return;const e=this._resolveAreaRelocations();this._areaRelocationIds=new Set(e.relocateIds);const t=new Set,i=new Map;let n=!1;for(const r of e.decisions){if(!r.relocate)continue;const e=fg(this._layout,r.id);try{await this._persistDevicePlacement(r.id,null),t.add(r.id),e&&i.set(r.id,e),this._areaRelocationIds.delete(r.id)}catch(t){n=!0,this._layout=vg(this._layout,r.id,e),this._showToast(this._t("toast.pos_save_failed",{err:this._errText(t)}))}}const r=this._settings,o=function(e,t,i=new Set){const n=Q_(e);for(const e of t.decisions)e.removeSnapshot?delete n[e.id]:e.updateSnapshot&&e.binding&&e.area&&(e.relocate&&!i.has(e.id)||(n[e.id]={binding:e.binding,area:e.area}));return n}(r.marker_area_snapshot,e,t),s=[...new Set([...Array.isArray(r.new_device_ids)?r.new_device_ids:[],...t])],a=cc(o)!==cc(Q_(r.marker_area_snapshot)),l=cc(s)!==cc(Array.isArray(r.new_device_ids)?r.new_device_ids:[]);if(a||l){const e=r.marker_area_snapshot,n=r.new_device_ids,a={...this._serverCfg,settings:{...r,marker_area_snapshot:o,...l?{new_device_ids:s}:{}}};this._setAreaLifecycleConfig(a);try{this._saveConfigDebounced.pending()&&this._saveConfigDebounced.cancel(),await this._writeConfig()}catch(r){const a=this._settings;if(cc(a.marker_area_snapshot)===cc(o)&&cc(a.new_device_ids)===cc(l?s:n)){const t={...a};void 0===e?delete t.marker_area_snapshot:t.marker_area_snapshot=e,void 0===n?delete t.new_device_ids:t.new_device_ids=n;const i={...this._serverCfg,settings:t};this._setAreaLifecycleConfig(i),this._adoption.refreshConfigFingerprint()}for(const e of t)this._areaRelocationIds.add(e);const c=new Set;for(const[e,t]of i)try{await this._persistDevicePlacement(e,t)}catch(t){c.add(e),this._showToast(this._t("toast.pos_save_failed",{err:this._errText(t)}))}this._areaRelocationSyncKey="",this._regSignature="";if("conflict"===(r&&"object"==typeof r&&"code"in r?r.code:void 0)?(this._showToast(this._t("toast.conflict")),await this._reloadConfigOnly(!0)):this._showToast(this._t("toast.cfg_save_failed",{err:this._errText(r)})),c.size&&this._serverCfg){const e=this._settings,t=[...new Set([...Array.isArray(e.new_device_ids)?e.new_device_ids:[],...c])],i={...this._serverCfg,settings:{...e,new_device_ids:t}};this._setAreaLifecycleConfig(i);try{await this._writeConfig()}catch(e){this._showToast(this._t("toast.cfg_save_failed",{err:this._errText(e)}))}}}}n&&(this._areaRelocationSyncKey=""),this.requestUpdate()}))}get _newIds(){const e=this._settings.new_device_ids;return new Set([...Array.isArray(e)?e:[],...this._areaRelocationIds])}_ackNewDevice(e){if(!this._newIds.has(e)||!this._serverCfg)return;const t=this._settings;this._serverCfg={...this._serverCfg,settings:{...t,new_device_ids:(t.new_device_ids||[]).filter(t=>t!==e)}},this._saveConfig(),this.requestUpdate()}get _markers(){return this._serverCfg?.markers||[]}_roomLqi(e){if(!e)return null;const t=[];for(const i of this._renderDevices){if(i.area!==e||i.virtual)continue;const n=Ld(this._renderPlanHass,i.entities);null!=n&&t.push(n)}return Ii(t)}_roomBounds(e){if(e.poly&&e.poly.length){const t=e.poly.map(e=>e[0]),i=e.poly.map(e=>e[1]),n=Math.min(...t),r=Math.min(...i);return{x:n,y:r,w:Math.max(...t)-n,h:Math.max(...i)-r}}return{x:e.x??0,y:e.y??0,w:e.w??0,h:e.h??0}}_defaultPositions(){const e={},t=this._config?.icon_size??2.5;for(const i of this._model){const n=t/100*Ml(i)*1.3;for(const t of i.rooms){if(!t.area)continue;const r=this._devices.filter(e=>e.area===t.area&&e.space===i.id);if(!r.length)continue;const o=this._roomBounds(t),s=.1*Math.min(o.w,o.h),a=o.w-2*s,l=o.h-2*s,c=Math.max(1,Math.round(Math.sqrt(r.length*a/Math.max(l,1)))),h=Math.ceil(r.length/c),d=a/c,u=l/Math.max(h,1),p=r.map((e,t)=>({x:o.x+s+d*(t%c+.5),y:o.y+s+u*(Math.floor(t/c)+.5)}));Ei(p,o,n,.5*s),r.forEach((t,i)=>e[t.id]=al(p[i]))}}return e}_pos(e){const t=this._renderDeviceSnapshot?.positions.get(e.id);return t?{x:t.x,y:t.y}:this._livePos(e)}_livePos(e){const t=this._spaceModelById(e.space),i=this._areaRelocationIds.has(e.id)?void 0:this._layout[e.id];if(i)if(this._norm){if(i.s===e.space)return{x:i.x*_v,y:i.y*_v}}else if(void 0===i.s)return{x:i.x,y:i.y};return this._defPos[e.id]?this._defPos[e.id]:t?al($l(t)):{x:500,y:500}}_devicePlacementForCanvas(e,t,i){if(!this._norm)return{x:Math.round(t),y:Math.round(i)};const n=this._gridPitch,r=Math.round(t/n)*n,o=Math.round(i/n)*n;return{s:e.space,x:cl(r/_v),y:cl(o/_v)}}_previewDevicePlacement(e,t){this._layout=vg(this._layout,e,t),this.requestUpdate()}_cancelDeviceDrag(){const e=this._deviceDrag;if(!e)return!1;this._editorRuntime?._cancelPointerMove("device"),this._deviceDrag=null,this._deviceHits.cancel(e.pointerId);try{e.source?.hasPointerCapture?.(e.pointerId)&&e.source.releasePointerCapture(e.pointerId)}catch{}return this._previewDevicePlacement(e.id,e.before),!0}async _persistDevicePlacement(e,t){if(this._layout=vg(this._layout,e,t),this._serverStorage){let i=null,n=!1;try{let r;if(null===t)i=null,this._sentPos.set(e,i),n=!0,r=await this.hass.callWS({type:"houseplan/layout/delete",device_id:e});else{const t=xo(this._layout[e]);cc(t)!==cc(this._layout[e])&&(this._layout={...this._layout,[e]:t}),i=t,this._sentPos.set(e,i),n=!0,r=await this.hass.callWS({type:"houseplan/layout/update",device_id:e,pos:t})}this._noteLayoutRev(r),this._adoption.refreshLayoutFingerprint(),this._cacheSnapshot()}finally{n&&this._sentPos.get(e)===i&&this._sentPos.delete(e)}return}this._persistLocalLayout()}_devicePositionStateValid(e){const t=this._devices.find(t=>t.id===e.deviceId);return!!t&&t.space===e.spaceId&&"ha_disabled"!==t.bindingStatus?.kind&&!!this._spaceModelById(e.spaceId)}async _runDevicePositionHistory(e){if(this._cancelDeviceDrag()||this._devicePositionBusy)return;const t="undo"===e?this._devicePositionHistory.undo():this._devicePositionHistory.redo();if(!t)return;const i="undo"===e?t.before:t.after;if(!this._devicePositionStateValid(i))return this._devicePositionHistory.clear(),this._showToast(this._t("history.device_stale")),void this.requestUpdate();const n=fg(this._layout,i.deviceId);i.spaceId!==this._space&&(this._commitSpace(i.spaceId),this._restoreZoom()),this._devicePositionBusy=!0,this._previewDevicePlacement(i.deviceId,i.placement);try{await this._persistDevicePlacement(i.deviceId,i.placement),this._showToast(this._t("undo"===e?"history.undone":"history.redone",{name:t.name}))}catch(t){this._previewDevicePlacement(i.deviceId,n),"undo"===e?this._devicePositionHistory.redo():this._devicePositionHistory.undo(),this._showToast(this._t("toast.pos_save_failed",{err:this._errText(t)}))}finally{this._devicePositionBusy=!1,this.requestUpdate()}}_undoDevicePosition(){this._runDevicePositionHistory("undo")}_redoDevicePosition(){this._runDevicePositionHistory("redo")}_savePos(e,t,i){this._spaceModelById(e.space)&&(this._layout=vg(this._layout,e.id,this._devicePlacementForCanvas(e,t,i)),this._dirtyPos.add(e.id),this._persistLayout())}_devicePresentation(e,t=!1!==this._config?.show_signal,i=!1){const n=i?null:this._renderDeviceSnapshot?.presentations.get(f_(e.id,t));return n||p_(this._renderPlanHass,e,{liveStates:!1!==this._config?.live_states,showTemperature:!1!==this._config?.show_temperature,showSignal:t,designPreview:i,activityRuntime:this._activityRt.get(e.id),sourceDetails:!1,lightDevices:this._renderDevices,registryHass:this._fullRegistryHass,reducedMotion:this._reducedMotion})}_deviceVisual(e){return this._devicePresentation(e).visual}_stateClass(e,t=this._deviceVisual(e)){const i=this._devicePresentation(e);return i.effectiveHidden?"":("icon_ripple"!==i.display||!1===this._config?.live_states||"alarm"===t.status||t.activity,u_({...i,visual:t}).join(" "))}_liveTemp(e){if(!this._config?.show_temperature)return null;if(!0===e.marker?.use_climate_temp){const t=qd(this._renderPlanHass,e.entities);if(null!=t)return t}return"mdi:thermometer"!==e.icon&&"mdi:air-filter"!==e.icon?null:Bd(this._renderPlanHass,e.entities)}_bindingEntities(e){if("virtual"===e||!e)return[];const t=this._bindingStatus(e);return"active"===t.kind?t.enabledEntityIds:t.allEntityIds}_bindingHasClimate(e){return this._bindingEntities(e).some(e=>e.startsWith("climate."))}_bindingHasAlarm(e){return this._bindingEntities(e).some(e=>{const t=this._planHass?.states?.[e]||this.hass?.states?.[e],i=this._fullRegistryHass.entities[e]||this.hass?.entities?.[e];return Yn(e.split(".")[0],t?.attributes?.device_class||i?.device_class||i?.original_device_class)})}_deviceBindingActive(e,t=!0){if(e.virtual||"virtual"===e.bindingKind)return!0;if(!e.bindingKind||!e.bindingRef)return!1;const i=this._bindingStatus(`${e.bindingKind}:${e.bindingRef}`);return"active"===i.kind||(t&&this._showToast(this._t("ha_disabled"===i.kind?"toast.ha_disabled_action":"toast.ha_binding_unverified")),!1)}_openMoreInfo(e){e?this._planEntityAvailable(e)?(this._kiosk&&(this._cyclePausedUntil=Math.max(this._cyclePausedUntil,Date.now()+6e4)),this._nativeMoreInfoEntity=e,gv(this,"hass-more-info",{entityId:e})):this._showToast(this._t("toast.ha_disabled_action")):this._showToast(this._t("toast.no_entity"))}_interruptViewGesture(e,t){if(clearTimeout(this._holdTimer),clearTimeout(this._kioskHoldTimer),void 0!==e)for(const i of[t,this._stageEl])try{i?.hasPointerCapture?.(e)&&i.releasePointerCapture(e)}catch{}this._pointers.clear(),this._panStart=null,this._panLock=null,this._pinchStart=null,this._swipeStart=null,this._roomPointer=null,this._doubleFit.clear(),this._deviceHits.clearPointers()}_closeInfoCard(){this._interruptViewGesture(),this._holdFired=!1,this._infoCard=null}_invalidateDeviceHitGeometry(){this._deviceHits.invalidate()}_resetDeviceHitState(){this._deviceHits.reset(this.renderRoot)}_deviceHitOwnerAt(e,t){return"view"!==this._mode&&"devices"!==this._mode?null:this._deviceHits.at(this.renderRoot,this._renderDevices,this._space,e,t)}_deviceForPointerEvent(e,t){return this._deviceHits.pointer(this.renderRoot,this._renderDevices,this._space,e,t)}_deviceForClickEvent(e,t){return this._deviceHits.click(this.renderRoot,this._renderDevices,this._space,e,t)}_showDeviceTip(e,t){this._liveRt?this._liveRt.devicePointerTip(e,t):this._ensureLiveRuntime().then(()=>this._liveRt?.devicePointerTip(e,t))}_showDeviceFocusTip(e,t){const i=e.currentTarget;this._liveRt?this._liveRt.deviceFocusTip(i,t):this._ensureLiveRuntime().then(()=>this._liveRt?.deviceFocusTip(i,t))}_hideDeviceFocusTip(e){this._liveRt?.deviceBlur(e)}_clearPointerHover(){this._liveRt?this._liveRt.pointerLeave():this._clearTransientHover()}_ctxDevice(e,t){"view"===this._mode&&(t=this._deviceForPointerEvent(e,t),e.preventDefault(),e.stopPropagation(),this._deviceBindingActive(t)&&(t.primary?this._openMoreInfo(t.primary):this._infoCard=t))}_clickDevice(e,t){if("view"!==this._mode&&"devices"!==this._mode)return;if(e.stopPropagation(),t=this._deviceForClickEvent(e,t),this._deviceDrag?.moved||this._suppressClick||this._holdFired)return;if("devices"===this._mode)return void this._openMarkerDialog(t);const i=this._devices.find(e=>e.id===t.id);if(!i)return;const n=Tu(i.tapAction,i.primary?.split(".")[0]);if("none"===n)return;const r=(e,t)=>{i.marker?.tap_confirm?this._tapConfirm={kind:"run",text:e,exec:t}:t()};if("toggle"===n){const e=this._toggleIntent(i);if(!e)return;if(!Iu(e))return void this._showUnavailableToggleTargets(e);const t=e=>{const t=Iu(e);if(!t)return;if("virtual-light"===t.kind)return this._startDevicePressFeedback(i.id),void this.hass.callWS({type:"houseplan/virtual_light/toggle",marker_id:t.markerId}).then(e=>{const t=Wh(this._virtualLights,e);t!==this._virtualLights&&(this._virtualLights=t,this._capturedSnapshotVirtual="",this._cacheSnapshot(),this.requestUpdate())}).catch(e=>this._showToast(this._t("toast.virtual_light_toggle_failed",{err:this._errText(e)})));const{command:n}=t;this._startDevicePressFeedback(i.id),this.hass.callService(n.domain,n.service,n.data).catch(e=>this._showToast(this._t("toast.error",{err:this._errText(e)})))},n=((o=e).targets.length?o.targets:o.skippedTargets).map(e=>e.name||e.entityId||e.ref).join(", ")||i.name;if(i.marker?.tap_confirm){const r=this._toggleConfirmationLines(e);if(!r.length)return;this._tapConfirm={kind:"toggle",text:this._t("confirm.tap_toggle",{name:n}),lines:r,initialIntent:e,deviceId:i.id,exec:()=>{const n=this._devices.find(e=>e.id===i.id),r=n?this._toggleIntent(n):null;r&&!Iu(r)&&this._showUnavailableToggleTargets(r)||(r&&Eu(e,r)?t(r):this._showToast(this._t("toast.tap_target_changed")))}}}else t(e);return}var o;if("info"===n)return this._interruptViewGesture(),void(this._infoCard=i);if(this._deviceBindingActive(i)){if("run"===n){const e=i.marker?.tap_target||"",t=function(e){const t=String(e||"").split(".")[0];return"automation"===t?{domain:"automation",service:"trigger"}:"script"===t?{domain:"script",service:"turn_on"}:"scene"===t?{domain:"scene",service:"turn_on"}:null}(e),n=this.hass.states[e];if(!t||!n)return void this._showToast(this._t("toast.run_target_missing"));const o=n.attributes?.friendly_name||e;return void r(this._t("confirm.tap_run",{name:o}),()=>{this._deviceBindingActive(i)&&this._planEntityAvailable(e)&&(this._startDevicePressFeedback(i.id),this.hass.callService(t.domain,t.service,{entity_id:e}).then(()=>{this._stampActivity(i.id,"event",this._activitySourceKey(i)),this.requestUpdate(),this._showToast(this._t("toast.run_started",{name:o}))}).catch(e=>this._showToast(this._t("toast.error",{err:this._errText(e)}))))})}"more-info"===n&&i.primary?this._openMoreInfo(i.primary):this._infoCard=i}}_showUnavailableToggleTargets(e){const t=function(e){if(!e||"group"!==e.kind||Iu(e)||"configured-targets-missing"!==e.noneReason)return[];if(!e.skippedTargets.length||e.skippedTargets.some(e=>!Ou.has(e.reason)&&"secure"!==e.reason))return[];const t=[],i=new Set;for(const n of e.skippedTargets){if(!Ou.has(n.reason))continue;const e=String(n.name||n.entityId||n.ref||"").trim();e&&!i.has(e)&&(i.add(e),t.push(e))}return t}(e);return!!t.length&&(this._showToast(1===t.length?this._t("toast.toggle_target_unavailable",{name:t[0]}):this._t("toast.toggle_targets_unavailable",{names:t.join(", ")})),!0)}_keyDevice(e,t){"Enter"!==e.key&&" "!==e.key||"view"!==this._mode&&"devices"!==this._mode||(e.preventDefault(),this._clickDevice(e,t))}_startDevicePressFeedback(e){const t=[...this.renderRoot.querySelectorAll(".dev[data-id]")].find(t=>t.dataset.id===e),i=t?.querySelector(".device-shell");if(!i||"function"!=typeof i.animate)return;const n=Number.parseFloat(this.ownerDocument.defaultView?.getComputedStyle(i).scale||""),r=Number.isFinite(n)?Math.max(.95,Math.min(1,n)):1;this._devicePressAnimations.get(e)?.cancel();const o=this._reducedMotion?[{outlineColor:"transparent",outlineStyle:"solid",outlineWidth:"0px"},{outlineColor:"var(--hp-accent, #3ea6ff)",outlineStyle:"solid",outlineWidth:"2px",outlineOffset:"2px",offset:.5},{outlineColor:"transparent",outlineStyle:"solid",outlineWidth:"0px"}]:[{scale:String(r)},{scale:"0.95",offset:.5},{scale:"1"}],s=i.animate(o,{duration:200,easing:"cubic-bezier(.22,.61,.36,1)"});this._devicePressAnimations.set(e,s);const a=()=>{this._devicePressAnimations.get(e)===s&&this._devicePressAnimations.delete(e)};s.addEventListener("finish",a,{once:!0}),s.addEventListener("cancel",a,{once:!0})}_cancelDevicePressFeedback(){for(const e of this._devicePressAnimations.values())e.cancel();this._devicePressAnimations.clear()}_pruneDevicePressFeedback(){if(!this._devicePressAnimations.size)return;const e=new Set([...this.renderRoot.querySelectorAll(".dev[data-id]")].map(e=>e.dataset.id||""));for(const[t,i]of this._devicePressAnimations)e.has(t)||(i.cancel(),this._devicePressAnimations.delete(t))}_t(e,t){return xp(kp(this.hass,this._config?.language),e,t)}get _colorPickerLabels(){return{title:this._t("color_picker.title"),hue:this._t("color_picker.hue"),saturation:this._t("color_picker.saturation"),value:this._t("color_picker.value"),hex:this._t("color_picker.hex"),invalidHex:this._t("color_picker.invalid_hex"),confirm:this._t("color_picker.confirm")}}_help(e){return this._editorRuntimeOrThrow()._help(e)}get _stageEl(){return this.renderRoot.querySelector(".stage")}_contentItems(e){const t=[];for(const i of this._devices){if(i.space!==e.id||i.hidden)continue;const n=this._pos(i);t.push({minX:n.x,minY:n.y,maxX:n.x,maxY:n.y})}if(e.id===this._space){for(const e of this._openingsR){const i=Number(e.angle)*Math.PI/180,n=Math.cos(i)*e.rlen/2,r=Math.sin(i)*e.rlen/2,o=pl([[e.rx-n,e.ry-r],[e.rx+n,e.ry+r]]);o&&t.push(o)}const i=this._decorH;for(const e of this._decorList){if("image"===e.kind&&!this._decorAssets.has(e.asset_id)&&"decor"!==this._mode)continue;const n=pl("line"===e.kind?[[e.x1*_v,e.y1*i],[e.x2*_v,e.y2*i]]:"text"===e.kind?[[e.x*_v,e.y*i]]:Nr({x:e.x*_v,y:e.y*i,w:e.w*_v,h:e.h*i,angle:e.angle}));n&&t.push(n)}for(const i of this._physicalBodiesR(e)){const e=pl(i);e&&t.push(e)}}return vl(e,t)}_frameOf(){const e=this._spaceModel();if(!e){this._frame=null;const e={x:0,y:0,w:_v,h:_v};return{rect:e,all:e,outliers:0}}const t=this._frame,i="view"!==this._mode;if(t&&t.id===e.id&&this._bdDrag)return t;if(t&&t.id===e.id&&t.model===e&&t.layout===this._layout&&t.devs===this._devices&&t.far===this._showFar&&t.grow===i)return t;const n=kl(this._contentItems(e));let r=n.all||Sl(e),o=this._showFar?r:n.core||Sl(e);return t&&t.id===e.id&&i&&t.grow&&(o=mv(t.rect,o),r=mv(t.all,r)),this._frame={id:e.id,model:e,layout:this._layout,devs:this._devices,far:this._showFar,grow:i,rect:o,all:r,outliers:n.outliers},this._frame}_isoSource(){const e=this._isoSceneRuntime;if(!e)return null;const t=this._spaceModel();if(!t)return null;const i=this._spaceWalls,n=this._openCuts(),r=this._openingsR;return e.createIsoStructuralSource({space:t,walls:i,openCuts:n,openings:r,partitionCuts:()=>this._partitionOpeningCuts(t),roomOpenings:()=>this._roomWallOpeningInputs(r,t),cellCm:this._cellCm,gridPitch:this._gridPitch,wallKeyPitch:this._wallKeyPitch,coordinateScale:_v,onBuild:()=>{this._isoStructuralBuildCount+=1}})}_isoSceneKey(){if(!this._labsIso||"view"!==this._mode)return null;try{return this._isoSource()?.key??null}catch{return this._isoInvalidKey()}}_isoInvalidKey(){return`${this._space}|invalid|${this._cfgEpoch}`}_clearIsoInvalidFallback(e){const t=`${this._space}|invalid|`;for(const i of this._isoFallback)i.startsWith(t)&&i!==e&&this._isoFallback.delete(i)}_isoScene(e=this._isoSource()){const t=this._isoSceneRuntime;if(!t||!e)return null;let i=this._frameOf().rect;const n=this._spaceDisplayForRender(),r=this._spaceModel();if(r&&n.showNames)for(const e of r.rooms)if(e.name){const t=this._labelPos(e,r.id);i=mv(i,{x:t.x,y:t.y,w:0,h:0})}const o=t.resolveIsoScene({source:e,cache:this._isoGeometryCache,cellCm:this._cellCm,liveFrame:i});if(!r||!n.showBorders)return o;const s=this._config?.icon_size??2.5,a=s>8?2.5:s,l=this._stageEl?.getBoundingClientRect?.()??null,c=l?.height?l.width/l.height:o.frame.w/o.frame.h,h=Oi([o.frame.x,o.frame.y,o.frame.w,o.frame.h],c),d=this._isoOverlayScene(r,this._renderDevices.filter(e=>e.space===r.id&&!e.hidden),h,n,t.resolveIsoDecorationLayers(n),o,a,x_(a),n.showLqi??this._config?.show_signal??!0,!1),u=d&&t.resolveIsoOverlayFitEnvelope({baseBounds:o.frame,entries:d.entries,stageSize:l,targetView:e=>Oi([e.x,e.y,e.w,e.h],c)});return u?{...o,frame:u.bounds,overlayFitEntries:d.entries}:o}_latchIsoFallback(e,t){if(this._isoFallback.has(e))return;this._isoFallback.add(e);const i=e.includes("|invalid|")?"invalid":e.split("|").pop()||"invalid";console.warn("HOUSEPLAN ISO FALLBACK: #89/#160",wf("structural",i,!0))}_effectiveProjection(){if(this._isoProjectionSnapshot)return this._isoProjectionSnapshot;const e=e=>this._isoProjectionSnapshot=e,t=()=>("iso"===this._renderProjection&&(this._cancelCameraTransition(!1),this._view=null,this._viewModeSnap=null),e("flat"));if(this._renderIsoScene=null,"iso"!==this._desiredProjection||!this._model.length||!this._isoSceneRuntime)return e("flat");if(!this._spaceDisplayForRender().showBorders)return this._isoFallback.has(`${this._space}|no-borders`)?t():e("iso");let i=this._isoInvalidKey();if(this._clearIsoInvalidFallback(i),this._isoFallback.has(i))return t();try{const n=this._isoSource();if(!n)return e("flat");if(i=n.key,this._isoFallback.has(i))return t();const r=this._isoScene(n);return r?this._isoFallback.has(r.key)?t():(this._renderIsoScene=r,e("iso")):e("flat")}catch(e){return this._latchIsoFallback(i,e),t()}}_scenePoint(e){return"iso"===this._renderProjection?lf(e,0):e}_floorView(e){if("iso"!==this._renderProjection)return e;const t=cf([e.x,e.y]),i=cf([e.x+e.w,e.y+e.h]);return{x:t[0],y:t[1],w:i[0]-t[0],h:i[1]-t[1]}}_isoOverlayScene(e,t,i,n,r,o,s,a,l,c=!0){const h=this._isoSceneRuntime;return h&&r?.structural&&o?h.buildIsoOverlayRenderScene({space:e,devices:t,openings:this._openingsR,view:i,display:n,wallSilhouettes:o.wallSilhouettes,resolveCollisions:c,iconPct:s,deviceBasePct:a,showLqi:l,cellCm:this._cellCm,kioskIconScale:"view"===this._mode?this._kioskScale.icon:1,kioskFontScale:"view"===this._mode?this._kioskScale.font:1,stageSize:this._stageEl?.getBoundingClientRect?.(),positionOf:e=>this._pos(e),presentationOf:(e,t)=>this._devicePresentation(e,t),labelPositionOf:(e,t)=>this._labelPos(e,t),labelScaleOf:e=>this._labelScale(e),openingEntityAvailable:e=>this._renderOpeningEntityAvailable(e),openingWallIndex:()=>this._openingWallIndexFor(e,this._openCuts()).value}):null}_baseVb(e=this._effectiveProjection(),t=this._renderIsoScene){if("iso"===e){if(!this._spaceDisplayForRender().showBorders){const e=uf({rect:this._frameOf().rect,wallHeight:0});return[e.x,e.y,e.w,e.h]}const e=t?.frame??this._frameOf().rect;return[e.x,e.y,e.w,e.h]}const i=this._frameOf().rect;return[i.x,i.y,i.w,i.h]}get _outliers(){return this._showFar?0:this._frameOf().outliers}_fitFar(){this._clearRoomFocus(),this._showFar=!0,this._frame=null,this.requestUpdate(),this._resetZoom()}_clearRoomFocus(e=!1){this._doubleFit.clear(),this._roomFocus=null,e&&(this._roomPointer=null)}_roomFitBounds(e,t){const i=ni(e);if(!i||!e.id)return null;const n=this._spaceWalls,r=this._openCuts(),o=this._wallUnionGeometry(),s=n.length&&this._innerRoomContour(t,e.id,r,o?.roomGeom,o?.multiWallNodes)||i,a=this._spaceDisplayForRender();let l=[];if(a.showBorders&&n.length){const i=Fs(t.rooms,e.id,n,r,this._wallKeyPitch,this._cellCm,this._gridPitch,_v);i&&(l=aa(i.poly,i.offsets,o?.multiWallNodes)||i.poly)}const c=this._effectiveProjection();return function(e){const t=e.floor,i=e.wall||[],n=e.padding??0;if(!t.length||!t.every(vf)||!i.every(vf)||!Number.isFinite(n)||n<0)return null;if("flat"===e.projection)return bf([...t,...i],n);const r=e.wallHeight??0,o=e.floorDepth??0;if(!Number.isFinite(r)||r<0||!Number.isFinite(o)||o<0)return null;try{const e=[];for(const i of t){const t=[i[0],i[1]];e.push(lf(t,0)),o>0&&e.push(lf(t,-o))}for(const t of i){const i=[t[0],t[1]];e.push(lf(i,0)),r>0&&e.push(lf(i,r))}return bf(e,n)}catch{return null}}({floor:s,wall:l,projection:c,wallHeight:"iso"===c&&a.showBorders?Wa(84,this._cellCm):0,floorDepth:"iso"===c&&a.showBorders?Wa(10,this._cellCm):0,padding:a.showBorders?Wa(1.25,this._cellCm):0})}_fitRoom(e,t=!0){if("view"!==this._mode)return!1;this._doubleFit.clear();const i=this._spaceModel(),n=i?.rooms.find(t=>t.id===e);if(!i||!n)return this._clearRoomFocus(),!1;let r=this._roomFitBounds(n,i);if(!r)return this._clearRoomFocus(),!1;this._roomFocus={spaceId:i.id,roomId:e};const o=this._stageEl;if(!o||o.clientWidth<=0||o.clientHeight<=0)return!0;const s=Oi(this._baseVb(),o.clientWidth/o.clientHeight),a=e=>function(e){const t=e.safeFraction??.8,{bounds:i,baseFit:n,stageWidth:r,stageHeight:o,minZoom:s,maxZoom:a}=e;if(!yf(i)||!yf(n)||!Number.isFinite(r)||r<=0||!Number.isFinite(o)||o<=0||!Number.isFinite(s)||s<=0||!Number.isFinite(a)||a1)return null;const l=r/o,c=Math.max(i.w/t,i.h/t*l);if(!Number.isFinite(c)||c<=0)return null;const h=Math.min(a,Math.max(s,n.w/c)),d=n.w/h,u=d/l;return{zoom:h,viewBox:{x:i.x+i.w/2-d/2,y:i.y+i.h/2-u/2,w:d,h:u}}}({bounds:e,baseFit:s,stageWidth:o.clientWidth,stageHeight:o.clientHeight,minZoom:wv.ZOOM_MIN,maxZoom:wv.ZOOM_MAX});let l=a(r);const c=this._isoSceneRuntime,h=this._renderIsoScene?.overlayFitEntries;if(l&&"iso"===this._effectiveProjection()&&c&&h?.length){const e=c.resolveIsoOverlayFitEnvelope({baseBounds:r,entries:h,ownerId:n.id,stageSize:{width:o.clientWidth,height:o.clientHeight},targetView:e=>a(e)?.viewBox??null});e&&(r=e.bounds,l=a(r))}if(!l)return this._clearRoomFocus(),!1;const d=this._cameraState(),u=function(e,t,i,n){const r=[e,t,i,n],o=Math.min(...r.map(e=>e.x)),s=Math.min(...r.map(e=>e.y));return{x:o,y:s,w:Math.max(...r.map(e=>e.x+e.w))-o,h:Math.max(...r.map(e=>e.y+e.h))-s}}(s,d.viewBox,l.viewBox,r);return l.viewBox=this._clampView(l.viewBox,u),t?(this._prepareCameraCommand(),this._startCameraTransition(l,u,"room",220),!0):(this._cancelCameraTransition(!1),Xg(d,l)||(this._zoom=l.zoom,this._view={...l.viewBox},this.requestUpdate()),!0)}_fitAll(e="fit"){this._clearRoomFocus(),this._showFar=!0,this._frame=null,this.requestUpdate(),this._resetZoom(e)}_renderFarHint(){return this._kiosk||"view"!==this._mode||this._booting||!this._outliers?G:j`
+
`:G}houseplanContinuityTrace(){return[...this._continuityHistory,...this._continuity.trace].slice(-80).map(e=>({...e,...e.stage?{stage:[...e.stage]}:{}}))}getCardSize(){return 12}getGridOptions(){return{columns:"full"}}get _norm(){return!(!this._serverCfg||!this._serverCfg.spaces.length)}_cfgFingerprint(){const e=this._serverCfg?.spaces||[];let t=e.length+":";for(const i of e){t+=(i.id||"")+","+(i.plan_aspect||"")+","+(i.plan_url||"").length+","+(i.plan_x??"")+","+(i.plan_y??"")+","+(i.plan_scale??"")+","+(i.plan_scale_x??"")+","+(i.plan_scale_y??"")+","+(i.plan_angle??"")+","+(i.rooms?.length||0)+","+(i.openings?.length||0)+","+(i.decor?.length||0)+";";for(const e of i.rooms||[]){const i=e.poly?.[0],n=e.poly?.[e.poly.length-1];t+=(e.poly?.length||0)+"."+(e.id||"")+"."+(e.open_to||[]).join("+")+"."+(e.area||"")+"."+JSON.stringify(e.settings||0)+"."+(e.x??"")+","+(e.y??"")+","+(e.w??"")+","+(e.h??"")+","+(i?i[0]+"/"+i[1]:"")+","+(n?n[0]+"/"+n[1]:"")+";"}}return t}get _model(){if(!this._serverCfg)return[];const e=this._cfgEpoch+"|"+this._cfgFingerprint();if(this._modelCache&&this._modelCache.key===e)return this._modelCache.model;const t=this._buildModel();return this._modelCache={key:e,model:t},t}_buildModel(){if(!this._serverCfg)return[];const e=this._renderCfg;return el(e).map((t,i)=>{const n=e.spaces[i]?.plan_url;return t.bg&&n?{...t,bg:{...t.bg,href:n}}:t})}_spaceModel(){return this._hasFixedFloor?kc(this._model,this._space):(e=this._model,t=this._space,e.find(e=>e.id===t)??e[0]);var e,t}_spaceModelById(e){return kc(this._model,e)}_syncEmptySpaceState(){if(!!this._serverCfg&&0===this._serverCfg.spaces.length){if(!this._emptySpaceStateActive){this._emptySpaceStateActive=!0,this._clearRoomFocus(!0);for(const e of this._pointers.keys())for(const t of this.renderRoot.querySelectorAll("*"))try{t.hasPointerCapture?.(e)&&t.releasePointerCapture(e)}catch{}this._pointers.clear(),this._panStart=null,this._panLock=null,this._pinchStart=null,this._swipeStart=null,this._drag=null,this._deviceDrag=null,this._resetDeviceHitState(),this._rlResize=null,this._vacFit=null,this._compassDrag=!1,this._cancelModeTransition(!1),this._mode="view",this._clearGeometryGesture(),this._geometryHistory.clear(),this._devicePositionHistory.clear(),this._tip=null,this._hoverRoom=null,this._openingInfo=null,this._closeInfoCard(),this._deviceInbox=null,this._deviceInboxReturn=null,this._markerDialog=null,this._physicalDialog=null,this._backdropDialog=null,this._decorShapeDialog=null,this._decorTextDialog=null,this._roomDialog=!1,"edit"===this._spaceDialog?.mode&&(this._spaceDialog=null),this._editorSecondary?.closeForNavigation(),this._saveConfigDebounced.cancel(),this._frame=null,this._planSnapGeometryCache=null,this._hiddenWallDiagnosticCache=null,this._decorSnapCache=null,this._commitSpace("",!0)}}else this._emptySpaceStateActive=!1}get _areaToSpace(){const e={};for(const t of this._model)for(const i of t.rooms)i.area&&(e[i.area]={space:t.id,room:i});return e}get _settings(){return this._serverCfg?.settings||{}}get _showAll(){return this._showHidden||!this._settings.filter_seeded&&!!this._settings.show_all}_seedHiddenDevices(){if(!(this._loadOk&&this._serverCfg&&this._norm&&this._canEdit))return;const e=this._serverCfg,t=eu({hass:this.hass,registry:this._haRegistry,areaToSpace:Object.fromEntries(Object.entries(this._areaToSpace).map(([e,t])=>[e,t.space])),markers:this._markers,settings:this._settings,excluded:this._excluded,firstSpaceId:this._model[0]?.id||"",iconRules:this._iconRules});if(!t.length&&e.settings?.filter_seeded)return;e.markers=e.markers||[];const i=[];for(const n of t){const t="h"+n.slice(n.indexOf(":")+1);e.markers.push({id:t,binding:n,hidden:!0}),i.push(n.slice(n.indexOf(":")+1))}const n={...e.settings||{},filter_seeded:!0};delete n.show_all,i.length&&Array.isArray(n.new_device_ids)&&(n.new_device_ids=n.new_device_ids.filter(e=>!i.includes(e))),e.settings=n,this._regSignature="",this._maybeRebuildDevices(),this._saveConfig(),this.requestUpdate()}get _iconRules(){const e=this._settings.icon_rules;if(!e||!Array.isArray(e)||!e.length)return;const t=JSON.stringify(e);return t!==this._rulesCompiledSrc&&(this._rulesCompiledSrc=t,this._rulesCompiled=Ee(e)),this._rulesCompiled}get _fillColors(){return vn(this._settings)}get _excluded(){return lu(this._settings)}_setAreaLifecycleConfig(e){this._cfgEpochPreservedConfig=e,this._serverCfg=e}willUpdate(e){if(this._isoProjectionSnapshot=null,this._summary?.willUpdate(),e.has("hass")&&this._configReloadAuthority.observeContext(Vu(this)),e.has("_serverCfg")){const e=this._cfgEpochPreservedConfig===this._serverCfg;this._cfgEpochPreservedConfig=null,e||this._cfgEpoch++,this._renderLife.invalidate()}if(this._syncEmptySpaceState(),this._dangerConfirm&&(this._dangerConfirmMissingSpace()||"warm"===this._syncDangerConfirmLocaleGate())&&this._cancelDangerConfirm(),e.has("hass")&&this.hass){const t=this._visibleDeviceSnapshot||this._candidateDeviceSnapshot;this._renderLife.observe(e.get("hass"),this.hass,t?{entityIds:t.entityIds}:null,()=>Mg(this))}this._continuity.hasCompleteFrame&&"steady"===this._continuity.state&&this._continuity.refreshCompleteFrame(this._visualFrameFingerprint()),this._captureRenderDeviceSnapshot()}updated(){this._summary?.updated(),this._liveRt?.commit(),this._editorRuntime?._commitLiveEditor(),this._pruneDevicePressFeedback(),this._syncDayCycleClock(),this._syncRadarLive(),this._warmSnapshot(),this._editorRuntime&&this._dtMeasure();const e=this._stageEl;e&&!this._roViewport&&(this._roViewport=new ResizeObserver(()=>{this._invalidateDeviceHitGeometry(),this._refitView(),requestAnimationFrame(()=>this._summary?.resized())}),this._roViewport.observe(e)),e&&this._booting&&!this._bootTimer&&this._bootWatch();const t=this.renderRoot.querySelector(".hdr");if(t&&e&&!this._roHdr){const i=()=>{const t=ef(this.renderRoot,e,this.panelHost);null!==t&&(t>=0&&t!==this._hdrH&&(this._hdrH=t),t>=0&&!this._booting&&!this._config?.kiosk&&e.clientHeight>0&&this._warmPatch({hdrH:t,stageH:e.clientHeight}))};this._roHdr=new ResizeObserver(()=>requestAnimationFrame(i)),this._roHdr.observe(t),this._onWinResize=()=>requestAnimationFrame(i),window.addEventListener("resize",this._onWinResize),i()}if(e&&!this._view&&this._refitView(),this._editorSecondary?.afterRender(),this._settleContinuityFrame(),this._serverStorage&&this._loadOk&&this._canManageConfiguration&&0===this._model.length&&!this._spaceDialog&&!this._importDialog&&!this._onboardingShown){this._onboardingShown=!0;const e=function(e){const t=e?.floors;if(!t||"object"!=typeof t)return[];const i=[];for(const e of Object.values(t))e&&e.floor_id&&i.push({id:e.floor_id,name:e.name||e.floor_id,level:e.level??null});return i.sort((e,t)=>{const i=e.level??1e9,n=t.level??1e9;return i!==n?i-n:e.name.localeCompare(t.name)}),i}(this.hass);e.length?this._importDialog={floors:e.map(e=>({...e,checked:!0}))}:this._openSpaceDialog("create")}}_adoptConfigCapabilities(e){xg(this,e)}_syncRadarLive(){const e=this._serverCfg?.settings?.radar,t=(this._serverCfg?.markers||[]).some(e=>Cg(e,this._space));this._radarLive.sync(this._space,1===this._haRadarStage1Api&&"view"===this._mode&&!1!==e?.show_live&&t&&"hidden"!==this.ownerDocument.visibilityState)}async _syncDecorAssets(e){const t=++this._decorAssetSyncToken;if(1!==this._haDecorAssetsApi||!this.hass)return void(this._decorAssets=new Map);const i=await um(this.hass,cm(e),this._cfgRev);t===this._decorAssetSyncToken&&(this._decorAssets=i,this._resign(),this.requestUpdate())}_adoptAuthoritative(e){return ju(this,e)}_rollbackOptimistic(e){const t=this._adoption.rollbackOptimistic(e);return t&&this.requestUpdate(),t}_resumePendingNavMode(){if(!this._pendingNavMode||!this._canEdit||this._config?.kiosk)return!1;const e=this._pendingNavMode;return this._pendingNavMode=null,this._setMode(e,!1),!0}_getAuthoritativeConfig(){return e=this,async function(e,t){const i=await e();return t(i),i}(()=>e.hass.callWS({type:"houseplan/config/get"}),t=>xg(e,t));var e}async _loadFromServer(){this._loading=!0,this._loadTries++;const e=this._space,t=!!this._view;let i=!1;const n=()=>{i=!0,this._regSignature="",this._maybeRebuildDevices()};try{const[i,r]=await Promise.all([this._getAuthoritativeConfig(),this.hass.callWS({type:"houseplan/layout/get"})]);if("adopted"!==(await this._adoptAuthoritative({cfgResp:i,layResp:r,reason:"structural-response",profile:"reload",beforeAdopt:()=>{this._connectionWasLost=!1,this._serverStorage=!0},afterAdopt:()=>{this._warmVpArmed&&this._space===this._warmVp?.space?this._warmVpArmed=!1:t&&this._space===e||this._restoreZoom(),this._loadOk=!0,n()}})).status)return;this.hass.callWS({type:"houseplan/trail/get"}).then(e=>{this._vacSrvTrails=e?.trails||{},this.requestUpdate()}).catch(()=>{}),this._ensureLiveSyncSubscriptions()}catch(e){if(this._serverCfg)this._scheduleLoadRetry(!0);else if(this._loadTries>=8){this._serverStorage=!1;try{this._layout=JSON.parse(localStorage.getItem(lv)||"{}")||{}}catch{this._layout={}}}}finally{this._loading=!1,this._continuityDataReady=!0,i||n(),this.requestUpdate()}}_ensureLiveSyncSubscriptions(){const e=this.hass?.connection;if(!e)return;if(e!==this._liveSyncConnection&&(this._unsubCfg?.(),this._unsubCfg=null,this._unsubLayout?.(),this._unsubLayout=null,this._unsubTrail?.(),this._unsubTrail=void 0,this._unsubVirtual?.(),this._unsubVirtual=null,this._liveSyncGeneration++,this._liveSyncAttempt=null,this._liveSyncConnection=e),this._liveSyncAttempt)return;const t=this._liveSyncGeneration,i=[],n=(n,r,o,s)=>{n()||i.push(async()=>{const i=await e.subscribeEvents(s,o);t===this._liveSyncGeneration&&this.isConnected&&this.hass?.connection===e&&!n()?r(i):i?.()})};if(n(()=>this._unsubCfg,e=>{this._unsubCfg=e},"houseplan_config_updated",e=>{const t=Number(e?.data?.rev??-1);t!==this._cfgRev&&this._reloadConfigOnly(!1,t)}),n(()=>this._unsubTrail,e=>{this._unsubTrail=e},"houseplan_trail_updated",async()=>{try{const e=await this.hass.callWS({type:"houseplan/trail/get"});this._vacSrvTrails=e?.trails||{},this.requestUpdate()}catch{}}),n(()=>this._unsubLayout,e=>{this._unsubLayout=e},"houseplan_layout_updated",e=>this._onLayoutEvent(Number(e?.data?.rev??-1))),n(()=>this._unsubVirtual,e=>{this._unsubVirtual=e},"houseplan_virtual_light_updated",e=>{const t=Wh(this._virtualLights,e?.data);t!==this._virtualLights&&(this._virtualLights=t,this._capturedSnapshotVirtual="",this._cacheSnapshot(),this.requestUpdate())}),!i.length)return;const r=function(e){return Promise.allSettled(e.map(e=>Promise.resolve().then(e)))}(i).then(()=>{});this._liveSyncAttempt=r,r.finally(()=>{this._liveSyncAttempt===r&&(this._liveSyncAttempt=null)})}async _reloadConfigOnly(e=!1,t){return Ku(this,e,t)}_scheduleLoadRetry(e=!1){if(void 0!==this._loadRetryTimer)return;const t=Math.min(8e3,500*2**Math.min(4,Math.max(1,this._loadTries-7)));this._loadRetryTimer=window.setTimeout(()=>{this._loadRetryTimer=void 0,!e&&this._loadOk||this._loading||!this.hass||this._loadFromServer()},t)}async _ensureLiveRuntime(){if(this._liveRt)return;const e=await import("./live-interaction-runtime-DPmKLJbP.js");this._liveRt=new e.LiveRuntime(this),this.isConnected&&this.requestUpdate()}_liveVp(e=!1){this._liveRt?this._liveRt.viewport(e):this.requestUpdate()}_syncLiveHover(){this._liveRt?this._liveRt.hover():this.requestUpdate()}_flushHa(){this._liveRt?.take()&&(this._terminalFrame=2,super.requestUpdate())}_ensureHaRegistryAuthority(){const e=this.hass?.connection||null;e&&e!==this._haRegistryConnection&&(this._haRegistryRelease?.(),this._haRegistryConnection=e,this._haRegistryRev=-1,this._haBindingCacheKey="",this._renderLife.invalidate(),this._areaSnapshotCleanupCandidates.clear(),this._planHassMemo=null,this._haRegistryRelease=td(this.hass,this._onHaRegistryUpdate),this._onHaRegistryUpdate())}get _haRegistry(){return nd(this.hass)}get _planHass(){const e=this._haRegistry,t=od(this.hass,e),i=this._planHassMemo;if(i&&i.hass===this.hass&&i.sig===t)return i.active;const n=ad(this.hass,e),r=ld(this.hass,e);return this._planHassMemo={hass:this.hass,sig:t,active:n,full:r},n}_captureRenderDeviceSnapshot(){if(!this.hass)return;const e=Date.now(),t=[...this._activityRt.entries()].map(([t,i])=>`${t}:${i.gen}:${i.flashTs}:`+(i.flashKind&&(i.expiresAt||i.flashTs+tg)>e?1:0)).join("|"),i=Bh(this._virtualLights);if(this._capturedSnapshotSequence===this._hassSequence&&this._capturedSnapshotDevices===this._devices&&this._capturedSnapshotLayout===this._layout&&this._capturedSnapshotConfigEpoch===this._cfgEpoch&&this._capturedSnapshotVirtual===i&&this._capturedSnapshotActivity===t)return;const n=this._planHass,r=new Map,o=new Map,s=new Set(["sun.sun"]);for(const e of this._summary?.entityIds()||[])s.add(e);this._vacFit?.source&&s.add(this._vacFit.source);const a=new Set,l=new Set,c=e=>{if(!e)return;const t=e.indexOf(":");if(t<0)return void s.add(e);const i=e.slice(0,t),n=e.slice(t+1);"device"===i?a.add(n):"entity"===i&&s.add(n)};for(const e of this._model)for(const t of e.rooms)t.area&&l.add(t.area),c(t.settings?.temp_source),c(t.settings?.hum_source);for(const e of this._serverCfg?.spaces||[])for(const t of e.openings||[])for(const e of ui(t))s.add(e);for(const e of this._serverCfg?.spaces||[])for(const t of e.decor||[])if("text"===t.kind){for(const e of String(t.text||"").matchAll(/\{([^{}\r\n]+)\}/g)){const t=Xi(e[1]);t?.entity&&s.add(t.entity)}t.entity&&s.add(t.entity),o.set(`decor:${e.id}:${t.id}`,tn(t.text,t,n,e=>!!n.entities?.[e]&&!!n.states?.[e]&&!Jd(n,e,Zd(this._markers))))}const h=Ed(n,this._devices,null,this._virtualLights);for(const e of this._devices){for(const t of[!1,!0])r.set(f_(e.id,t),p_(n,e,{liveStates:!1!==this._config?.live_states,showTemperature:!1!==this._config?.show_temperature,showSignal:t,activityRuntime:this._activityRt.get(e.id),sourceDetails:!1,lightDevices:this._devices,lightSources:h,registryHass:this._fullRegistryHass,reducedMotion:this._reducedMotion}));if(this._isVacDev(e)){const t=this._vacSource(e,n),i=t?Wc(n?.states?.[t]?.attributes):null,r=this._vacRt.get(e.id),s=lh(e.id,e.marker?.vacuum??null,e.space,t),a=hh({routes:s,observed:dh(s,[t],t=>this._vacObservedMapId(e,t,n)),spaceIds:new Set(this._model.map(e=>e.id))});o.set(`vacuum:${e.id}`,{source:t,telemetry:i,routes:s,resolution:a,mapId:i?this._vacMapId(e,i,n):null,runtime:r?{trail:r.trail,lastTs:r.lastTs,moving:r.moving,jump:r.jump}:null,server:this._vacSrvTrails[e.id]||null})}}const d=g_({sourceSequence:this._hassSequence,hass:n,devices:this._devices,presentations:r,positions:(u=this._model.length>0,p=this._devices,_=e=>this._livePos(e),u?new Map(p.map(e=>[e.id,_(e)])):new Map),facts:o,entityIds:s,deviceIds:a,areaIds:l});var u,p,_;this._capturedSnapshotSequence=this._hassSequence,this._capturedSnapshotDevices=this._devices,this._capturedSnapshotLayout=this._layout,this._capturedSnapshotActivity=t,this._capturedSnapshotConfigEpoch=this._cfgEpoch,this._capturedSnapshotVirtual=i,this._visibleDeviceSnapshot&&"steady"!==this._continuity.state?this._candidateDeviceSnapshot=d:(this._visibleDeviceSnapshot=d,this._candidateDeviceSnapshot=null)}get _renderDeviceSnapshot(){return this._stagedDeviceSnapshotToken===this._continuity.token?this._candidateDeviceSnapshot||this._visibleDeviceSnapshot:this._visibleDeviceSnapshot||this._candidateDeviceSnapshot}get _renderPlanHass(){return this._renderDeviceSnapshot?.hass||this._planHass}get _renderDevices(){return this._renderDeviceSnapshot?.devices||this._devices}get _renderVacuumDevices(){return this._renderDeviceSnapshot?.vacuumDevices||this._devices}get _fullRegistryHass(){return this._planHass,this._planHassMemo?.full||this.hass}_bindingStatus(e){return dd(this.hass,e,this._haRegistry)}houseplanDiagnostics(){const{registry:e,bindings:t}=this._renderLife.diagnostics(this.hass,this._markers,e=>this._bindingStatus(e));return{registry:{...e,lastSuccessAgeMs:e.lastSuccess?Math.max(0,Date.now()-e.lastSuccess):null},bindings:t}}_openBindingInHa(e){const[t,i]=e.split(":");if(i)if("device"!==t){if("entity"===t){const e=this._fullRegistryHass.entities?.[i];e?.device_id&&fv("/config/devices/device/"+encodeURIComponent(e.device_id))}}else fv("/config/devices/device/"+encodeURIComponent(i))}_bindingHasHaPage(e){const[t,i]=e.split(":");return!!i&&("device"===t||"entity"===t&&!!this._fullRegistryHass.entities?.[i]?.device_id)}_toggleMarkerDialogVisibility(){const e=this._markerDialog;if(!e)return;const t="ha"===e.bindingMode?this._bindingStatus(e.binding):null,i=e.hideFromPlan||"ha_disabled"===t?.kind;i&&"ha_disabled"===t?.kind?this._showToast(this._t("entity"===t.reason?"toast.ha_disabled_show_entity":"toast.ha_disabled_show_device")):i&&"unverified"===t?.kind?this._showToast(this._t("toast.ha_binding_unverified")):this._markerDialog={...e,hideFromPlan:!i}}_hookConnection(){const e=this.hass?.connection;e&&e!==this._connHooked&&(this._connHooked?.removeEventListener?.("ready",this._onConnReady),this._connHooked?.removeEventListener?.("disconnected",this._onConnLost),this._connHooked?.removeEventListener?.("reconnect-error",this._onConnLost),e.addEventListener?.("ready",this._onConnReady),e.addEventListener?.("disconnected",this._onConnLost),e.addEventListener?.("reconnect-error",this._onConnLost),this._connHooked=e)}_display(e){return this._signer.display(this.hass,e)}_referencedContentUrls(){const e=Nn(this._serverCfg);for(const t of this._decorAssets.values())e.add(t.url);return e}_resign(){this._signer.resign(this.hass,this._referencedContentUrls())}_onLayoutEvent(e){e<=this._layoutRev||(clearTimeout(this._layoutSyncTimer),this._layoutSyncTimer=window.setTimeout(()=>{e<=this._layoutRev||this._reloadLayoutOnly()},200))}_noteLayoutRev(e){this._adoption.noteLayoutRevision(e?.rev)}async _reloadLayoutOnly(){if(!this._serverStorage||!this.hass?.callWS)return;this._beginContinuityCandidate("layout-reload",!1);const e=new Map;for(const t of this._dirtyPos)this._layout[t]&&e.set(t,this._layout[t]);this._persistLayout.pending()&&this._persistLayout.flush();for(const[t,i]of this._sentPos)e.set(t,i);try{const t=await this.hass.callWS({type:"houseplan/layout/get"}),i={...t?.layout||{}};for(const[t,n]of e)null===n?delete i[t]:i[t]=n;this._adoption.adoptMergedLayout(i,t,()=>{this._cancelDeviceDrag(),this._devicePositionHistory.clear()}),this._canOptimizeUndo=!!t?.can_optimize_undo,this._undoKind=t?.undo_kind||null,this._cacheSnapshot(),this.requestUpdate()}catch{}finally{this._continuityDataReady=!0,this.requestUpdate()}}_persistLocalLayout(){this._layout=So(lo(this._layout)),localStorage.setItem(lv,JSON.stringify(this._layout))}_maybeRebuildDevices(){const e=this.hass;if(!e?.devices||!e?.entities||!e?.areas)return;const t=this._haRegistry,i=od(e,t)+":"+Object.keys(e.areas).length+":"+(this._norm?"n":"l")+":"+kp(e,this._config?.language);if(i===this._regSignature&&this._devices.length)return;this._regSignature=i;const n=new Map(this._devices.map(e=>[e.id,e.bindingStatus?.kind||"active"]));this._devices=iu({hass:e,registry:t,areaToSpace:Object.fromEntries(Object.entries(this._areaToSpace).map(([e,t])=>[e,t.space])),markers:this._markers,settings:this._settings,excluded:this._excluded,showAll:this._showAll,firstSpaceId:this._model[0]?.id||"",loc:e=>this._t(e),iconRules:this._iconRules});const r=this._markers.filter(e=>!e.removed&&"virtual"!==e.binding).map(e=>e.binding).sort(),o=t.revision+":"+r.join("|");if(t.authoritative&&o!==this._haBindingCacheKey){const i=new Map;for(const n of r)i.set(n,dd(e,n,t));!function(e){if("undefined"==typeof localStorage||!e.size)return;const t=hd(),i=Date.now();for(const[n,r]of e)"active"===r.kind?t[n]={kind:"active",ts:i}:"ha_disabled"===r.kind&&(t[n]={kind:"ha_disabled",reason:r.reason,ts:i});const n=Object.fromEntries(Object.entries(t).sort((e,t)=>t[1].ts-e[1].ts).slice(0,1500));Yh=n;try{localStorage.setItem(Kh,JSON.stringify(n))}catch{}}(i),this._haBindingCacheKey=o}let s=null;if(t.authoritative&&(s=this._resolveAreaRelocations(t),this._areaRelocationIds=new Set(s.relocateIds),this._areaRelocationIds.size)){this._cancelDeviceDrag();const e=this._areaRelocationIds;this._devicePositionHistory.removeWhere(({before:t,after:i})=>e.has(t.deviceId)||e.has(i.deviceId));const t=this._markerDialog;if(t?.devId&&!t.roomTouched&&this._areaRelocationIds.has(t.devId)){const e=this._devices.find(e=>e.id===t.devId);e&&(this._markerDialog={...t,room:e.marker?.room_id?`${e.space}#@${e.marker.room_id}`:e.space&&e.area?`${e.space}#${e.area}`:""})}}this._defPos=this._defaultPositions(),this._syncNewDevices(),this._seedHiddenDevices(),s&&this._syncAreaRelocations(s),this._syncActivityRuntime();const a=new Set(this._devices.filter(e=>!e.hidden).map(e=>e.id));for(const e of this._vacRt.keys())a.has(e)||this._vacRt.delete(e);if(this._infoCard){const e=this._devices.find(e=>e.id===this._infoCard.id);this._infoCard=e&&"ha_disabled"!==e.bindingStatus?.kind?e:null}const l=this._devices.some(e=>"ha_disabled"===e.bindingStatus?.kind&&"ha_disabled"!==n.get(e.id));l&&("ha_disabled"!==this._infoCard?.bindingStatus?.kind&&"ha_disabled"!==this._devices.find(e=>e.id===this._infoCard?.id)?.bindingStatus?.kind||this._closeInfoCard(),this._deviceDrag&&"ha_disabled"===this._devices.find(e=>e.id===this._deviceDrag.id)?.bindingStatus?.kind&&(this._cancelDeviceDrag(),this._devicePositionHistory.clear()),clearTimeout(this._holdTimer),this._holdFired=!1,this._tip=null,this._tapConfirm=null),this._nativeMoreInfoEntity&&!this._planEntityAvailable(this._nativeMoreInfoEntity)&&(gv(this,"hass-more-info",{entityId:null}),this._nativeMoreInfoEntity=null)}_resolveAreaRelocations(e=this._haRegistry){const t=function(e){const t=Q_(e.snapshot),i=new Set(Object.values(t).map(e=>e.binding)),n=new Map;for(const[t,r]of e.previousCandidates||[])J_(t)&&Number.isFinite(r)&&i.has(t)&&n.set(t,r);const r=new Set,o=new Set;for(const t of e.markers||[])t.removed||(Z_(t.id)&&r.add(t.id),J_(t.binding)&&o.add(t.binding));const s=new Set(Object.keys(e.registryDevices||{})),a=new Set(Object.keys(e.registryEntities||{})),l=new Set(Object.keys(e.liveStates||{})),c=new Map;for(const[e,i]of Object.entries(t)){const t=c.get(i.binding)||[];t.push(e),c.set(i.binding,t)}const h=new Set;let d=!1;for(const[t,i]of c){const[c,u]=rm(t);if(o.has(t)||i.some(e=>r.has(e))||("device"===c?s.has(u):a.has(u)||l.has(u))){n.delete(t);continue}const p="device"===c?s.size>0:a.size>0;if(!e.authoritative||!p)continue;const _=n.get(t);if(void 0!==_){if(_!==e.revision)for(const e of i)h.add(e)}else n.set(t,e.revision),d=!0}return{removeIds:h,candidates:n,needsConfirmationRefresh:d}}({snapshot:this._settings.marker_area_snapshot,authoritative:e.authoritative,revision:e.revision,registryDevices:e.devices,registryEntities:e.entities,liveStates:this.hass?.states,markers:this._markers,previousCandidates:this._areaSnapshotCleanupCandidates});return this._areaSnapshotCleanupCandidates=t.candidates,t.needsConfirmationRefresh&&this._canEdit&&id(this.hass),om({devices:this._devices,model:this._model,layout:this._layout,snapshot:this._settings.marker_area_snapshot,authoritative:e.authoritative,cleanupSnapshotIds:t.removeIds,coordinateScale:_v})}_syncNewDevices(){if(!this._norm||!this._loadOk||!this._serverCfg)return;const e=this._devices.filter(e=>!e.marker&&!e.virtual).map(e=>e.id).sort(),t=e.join(",");if(t===this._newSyncKey)return;this._newSyncKey=t;const i=this._settings,{fresh:n,known:r}=function(e,t){if(!Array.isArray(t))return{fresh:[],known:[...e]};const i=new Set(t),n=e.filter(e=>!i.has(e));return{fresh:n,known:n.length?[...t,...n]:t}}(e,i.known_devices);if(!Array.isArray(i.known_devices)||n.length){const e=[...new Set([...i.new_device_ids||[],...n])];this._serverCfg={...this._serverCfg,settings:{...i,known_devices:r,new_device_ids:e}},this._saveConfig()}}_syncAreaRelocations(e){if(!(this._loadOk&&this._serverCfg&&this._norm&&this._canEdit&&this._haRegistry.authoritative))return;const t=e.decisions.filter(e=>e.updateSnapshot||e.removeSnapshot);if(!t.length)return;const i=cc({snapshot:Q_(this._settings.marker_area_snapshot),decisions:t});i!==this._areaRelocationSyncKey&&(this._areaRelocationSyncKey=i,this._areaRelocationWrite=this._areaRelocationWrite.catch(()=>{}).then(async()=>{if(!this._serverCfg||!this._haRegistry.authoritative)return;const e=this._resolveAreaRelocations();this._areaRelocationIds=new Set(e.relocateIds);const t=new Set,i=new Map;let n=!1;for(const r of e.decisions){if(!r.relocate)continue;const e=fg(this._layout,r.id);try{await this._persistDevicePlacement(r.id,null),t.add(r.id),e&&i.set(r.id,e),this._areaRelocationIds.delete(r.id)}catch(t){n=!0,this._layout=vg(this._layout,r.id,e),this._showToast(this._t("toast.pos_save_failed",{err:this._errText(t)}))}}const r=this._settings,o=function(e,t,i=new Set){const n=Q_(e);for(const e of t.decisions)e.removeSnapshot?delete n[e.id]:e.updateSnapshot&&e.binding&&e.area&&(e.relocate&&!i.has(e.id)||(n[e.id]={binding:e.binding,area:e.area}));return n}(r.marker_area_snapshot,e,t),s=[...new Set([...Array.isArray(r.new_device_ids)?r.new_device_ids:[],...t])],a=cc(o)!==cc(Q_(r.marker_area_snapshot)),l=cc(s)!==cc(Array.isArray(r.new_device_ids)?r.new_device_ids:[]);if(a||l){const e=r.marker_area_snapshot,n=r.new_device_ids,a={...this._serverCfg,settings:{...r,marker_area_snapshot:o,...l?{new_device_ids:s}:{}}};this._setAreaLifecycleConfig(a);try{this._saveConfigDebounced.pending()&&this._saveConfigDebounced.cancel(),await this._writeConfig()}catch(r){const a=this._settings;if(cc(a.marker_area_snapshot)===cc(o)&&cc(a.new_device_ids)===cc(l?s:n)){const t={...a};void 0===e?delete t.marker_area_snapshot:t.marker_area_snapshot=e,void 0===n?delete t.new_device_ids:t.new_device_ids=n;const i={...this._serverCfg,settings:t};this._setAreaLifecycleConfig(i),this._adoption.refreshConfigFingerprint()}for(const e of t)this._areaRelocationIds.add(e);const c=new Set;for(const[e,t]of i)try{await this._persistDevicePlacement(e,t)}catch(t){c.add(e),this._showToast(this._t("toast.pos_save_failed",{err:this._errText(t)}))}this._areaRelocationSyncKey="",this._regSignature="";if("conflict"===(r&&"object"==typeof r&&"code"in r?r.code:void 0)?(this._showToast(this._t("toast.conflict")),await this._reloadConfigOnly(!0)):this._showToast(this._t("toast.cfg_save_failed",{err:this._errText(r)})),c.size&&this._serverCfg){const e=this._settings,t=[...new Set([...Array.isArray(e.new_device_ids)?e.new_device_ids:[],...c])],i={...this._serverCfg,settings:{...e,new_device_ids:t}};this._setAreaLifecycleConfig(i);try{await this._writeConfig()}catch(e){this._showToast(this._t("toast.cfg_save_failed",{err:this._errText(e)}))}}}}n&&(this._areaRelocationSyncKey=""),this.requestUpdate()}))}get _newIds(){const e=this._settings.new_device_ids;return new Set([...Array.isArray(e)?e:[],...this._areaRelocationIds])}_ackNewDevice(e){if(!this._newIds.has(e)||!this._serverCfg)return;const t=this._settings;this._serverCfg={...this._serverCfg,settings:{...t,new_device_ids:(t.new_device_ids||[]).filter(t=>t!==e)}},this._saveConfig(),this.requestUpdate()}get _markers(){return this._serverCfg?.markers||[]}_roomLqi(e){if(!e)return null;const t=[];for(const i of this._renderDevices){if(i.area!==e||i.virtual)continue;const n=Ld(this._renderPlanHass,i.entities);null!=n&&t.push(n)}return Ii(t)}_roomBounds(e){if(e.poly&&e.poly.length){const t=e.poly.map(e=>e[0]),i=e.poly.map(e=>e[1]),n=Math.min(...t),r=Math.min(...i);return{x:n,y:r,w:Math.max(...t)-n,h:Math.max(...i)-r}}return{x:e.x??0,y:e.y??0,w:e.w??0,h:e.h??0}}_defaultPositions(){const e={},t=this._config?.icon_size??2.5;for(const i of this._model){const n=t/100*Ml(i)*1.3;for(const t of i.rooms){if(!t.area)continue;const r=this._devices.filter(e=>e.area===t.area&&e.space===i.id);if(!r.length)continue;const o=this._roomBounds(t),s=.1*Math.min(o.w,o.h),a=o.w-2*s,l=o.h-2*s,c=Math.max(1,Math.round(Math.sqrt(r.length*a/Math.max(l,1)))),h=Math.ceil(r.length/c),d=a/c,u=l/Math.max(h,1),p=r.map((e,t)=>({x:o.x+s+d*(t%c+.5),y:o.y+s+u*(Math.floor(t/c)+.5)}));Ei(p,o,n,.5*s),r.forEach((t,i)=>e[t.id]=al(p[i]))}}return e}_pos(e){const t=this._renderDeviceSnapshot?.positions.get(e.id);return t?{x:t.x,y:t.y}:this._livePos(e)}_livePos(e){const t=this._spaceModelById(e.space),i=this._areaRelocationIds.has(e.id)?void 0:this._layout[e.id];if(i)if(this._norm){if(i.s===e.space)return{x:i.x*_v,y:i.y*_v}}else if(void 0===i.s)return{x:i.x,y:i.y};return this._defPos[e.id]?this._defPos[e.id]:t?al($l(t)):{x:500,y:500}}_devicePlacementForCanvas(e,t,i){if(!this._norm)return{x:Math.round(t),y:Math.round(i)};const n=this._gridPitch,r=Math.round(t/n)*n,o=Math.round(i/n)*n;return{s:e.space,x:cl(r/_v),y:cl(o/_v)}}_previewDevicePlacement(e,t){this._layout=vg(this._layout,e,t),this.requestUpdate()}_cancelDeviceDrag(){const e=this._deviceDrag;if(!e)return!1;this._editorRuntime?._cancelPointerMove("device"),this._deviceDrag=null,this._deviceHits.cancel(e.pointerId);try{e.source?.hasPointerCapture?.(e.pointerId)&&e.source.releasePointerCapture(e.pointerId)}catch{}return this._previewDevicePlacement(e.id,e.before),!0}async _persistDevicePlacement(e,t){if(this._layout=vg(this._layout,e,t),this._serverStorage){let i=null,n=!1;try{let r;if(null===t)i=null,this._sentPos.set(e,i),n=!0,r=await this.hass.callWS({type:"houseplan/layout/delete",device_id:e});else{const t=xo(this._layout[e]);cc(t)!==cc(this._layout[e])&&(this._layout={...this._layout,[e]:t}),i=t,this._sentPos.set(e,i),n=!0,r=await this.hass.callWS({type:"houseplan/layout/update",device_id:e,pos:t})}this._noteLayoutRev(r),this._adoption.refreshLayoutFingerprint(),this._cacheSnapshot()}finally{n&&this._sentPos.get(e)===i&&this._sentPos.delete(e)}return}this._persistLocalLayout()}_devicePositionStateValid(e){const t=this._devices.find(t=>t.id===e.deviceId);return!!t&&t.space===e.spaceId&&"ha_disabled"!==t.bindingStatus?.kind&&!!this._spaceModelById(e.spaceId)}async _runDevicePositionHistory(e){if(this._cancelDeviceDrag()||this._devicePositionBusy)return;const t="undo"===e?this._devicePositionHistory.undo():this._devicePositionHistory.redo();if(!t)return;const i="undo"===e?t.before:t.after;if(!this._devicePositionStateValid(i))return this._devicePositionHistory.clear(),this._showToast(this._t("history.device_stale")),void this.requestUpdate();const n=fg(this._layout,i.deviceId);i.spaceId!==this._space&&(this._commitSpace(i.spaceId),this._restoreZoom()),this._devicePositionBusy=!0,this._previewDevicePlacement(i.deviceId,i.placement);try{await this._persistDevicePlacement(i.deviceId,i.placement),this._showToast(this._t("undo"===e?"history.undone":"history.redone",{name:t.name}))}catch(t){this._previewDevicePlacement(i.deviceId,n),"undo"===e?this._devicePositionHistory.redo():this._devicePositionHistory.undo(),this._showToast(this._t("toast.pos_save_failed",{err:this._errText(t)}))}finally{this._devicePositionBusy=!1,this.requestUpdate()}}_undoDevicePosition(){this._runDevicePositionHistory("undo")}_redoDevicePosition(){this._runDevicePositionHistory("redo")}_savePos(e,t,i){this._spaceModelById(e.space)&&(this._layout=vg(this._layout,e.id,this._devicePlacementForCanvas(e,t,i)),this._dirtyPos.add(e.id),this._persistLayout())}_devicePresentation(e,t=!1!==this._config?.show_signal,i=!1){const n=i?null:this._renderDeviceSnapshot?.presentations.get(f_(e.id,t));return n||p_(this._renderPlanHass,e,{liveStates:!1!==this._config?.live_states,showTemperature:!1!==this._config?.show_temperature,showSignal:t,designPreview:i,activityRuntime:this._activityRt.get(e.id),sourceDetails:!1,lightDevices:this._renderDevices,registryHass:this._fullRegistryHass,reducedMotion:this._reducedMotion})}_deviceVisual(e){return this._devicePresentation(e).visual}_stateClass(e,t=this._deviceVisual(e)){const i=this._devicePresentation(e);return i.effectiveHidden?"":("icon_ripple"!==i.display||!1===this._config?.live_states||"alarm"===t.status||t.activity,u_({...i,visual:t}).join(" "))}_liveTemp(e){if(!this._config?.show_temperature)return null;if(!0===e.marker?.use_climate_temp){const t=qd(this._renderPlanHass,e.entities);if(null!=t)return t}return"mdi:thermometer"!==e.icon&&"mdi:air-filter"!==e.icon?null:Bd(this._renderPlanHass,e.entities)}_bindingEntities(e){if("virtual"===e||!e)return[];const t=this._bindingStatus(e);return"active"===t.kind?t.enabledEntityIds:t.allEntityIds}_bindingHasClimate(e){return this._bindingEntities(e).some(e=>e.startsWith("climate."))}_bindingHasAlarm(e){return this._bindingEntities(e).some(e=>{const t=this._planHass?.states?.[e]||this.hass?.states?.[e],i=this._fullRegistryHass.entities[e]||this.hass?.entities?.[e];return Yn(e.split(".")[0],t?.attributes?.device_class||i?.device_class||i?.original_device_class)})}_deviceBindingActive(e,t=!0){if(e.virtual||"virtual"===e.bindingKind)return!0;if(!e.bindingKind||!e.bindingRef)return!1;const i=this._bindingStatus(`${e.bindingKind}:${e.bindingRef}`);return"active"===i.kind||(t&&this._showToast(this._t("ha_disabled"===i.kind?"toast.ha_disabled_action":"toast.ha_binding_unverified")),!1)}_openMoreInfo(e){e?this._planEntityAvailable(e)?(this._kiosk&&(this._cyclePausedUntil=Math.max(this._cyclePausedUntil,Date.now()+6e4)),this._nativeMoreInfoEntity=e,gv(this,"hass-more-info",{entityId:e})):this._showToast(this._t("toast.ha_disabled_action")):this._showToast(this._t("toast.no_entity"))}_interruptViewGesture(e,t){if(clearTimeout(this._holdTimer),clearTimeout(this._kioskHoldTimer),void 0!==e)for(const i of[t,this._stageEl])try{i?.hasPointerCapture?.(e)&&i.releasePointerCapture(e)}catch{}this._pointers.clear(),this._panStart=null,this._panLock=null,this._pinchStart=null,this._swipeStart=null,this._roomPointer=null,this._doubleFit.clear(),this._deviceHits.clearPointers()}_closeInfoCard(){this._interruptViewGesture(),this._holdFired=!1,this._infoCard=null}_invalidateDeviceHitGeometry(){this._deviceHits.invalidate()}_resetDeviceHitState(){this._deviceHits.reset(this.renderRoot)}_deviceHitOwnerAt(e,t){return"view"!==this._mode&&"devices"!==this._mode?null:this._deviceHits.at(this.renderRoot,this._renderDevices,this._space,e,t)}_deviceForPointerEvent(e,t){return this._deviceHits.pointer(this.renderRoot,this._renderDevices,this._space,e,t)}_deviceForClickEvent(e,t){return this._deviceHits.click(this.renderRoot,this._renderDevices,this._space,e,t)}_showDeviceTip(e,t){this._liveRt?this._liveRt.devicePointerTip(e,t):this._ensureLiveRuntime().then(()=>this._liveRt?.devicePointerTip(e,t))}_showDeviceFocusTip(e,t){const i=e.currentTarget;this._liveRt?this._liveRt.deviceFocusTip(i,t):this._ensureLiveRuntime().then(()=>this._liveRt?.deviceFocusTip(i,t))}_hideDeviceFocusTip(e){this._liveRt?.deviceBlur(e)}_clearPointerHover(){this._liveRt?this._liveRt.pointerLeave():this._clearTransientHover()}_ctxDevice(e,t){"view"===this._mode&&(t=this._deviceForPointerEvent(e,t),e.preventDefault(),e.stopPropagation(),this._deviceBindingActive(t)&&(t.primary?this._openMoreInfo(t.primary):this._infoCard=t))}_clickDevice(e,t){if("view"!==this._mode&&"devices"!==this._mode)return;if(e.stopPropagation(),t=this._deviceForClickEvent(e,t),this._deviceDrag?.moved||this._suppressClick||this._holdFired)return;if("devices"===this._mode)return void this._openMarkerDialog(t);const i=this._devices.find(e=>e.id===t.id);if(!i)return;const n=Tu(i.tapAction,i.primary?.split(".")[0]);if("none"===n)return;const r=(e,t)=>{i.marker?.tap_confirm?this._tapConfirm={kind:"run",text:e,exec:t}:t()};if("toggle"===n){const e=this._toggleIntent(i);if(!e)return;if(!Iu(e))return void this._showUnavailableToggleTargets(e);const t=e=>{const t=Iu(e);if(!t)return;if("virtual-light"===t.kind)return this._startDevicePressFeedback(i.id),void this.hass.callWS({type:"houseplan/virtual_light/toggle",marker_id:t.markerId}).then(e=>{const t=Wh(this._virtualLights,e);t!==this._virtualLights&&(this._virtualLights=t,this._capturedSnapshotVirtual="",this._cacheSnapshot(),this.requestUpdate())}).catch(e=>this._showToast(this._t("toast.virtual_light_toggle_failed",{err:this._errText(e)})));const{command:n}=t;this._startDevicePressFeedback(i.id),this.hass.callService(n.domain,n.service,n.data).catch(e=>this._showToast(this._t("toast.error",{err:this._errText(e)})))},n=((o=e).targets.length?o.targets:o.skippedTargets).map(e=>e.name||e.entityId||e.ref).join(", ")||i.name;if(i.marker?.tap_confirm){const r=this._toggleConfirmationLines(e);if(!r.length)return;this._tapConfirm={kind:"toggle",text:this._t("confirm.tap_toggle",{name:n}),lines:r,initialIntent:e,deviceId:i.id,exec:()=>{const n=this._devices.find(e=>e.id===i.id),r=n?this._toggleIntent(n):null;r&&!Iu(r)&&this._showUnavailableToggleTargets(r)||(r&&Eu(e,r)?t(r):this._showToast(this._t("toast.tap_target_changed")))}}}else t(e);return}var o;if("info"===n)return this._interruptViewGesture(),void(this._infoCard=i);if(this._deviceBindingActive(i)){if("run"===n){const e=i.marker?.tap_target||"",t=function(e){const t=String(e||"").split(".")[0];return"automation"===t?{domain:"automation",service:"trigger"}:"script"===t?{domain:"script",service:"turn_on"}:"scene"===t?{domain:"scene",service:"turn_on"}:null}(e),n=this.hass.states[e];if(!t||!n)return void this._showToast(this._t("toast.run_target_missing"));const o=n.attributes?.friendly_name||e;return void r(this._t("confirm.tap_run",{name:o}),()=>{this._deviceBindingActive(i)&&this._planEntityAvailable(e)&&(this._startDevicePressFeedback(i.id),this.hass.callService(t.domain,t.service,{entity_id:e}).then(()=>{this._stampActivity(i.id,"event",this._activitySourceKey(i)),this.requestUpdate(),this._showToast(this._t("toast.run_started",{name:o}))}).catch(e=>this._showToast(this._t("toast.error",{err:this._errText(e)}))))})}"more-info"===n&&i.primary?this._openMoreInfo(i.primary):this._infoCard=i}}_showUnavailableToggleTargets(e){const t=function(e){if(!e||"group"!==e.kind||Iu(e)||"configured-targets-missing"!==e.noneReason)return[];if(!e.skippedTargets.length||e.skippedTargets.some(e=>!Ou.has(e.reason)&&"secure"!==e.reason))return[];const t=[],i=new Set;for(const n of e.skippedTargets){if(!Ou.has(n.reason))continue;const e=String(n.name||n.entityId||n.ref||"").trim();e&&!i.has(e)&&(i.add(e),t.push(e))}return t}(e);return!!t.length&&(this._showToast(1===t.length?this._t("toast.toggle_target_unavailable",{name:t[0]}):this._t("toast.toggle_targets_unavailable",{names:t.join(", ")})),!0)}_keyDevice(e,t){"Enter"!==e.key&&" "!==e.key||"view"!==this._mode&&"devices"!==this._mode||(e.preventDefault(),this._clickDevice(e,t))}_startDevicePressFeedback(e){const t=[...this.renderRoot.querySelectorAll(".dev[data-id]")].find(t=>t.dataset.id===e),i=t?.querySelector(".device-shell");if(!i||"function"!=typeof i.animate)return;const n=Number.parseFloat(this.ownerDocument.defaultView?.getComputedStyle(i).scale||""),r=Number.isFinite(n)?Math.max(.95,Math.min(1,n)):1;this._devicePressAnimations.get(e)?.cancel();const o=this._reducedMotion?[{outlineColor:"transparent",outlineStyle:"solid",outlineWidth:"0px"},{outlineColor:"var(--hp-accent, #3ea6ff)",outlineStyle:"solid",outlineWidth:"2px",outlineOffset:"2px",offset:.5},{outlineColor:"transparent",outlineStyle:"solid",outlineWidth:"0px"}]:[{scale:String(r)},{scale:"0.95",offset:.5},{scale:"1"}],s=i.animate(o,{duration:200,easing:"cubic-bezier(.22,.61,.36,1)"});this._devicePressAnimations.set(e,s);const a=()=>{this._devicePressAnimations.get(e)===s&&this._devicePressAnimations.delete(e)};s.addEventListener("finish",a,{once:!0}),s.addEventListener("cancel",a,{once:!0})}_cancelDevicePressFeedback(){for(const e of this._devicePressAnimations.values())e.cancel();this._devicePressAnimations.clear()}_pruneDevicePressFeedback(){if(!this._devicePressAnimations.size)return;const e=new Set([...this.renderRoot.querySelectorAll(".dev[data-id]")].map(e=>e.dataset.id||""));for(const[t,i]of this._devicePressAnimations)e.has(t)||(i.cancel(),this._devicePressAnimations.delete(t))}_t(e,t){return xp(kp(this.hass,this._config?.language),e,t)}get _colorPickerLabels(){return{title:this._t("color_picker.title"),hue:this._t("color_picker.hue"),saturation:this._t("color_picker.saturation"),value:this._t("color_picker.value"),hex:this._t("color_picker.hex"),invalidHex:this._t("color_picker.invalid_hex"),confirm:this._t("color_picker.confirm")}}_help(e){return this._editorRuntimeOrThrow()._help(e)}get _stageEl(){return this.renderRoot.querySelector(".stage")}_contentItems(e){const t=[];for(const i of this._devices){if(i.space!==e.id||i.hidden)continue;const n=this._pos(i);t.push({minX:n.x,minY:n.y,maxX:n.x,maxY:n.y})}if(e.id===this._space){for(const e of this._openingsR){const i=Number(e.angle)*Math.PI/180,n=Math.cos(i)*e.rlen/2,r=Math.sin(i)*e.rlen/2,o=pl([[e.rx-n,e.ry-r],[e.rx+n,e.ry+r]]);o&&t.push(o)}const i=this._decorH;for(const e of this._decorList){if("image"===e.kind&&!this._decorAssets.has(e.asset_id)&&"decor"!==this._mode)continue;const n=pl("line"===e.kind?[[e.x1*_v,e.y1*i],[e.x2*_v,e.y2*i]]:"text"===e.kind?[[e.x*_v,e.y*i]]:Nr({x:e.x*_v,y:e.y*i,w:e.w*_v,h:e.h*i,angle:e.angle}));n&&t.push(n)}for(const i of this._physicalBodiesR(e)){const e=pl(i);e&&t.push(e)}}return vl(e,t)}_frameOf(){const e=this._spaceModel();if(!e){this._frame=null;const e={x:0,y:0,w:_v,h:_v};return{rect:e,all:e,outliers:0}}const t=this._frame,i="view"!==this._mode;if(t&&t.id===e.id&&this._bdDrag)return t;if(t&&t.id===e.id&&t.model===e&&t.layout===this._layout&&t.devs===this._devices&&t.far===this._showFar&&t.grow===i)return t;const n=kl(this._contentItems(e));let r=n.all||Sl(e),o=this._showFar?r:n.core||Sl(e);return t&&t.id===e.id&&i&&t.grow&&(o=mv(t.rect,o),r=mv(t.all,r)),this._frame={id:e.id,model:e,layout:this._layout,devs:this._devices,far:this._showFar,grow:i,rect:o,all:r,outliers:n.outliers},this._frame}_isoSource(){const e=this._isoSceneRuntime;if(!e)return null;const t=this._spaceModel();if(!t)return null;const i=this._spaceWalls,n=this._openCuts(),r=this._openingsR;return e.createIsoStructuralSource({space:t,walls:i,openCuts:n,openings:r,partitionCuts:()=>this._partitionOpeningCuts(t),roomOpenings:()=>this._roomWallOpeningInputs(r,t),cellCm:this._cellCm,gridPitch:this._gridPitch,wallKeyPitch:this._wallKeyPitch,coordinateScale:_v,onBuild:()=>{this._isoStructuralBuildCount+=1}})}_isoSceneKey(){if(!this._labsIso||"view"!==this._mode)return null;try{return this._isoSource()?.key??null}catch{return this._isoInvalidKey()}}_isoInvalidKey(){return`${this._space}|invalid|${this._cfgEpoch}`}_clearIsoInvalidFallback(e){const t=`${this._space}|invalid|`;for(const i of this._isoFallback)i.startsWith(t)&&i!==e&&this._isoFallback.delete(i)}_isoScene(e=this._isoSource()){const t=this._isoSceneRuntime;if(!t||!e)return null;let i=this._frameOf().rect;const n=this._spaceDisplayForRender(),r=this._spaceModel();if(r&&n.showNames)for(const e of r.rooms)if(e.name){const t=this._labelPos(e,r.id);i=mv(i,{x:t.x,y:t.y,w:0,h:0})}const o=t.resolveIsoScene({source:e,cache:this._isoGeometryCache,cellCm:this._cellCm,liveFrame:i});if(!r||!n.showBorders)return o;const s=this._config?.icon_size??2.5,a=s>8?2.5:s,l=this._stageEl?.getBoundingClientRect?.()??null,c=l?.height?l.width/l.height:o.frame.w/o.frame.h,h=Oi([o.frame.x,o.frame.y,o.frame.w,o.frame.h],c),d=this._isoOverlayScene(r,this._renderDevices.filter(e=>e.space===r.id&&!e.hidden),h,n,t.resolveIsoDecorationLayers(n),o,a,x_(a),n.showLqi??this._config?.show_signal??!0,!1),u=d&&t.resolveIsoOverlayFitEnvelope({baseBounds:o.frame,entries:d.entries,stageSize:l,targetView:e=>Oi([e.x,e.y,e.w,e.h],c)});return u?{...o,frame:u.bounds,overlayFitEntries:d.entries}:o}_latchIsoFallback(e,t){if(this._isoFallback.has(e))return;this._isoFallback.add(e);const i=e.includes("|invalid|")?"invalid":e.split("|").pop()||"invalid";console.warn("HOUSEPLAN ISO FALLBACK: #89/#160",wf("structural",i,!0))}_effectiveProjection(){if(this._isoProjectionSnapshot)return this._isoProjectionSnapshot;const e=e=>this._isoProjectionSnapshot=e,t=()=>("iso"===this._renderProjection&&(this._cancelCameraTransition(!1),this._view=null,this._viewModeSnap=null),e("flat"));if(this._renderIsoScene=null,"iso"!==this._desiredProjection||!this._model.length||!this._isoSceneRuntime)return e("flat");if(!this._spaceDisplayForRender().showBorders)return this._isoFallback.has(`${this._space}|no-borders`)?t():e("iso");let i=this._isoInvalidKey();if(this._clearIsoInvalidFallback(i),this._isoFallback.has(i))return t();try{const n=this._isoSource();if(!n)return e("flat");if(i=n.key,this._isoFallback.has(i))return t();const r=this._isoScene(n);return r?this._isoFallback.has(r.key)?t():(this._renderIsoScene=r,e("iso")):e("flat")}catch(e){return this._latchIsoFallback(i,e),t()}}_scenePoint(e){return"iso"===this._renderProjection?lf(e,0):e}_floorView(e){if("iso"!==this._renderProjection)return e;const t=cf([e.x,e.y]),i=cf([e.x+e.w,e.y+e.h]);return{x:t[0],y:t[1],w:i[0]-t[0],h:i[1]-t[1]}}_isoOverlayScene(e,t,i,n,r,o,s,a,l,c=!0){const h=this._isoSceneRuntime;return h&&r?.structural&&o?h.buildIsoOverlayRenderScene({space:e,devices:t,openings:this._openingsR,view:i,display:n,wallSilhouettes:o.wallSilhouettes,resolveCollisions:c,iconPct:s,deviceBasePct:a,showLqi:l,cellCm:this._cellCm,kioskIconScale:"view"===this._mode?this._kioskScale.icon:1,kioskFontScale:"view"===this._mode?this._kioskScale.font:1,stageSize:this._stageEl?.getBoundingClientRect?.(),positionOf:e=>this._pos(e),presentationOf:(e,t)=>this._devicePresentation(e,t),labelPositionOf:(e,t)=>this._labelPos(e,t),labelScaleOf:e=>this._labelScale(e),openingEntityAvailable:e=>this._renderOpeningEntityAvailable(e),openingWallIndex:()=>this._openingWallIndexFor(e,this._openCuts()).value}):null}_baseVb(e=this._effectiveProjection(),t=this._renderIsoScene){if("iso"===e){if(!this._spaceDisplayForRender().showBorders){const e=uf({rect:this._frameOf().rect,wallHeight:0});return[e.x,e.y,e.w,e.h]}const e=t?.frame??this._frameOf().rect;return[e.x,e.y,e.w,e.h]}const i=this._frameOf().rect;return[i.x,i.y,i.w,i.h]}get _outliers(){return this._showFar?0:this._frameOf().outliers}_fitFar(){this._clearRoomFocus(),this._showFar=!0,this._frame=null,this.requestUpdate(),this._resetZoom()}_clearRoomFocus(e=!1){this._doubleFit.clear(),this._roomFocus=null,e&&(this._roomPointer=null)}_roomFitBounds(e,t){const i=ni(e);if(!i||!e.id)return null;const n=this._spaceWalls,r=this._openCuts(),o=this._wallUnionGeometry(),s=n.length&&this._innerRoomContour(t,e.id,r,o?.roomGeom,o?.multiWallNodes)||i,a=this._spaceDisplayForRender();let l=[];if(a.showBorders&&n.length){const i=Fs(t.rooms,e.id,n,r,this._wallKeyPitch,this._cellCm,this._gridPitch,_v);i&&(l=aa(i.poly,i.offsets,o?.multiWallNodes)||i.poly)}const c=this._effectiveProjection();return function(e){const t=e.floor,i=e.wall||[],n=e.padding??0;if(!t.length||!t.every(vf)||!i.every(vf)||!Number.isFinite(n)||n<0)return null;if("flat"===e.projection)return bf([...t,...i],n);const r=e.wallHeight??0,o=e.floorDepth??0;if(!Number.isFinite(r)||r<0||!Number.isFinite(o)||o<0)return null;try{const e=[];for(const i of t){const t=[i[0],i[1]];e.push(lf(t,0)),o>0&&e.push(lf(t,-o))}for(const t of i){const i=[t[0],t[1]];e.push(lf(i,0)),r>0&&e.push(lf(i,r))}return bf(e,n)}catch{return null}}({floor:s,wall:l,projection:c,wallHeight:"iso"===c&&a.showBorders?Wa(84,this._cellCm):0,floorDepth:"iso"===c&&a.showBorders?Wa(10,this._cellCm):0,padding:a.showBorders?Wa(1.25,this._cellCm):0})}_fitRoom(e,t=!0){if("view"!==this._mode)return!1;this._doubleFit.clear();const i=this._spaceModel(),n=i?.rooms.find(t=>t.id===e);if(!i||!n)return this._clearRoomFocus(),!1;let r=this._roomFitBounds(n,i);if(!r)return this._clearRoomFocus(),!1;this._roomFocus={spaceId:i.id,roomId:e};const o=this._stageEl;if(!o||o.clientWidth<=0||o.clientHeight<=0)return!0;const s=Oi(this._baseVb(),o.clientWidth/o.clientHeight),a=e=>function(e){const t=e.safeFraction??.8,{bounds:i,baseFit:n,stageWidth:r,stageHeight:o,minZoom:s,maxZoom:a}=e;if(!yf(i)||!yf(n)||!Number.isFinite(r)||r<=0||!Number.isFinite(o)||o<=0||!Number.isFinite(s)||s<=0||!Number.isFinite(a)||a1)return null;const l=r/o,c=Math.max(i.w/t,i.h/t*l);if(!Number.isFinite(c)||c<=0)return null;const h=Math.min(a,Math.max(s,n.w/c)),d=n.w/h,u=d/l;return{zoom:h,viewBox:{x:i.x+i.w/2-d/2,y:i.y+i.h/2-u/2,w:d,h:u}}}({bounds:e,baseFit:s,stageWidth:o.clientWidth,stageHeight:o.clientHeight,minZoom:wv.ZOOM_MIN,maxZoom:wv.ZOOM_MAX});let l=a(r);const c=this._isoSceneRuntime,h=this._renderIsoScene?.overlayFitEntries;if(l&&"iso"===this._effectiveProjection()&&c&&h?.length){const e=c.resolveIsoOverlayFitEnvelope({baseBounds:r,entries:h,ownerId:n.id,stageSize:{width:o.clientWidth,height:o.clientHeight},targetView:e=>a(e)?.viewBox??null});e&&(r=e.bounds,l=a(r))}if(!l)return this._clearRoomFocus(),!1;const d=this._cameraState(),u=function(e,t,i,n){const r=[e,t,i,n],o=Math.min(...r.map(e=>e.x)),s=Math.min(...r.map(e=>e.y));return{x:o,y:s,w:Math.max(...r.map(e=>e.x+e.w))-o,h:Math.max(...r.map(e=>e.y+e.h))-s}}(s,d.viewBox,l.viewBox,r);return l.viewBox=this._clampView(l.viewBox,u),t?(this._prepareCameraCommand(),this._startCameraTransition(l,u,"room",220),!0):(this._cancelCameraTransition(!1),Xg(d,l)||(this._zoom=l.zoom,this._view={...l.viewBox},this.requestUpdate()),!0)}_fitAll(e="fit"){this._clearRoomFocus(),this._showFar=!0,this._frame=null,this.requestUpdate(),this._resetZoom(e)}_renderFarHint(){return this._kiosk||"view"!==this._mode||this._booting||!this._outliers?G:j`
${this._t("canvas.far_objects",{n:this._outliers})}
this._fitFar()}>${this._t("canvas.show_far")}
@@ -816,7 +816,7 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="33e3bf530b13e01b6cc86d437770676c1644
${this._renderOpeningLocks(S,R?.locks)}
${g.showNames||this._markup?a.rooms.map(e=>this._renderRoomLabel(e,a,S,g,R?.rooms.get(e))):G}
${this._markup?a.rooms.map(e=>this._renderRoomGear(e,a,S)):G}
- ${q={hass:this.hass,settings:this._settings,devices:this._renderDevices,registry:this._haRegistry,currentSpace:a.id,spaces:this._serverCfg?.spaces,viewKey:S,view:"view"===this._mode,kiosk:this._kiosk},q.view&&!q.kiosk&&!0===q.hass?.user?.is_admin&&zg(q.settings).enabled?(import("./hp-zigbee-topology-overlay-B-TXG5n3.js"),j` `):G}
diff --git a/custom_components/houseplan/frontend/houseplan-assets/houseplan-editor-runtime-DCSkoKEw.js b/custom_components/houseplan/frontend/houseplan-assets/houseplan-editor-runtime-BXjfKYAx.js
similarity index 99%
rename from custom_components/houseplan/frontend/houseplan-assets/houseplan-editor-runtime-DCSkoKEw.js
rename to custom_components/houseplan/frontend/houseplan-assets/houseplan-editor-runtime-BXjfKYAx.js
index 0529a4f7..f1cf638b 100644
--- a/custom_components/houseplan/frontend/houseplan-assets/houseplan-editor-runtime-DCSkoKEw.js
+++ b/custom_components/houseplan/frontend/houseplan-assets/houseplan-editor-runtime-BXjfKYAx.js
@@ -1,4 +1,4 @@
-globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="33e3bf530b13e01b6cc86d437770676c16441418afa14b0324be617fc2d3bb22";import{e as t,i as e,E as s,s as i,a as o,n as a,f as n,b as r,l,o as h,r as c,A as d,c as p,d as u,g as _,h as m,v as g,j as f,k as b,m as v,p as y,q as w,t as $,u as k,w as x,T as M,x as C,y as S,D as P,z as D,B as I,C as L,F as T,G as R,H as z,I as F,J as N,K as A,L as E,M as O,N as B,O as H,P as W,Q as j,R as G,S as q,U,V as K,W as V,X as J,Y as Z,Z as Y,_ as X,$ as Q,a0 as tt,a1 as et,a2 as st,a3 as it,a4 as ot,a5 as at,a6 as nt,a7 as rt,a8 as lt,a9 as ht,aa as ct,ab as dt,ac as pt,ad as ut,ae as _t,af as mt,ag as gt,ah as ft,ai as bt,aj as vt,ak as yt,al as wt,am as $t,an as kt,ao as xt,ap as Mt,aq as Ct,ar as St,as as Pt,at as Dt,au as It,av as Lt,aw as Tt,ax as Rt,ay as zt,az as Ft,aA as Nt,aB as At,aC as Et,aD as Ot,aE as Bt,aF as Ht,aG as Wt,aH as jt,aI as Gt,aJ as qt,aK as Ut,aL as Kt,aM as Vt,aN as Jt,aO as Zt,aP as Yt,aQ as Xt,aR as Qt,aS as te,aT as ee,aU as se,aV as ie,aW as oe,aX as ae,aY as ne,aZ as re,a_ as le,a$ as he,b0 as ce,b1 as de,b2 as pe,b3 as ue,b4 as _e,b5 as me,b6 as ge,b7 as fe,b8 as be,b9 as ve,ba as ye,bb as we,bc as $e,bd as ke,be as xe,bf as Me,bg as Ce,bh as Se,bi as Pe,bj as De,bk as Ie,bl as Le,bm as Te,bn as Re,bo as ze,bp as Fe,bq as Ne,br as Ae,bs as Ee,bt as Oe,bu as Be,bv as He,bw as We,bx as je,by as Ge,bz as qe,bA as Ue,bB as Ke,bC as Ve,bD as Je,bE as Ze,bF as Ye,bG as Xe,bH as Qe,bI as ts,bJ as es,bK as ss,bL as is,bM as os,bN as as,bO as ns,bP as rs,bQ as ls,bR as hs,bS as cs,bT as ds,bU as ps,bV as us,bW as _s,bX as ms,bY as gs,bZ as fs,b_ as bs,b$ as vs,c0 as ys,c1 as ws,c2 as $s,c3 as ks,c4 as xs,c5 as Ms,c6 as Cs,c7 as Ss,c8 as Ps,c9 as Ds,ca as Is,cb as Ls,cc as Ts,cd as Rs,ce as zs,cf as Fs,cg as Ns,ch as As,ci as Es,cj as Os,ck as Bs,cl as Hs,cm as Ws,cn as js,co as Gs,cp as qs,cq as Us,cr as Ks,cs as Vs,ct as Js,cu as Zs,cv as Ys,cw as Xs,cx as Qs,cy as ti,cz as ei,cA as si,cB as ii,cC as oi,cD as ai,cE as ni,cF as ri,cG as li,cH as hi,cI as ci,cJ as di,cK as pi,cL as ui,cM as _i,cN as mi,cO as gi,cP as fi,cQ as bi,cR as vi,cS as yi,cT as wi,cU as $i,cV as ki,cW as xi,cX as Mi,cY as Ci,cZ as Si,c_ as Pi,c$ as Di,d0 as Ii,d1 as Li,d2 as Ti,d3 as Ri,d4 as zi,d5 as Fi,d6 as Ni,d7 as Ai,d8 as Ei,d9 as Oi,da as Bi,db as Hi,dc as Wi,dd as ji,de as Gi,df as qi,dg as Ui,dh as Ki,di as Vi,dj as Ji,dk as Zi,dl as Yi,dm as Xi,dn as Qi,dp as to,dq as eo,dr as so,ds as io,dt as oo,du as ao,dv as no,dw as ro,dx as lo,dy as ho,dz as co,dA as po,dB as uo}from"./houseplan-card-B1GLwcbS.js";import{r as _o,s as mo,d as go,f as fo,e as bo,a as vo,c as yo,t as wo,b as $o,g as ko,h as xo,i as Mo,j as Co,k as So,l as Po,m as Do,u as Io,n as Lo,o as To,p as Ro,q as zo,v as Fo,w as No,x as Ao,y as Eo,z as Oo,F as Bo,A as Ho,B as Wo,C as jo,D as Go,E as qo,G as Uo,H as Ko,I as Vo,J as Jo,K as Zo}from"./backdrop-pick-CpXppwyK.js";import{h as Yo,t as Xo,m as Qo,T as ta}from"./zigbee-topology-0vQ1r_Y7.js";import{GENERATED_FURNITURE_ART as ea,FURNITURE_ART_FINGERPRINT as sa}from"./furniture-plan-art.generated-B89AgatN.js";import"./form-kit.styles-B2L2lNpH.js";const ia={},oa=t(class extends e{constructor(){super(...arguments),this.ot=ia}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 s}else if(this.ot===e)return s;return this.ot=Array.isArray(e)?Array.from(e):e,this.render(e,i)}});var aa={"gs.show_room_tooltip":"Show the room information window on hover","support.about_group":"About the card","support.guide_group":"Documentation","support.guide":"User guide","support.form_group":"Send a report or suggestion","support.contact":"Contact details (email/tg/WhatsApp), optional.","support.message":"Message","support.attach":"Attach anonymized information from your plan","support.attach_hint":"Includes only allowed plan geometry, settings and bounded runtime facts. Excludes names, Home Assistant IDs, live states, URLs, files, and your message/contact.","support.geometry_warning":"The package contains no names or Home Assistant IDs, but it does contain the exact geometry and dimensions of your home.","support.close_busy_title":"Stop the current operation?","support.close_busy_body":"House Plan is preparing or sending the report. Closing now stops waiting for the result.","support.building":"Preparing anonymized data…","support.preview_summary":"Package v{version} · {spaces} spaces · {size} KiB","support.prepared":"Snapshot prepared {n} min ago","support.show_data":"Show data","support.download":"Download JSON","support.refresh":"Refresh snapshot","support.privacy":"When you send, your message, optional contact and, if selected, exact geometry leave your Home Assistant through the House Plan project relay and are visible to maintainers. The project node keeps the report for up to 30 days. Network infrastructure sees your HA server address, but House Plan does not retain it raw; rate-limit and idempotency metadata is kept for up to 24 hours.","support.error_title":"The report was not sent","support.manual_recovery":"You can keep the message and attachment and continue manually:","support.copy_message":"Copy message","support.success":"Report sent: {id}. Save this number when contacting support.","support.copy_id":"Copy ID","support.sending":"Sending…","support.retry":"Retry","support.send":"Send","support.update_required":"Update the House Plan card and integration to compatible versions to send reports.","support.message_copied":"Message copied","support.id_copied":"Report ID copied","support.copy_failed":"Could not access the clipboard. Select and copy the text manually.","support.validation.message_required":"Enter a message.","support.validation.message_too_long":"The message must contain no more than 10,000 characters.","support.validation.contact_too_long":"Contact details must contain no more than 320 characters.","support.validation.preview_missing":"Wait for the attachment preview or turn the attachment off.","support.validation.preview_expired":"The attachment preview expired. Refresh the snapshot.","support.error.support_invalid_message":"Check the message and try again.","support.error.support_preview_expired":"The attachment preview expired or is no longer available. Refresh the snapshot.","support.error.support_package_too_large":"The anonymized package exceeds the 8 MiB limit.","support.error.support_rate_limited":"Too many reports or previews were requested. Try again later.","support.error.support_unavailable":"The private support service is temporarily unavailable. Your draft remains here.","support.error.support_rejected":"The report did not pass the support service validation.","support.error.unauthorized":"You do not have permission to send this report.","vac.routes_section":"Maps and floors","vac.routes_current_map":"Current map","vac.routes_no_map":"no telemetry","vac.routes_status":"Routing","vac.routes_state_ready":"map assigned and calibrated","vac.routes_state_needs_calibration":"map assigned, calibration needed","vac.routes_state_unmapped":"current map is not assigned to a floor","vac.routes_state_ambiguous":"two maps are indistinguishable — no floor is chosen","vac.routes_state_missing_space":"the map's space was deleted","vac.routes_state_none":"no map data","vac.routes_empty":"No map is assigned to a floor yet.","vac.route_map_default":"no map id","vac.route_active":"Active","vac.route_space":"Space","vac.route_space_none":"not selected","vac.route_status_ready":"ready","vac.route_status_needs_calibration":"needs calibration","vac.route_status_ambiguous":"ambiguous","vac.route_status_missing_space":"space deleted","vac.route_missing_space_group":"Deleted space","vac.route_add_current":"Add current map","vac.route_delete":"Remove map","vac.route_delete_title":"Remove the map from its floor?","vac.route_delete_body":"Calibration and saved paths for this map will be removed. Continue?","vac.route_delete_confirm":"Remove","vac.route_space_title":"Move the map to another space?","vac.route_space_body":"Calibration and saved paths for this map will be removed. Continue?","vac.route_space_confirm":"Move","vac.route_missing_space_hint":"One of the maps points at a deleted space: pick a new one or remove the map. Until then the robot is not drawn for that map.","vac.route_default_hint":"The source reports no stable map id. Several floors cannot be told apart without another source or the robot's own selected map.","vac.route_target_hint":"The dock stays in the “{space}” space regardless of the current map.","vac.route_add_source":"Add a map source","vac.route_add_source_hint":"For integrations that give each map its own camera. The “All cameras” section above widens this list.","vac.route_source_no_map":"no map reported"};const na={en:aa,ru:{"gs.show_room_tooltip":"Показывать окно с информацией при наведении на комнату","support.about_group":"О карточке","support.guide_group":"Документация","support.guide":"Руководство пользователя","support.form_group":"Отправить репорт или предложение","support.contact":"Контакт для связи (email/tg/WhatsApp), необязательно.","support.message":"Сообщение","support.attach":"Прикрепить обезличенную информацию из вашего плана","support.attach_hint":"В пакет входят только разрешённые геометрия, настройки и ограниченные сведения о среде. Не входят имена, HA id, текущие состояния, URL, файлы, сообщение и контакт.","support.geometry_warning":"Пакет не содержит имён и HA id, но содержит точную геометрию и размеры дома.","support.close_busy_title":"Прервать текущую операцию?","support.close_busy_body":"House Plan подготавливает или отправляет репорт. При закрытии ожидание результата прекратится.","support.building":"Подготавливаем обезличенные данные…","support.preview_summary":"Пакет v{version} · пространств: {spaces} · {size} КиБ","support.prepared":"Снимок подготовлен {n} мин назад","support.show_data":"Показать данные","support.download":"Скачать JSON","support.refresh":"Обновить снимок","support.privacy":"При отправке сообщение, необязательный контакт и, если выбран пакет, точная геометрия покидают ваш Home Assistant через relay проекта House Plan и доступны мейнтейнерам. Узел проекта хранит репорт до 30 дней. Сетевая инфраструктура видит адрес сервера HA, но House Plan не сохраняет его в исходном виде; метаданные лимитов и идемпотентности хранятся до 24 часов.","support.error_title":"Репорт не отправлен","support.manual_recovery":"Сообщение и вложение можно сохранить и продолжить вручную:","support.copy_message":"Копировать сообщение","support.success":"Репорт отправлен: {id}. Сохраните номер для связи с поддержкой.","support.copy_id":"Копировать ID","support.sending":"Отправляем…","support.retry":"Повторить","support.send":"Отправить","support.update_required":"Обновите карточку и интеграцию House Plan до совместимых версий, чтобы отправлять репорты.","support.message_copied":"Сообщение скопировано","support.id_copied":"ID репорта скопирован","support.copy_failed":"Не удалось получить доступ к буферу обмена. Выделите и скопируйте текст вручную.","support.validation.message_required":"Введите сообщение.","support.validation.message_too_long":"Сообщение должно содержать не более 10 000 символов.","support.validation.contact_too_long":"Контакт должен содержать не более 320 символов.","support.validation.preview_missing":"Дождитесь предпросмотра вложения или отключите его.","support.validation.preview_expired":"Предпросмотр вложения истёк. Обновите снимок.","support.error.support_invalid_message":"Проверьте сообщение и повторите попытку.","support.error.support_preview_expired":"Предпросмотр вложения истёк или больше недоступен. Обновите снимок.","support.error.support_package_too_large":"Обезличенный пакет превышает лимит 8 МиБ.","support.error.support_rate_limited":"Запрошено слишком много репортов или предпросмотров. Повторите позже.","support.error.support_unavailable":"Закрытая служба поддержки временно недоступна. Черновик сохранён в этом окне.","support.error.support_rejected":"Репорт не прошёл проверку службы поддержки.","support.error.unauthorized":"У вас нет прав на отправку этого репорта.","vac.routes_section":"Карты и этажи","vac.routes_current_map":"Текущая карта","vac.routes_no_map":"источник молчит","vac.routes_status":"Маршрутизация","vac.routes_state_ready":"карта сопоставлена и откалибрована","vac.routes_state_needs_calibration":"карта сопоставлена, нужна калибровка","vac.routes_state_unmapped":"текущая карта не сопоставлена этажу","vac.routes_state_ambiguous":"две карты неразличимы — этаж не выбирается","vac.routes_state_missing_space":"пространство карты удалено","vac.routes_state_none":"нет данных о карте","vac.routes_empty":"Ни одна карта ещё не сопоставлена этажу.","vac.route_map_default":"без идентификатора","vac.route_active":"Текущая","vac.route_space":"Пространство","vac.route_space_none":"не выбрано","vac.route_status_ready":"готова","vac.route_status_needs_calibration":"нужна калибровка","vac.route_status_ambiguous":"неоднозначна","vac.route_status_missing_space":"пространство удалено","vac.route_missing_space_group":"Пространство удалено","vac.route_add_current":"Добавить текущую карту","vac.route_delete":"Удалить карту","vac.route_delete_title":"Удалить карту с этажа?","vac.route_delete_body":"Калибровка и сохранённые пути этой карты будут удалены. Продолжить?","vac.route_delete_confirm":"Удалить","vac.route_space_title":"Перенести карту в другое пространство?","vac.route_space_body":"Калибровка и сохранённые пути этой карты будут удалены. Продолжить?","vac.route_space_confirm":"Перенести","vac.route_missing_space_hint":"Одна из карт ссылается на удалённое пространство: выберите новое или удалите карту. Пока ссылка не исправлена, робот на этой карте не рисуется.","vac.route_default_hint":"Источник не сообщает стабильный идентификатор карты. Несколько этажей нельзя различить без другого источника или собственной карты робота.","vac.route_target_hint":"Док остаётся в пространстве «{space}» независимо от текущей карты.","vac.route_add_source":"Добавить источник карты","vac.route_add_source_hint":"Для интеграций, где у каждой карты своя камера. Список расширяется разделом «Все камеры» выше.","vac.route_source_no_map":"карта не читается"},de:{"gs.show_room_tooltip":"Rauminformationen beim Darüberfahren anzeigen","support.about_group":"Über die Karte","support.guide_group":"Dokumentation","support.guide":"Benutzerhandbuch","support.form_group":"Bericht oder Vorschlag senden","support.contact":"Kontakt (E-Mail/tg/WhatsApp), optional.","support.message":"Nachricht","support.attach":"Anonymisierte Informationen aus dem Plan anhängen","support.attach_hint":"Enthält nur erlaubte Plangeometrie, Einstellungen und begrenzte Laufzeitdaten. Namen, Home-Assistant-IDs, Live-Zustände, URLs, Dateien, Nachricht und Kontakt werden ausgeschlossen.","support.geometry_warning":"Das Paket enthält keine Namen oder Home-Assistant-IDs, aber die exakte Geometrie und die Maße Ihres Hauses.","support.close_busy_title":"Aktuellen Vorgang abbrechen?","support.close_busy_body":"House Plan bereitet den Bericht vor oder sendet ihn. Beim Schließen wird nicht weiter auf das Ergebnis gewartet.","support.building":"Anonymisierte Daten werden vorbereitet…","support.preview_summary":"Paket v{version} · {spaces} Bereiche · {size} KiB","support.prepared":"Schnappschuss vor {n} Min. erstellt","support.show_data":"Daten anzeigen","support.download":"JSON herunterladen","support.refresh":"Schnappschuss aktualisieren","support.privacy":"Beim Senden verlassen Ihre Nachricht, der optionale Kontakt und, falls ausgewählt, die exakte Geometrie Ihren Home Assistant über das House-Plan-Projektrelay und sind für die Maintainer sichtbar. Der Projektserver speichert den Bericht bis zu 30 Tage. Die Netzwerkinfrastruktur sieht die Adresse Ihres HA-Servers, House Plan speichert sie jedoch nicht im Rohformat; Limit- und Idempotenzdaten bleiben bis zu 24 Stunden erhalten.","support.error_title":"Der Bericht wurde nicht gesendet","support.manual_recovery":"Nachricht und Anhang können gespeichert und manuell weitergegeben werden:","support.copy_message":"Nachricht kopieren","support.success":"Bericht gesendet: {id}. Bewahren Sie diese Nummer für den Support auf.","support.copy_id":"ID kopieren","support.sending":"Wird gesendet…","support.retry":"Erneut versuchen","support.send":"Senden","support.update_required":"Aktualisieren Sie House-Plan-Karte und Integration auf kompatible Versionen, um Berichte zu senden.","support.message_copied":"Nachricht kopiert","support.id_copied":"Berichts-ID kopiert","support.copy_failed":"Kein Zugriff auf die Zwischenablage. Markieren und kopieren Sie den Text manuell.","support.validation.message_required":"Geben Sie eine Nachricht ein.","support.validation.message_too_long":"Die Nachricht darf höchstens 10.000 Zeichen enthalten.","support.validation.contact_too_long":"Der Kontakt darf höchstens 320 Zeichen enthalten.","support.validation.preview_missing":"Warten Sie auf die Vorschau oder deaktivieren Sie den Anhang.","support.validation.preview_expired":"Die Anhangsvorschau ist abgelaufen. Aktualisieren Sie den Schnappschuss.","support.error.support_invalid_message":"Prüfen Sie die Nachricht und versuchen Sie es erneut.","support.error.support_preview_expired":"Die Anhangsvorschau ist abgelaufen oder nicht mehr verfügbar. Aktualisieren Sie den Schnappschuss.","support.error.support_package_too_large":"Das anonymisierte Paket überschreitet das Limit von 8 MiB.","support.error.support_rate_limited":"Zu viele Berichte oder Vorschauen wurden angefordert. Versuchen Sie es später erneut.","support.error.support_unavailable":"Der private Supportdienst ist vorübergehend nicht verfügbar. Der Entwurf bleibt in diesem Fenster erhalten.","support.error.support_rejected":"Der Bericht hat die Prüfung des Supportdienstes nicht bestanden.","support.error.unauthorized":"Sie dürfen diesen Bericht nicht senden.","vac.routes_section":"Karten und Etagen","vac.routes_current_map":"Aktuelle Karte","vac.routes_no_map":"keine Telemetrie","vac.routes_status":"Zuordnung","vac.routes_state_ready":"Karte zugeordnet und kalibriert","vac.routes_state_needs_calibration":"Karte zugeordnet, Kalibrierung nötig","vac.routes_state_unmapped":"aktuelle Karte keiner Etage zugeordnet","vac.routes_state_ambiguous":"zwei Karten nicht unterscheidbar — keine Etage gewählt","vac.routes_state_missing_space":"der Raum der Karte wurde gelöscht","vac.routes_state_none":"keine Kartendaten","vac.routes_empty":"Noch keine Karte einer Etage zugeordnet.","vac.route_map_default":"ohne Karten-ID","vac.route_active":"Aktiv","vac.route_space":"Raum","vac.route_space_none":"nicht gewählt","vac.route_status_ready":"bereit","vac.route_status_needs_calibration":"Kalibrierung nötig","vac.route_status_ambiguous":"mehrdeutig","vac.route_status_missing_space":"Raum gelöscht","vac.route_missing_space_group":"Gelöschter Bereich","vac.route_add_current":"Aktuelle Karte hinzufügen","vac.route_delete":"Karte entfernen","vac.route_delete_title":"Karte von der Etage entfernen?","vac.route_delete_body":"Kalibrierung und gespeicherte Pfade dieser Karte werden entfernt. Fortfahren?","vac.route_delete_confirm":"Entfernen","vac.route_space_title":"Karte in einen anderen Raum verschieben?","vac.route_space_body":"Kalibrierung und gespeicherte Pfade dieser Karte werden entfernt. Fortfahren?","vac.route_space_confirm":"Verschieben","vac.route_missing_space_hint":"Eine Karte verweist auf einen gelöschten Raum: neuen wählen oder Karte entfernen. Bis dahin wird der Roboter für diese Karte nicht gezeichnet.","vac.route_default_hint":"Die Quelle meldet keine stabile Karten-ID. Mehrere Etagen lassen sich ohne andere Quelle oder die vom Roboter gewählte Karte nicht unterscheiden.","vac.route_target_hint":"Die Station bleibt unabhängig von der aktuellen Karte im Raum „{space}“.","vac.route_add_source":"Kartenquelle hinzufügen","vac.route_add_source_hint":"Für Integrationen, die jeder Karte eine eigene Kamera geben. Der Abschnitt „Alle Kameras“ oben erweitert diese Liste.","vac.route_source_no_map":"keine Karte gemeldet"},fr:{"gs.show_room_tooltip":"Afficher les informations de la pièce au survol","support.about_group":"À propos de la carte","support.guide_group":"Documentation d’aide","support.guide":"Guide utilisateur","support.form_group":"Envoyer un rapport ou une suggestion","support.contact":"Contact (e-mail/tg/WhatsApp), facultatif.","support.message":"Votre message","support.attach":"Joindre des informations anonymisées de votre plan","support.attach_hint":"Inclut uniquement la géométrie, les réglages autorisés et des données d’exécution limitées. Exclut les noms, identifiants Home Assistant, états en direct, URL, fichiers, message et contact.","support.geometry_warning":"Le paquet ne contient ni noms ni identifiants Home Assistant, mais il contient la géométrie et les dimensions exactes de votre logement.","support.close_busy_title":"Interrompre l’opération en cours ?","support.close_busy_body":"House Plan prépare ou envoie le rapport. Fermer maintenant arrête l’attente du résultat.","support.building":"Préparation des données anonymisées…","support.preview_summary":"Paquet v{version} · {spaces} espaces · {size} Kio","support.prepared":"Instantané préparé il y a {n} min","support.show_data":"Afficher les données","support.download":"Télécharger le JSON","support.refresh":"Actualiser l’instantané","support.privacy":"Lors de l’envoi, votre message, le contact facultatif et, si elle est sélectionnée, la géométrie exacte quittent votre Home Assistant via le relais du projet House Plan et sont visibles par les mainteneurs. Le serveur du projet conserve le rapport jusqu’à 30 jours. L’infrastructure réseau voit l’adresse de votre serveur HA, mais House Plan ne la conserve pas en clair ; les métadonnées de limitation et d’idempotence sont gardées jusqu’à 24 heures.","support.error_title":"Le rapport n’a pas été envoyé","support.manual_recovery":"Vous pouvez conserver le message et la pièce jointe puis continuer manuellement :","support.copy_message":"Copier le message","support.success":"Rapport envoyé : {id}. Conservez ce numéro pour contacter l’assistance.","support.copy_id":"Copier l’ID","support.sending":"Envoi…","support.retry":"Réessayer","support.send":"Envoyer","support.update_required":"Mettez à jour la carte et l’intégration House Plan vers des versions compatibles pour envoyer des rapports.","support.message_copied":"Message copié","support.id_copied":"ID du rapport copié","support.copy_failed":"Impossible d’accéder au presse-papiers. Sélectionnez et copiez le texte manuellement.","support.validation.message_required":"Saisissez un message.","support.validation.message_too_long":"Le message ne doit pas dépasser 10 000 caractères.","support.validation.contact_too_long":"Le contact ne doit pas dépasser 320 caractères.","support.validation.preview_missing":"Attendez l’aperçu de la pièce jointe ou désactivez-la.","support.validation.preview_expired":"L’aperçu de la pièce jointe a expiré. Actualisez l’instantané.","support.error.support_invalid_message":"Vérifiez le message et réessayez.","support.error.support_preview_expired":"L’aperçu de la pièce jointe a expiré ou n’est plus disponible. Actualisez l’instantané.","support.error.support_package_too_large":"Le paquet anonymisé dépasse la limite de 8 Mio.","support.error.support_rate_limited":"Trop de rapports ou d’aperçus ont été demandés. Réessayez plus tard.","support.error.support_unavailable":"Le service d’assistance privé est temporairement indisponible. Le brouillon reste dans cette fenêtre.","support.error.support_rejected":"Le rapport n’a pas passé la validation du service d’assistance.","support.error.unauthorized":"Vous n’êtes pas autorisé à envoyer ce rapport.","vac.routes_section":"Cartes et étages","vac.routes_current_map":"Carte actuelle","vac.routes_no_map":"aucune télémétrie","vac.routes_status":"Routage","vac.routes_state_ready":"carte assignée et calibrée","vac.routes_state_needs_calibration":"carte assignée, calibrage requis","vac.routes_state_unmapped":"carte actuelle non assignée à un étage","vac.routes_state_ambiguous":"deux cartes indiscernables — aucun étage choisi","vac.routes_state_missing_space":"l'espace de la carte a été supprimé","vac.routes_state_none":"aucune donnée de carte","vac.routes_empty":"Aucune carte n'est encore assignée à un étage.","vac.route_map_default":"sans identifiant","vac.route_active":"Active","vac.route_space":"Espace","vac.route_space_none":"non sélectionné","vac.route_status_ready":"prête","vac.route_status_needs_calibration":"calibrage requis","vac.route_status_ambiguous":"ambiguë","vac.route_status_missing_space":"espace supprimé","vac.route_missing_space_group":"Espace supprimé","vac.route_add_current":"Ajouter la carte actuelle","vac.route_delete":"Supprimer la carte","vac.route_delete_title":"Retirer la carte de son étage ?","vac.route_delete_body":"Le calibrage et les trajets enregistrés de cette carte seront supprimés. Continuer ?","vac.route_delete_confirm":"Supprimer","vac.route_space_title":"Déplacer la carte vers un autre espace ?","vac.route_space_body":"Le calibrage et les trajets enregistrés de cette carte seront supprimés. Continuer ?","vac.route_space_confirm":"Déplacer","vac.route_missing_space_hint":"Une carte pointe vers un espace supprimé : choisissez-en un autre ou supprimez la carte. D'ici là, le robot n'est pas dessiné pour cette carte.","vac.route_default_hint":"La source ne fournit pas d'identifiant de carte stable. Plusieurs étages ne peuvent pas être distingués sans une autre source ou la carte sélectionnée du robot.","vac.route_target_hint":"La station reste dans l'espace « {space} » quelle que soit la carte actuelle.","vac.route_add_source":"Ajouter une source de carte","vac.route_add_source_hint":"Pour les intégrations qui donnent à chaque carte sa propre caméra. La section « Toutes les caméras » ci-dessus élargit cette liste.","vac.route_source_no_map":"aucune carte signalée"}};function ra(t,e,s){return i(na[t]?.[e]??aa[e]??e,s)}function la(t,e,s,i,o){return{markerId:t,source:i,mapId:o,space:e.length?"":s}}function ha(t,e,s){return{...t,space:s.has(e)?e:""}}function ca(t,e=Math.random){const s=new Set(t);for(let t=0;t<64;t+=1){const t="vr_"+Math.floor(16777215*e()).toString(36).padStart(5,"0");if(!s.has(t))return t}return"vr_"+Date.now().toString(36)}function da(t,e,s){return t.map(t=>t.id===e?{...t,calibration:s}:t)}const pa=new WeakMap,ua=(t,e)=>{const s=(t._serverCfg?.spaces||[]).find(t=>t?.id===e);return String(s?.name||s?.id||e)};function _a(t,e,s){const i=t.host,n=l(i.hass,i._config?.language),r=(t,e)=>ra(n,t,e),u=e.marker?.vacuum||{},_=Array.isArray(u.map_routes),m=i._vacSource(e)||"",g=o(e.id,u,e.space,m),f=(i._serverCfg?.spaces||[]).filter(t=>"string"==typeof t?.id&&!!t.id).map(t=>({id:t.id,name:String(t.name||t.id)})),b=new Set(f.map(t=>t.id)),v=h(g,[m],t=>i._vacObservedMapId(e,t)),y=c({routes:g,observed:v,spaceIds:b}),w="ready"===y.kind||"needs_calibration"===y.kind||"missing_space"===y.kind?y.route.id:"",$=m?v[m]:void 0,k=async s=>{let o=_?u.map_routes??null:null;if(!o&&(o=function(t,e,s,i){if(!s)return null;const o=t?.calibration;if(!o||"object"!=typeof o)return null;const n=new Set,r=[];for(const t of Object.keys(o)){const l=a(o[t]);if(!l)continue;const h=i(n);n.add(h),r.push({id:h,source:s,map_id:t,space:e,calibration:l})}return r.length?r:null}(u,e.space,m,t=>ca(t))??[],!m&&Object.keys(u.calibration||{}).length))return!1;const n=s(o);return!!n&&(async s=>{const o=i._serverCfg;if(!o)return!1;const a=JSON.parse(JSON.stringify(o));a.markers=a.markers||[];let n=a.markers.find(t=>t.id===e.id);if(!n){if("device"!==e.bindingKind&&"entity"!==e.bindingKind||!e.bindingRef)return!1;n={id:e.id,binding:`${e.bindingKind}:${e.bindingRef}`,space:e.space||null,area:e.area||null,hidden:!!e.hidden},a.markers.push(n)}n.vacuum={...n.vacuum||{},map_routes:s},delete n.vacuum.calibration;const r=i._adoption.beginOptimistic(o,a);i._adoption.stageLocalConfig(a),i._regSignature="",i._maybeRebuildDevices(),i.requestUpdate(),i._saveConfigDebounced.pending()&&i._saveConfigDebounced.cancel();try{return await t._saveConfigNow(),!0}catch(t){return i._rollbackOptimistic(r),i._regSignature="",i._maybeRebuildDevices(),i.requestUpdate(),i._showToast(i._t("toast.cfg_save_failed",{err:i._errText(t)})),!1}})(n)},x=s.candidates.filter(t=>t.entityId!==m&&!g.some(e=>e.source===t.entityId)),M=async(t,e)=>{if(!e||e===t.space)return;await i._confirmDanger({key:"vacuum_route_space",kind:"warning",title:r("vac.route_space_title"),message:r("vac.route_space_body"),objectName:t.map_id||r("vac.route_map_default"),confirmLabel:r("vac.route_space_confirm"),cancelLabel:i._t("btn.cancel")})&&await k(s=>function(t,e,s,i){return t.map(t=>t.id===e?{...t,id:i,space:s,calibration:null}:t)}(s,t.id,e,ca(new Set(g.map(t=>t.id)))))},C=new Map(f.map((t,e)=>[t.id,e])),S=(t,e)=>t.map_id.localeCompare(e.map_id)||t.source.localeCompare(e.source)||t.id.localeCompare(e.id),P=g.filter(t=>b.has(t.space)).sort((t,e)=>(C.get(t.space)??0)-(C.get(e.space)??0)||S(t,e)),D=g.filter(t=>!b.has(t.space)).sort(S),I=[...P,...D],L=!!m&&void 0!==$&&!g.some(t=>t.source===m&&t.map_id===$);let T=pa.get(t);const R=T?.source||"",z=T?.mapId||"",F=!!T&&g.some(t=>t.source===R&&t.map_id===z);T&&(T.markerId!==e.id||i._vacObservedMapId(e,T.source)!==T.mapId||F&&!T.saving)&&(pa.delete(t),T=void 0),T?.space&&!b.has(T.space)&&(T=ha(T,"",b),pa.set(t,T));const N=s=>p`
+globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="44c8db0207714f5476f58cdacdfaae63754967422e492b7fadf3551ecaee4380";import{e as t,i as e,E as s,s as i,a as o,n as a,f as n,b as r,l,o as h,r as c,A as d,c as p,d as u,g as _,h as m,v as g,j as f,k as b,m as v,p as y,q as w,t as $,u as k,w as x,T as M,x as C,y as S,D as P,z as D,B as I,C as L,F as T,G as R,H as z,I as F,J as N,K as A,L as E,M as O,N as B,O as H,P as W,Q as j,R as G,S as q,U,V as K,W as V,X as J,Y as Z,Z as Y,_ as X,$ as Q,a0 as tt,a1 as et,a2 as st,a3 as it,a4 as ot,a5 as at,a6 as nt,a7 as rt,a8 as lt,a9 as ht,aa as ct,ab as dt,ac as pt,ad as ut,ae as _t,af as mt,ag as gt,ah as ft,ai as bt,aj as vt,ak as yt,al as wt,am as $t,an as kt,ao as xt,ap as Mt,aq as Ct,ar as St,as as Pt,at as Dt,au as It,av as Lt,aw as Tt,ax as Rt,ay as zt,az as Ft,aA as Nt,aB as At,aC as Et,aD as Ot,aE as Bt,aF as Ht,aG as Wt,aH as jt,aI as Gt,aJ as qt,aK as Ut,aL as Kt,aM as Vt,aN as Jt,aO as Zt,aP as Yt,aQ as Xt,aR as Qt,aS as te,aT as ee,aU as se,aV as ie,aW as oe,aX as ae,aY as ne,aZ as re,a_ as le,a$ as he,b0 as ce,b1 as de,b2 as pe,b3 as ue,b4 as _e,b5 as me,b6 as ge,b7 as fe,b8 as be,b9 as ve,ba as ye,bb as we,bc as $e,bd as ke,be as xe,bf as Me,bg as Ce,bh as Se,bi as Pe,bj as De,bk as Ie,bl as Le,bm as Te,bn as Re,bo as ze,bp as Fe,bq as Ne,br as Ae,bs as Ee,bt as Oe,bu as Be,bv as He,bw as We,bx as je,by as Ge,bz as qe,bA as Ue,bB as Ke,bC as Ve,bD as Je,bE as Ze,bF as Ye,bG as Xe,bH as Qe,bI as ts,bJ as es,bK as ss,bL as is,bM as os,bN as as,bO as ns,bP as rs,bQ as ls,bR as hs,bS as cs,bT as ds,bU as ps,bV as us,bW as _s,bX as ms,bY as gs,bZ as fs,b_ as bs,b$ as vs,c0 as ys,c1 as ws,c2 as $s,c3 as ks,c4 as xs,c5 as Ms,c6 as Cs,c7 as Ss,c8 as Ps,c9 as Ds,ca as Is,cb as Ls,cc as Ts,cd as Rs,ce as zs,cf as Fs,cg as Ns,ch as As,ci as Es,cj as Os,ck as Bs,cl as Hs,cm as Ws,cn as js,co as Gs,cp as qs,cq as Us,cr as Ks,cs as Vs,ct as Js,cu as Zs,cv as Ys,cw as Xs,cx as Qs,cy as ti,cz as ei,cA as si,cB as ii,cC as oi,cD as ai,cE as ni,cF as ri,cG as li,cH as hi,cI as ci,cJ as di,cK as pi,cL as ui,cM as _i,cN as mi,cO as gi,cP as fi,cQ as bi,cR as vi,cS as yi,cT as wi,cU as $i,cV as ki,cW as xi,cX as Mi,cY as Ci,cZ as Si,c_ as Pi,c$ as Di,d0 as Ii,d1 as Li,d2 as Ti,d3 as Ri,d4 as zi,d5 as Fi,d6 as Ni,d7 as Ai,d8 as Ei,d9 as Oi,da as Bi,db as Hi,dc as Wi,dd as ji,de as Gi,df as qi,dg as Ui,dh as Ki,di as Vi,dj as Ji,dk as Zi,dl as Yi,dm as Xi,dn as Qi,dp as to,dq as eo,dr as so,ds as io,dt as oo,du as ao,dv as no,dw as ro,dx as lo,dy as ho,dz as co,dA as po,dB as uo}from"./houseplan-card-BQWwo3i7.js";import{r as _o,s as mo,d as go,f as fo,e as bo,a as vo,c as yo,t as wo,b as $o,g as ko,h as xo,i as Mo,j as Co,k as So,l as Po,m as Do,u as Io,n as Lo,o as To,p as Ro,q as zo,v as Fo,w as No,x as Ao,y as Eo,z as Oo,F as Bo,A as Ho,B as Wo,C as jo,D as Go,E as qo,G as Uo,H as Ko,I as Vo,J as Jo,K as Zo}from"./backdrop-pick-D57BQQbo.js";import{h as Yo,t as Xo,m as Qo,T as ta}from"./zigbee-topology-DThgDHY1.js";import{GENERATED_FURNITURE_ART as ea,FURNITURE_ART_FINGERPRINT as sa}from"./furniture-plan-art.generated-CiyoNIND.js";import"./form-kit.styles-BqBbEnaz.js";const ia={},oa=t(class extends e{constructor(){super(...arguments),this.ot=ia}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 s}else if(this.ot===e)return s;return this.ot=Array.isArray(e)?Array.from(e):e,this.render(e,i)}});var aa={"gs.show_room_tooltip":"Show the room information window on hover","support.about_group":"About the card","support.guide_group":"Documentation","support.guide":"User guide","support.form_group":"Send a report or suggestion","support.contact":"Contact details (email/tg/WhatsApp), optional.","support.message":"Message","support.attach":"Attach anonymized information from your plan","support.attach_hint":"Includes only allowed plan geometry, settings and bounded runtime facts. Excludes names, Home Assistant IDs, live states, URLs, files, and your message/contact.","support.geometry_warning":"The package contains no names or Home Assistant IDs, but it does contain the exact geometry and dimensions of your home.","support.close_busy_title":"Stop the current operation?","support.close_busy_body":"House Plan is preparing or sending the report. Closing now stops waiting for the result.","support.building":"Preparing anonymized data…","support.preview_summary":"Package v{version} · {spaces} spaces · {size} KiB","support.prepared":"Snapshot prepared {n} min ago","support.show_data":"Show data","support.download":"Download JSON","support.refresh":"Refresh snapshot","support.privacy":"When you send, your message, optional contact and, if selected, exact geometry leave your Home Assistant through the House Plan project relay and are visible to maintainers. The project node keeps the report for up to 30 days. Network infrastructure sees your HA server address, but House Plan does not retain it raw; rate-limit and idempotency metadata is kept for up to 24 hours.","support.error_title":"The report was not sent","support.manual_recovery":"You can keep the message and attachment and continue manually:","support.copy_message":"Copy message","support.success":"Report sent: {id}. Save this number when contacting support.","support.copy_id":"Copy ID","support.sending":"Sending…","support.retry":"Retry","support.send":"Send","support.update_required":"Update the House Plan card and integration to compatible versions to send reports.","support.message_copied":"Message copied","support.id_copied":"Report ID copied","support.copy_failed":"Could not access the clipboard. Select and copy the text manually.","support.validation.message_required":"Enter a message.","support.validation.message_too_long":"The message must contain no more than 10,000 characters.","support.validation.contact_too_long":"Contact details must contain no more than 320 characters.","support.validation.preview_missing":"Wait for the attachment preview or turn the attachment off.","support.validation.preview_expired":"The attachment preview expired. Refresh the snapshot.","support.error.support_invalid_message":"Check the message and try again.","support.error.support_preview_expired":"The attachment preview expired or is no longer available. Refresh the snapshot.","support.error.support_package_too_large":"The anonymized package exceeds the 8 MiB limit.","support.error.support_rate_limited":"Too many reports or previews were requested. Try again later.","support.error.support_unavailable":"The private support service is temporarily unavailable. Your draft remains here.","support.error.support_rejected":"The report did not pass the support service validation.","support.error.unauthorized":"You do not have permission to send this report.","vac.routes_section":"Maps and floors","vac.routes_current_map":"Current map","vac.routes_no_map":"no telemetry","vac.routes_status":"Routing","vac.routes_state_ready":"map assigned and calibrated","vac.routes_state_needs_calibration":"map assigned, calibration needed","vac.routes_state_unmapped":"current map is not assigned to a floor","vac.routes_state_ambiguous":"two maps are indistinguishable — no floor is chosen","vac.routes_state_missing_space":"the map's space was deleted","vac.routes_state_none":"no map data","vac.routes_empty":"No map is assigned to a floor yet.","vac.route_map_default":"no map id","vac.route_active":"Active","vac.route_space":"Space","vac.route_space_none":"not selected","vac.route_status_ready":"ready","vac.route_status_needs_calibration":"needs calibration","vac.route_status_ambiguous":"ambiguous","vac.route_status_missing_space":"space deleted","vac.route_missing_space_group":"Deleted space","vac.route_add_current":"Add current map","vac.route_delete":"Remove map","vac.route_delete_title":"Remove the map from its floor?","vac.route_delete_body":"Calibration and saved paths for this map will be removed. Continue?","vac.route_delete_confirm":"Remove","vac.route_space_title":"Move the map to another space?","vac.route_space_body":"Calibration and saved paths for this map will be removed. Continue?","vac.route_space_confirm":"Move","vac.route_missing_space_hint":"One of the maps points at a deleted space: pick a new one or remove the map. Until then the robot is not drawn for that map.","vac.route_default_hint":"The source reports no stable map id. Several floors cannot be told apart without another source or the robot's own selected map.","vac.route_target_hint":"The dock stays in the “{space}” space regardless of the current map.","vac.route_add_source":"Add a map source","vac.route_add_source_hint":"For integrations that give each map its own camera. The “All cameras” section above widens this list.","vac.route_source_no_map":"no map reported"};const na={en:aa,ru:{"gs.show_room_tooltip":"Показывать окно с информацией при наведении на комнату","support.about_group":"О карточке","support.guide_group":"Документация","support.guide":"Руководство пользователя","support.form_group":"Отправить репорт или предложение","support.contact":"Контакт для связи (email/tg/WhatsApp), необязательно.","support.message":"Сообщение","support.attach":"Прикрепить обезличенную информацию из вашего плана","support.attach_hint":"В пакет входят только разрешённые геометрия, настройки и ограниченные сведения о среде. Не входят имена, HA id, текущие состояния, URL, файлы, сообщение и контакт.","support.geometry_warning":"Пакет не содержит имён и HA id, но содержит точную геометрию и размеры дома.","support.close_busy_title":"Прервать текущую операцию?","support.close_busy_body":"House Plan подготавливает или отправляет репорт. При закрытии ожидание результата прекратится.","support.building":"Подготавливаем обезличенные данные…","support.preview_summary":"Пакет v{version} · пространств: {spaces} · {size} КиБ","support.prepared":"Снимок подготовлен {n} мин назад","support.show_data":"Показать данные","support.download":"Скачать JSON","support.refresh":"Обновить снимок","support.privacy":"При отправке сообщение, необязательный контакт и, если выбран пакет, точная геометрия покидают ваш Home Assistant через relay проекта House Plan и доступны мейнтейнерам. Узел проекта хранит репорт до 30 дней. Сетевая инфраструктура видит адрес сервера HA, но House Plan не сохраняет его в исходном виде; метаданные лимитов и идемпотентности хранятся до 24 часов.","support.error_title":"Репорт не отправлен","support.manual_recovery":"Сообщение и вложение можно сохранить и продолжить вручную:","support.copy_message":"Копировать сообщение","support.success":"Репорт отправлен: {id}. Сохраните номер для связи с поддержкой.","support.copy_id":"Копировать ID","support.sending":"Отправляем…","support.retry":"Повторить","support.send":"Отправить","support.update_required":"Обновите карточку и интеграцию House Plan до совместимых версий, чтобы отправлять репорты.","support.message_copied":"Сообщение скопировано","support.id_copied":"ID репорта скопирован","support.copy_failed":"Не удалось получить доступ к буферу обмена. Выделите и скопируйте текст вручную.","support.validation.message_required":"Введите сообщение.","support.validation.message_too_long":"Сообщение должно содержать не более 10 000 символов.","support.validation.contact_too_long":"Контакт должен содержать не более 320 символов.","support.validation.preview_missing":"Дождитесь предпросмотра вложения или отключите его.","support.validation.preview_expired":"Предпросмотр вложения истёк. Обновите снимок.","support.error.support_invalid_message":"Проверьте сообщение и повторите попытку.","support.error.support_preview_expired":"Предпросмотр вложения истёк или больше недоступен. Обновите снимок.","support.error.support_package_too_large":"Обезличенный пакет превышает лимит 8 МиБ.","support.error.support_rate_limited":"Запрошено слишком много репортов или предпросмотров. Повторите позже.","support.error.support_unavailable":"Закрытая служба поддержки временно недоступна. Черновик сохранён в этом окне.","support.error.support_rejected":"Репорт не прошёл проверку службы поддержки.","support.error.unauthorized":"У вас нет прав на отправку этого репорта.","vac.routes_section":"Карты и этажи","vac.routes_current_map":"Текущая карта","vac.routes_no_map":"источник молчит","vac.routes_status":"Маршрутизация","vac.routes_state_ready":"карта сопоставлена и откалибрована","vac.routes_state_needs_calibration":"карта сопоставлена, нужна калибровка","vac.routes_state_unmapped":"текущая карта не сопоставлена этажу","vac.routes_state_ambiguous":"две карты неразличимы — этаж не выбирается","vac.routes_state_missing_space":"пространство карты удалено","vac.routes_state_none":"нет данных о карте","vac.routes_empty":"Ни одна карта ещё не сопоставлена этажу.","vac.route_map_default":"без идентификатора","vac.route_active":"Текущая","vac.route_space":"Пространство","vac.route_space_none":"не выбрано","vac.route_status_ready":"готова","vac.route_status_needs_calibration":"нужна калибровка","vac.route_status_ambiguous":"неоднозначна","vac.route_status_missing_space":"пространство удалено","vac.route_missing_space_group":"Пространство удалено","vac.route_add_current":"Добавить текущую карту","vac.route_delete":"Удалить карту","vac.route_delete_title":"Удалить карту с этажа?","vac.route_delete_body":"Калибровка и сохранённые пути этой карты будут удалены. Продолжить?","vac.route_delete_confirm":"Удалить","vac.route_space_title":"Перенести карту в другое пространство?","vac.route_space_body":"Калибровка и сохранённые пути этой карты будут удалены. Продолжить?","vac.route_space_confirm":"Перенести","vac.route_missing_space_hint":"Одна из карт ссылается на удалённое пространство: выберите новое или удалите карту. Пока ссылка не исправлена, робот на этой карте не рисуется.","vac.route_default_hint":"Источник не сообщает стабильный идентификатор карты. Несколько этажей нельзя различить без другого источника или собственной карты робота.","vac.route_target_hint":"Док остаётся в пространстве «{space}» независимо от текущей карты.","vac.route_add_source":"Добавить источник карты","vac.route_add_source_hint":"Для интеграций, где у каждой карты своя камера. Список расширяется разделом «Все камеры» выше.","vac.route_source_no_map":"карта не читается"},de:{"gs.show_room_tooltip":"Rauminformationen beim Darüberfahren anzeigen","support.about_group":"Über die Karte","support.guide_group":"Dokumentation","support.guide":"Benutzerhandbuch","support.form_group":"Bericht oder Vorschlag senden","support.contact":"Kontakt (E-Mail/tg/WhatsApp), optional.","support.message":"Nachricht","support.attach":"Anonymisierte Informationen aus dem Plan anhängen","support.attach_hint":"Enthält nur erlaubte Plangeometrie, Einstellungen und begrenzte Laufzeitdaten. Namen, Home-Assistant-IDs, Live-Zustände, URLs, Dateien, Nachricht und Kontakt werden ausgeschlossen.","support.geometry_warning":"Das Paket enthält keine Namen oder Home-Assistant-IDs, aber die exakte Geometrie und die Maße Ihres Hauses.","support.close_busy_title":"Aktuellen Vorgang abbrechen?","support.close_busy_body":"House Plan bereitet den Bericht vor oder sendet ihn. Beim Schließen wird nicht weiter auf das Ergebnis gewartet.","support.building":"Anonymisierte Daten werden vorbereitet…","support.preview_summary":"Paket v{version} · {spaces} Bereiche · {size} KiB","support.prepared":"Schnappschuss vor {n} Min. erstellt","support.show_data":"Daten anzeigen","support.download":"JSON herunterladen","support.refresh":"Schnappschuss aktualisieren","support.privacy":"Beim Senden verlassen Ihre Nachricht, der optionale Kontakt und, falls ausgewählt, die exakte Geometrie Ihren Home Assistant über das House-Plan-Projektrelay und sind für die Maintainer sichtbar. Der Projektserver speichert den Bericht bis zu 30 Tage. Die Netzwerkinfrastruktur sieht die Adresse Ihres HA-Servers, House Plan speichert sie jedoch nicht im Rohformat; Limit- und Idempotenzdaten bleiben bis zu 24 Stunden erhalten.","support.error_title":"Der Bericht wurde nicht gesendet","support.manual_recovery":"Nachricht und Anhang können gespeichert und manuell weitergegeben werden:","support.copy_message":"Nachricht kopieren","support.success":"Bericht gesendet: {id}. Bewahren Sie diese Nummer für den Support auf.","support.copy_id":"ID kopieren","support.sending":"Wird gesendet…","support.retry":"Erneut versuchen","support.send":"Senden","support.update_required":"Aktualisieren Sie House-Plan-Karte und Integration auf kompatible Versionen, um Berichte zu senden.","support.message_copied":"Nachricht kopiert","support.id_copied":"Berichts-ID kopiert","support.copy_failed":"Kein Zugriff auf die Zwischenablage. Markieren und kopieren Sie den Text manuell.","support.validation.message_required":"Geben Sie eine Nachricht ein.","support.validation.message_too_long":"Die Nachricht darf höchstens 10.000 Zeichen enthalten.","support.validation.contact_too_long":"Der Kontakt darf höchstens 320 Zeichen enthalten.","support.validation.preview_missing":"Warten Sie auf die Vorschau oder deaktivieren Sie den Anhang.","support.validation.preview_expired":"Die Anhangsvorschau ist abgelaufen. Aktualisieren Sie den Schnappschuss.","support.error.support_invalid_message":"Prüfen Sie die Nachricht und versuchen Sie es erneut.","support.error.support_preview_expired":"Die Anhangsvorschau ist abgelaufen oder nicht mehr verfügbar. Aktualisieren Sie den Schnappschuss.","support.error.support_package_too_large":"Das anonymisierte Paket überschreitet das Limit von 8 MiB.","support.error.support_rate_limited":"Zu viele Berichte oder Vorschauen wurden angefordert. Versuchen Sie es später erneut.","support.error.support_unavailable":"Der private Supportdienst ist vorübergehend nicht verfügbar. Der Entwurf bleibt in diesem Fenster erhalten.","support.error.support_rejected":"Der Bericht hat die Prüfung des Supportdienstes nicht bestanden.","support.error.unauthorized":"Sie dürfen diesen Bericht nicht senden.","vac.routes_section":"Karten und Etagen","vac.routes_current_map":"Aktuelle Karte","vac.routes_no_map":"keine Telemetrie","vac.routes_status":"Zuordnung","vac.routes_state_ready":"Karte zugeordnet und kalibriert","vac.routes_state_needs_calibration":"Karte zugeordnet, Kalibrierung nötig","vac.routes_state_unmapped":"aktuelle Karte keiner Etage zugeordnet","vac.routes_state_ambiguous":"zwei Karten nicht unterscheidbar — keine Etage gewählt","vac.routes_state_missing_space":"der Raum der Karte wurde gelöscht","vac.routes_state_none":"keine Kartendaten","vac.routes_empty":"Noch keine Karte einer Etage zugeordnet.","vac.route_map_default":"ohne Karten-ID","vac.route_active":"Aktiv","vac.route_space":"Raum","vac.route_space_none":"nicht gewählt","vac.route_status_ready":"bereit","vac.route_status_needs_calibration":"Kalibrierung nötig","vac.route_status_ambiguous":"mehrdeutig","vac.route_status_missing_space":"Raum gelöscht","vac.route_missing_space_group":"Gelöschter Bereich","vac.route_add_current":"Aktuelle Karte hinzufügen","vac.route_delete":"Karte entfernen","vac.route_delete_title":"Karte von der Etage entfernen?","vac.route_delete_body":"Kalibrierung und gespeicherte Pfade dieser Karte werden entfernt. Fortfahren?","vac.route_delete_confirm":"Entfernen","vac.route_space_title":"Karte in einen anderen Raum verschieben?","vac.route_space_body":"Kalibrierung und gespeicherte Pfade dieser Karte werden entfernt. Fortfahren?","vac.route_space_confirm":"Verschieben","vac.route_missing_space_hint":"Eine Karte verweist auf einen gelöschten Raum: neuen wählen oder Karte entfernen. Bis dahin wird der Roboter für diese Karte nicht gezeichnet.","vac.route_default_hint":"Die Quelle meldet keine stabile Karten-ID. Mehrere Etagen lassen sich ohne andere Quelle oder die vom Roboter gewählte Karte nicht unterscheiden.","vac.route_target_hint":"Die Station bleibt unabhängig von der aktuellen Karte im Raum „{space}“.","vac.route_add_source":"Kartenquelle hinzufügen","vac.route_add_source_hint":"Für Integrationen, die jeder Karte eine eigene Kamera geben. Der Abschnitt „Alle Kameras“ oben erweitert diese Liste.","vac.route_source_no_map":"keine Karte gemeldet"},fr:{"gs.show_room_tooltip":"Afficher les informations de la pièce au survol","support.about_group":"À propos de la carte","support.guide_group":"Documentation d’aide","support.guide":"Guide utilisateur","support.form_group":"Envoyer un rapport ou une suggestion","support.contact":"Contact (e-mail/tg/WhatsApp), facultatif.","support.message":"Votre message","support.attach":"Joindre des informations anonymisées de votre plan","support.attach_hint":"Inclut uniquement la géométrie, les réglages autorisés et des données d’exécution limitées. Exclut les noms, identifiants Home Assistant, états en direct, URL, fichiers, message et contact.","support.geometry_warning":"Le paquet ne contient ni noms ni identifiants Home Assistant, mais il contient la géométrie et les dimensions exactes de votre logement.","support.close_busy_title":"Interrompre l’opération en cours ?","support.close_busy_body":"House Plan prépare ou envoie le rapport. Fermer maintenant arrête l’attente du résultat.","support.building":"Préparation des données anonymisées…","support.preview_summary":"Paquet v{version} · {spaces} espaces · {size} Kio","support.prepared":"Instantané préparé il y a {n} min","support.show_data":"Afficher les données","support.download":"Télécharger le JSON","support.refresh":"Actualiser l’instantané","support.privacy":"Lors de l’envoi, votre message, le contact facultatif et, si elle est sélectionnée, la géométrie exacte quittent votre Home Assistant via le relais du projet House Plan et sont visibles par les mainteneurs. Le serveur du projet conserve le rapport jusqu’à 30 jours. L’infrastructure réseau voit l’adresse de votre serveur HA, mais House Plan ne la conserve pas en clair ; les métadonnées de limitation et d’idempotence sont gardées jusqu’à 24 heures.","support.error_title":"Le rapport n’a pas été envoyé","support.manual_recovery":"Vous pouvez conserver le message et la pièce jointe puis continuer manuellement :","support.copy_message":"Copier le message","support.success":"Rapport envoyé : {id}. Conservez ce numéro pour contacter l’assistance.","support.copy_id":"Copier l’ID","support.sending":"Envoi…","support.retry":"Réessayer","support.send":"Envoyer","support.update_required":"Mettez à jour la carte et l’intégration House Plan vers des versions compatibles pour envoyer des rapports.","support.message_copied":"Message copié","support.id_copied":"ID du rapport copié","support.copy_failed":"Impossible d’accéder au presse-papiers. Sélectionnez et copiez le texte manuellement.","support.validation.message_required":"Saisissez un message.","support.validation.message_too_long":"Le message ne doit pas dépasser 10 000 caractères.","support.validation.contact_too_long":"Le contact ne doit pas dépasser 320 caractères.","support.validation.preview_missing":"Attendez l’aperçu de la pièce jointe ou désactivez-la.","support.validation.preview_expired":"L’aperçu de la pièce jointe a expiré. Actualisez l’instantané.","support.error.support_invalid_message":"Vérifiez le message et réessayez.","support.error.support_preview_expired":"L’aperçu de la pièce jointe a expiré ou n’est plus disponible. Actualisez l’instantané.","support.error.support_package_too_large":"Le paquet anonymisé dépasse la limite de 8 Mio.","support.error.support_rate_limited":"Trop de rapports ou d’aperçus ont été demandés. Réessayez plus tard.","support.error.support_unavailable":"Le service d’assistance privé est temporairement indisponible. Le brouillon reste dans cette fenêtre.","support.error.support_rejected":"Le rapport n’a pas passé la validation du service d’assistance.","support.error.unauthorized":"Vous n’êtes pas autorisé à envoyer ce rapport.","vac.routes_section":"Cartes et étages","vac.routes_current_map":"Carte actuelle","vac.routes_no_map":"aucune télémétrie","vac.routes_status":"Routage","vac.routes_state_ready":"carte assignée et calibrée","vac.routes_state_needs_calibration":"carte assignée, calibrage requis","vac.routes_state_unmapped":"carte actuelle non assignée à un étage","vac.routes_state_ambiguous":"deux cartes indiscernables — aucun étage choisi","vac.routes_state_missing_space":"l'espace de la carte a été supprimé","vac.routes_state_none":"aucune donnée de carte","vac.routes_empty":"Aucune carte n'est encore assignée à un étage.","vac.route_map_default":"sans identifiant","vac.route_active":"Active","vac.route_space":"Espace","vac.route_space_none":"non sélectionné","vac.route_status_ready":"prête","vac.route_status_needs_calibration":"calibrage requis","vac.route_status_ambiguous":"ambiguë","vac.route_status_missing_space":"espace supprimé","vac.route_missing_space_group":"Espace supprimé","vac.route_add_current":"Ajouter la carte actuelle","vac.route_delete":"Supprimer la carte","vac.route_delete_title":"Retirer la carte de son étage ?","vac.route_delete_body":"Le calibrage et les trajets enregistrés de cette carte seront supprimés. Continuer ?","vac.route_delete_confirm":"Supprimer","vac.route_space_title":"Déplacer la carte vers un autre espace ?","vac.route_space_body":"Le calibrage et les trajets enregistrés de cette carte seront supprimés. Continuer ?","vac.route_space_confirm":"Déplacer","vac.route_missing_space_hint":"Une carte pointe vers un espace supprimé : choisissez-en un autre ou supprimez la carte. D'ici là, le robot n'est pas dessiné pour cette carte.","vac.route_default_hint":"La source ne fournit pas d'identifiant de carte stable. Plusieurs étages ne peuvent pas être distingués sans une autre source ou la carte sélectionnée du robot.","vac.route_target_hint":"La station reste dans l'espace « {space} » quelle que soit la carte actuelle.","vac.route_add_source":"Ajouter une source de carte","vac.route_add_source_hint":"Pour les intégrations qui donnent à chaque carte sa propre caméra. La section « Toutes les caméras » ci-dessus élargit cette liste.","vac.route_source_no_map":"aucune carte signalée"}};function ra(t,e,s){return i(na[t]?.[e]??aa[e]??e,s)}function la(t,e,s,i,o){return{markerId:t,source:i,mapId:o,space:e.length?"":s}}function ha(t,e,s){return{...t,space:s.has(e)?e:""}}function ca(t,e=Math.random){const s=new Set(t);for(let t=0;t<64;t+=1){const t="vr_"+Math.floor(16777215*e()).toString(36).padStart(5,"0");if(!s.has(t))return t}return"vr_"+Date.now().toString(36)}function da(t,e,s){return t.map(t=>t.id===e?{...t,calibration:s}:t)}const pa=new WeakMap,ua=(t,e)=>{const s=(t._serverCfg?.spaces||[]).find(t=>t?.id===e);return String(s?.name||s?.id||e)};function _a(t,e,s){const i=t.host,n=l(i.hass,i._config?.language),r=(t,e)=>ra(n,t,e),u=e.marker?.vacuum||{},_=Array.isArray(u.map_routes),m=i._vacSource(e)||"",g=o(e.id,u,e.space,m),f=(i._serverCfg?.spaces||[]).filter(t=>"string"==typeof t?.id&&!!t.id).map(t=>({id:t.id,name:String(t.name||t.id)})),b=new Set(f.map(t=>t.id)),v=h(g,[m],t=>i._vacObservedMapId(e,t)),y=c({routes:g,observed:v,spaceIds:b}),w="ready"===y.kind||"needs_calibration"===y.kind||"missing_space"===y.kind?y.route.id:"",$=m?v[m]:void 0,k=async s=>{let o=_?u.map_routes??null:null;if(!o&&(o=function(t,e,s,i){if(!s)return null;const o=t?.calibration;if(!o||"object"!=typeof o)return null;const n=new Set,r=[];for(const t of Object.keys(o)){const l=a(o[t]);if(!l)continue;const h=i(n);n.add(h),r.push({id:h,source:s,map_id:t,space:e,calibration:l})}return r.length?r:null}(u,e.space,m,t=>ca(t))??[],!m&&Object.keys(u.calibration||{}).length))return!1;const n=s(o);return!!n&&(async s=>{const o=i._serverCfg;if(!o)return!1;const a=JSON.parse(JSON.stringify(o));a.markers=a.markers||[];let n=a.markers.find(t=>t.id===e.id);if(!n){if("device"!==e.bindingKind&&"entity"!==e.bindingKind||!e.bindingRef)return!1;n={id:e.id,binding:`${e.bindingKind}:${e.bindingRef}`,space:e.space||null,area:e.area||null,hidden:!!e.hidden},a.markers.push(n)}n.vacuum={...n.vacuum||{},map_routes:s},delete n.vacuum.calibration;const r=i._adoption.beginOptimistic(o,a);i._adoption.stageLocalConfig(a),i._regSignature="",i._maybeRebuildDevices(),i.requestUpdate(),i._saveConfigDebounced.pending()&&i._saveConfigDebounced.cancel();try{return await t._saveConfigNow(),!0}catch(t){return i._rollbackOptimistic(r),i._regSignature="",i._maybeRebuildDevices(),i.requestUpdate(),i._showToast(i._t("toast.cfg_save_failed",{err:i._errText(t)})),!1}})(n)},x=s.candidates.filter(t=>t.entityId!==m&&!g.some(e=>e.source===t.entityId)),M=async(t,e)=>{if(!e||e===t.space)return;await i._confirmDanger({key:"vacuum_route_space",kind:"warning",title:r("vac.route_space_title"),message:r("vac.route_space_body"),objectName:t.map_id||r("vac.route_map_default"),confirmLabel:r("vac.route_space_confirm"),cancelLabel:i._t("btn.cancel")})&&await k(s=>function(t,e,s,i){return t.map(t=>t.id===e?{...t,id:i,space:s,calibration:null}:t)}(s,t.id,e,ca(new Set(g.map(t=>t.id)))))},C=new Map(f.map((t,e)=>[t.id,e])),S=(t,e)=>t.map_id.localeCompare(e.map_id)||t.source.localeCompare(e.source)||t.id.localeCompare(e.id),P=g.filter(t=>b.has(t.space)).sort((t,e)=>(C.get(t.space)??0)-(C.get(e.space)??0)||S(t,e)),D=g.filter(t=>!b.has(t.space)).sort(S),I=[...P,...D],L=!!m&&void 0!==$&&!g.some(t=>t.source===m&&t.map_id===$);let T=pa.get(t);const R=T?.source||"",z=T?.mapId||"",F=!!T&&g.some(t=>t.source===R&&t.map_id===z);T&&(T.markerId!==e.id||i._vacObservedMapId(e,T.source)!==T.mapId||F&&!T.saving)&&(pa.delete(t),T=void 0),T?.space&&!b.has(T.space)&&(T=ha(T,"",b),pa.set(t,T));const N=s=>p`
${s.map_id||r("vac.route_map_default")}
@@ -441,7 +441,7 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="33e3bf530b13e01b6cc86d437770676c1644
icon=${o?"mdi:cog-outline":"mdi:floor-plan"} @hp-close=${$}>
${n?p`
${n}
`:d}
- ${ko({id:"basics",title:e("room.group_basics"),body:To([xo({label:e("room.name_label"),htmlFor:"room-name",error:k?i(k.message):void 0,control:p`
{t._nameSel=e.target.value,t.requestUpdate()}} />`}),xo({label:e("room.area_label"),htmlFor:"room-area",help:this._help("room.group_basics.help"),control:p`
{t._areaSel=e.target.value,!t._nameSel&&t._areaSel&&(t._nameSel=t.hass.areas[t._areaSel]?.name||""),t.requestUpdate()}}>
@@ -653,7 +653,7 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="33e3bf530b13e01b6cc86d437770676c1644
`:d}
`}}pl.properties={hass:{attribute:!1},presentation:{attribute:!1},registry:{attribute:!1},deviceName:{attribute:!1}},pl.styles=[At,zt`:host{display:block;min-width:0;}.devicepreview{margin:4px 0 14px;padding:14px;border:1px solid var(--divider-color,rgba(127,127,127,0.28));border-radius:14px;background:color-mix(in srgb,var(--card-background-color,#20232b) 92%,var(--primary-color,#03a9f4));color:var(--primary-text-color,#fff);overflow:hidden;}.previewhead{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-bottom:12px;}.previewbadge{padding:3px 9px;border-radius:999px;color:var(--secondary-text-color,#9aa0aa);background:color-mix(in srgb,var(--secondary-text-color,#9aa0aa) 12%,transparent);font-size:12px;font-weight:700;}.previewbadge.example{color:var(--warning-color,#ffb300);}.previewgrid{display:grid;grid-template-columns:minmax(170px,0.8fr) minmax(240px,1.2fr);gap:16px;align-items:stretch;}.previewstage{position:relative;min-height:168px;border-radius:12px;background:var(--secondary-background-color,rgba(0,0,0,0.16));overflow:hidden;pointer-events:none;container-type:inline-size;--icon-size:54px;--device-base-size:48.6px;}.previewfit{position:absolute;left:50%;top:50%;transform-origin:center;}.previewstage .dev{left:0;top:0;cursor:default;}:host([data-pointer-hover]) .previewstage .dev:hover{z-index:2;}.previewfacts{min-width:0;display:grid;align-content:start;gap:8px;}.previewfacts>div{display:grid;grid-template-columns:minmax(115px,0.8fr) minmax(0,1.3fr);gap:8px;}.previewfacts span{color:var(--secondary-text-color,#9aa0aa);}.previewfacts b{min-width:0;overflow-wrap:anywhere;}.previewnotice{margin:2px 0 0;color:var(--secondary-text-color,#9aa0aa);font-size:13px;}.previewdetails{margin-top:12px;}.previewdetails summary{cursor:pointer;color:var(--secondary-text-color,#9aa0aa);}.previewtable{display:grid;gap:8px;margin-top:9px;}.previewsource{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:3px 10px;font-size:13px;}.previewsource>*{min-width:0;overflow-wrap:anywhere;}.previewsource code{color:var(--secondary-text-color,#9aa0aa);}.previewdemo{min-height:40px;display:inline-flex;align-items:center;gap:8px;padding:8px 12px;border:1px solid var(--divider-color,rgba(127,127,127,0.35));border-radius:10px;background:transparent;color:inherit;cursor:pointer;}.previewdemos{display:flex;flex-wrap:wrap;gap:8px;margin-top:12px;}.previewdemo:focus-visible{outline:2px solid var(--primary-color,#03a9f4);outline-offset:2px;}.previewdemo:disabled{opacity:0.5;cursor:not-allowed;}@media (max-width:640px){.previewgrid{grid-template-columns:minmax(0,1fr);}.previewstage{min-height:142px;}.previewfacts>div{grid-template-columns:minmax(0,1fr);gap:2px;}}`],customElements.get("hp-device-preview")||customElements.define("hp-device-preview",pl);const ul={revision:0,topologies:[],states:{}};class _l extends Ft{constructor(){super(...arguments),this.value={enabled:!1,z2mBaseTopics:[]},this.savedEnabled=!1,this.devices=[],this._runtime=null,this._snapshot=ul,this._topicText="zigbee2mqtt",this._invalidTopic=!1,this.embedded=!1}disconnectedCallback(){this._release?.(),this._release=void 0,super.disconnectedCallback()}updated(t){t.has("hass")&&(this._release?.(),this._release=void 0,this._runtime=null,this._snapshot=ul),this.savedEnabled&&this._admin&&this._ensureRuntime()}willUpdate(t){t.has("value")&&(this._topicText=(this.value.z2mBaseTopics.length?this.value.z2mBaseTopics:["zigbee2mqtt"]).join("\n"),this._invalidTopic=!1)}get _admin(){return!0===this.hass?.user?.is_admin}_t(t,e){return Xo(l(this.hass),t,e)}_help(){const t=l(this.hass);return Yo(t,"help")&&Yo(t,"help_aria")?p`
`:d}async _ensureRuntime(){return this._runtime||(this._runtime=await import("./zigbee-topology-runtime-DtATTFz4.js"),this._snapshot=this._runtime.zigbeeTopologyRuntimeSnapshot(this.hass),this._release=this._runtime.subscribeZigbeeTopology(this.hass,()=>{this._snapshot=this._runtime.zigbeeTopologyRuntimeSnapshot(this.hass),this.requestUpdate()}),this.requestUpdate()),this._runtime}_emit(t){this._admin&&this.dispatchEvent(new CustomEvent("hp-topology-settings-change",{detail:t,bubbles:!0,composed:!0}))}_topics(){return this.value.z2mBaseTopics.length?this.value.z2mBaseTopics:["zigbee2mqtt"]}_editTopics(t){this._topicText=t;const e=t.split(/[\r\n,]+/).map(t=>t.trim()).filter(Boolean),s=e.map(Gt).filter(Boolean);this._invalidTopic=s.length!==e.length,this._invalidTopic?this.requestUpdate():this._emit({...this.value,z2mBaseTopics:[...new Set(s)].slice(0,8)})}_status(t){const e=this._snapshot.states[t];if(!e)return this._t("status_idle");if("loading"===e.phase)return this._t("status_loading");if("error"===e.phase)return this._t(`error_${e.error||"provider"}`);if("ready"!==e.phase||!e.obtainedAt)return this._t("status_idle");const s=new Date(e.obtainedAt).toLocaleTimeString(l(this.hass),{hour:"2-digit",minute:"2-digit"}),i=this._snapshot.topologies.find(e=>"zha"===t?"zha"===e.provider:`z2m:${e.instanceId}`===t),o=!!i&&!!this.registry&&Qo(i,this.devices,this.registry).warnings.length>0;return e.partial||o?this._t("status_partial",{time:s}):i&&!i.links.length?this._t("status_no_links",{time:s}):this._t(Date.now()-e.obtainedAt>ta?"status_stale":"status_ready",{time:s})}_busy(t){return"loading"===this._snapshot.states[t]?.phase}async _readZha(){this.savedEnabled&&this._admin&&(await this._ensureRuntime()).readZhaTopology(this.hass)}async _refreshZ2m(t){this.savedEnabled&&this._admin&&(await this._ensureRuntime()).refreshZ2mTopology(this.hass,t)}render(){if(this.embedded)return this._renderEmbedded();const t=this._admin,e=this.value.enabled,s=t&&this.savedEnabled,i=this._topics();return p`
+ .ariaLabel=${this._t("help_aria")}>`:d}async _ensureRuntime(){return this._runtime||(this._runtime=await import("./zigbee-topology-runtime-C1Eof5a4.js"),this._snapshot=this._runtime.zigbeeTopologyRuntimeSnapshot(this.hass),this._release=this._runtime.subscribeZigbeeTopology(this.hass,()=>{this._snapshot=this._runtime.zigbeeTopologyRuntimeSnapshot(this.hass),this.requestUpdate()}),this.requestUpdate()),this._runtime}_emit(t){this._admin&&this.dispatchEvent(new CustomEvent("hp-topology-settings-change",{detail:t,bubbles:!0,composed:!0}))}_topics(){return this.value.z2mBaseTopics.length?this.value.z2mBaseTopics:["zigbee2mqtt"]}_editTopics(t){this._topicText=t;const e=t.split(/[\r\n,]+/).map(t=>t.trim()).filter(Boolean),s=e.map(Gt).filter(Boolean);this._invalidTopic=s.length!==e.length,this._invalidTopic?this.requestUpdate():this._emit({...this.value,z2mBaseTopics:[...new Set(s)].slice(0,8)})}_status(t){const e=this._snapshot.states[t];if(!e)return this._t("status_idle");if("loading"===e.phase)return this._t("status_loading");if("error"===e.phase)return this._t(`error_${e.error||"provider"}`);if("ready"!==e.phase||!e.obtainedAt)return this._t("status_idle");const s=new Date(e.obtainedAt).toLocaleTimeString(l(this.hass),{hour:"2-digit",minute:"2-digit"}),i=this._snapshot.topologies.find(e=>"zha"===t?"zha"===e.provider:`z2m:${e.instanceId}`===t),o=!!i&&!!this.registry&&Qo(i,this.devices,this.registry).warnings.length>0;return e.partial||o?this._t("status_partial",{time:s}):i&&!i.links.length?this._t("status_no_links",{time:s}):this._t(Date.now()-e.obtainedAt>ta?"status_stale":"status_ready",{time:s})}_busy(t){return"loading"===this._snapshot.states[t]?.phase}async _readZha(){this.savedEnabled&&this._admin&&(await this._ensureRuntime()).readZhaTopology(this.hass)}async _refreshZ2m(t){this.savedEnabled&&this._admin&&(await this._ensureRuntime()).refreshZ2mTopology(this.hass,t)}render(){if(this.embedded)return this._renderEmbedded();const t=this._admin,e=this.value.enabled,s=t&&this.savedEnabled,i=this._topics();return p`
${this._t("title")}${this._help()}
${customElements.get("ha-switch")?p`${this.host._t("btn.save")}
- `}}const yd=(t,e)=>t[0]*e[1]-t[1]*e[0],wd=(t,e)=>t[0]*e[0]+t[1]*e[1],$d=(t,e)=>[t[0]-e[0],t[1]-e[1]],kd=(t,e,s)=>[t[0]+e[0]*s,t[1]+e[1]*s];function xd(t,e,s){return Math.abs(yd(t,e))<=s}function Md(t,e,s){return Math.abs(yd($d(t,e),s))}function Cd(t,e,s,i,o){const a=e[0]-t[0],n=e[1]-t[1],r=Math.hypot(a,n);if(!(r>o&&s>0))return[];const l=[a/r,n/r];return function(t,e,s){const i=e.map(([e,s])=>[Math.max(0,Math.min(e,s)),Math.min(t,Math.max(e,s))]).filter(([t,e])=>e>t+s).sort((t,e)=>t[0]-e[0]||t[1]-e[1]),o=[];for(const t of i){const e=o[o.length-1];!e||t[0]>e[1]+s?o.push([...t]):e[1]=Math.max(e[1],t[1])}const a=[];let n=0;for(const[t,e]of o)t>n+s&&a.push([n,t]),n=Math.max(n,e);return t>n+s&&a.push([n,t]),a}(r,i.flatMap(e=>{const i=e.b[0]-e.a[0],a=e.b[1]-e.a[1],n=Math.hypot(i,a);if(!(n>o&&xd(l,[i/n,a/n],1e-6)))return[];if(Md(e.a,t,l)>1.1*Math.max(s,o)||Md(e.b,t,l)>1.1*Math.max(s,o))return[];return[[wd($d(e.a,t),l),wd($d(e.b,t),l)]]}),o).flatMap(([e,i])=>{const o=ke({a:kd(t,l,e),b:kd(t,l,i),halfDepth:s});return o?[o]:[]})}function Sd(t){const e=t.coordScale??1,s=Math.max(t.epsilon??2e-4*t.gridPitch,1e-9),i=[];for(const s of t.rooms||[]){if(!s?.id)continue;const o=vt(t.rooms,s.id,t.walls,t.openCuts,t.pitch,t.cellCm,t.gridPitch,e);if(!o||o.poly.length<3)continue;const a=we(o.poly,o.offsets);!a||a.length<3||i.push({roomId:s.id,profile:o,inner:a})}i.sort((t,e)=>t.roomId.localeCompare(e.roomId));const o=(t.roomOpenings||[]).map(t=>{const e=t.angle*Math.PI/180,s=[Math.cos(e),Math.sin(e)],i=Math.max(0,t.length)/2;return{a:kd([t.x,t.y],s,-i),b:kd([t.x,t.y],s,i)}}),a=[];for(const i of $e(t.rooms,t.walls,t.openCuts,t.pitch,t.cellCm,t.gridPitch,e))for(const t of Cd(i.a,i.b,i.depthUnits/2,o,s))a.push({body:t});const n=new Map;for(const e of t.partitionCuts||[]){const t=n.get(e.hostId)||[];t.push(e),n.set(e.hostId,t)}for(const e of t.partitions||[]){const i=V(e.cm,t.cellCm,t.gridPitch)/2;for(const t of Cd(e.a,e.b,i,n.get(e.id)||[],s))a.push({body:t,partitionId:e.id})}return{rooms:i,boundaries:a,epsilon:s}}function Pd(t,e,s,i){const o=t.profile.offsets[e];if(!(o>0))return null;const a=function(t,e){const s=t[e],i=t[(e+1)%t.length],o=i[0]-s[0],a=i[1]-s[1],n=Math.hypot(o,a)||1;return function(t){let e=0;for(let s=0;s=0?[-a/n,o/n]:[a/n,-o/n]}(t.profile.poly,e),n=kd(s.center,a,o),r=[];for(let e=0;ei&&xd(s.axis,[l[0]/h,l[1]/h],1e-6)))continue;if(Md(o,n,s.axis)>i||Md(a,n,s.axis)>i)continue;const c=wd($d(o,n),s.axis),d=wd($d(a,n),s.axis);r.push([Math.min(c,d),Math.max(c,d)])}const l=function(t,e){t.sort((t,e)=>t[0]-e[0]||t[1]-e[1]);const s=[];for(const i of t){const t=s[s.length-1];!t||i[0]>t[1]+e?s.push([...i]):t[1]=Math.max(t[1],i[1])}return s}(r,i).find(([t,e])=>t<=i&&e>=-i);if(!l)return null;const[h,c]=l,d=kd(n,s.axis,-s.half),p=kd(n,s.axis,s.half),u=Math.max(0,-s.half-h),_=Math.max(0,c-s.half),m=u>0?kd(n,s.axis,h):d,g=_>0?kd(n,s.axis,c):p,f=wd(a,s.normal)>=0?1:-1,b=(e,i,o)=>({from:e,to:i,label:[(e[0]+i[0])/2,(e[1]+i[1])/2],axis:s.axis,labelNormal:a,distance:o,roomId:t.roomId,roomSide:f,source:"room-face"});return{left:b(d,m,u),right:b(p,g,_)}}function Dd(t){const e=kd(t.center,t.axis,-t.half),s=kd(t.center,t.axis,t.half),i=kd(t.center,t.axis,Math.min(-t.half,t.targetLo)),o=kd(t.center,t.axis,Math.max(t.half,t.targetHi)),a=(e,s)=>({from:e,to:s,label:[(e[0]+s[0])/2,(e[1]+s[1])/2],axis:t.axis,labelNormal:t.normal,distance:Math.hypot(s[0]-e[0],s[1]-e[1]),source:"host-end"});return[a(e,i),a(s,o)]}function Id(t,e,s,i){const o=$d(s,e),a=wd(o,o);if(!(a>i*i))return Math.hypot(...$d(t,e))<=i;const n=wd($d(t,e),o)/a;if(n<-i||n>1+i)return!1;const r=kd(e,o,Math.max(0,Math.min(1,n)));return Math.hypot(...$d(t,r))<=i}function Ld(t,e,s){let i=!1;for(let o=0,a=e.length-1;ot[1]!=h>t[1]&&t[0]<(l-n)*(t[1]-r)/(h-r)+n&&(i=!i)}return i}function Td(t,e,s,i,o,a){const n=$d(i,s),r=yd(e,n);if(Math.abs(r)<=a)return null;const l=$d(s,t),h=yd(l,n)/r,c=yd(l,e)/r;return h<-a||h>o+a||c<-a||c>1+a?null:Math.max(0,Math.min(o,h))}function Rd(t,e,s){const i=Dd(s),o="partition"===t.host?.kind?t.host.id:void 0;return[{base:i[0],direction:[-s.axis[0],-s.axis[1]]},{base:i[1],direction:s.axis}].map(({base:t,direction:s})=>{const i=t.distance,a=function(t,e,s,i,o,a){let n=null;for(const r of i)if(!o||r.partitionId!==o){if(Ld(t,r.body,a))return 0;for(let i=0;iwd($d(t,o),s));return{center:o,axis:s,normal:i,half:Math.max(0,t.renderedLength)/2,targetLo:Math.min(...a),targetHi:Math.max(...a)}}(t),i=e.rooms.flatMap(t=>{const i=function(t,e,s){const{profile:i}=t;let o=null;for(let t=0;t0))continue;const a=i.poly[t],n=i.poly[(t+1)%i.poly.length],r=$d(n,a),l=Math.hypot(r[0],r[1]);if(!(l>s&&xd(e.axis,[r[0]/l,r[1]/l],1e-6)))continue;if(Md(a,e.center,e.axis)>s||Md(n,e.center,e.axis)>s)continue;const h=wd($d(a,e.center),e.axis),c=wd($d(n,e.center),e.axis),d=Math.min(h,c),p=Math.max(h,c);if(d>-e.half+s||p0?d:p<0?-p:0);(!o||u2)return Dd(s);if(i.length){const t=i.map(({room:t,edge:i})=>Pd(t,i,s,e.epsilon));if(t.some(t=>!t))return Dd(s);const o=t;return[...o.map(t=>t.left),...o.map(t=>t.right)]}return Rd(t,e,s)}function Fd(t,e,s,i,o){const a=(n=t,JSON.parse(JSON.stringify(n)));var n;const r=[...new Set(i.filter(t=>"string"==typeof t&&t))],l={partitionsMerged:0,partitionsReconciled:0,openingsRehosted:0,changed:!1};if(!r.length||!Array.isArray(a?.partitions))return{space:a,report:l};const h=JSON.stringify(a),c=Ja(a.partitions,{pitch:o.pitch,seedIds:r,geometry:Ya(a)});c.merged&&(a.partitions=c.partitions);const d=Array.isArray(a.openings)?a.openings:[];c.merged&&Za(d,c.partitions,c.openingMoves,{coordScale:o.coordScale,cellCm:o.cellCm,gridPitch:o.gridPitch});const p=function(t,e,s){const i=new Set(t.map(t=>t.id)),o=new Map(s.map(t=>[t.fromId,t.toId]));return[...new Set(e.map(t=>o.get(t)||t).filter(t=>i.has(t)))].sort((t,e)=>t.localeCompare(e))}(c.partitions,r,c.openingMoves),u=pn(a,{rooms:e.rooms,wall_columns:e.wall_columns,partitions:c.partitions.map(t=>({...t,a:[t.a[0]*o.coordScale,t.a[1]*o.coordScale],b:[t.b[0]*o.coordScale,t.b[1]*o.coordScale]}))},a.walls,s,{...o,partitionIds:p});return u.partitionsReconciled&&(u.walls.length?a.walls=u.walls:delete a.walls,u.partitions.length?a.partitions=u.partitions:delete a.partitions,u.openings.length?a.openings=u.openings:delete a.openings),{space:a,report:{partitionsMerged:c.merged,partitionsReconciled:u.partitionsReconciled,openingsRehosted:u.openingsRehosted,changed:JSON.stringify(a)!==h}}}const Nd=t=>void 0===t?t:JSON.parse(JSON.stringify(t)),Ad=(t,e)=>!!t&&"object"==typeof t&&Object.prototype.hasOwnProperty.call(t,e);function Ed(t,e){const s=e?new Set(e):null;return(t||[]).filter(t=>"string"==typeof t?.id&&(!s||s.has(t.id))).map(t=>{const e=t.vacuum;return{markerId:t.id,roomIdPresent:Ad(t,"room_id"),...Ad(t,"room_id")?{roomId:Nd(t.room_id)}:{},vacuumPresent:Ad(t,"vacuum"),segmentMapPresent:Ad(e,"segment_map"),...Ad(e,"segment_map")?{segmentMap:Nd(e?.segment_map)}:{}}}).sort((t,e)=>t.markerId.localeCompare(e.markerId))}function Od(t,e){const s=Nd([...t||[]]),i=new Set;for(const t of s){if("string"!=typeof t?.id)continue;let s=!1;"delete"===e.kind?t.room_id===e.roomId&&(delete t.room_id,s=!0):t.room_id===e.dropId&&(t.room_id=e.keepId,s=!0);const o=t.vacuum?.segment_map;if(o&&"object"==typeof o&&!Array.isArray(o)){for(const t of Object.keys(o))"delete"===e.kind&&o[t]===e.roomId?(delete o[t],s=!0):"merge"===e.kind&&o[t]===e.dropId&&(o[t]=e.keepId,s=!0);"delete"===e.kind&&0===Object.keys(o).length&&(t.vacuum&&delete t.vacuum.segment_map,t.vacuum&&0===Object.keys(t.vacuum).length&&delete t.vacuum)}s&&i.add(t.id)}const o=[...i].sort((t,e)=>t.localeCompare(e));return{markers:s,before:Ed(t,o),after:Ed(s,o),changed:o.length}}const Bd="1.77.0-beta.4";uo.adopt(ea,sa);const Hd=2e3,Wd=(t,e,s,i)=>{for(t.delete(e),t.set(e,s);t.size>i;){const e=t.keys().next().value;if(void 0===e)break;t.delete(e)}},jd=1e3,Gd=2e3,qd=t=>{try{t.target?.setPointerCapture?.(t.pointerId)}catch{}},Ud="33e3bf530b13e01b6cc86d437770676c16441418afa14b0324be617fc2d3bb22";class Kd{constructor(t){this.host=t,this._junctionBaselineCache=new WeakMap,this._resizePreviewNodes=null,this._resizeBaselineLimits=[],this._resizeBaseFrameStable=!0,this._supportPreviewGeneration=0,this._decorAssetGuardReplace=null,this._undoGeometry=()=>{if(this.host._physicalDrag||this.host._physicalRotate)return void this._cancelPhysicalGesture();if(this.host._decorDraft)return this.host._decorDraft=null,void this.host.requestUpdate();if(this.host._decorMove||this.host._dtDrag||this.host._bdDrag)return void this._cancelDecorGesture();if(this.host._resize.dragging)return void this._rszCancelDrag();const t=this.host._geometryHistory.undo();t&&(this._applyGeometryState(t.before,!0)?this.host._showToast(this.host._t("history.undone",{name:t.name})):this.host._geometryHistory.clear())},this._redoGeometry=()=>{if(this.host._physicalDrag||this.host._physicalRotate)return void this._cancelPhysicalGesture();if(this.host._decorDraft)return this.host._decorDraft=null,void this.host.requestUpdate();if(this.host._decorMove||this.host._dtDrag||this.host._bdDrag)return void this._cancelDecorGesture();if(this.host._resize.dragging)return void this._rszCancelDrag();if(this.host._activeWallChainId&&this.host._wallChainRedo.length){const t=this.host._activeWallChainId,e=this.host._path.map(t=>[...t]),s=[...this.host._activeWallChainPartitionIds],i=[...this.host._wallChainSegmentCms],o=[...this.host._wallChainRedo],a=o[o.length-1],n=this.host._geometryHistory.redo();if(!n)return;return this._applyGeometryState(n.after,!0)?(this.host._activeWallChainId=t,this.host._path=[...e,[...a.point]],this.host._activeWallChainPartitionIds=[...s,a.id],this.host._wallChainSegmentCms=[...i,a.cm],this.host._wallChainRedo=o.slice(0,-1),this._clearPlanSnapHover(),void this.host._showToast(this.host._t("history.redone",{name:n.name}))):void this.host._geometryHistory.clear()}const t=this.host._geometryHistory.redo();t&&(this._applyGeometryState(t.after,!0)?this.host._showToast(this.host._t("history.redone",{name:t.name})):this.host._geometryHistory.clear())},this._savePhysicalDialog=()=>{const t=this.host._physicalDialog,e=this.host._curSpaceCfg,s=this.host._spaceModel();if(!t||!e||!s)return;const i=xt(t.cm);if(null==i)return void this._showPhysicalRange("column"===t.kind?xe:100,"column"===t.kind?1:0);const o=this.host._imperial?2.54*i:i,a="column"===t.kind?xe:100,n="column"===t.kind?1:0;if(!Number.isFinite(o)||oa)return void this._showPhysicalRange(a,n);if("column"===t.kind){const e=s.wall_columns.find(e=>e.id===t.id);if(!e)return;const i=xt(t.angle||"0");if("circle"!==t.shape&&(null==i||i<0||i>=90))return void this.host._showToast(this.host._t("toast.physical_angle"));const a="circle"===t.shape?{id:t.id,shape:"circle",center:e.center,cm:o}:{id:t.id,shape:"square",center:e.center,cm:o,angle:i};if(s.wall_columns.some(e=>e.id!==t.id&&Me(e,a,.02*this.host._gridPitch)))return void this.host._showToast(this.host._t("toast.column_duplicate"))}const r=this._geometrySnapshot();if("partition"===t.kind){const s=(e.partitions||[]).find(e=>e.id===t.id);if(s&&0===o&&Ce(e.openings,{kind:"partition",id:t.id}))return void this.host._showToast(this.host._t("toast.zero_wall_opening_conflict"));s&&(s.cm=o)}else if("column"===t.kind){const s=(e.wall_columns||[]).find(e=>e.id===t.id);s&&(s.cm=Se(o),s.shape="circle"===t.shape?"circle":"square","square"===s.shape?s.angle=xt(t.angle||"0"):delete s.angle)}const l=this._commitPhysicalGeometry(this.host._t("history.physical_edit"),r);this.host._physicalDialog=null,l||this.host.requestUpdate()},this._deletePhysicalSelection=async()=>{const t=this.host._physicalSel,e=this.host._curSpaceCfg;if(!t||!e)return;const s=this._geometrySnapshot();if("partition"===t.kind){const s=(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(s.length)return void(this.host._partitionDeleteDialog={id:t.id,openings:s.map(t=>JSON.parse(JSON.stringify(t)))})}const i="partition"===t.kind?"partitions":"wall_columns";e[i]=(e[i]||[]).filter(e=>e.id!==t.id),e[i].length||delete e[i],this.host._activeWallChainPartitionIds.includes(t.id)&&this._cancelPath(),this.host._physicalSel=null,this.host._physicalDialog=null,this._commitPhysicalGeometry(this.host._t("history.physical_delete"),s)},this._confirmPartitionDelete=()=>{const t=this.host._partitionDeleteDialog,e=this.host._curSpaceCfg;if(!t||!e)return;const s=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.host._partitionDeleteDialog=null,this.host._physicalSel=null,this.host._physicalDialog=null,this._commitPhysicalGeometry(this.host._t("history.physical_delete"),s)},this._furnShiftListener=t=>{if("Shift"!==t.key)return;const e=this.host._furnPreviewInput;if(!e)return;const s="keydown"===t.type;e.free!==s&&(this.host._furnPreviewInput={...e,free:s},this.host.requestUpdate())},this._furnShiftAttached=!1,this._confirmRoomDelete=t=>{const e=this.host._roomDeleteDialog,s=this.host._curSpaceCfg,i=this.host._spaceModel();if(!e||!s||!i)return;const o=i.rooms.find(t=>t.id===e.roomId);if(!o)return void(this.host._roomDeleteDialog=null);const a=this.host._openCuts(),n=Jc(O(i.rooms,this.host._spaceWalls,a,this.host._wallKeyPitch,this.host._cellCm,this.host._gridPitch,jd).filter(t=>t.roomId===o.id),i.partitions,this.host._openingsR.map(t=>({...t,x:t.rx,y:t.ry})),.02*this.host._gridPitch),r=new Set(n.materialize.filter(t=>!t.reusePartitionId).map(t=>t.interval.key)).size;if(t&&(s.partitions||[]).length+r>Gd)return void this.host._showToast(this.host._t("toast.physical_limit"));const l=this._geometrySnapshot(),h=Od(this.host._serverCfg?.markers||[],{kind:"delete",roomId:e.roomId});l&&h.changed&&(l.roomReferences=h.before);const c=Pe(i.rooms,this.host._spaceWalls,a,this.host._wallKeyPitch,this.host._cellCm,this.host._gridPitch,jd);if(t){s.partitions||=[];const t=new Map,e=new Map,i=t=>{const e=(s.wall_segments||[]).find(e=>{const s=[Number(e.a?.[0])*jd,Number(e.a?.[1])*jd],i=[Number(e.b?.[0])*jd,Number(e.b?.[1])*jd];return this._samePt(t.a,s)&&this._samePt(t.b,i)||this._samePt(t.a,i)&&this._samePt(t.b,s)});return"string"==typeof e?.id&&e.id?e.id:null},o=Date.now().toString(36);for(const a of n.materialize){let n=a.reusePartitionId?s.partitions.find(t=>t.id===a.reusePartitionId):e.get(a.interval.key);n||(n={id:i(a.interval)||`partition-room-${o}-${e.size}`,a:[a.interval.a[0]/jd,a.interval.a[1]/jd],b:[a.interval.b[0]/jd,a.interval.b[1]/jd],cm:a.interval.cm},s.partitions.push(n),e.set(a.interval.key,n)),t.set(a.interval.key,n)}for(const e of s.openings||[]){const s=n.openingIntervals.get(e.id),i=s?t.get(s):null,o=this.host._openingsR.find(t=>t.id===e.id);if(!i||!o)continue;const a={a:[i.a[0]*jd,i.a[1]*jd],b:[i.b[0]*jd,i.b[1]*jd]};e.host={kind:"partition",id:i.id,t:Zc([o.rx,o.ry],a)}}}else if(n.removeOpeningIds.length){const t=new Set(n.removeOpeningIds);s.openings=(s.openings||[]).filter(e=>!t.has(e.id)),s.openings.length||delete s.openings}s.rooms=s.rooms.filter(t=>t.id!==o.id),h.changed&&this.host._serverCfg&&(this.host._serverCfg.markers=h.markers),this.host._cfgEpoch++;const d=this.host._normalizeWalls(c,this.host._openCuts());d.length?s.walls=d:delete s.walls,this.host._roomDeleteDialog=null,this._commitPhysicalGeometry(this.host._t(t?"history.delete_room_keep_walls":"history.delete_room_with_walls"),l),this.host._regSignature="",this.host._maybeRebuildDevices(),this.host.requestUpdate()},this._rebindPartitionOpening=()=>{const t=this.host._openingDialog;if(!t?.id)return;const e=t.id;this._activateMarkupTool("opening"),"opening"===this.host._tool&&(this.host._openingRebindId=e,this.host._openingPreset={type:t.type,lengthCm:t.lengthCm,flipH:t.flipH,flipV:t.flipV,revision:++this.host._openingPresetRevision},this.host._openingDialog=null,this.host._openingHoverCandidate=null)},this._deviceInboxTabKey=t=>{if("ArrowLeft"!==t.key&&"ArrowRight"!==t.key)return;const e=this.host._deviceInbox;if(!e)return;const s=["on_plan","available","hidden","readd"],i="ArrowRight"===t.key?1:-1,o=(s.indexOf(e.tab)+i+s.length)%s.length;this.host._deviceInbox={...e,tab:s[o],limit:100,onlyNew:!1},t.preventDefault()},this._keepClosedAsPartitions=()=>{this.host._wallFaceBatch?this._decideWallFace(!1):this.host._contourClosed&&!this.host._pendingSplit&&this.host._curSpaceCfg&&this._finalizeWallChainPartitions(this.host._activeWallChainPartitionIds)&&(this.host._roomDialog=!1,this.host._path=[],this.host._activeWallChainId=null,this.host._activeWallChainPartitionIds=[],this.host._wallChainSegmentCms=[],this.host._wallChainRedo=[],this.host._closingWallCm=null,this.host.requestUpdate())},this._toggleServerPlans=async()=>{const t=this.host._spaceDialog;if(t)if(t.pickSaved)this.host._spaceDialog={...t,pickSaved:!1};else{this.host._spaceDialog={...t,pickSaved:!0,savedBusy:!0};try{const t=await this.host.hass.callWS({type:"houseplan/plans/list"}),e=this.host._spaceDialog;e&&(this.host._spaceDialog={...e,saved:t?.plans||[],savedBusy:!1})}catch(t){const e=this.host._spaceDialog;e&&(this.host._spaceDialog={...e,saved:[],savedBusy:!1}),this.host._showToast(this.host._t("toast.plans_list_failed",{err:this.host._errText(t)}))}}},this._openSettingsDialog=()=>{if(!this.host._norm)return;const t=this.host._glowRadiusCm,e=this.host._imperial?Math.round(t/30.48*10)/10:Math.round(t)/100;this.host._settingsDialog={colors:JSON.parse(JSON.stringify(this.host._fillColors)),glowRadius:e,bgColor:ze(this.host._settings,{bgColor:null})||null,northDeg:Re(this.host._settings,{}),bgMode:Te(this.host._settings,{}),sunRays:Le(this.host._settings,{}),sunRayOrigin:Ie(this.host._settings),radarShowLive:!1!==this.host._settings.radar?.show_live,showRoomTooltip:De(this.host._settings),zigbeeTopology:wt(this.host._settings),busy:!1},function(t,e){_o(t,"settings",$r(e))}(this.host,this.host._settingsDialog)},this._openSupportDialog=()=>{this.host._norm&&this.host._canEdit&&(clearTimeout(this._supportExpiryTimer),this._supportExpiryTimer=void 0,this._supportPreviewGeneration+=1,this.host._supportDialog={draftId:dd("draft"),idempotencyKey:dd("report"),submissionFingerprint:"",contact:"",message:"",attach:!1,status:"idle",preview:null,rawOpen:!1,errorCode:"",reportId:""})},this._openAlignDialog=()=>this._previewAlignDialog(!1),this._toggleOptimizeLivePositions=()=>{const t=this.host._alignDialog;t&&!t.busy&&t.report.liveMissingPositions.length&&this._previewAlignDialog(!t.removeLiveMissingPositions)},this._openBackupExport=()=>{this.host._settingsDialog=null,this.host._backupExportDialog={kind:"full",planOnly:!1,busy:!1,error:""}},this._decorStylePersistTimer=null,this._openRulesDialog=()=>{if(!this.host._norm)return;const t=this.host._settings.icon_rules,e=(t&&t.length?t:Fe).map(t=>({...t}));this.host._rulesDialog={rules:e,test:"",busy:!1}},this._discoveryPreviewMemo=null,this._decorImages=new vd(t,{decorSnap:(t,e)=>this._decorSnap(t,e),geometrySnapshot:()=>this._geometrySnapshot(),clearFurniturePreview:()=>this._clearFurniturePreview(),recordGeometry:(t,e)=>this._recordGeometry(t,e),saveConfig:()=>this._saveConfig(),saveShape:()=>this._decorSaveShape(),setGuardReplace:t=>{this._decorAssetGuardReplace=t},furnShiftDetach:()=>this._furnShiftDetach(),furnPick:t=>this._furnPick(t),furnFieldValue:t=>this._furnFieldValue(t),furnFieldToCm:t=>this._furnFieldToCm(t)}),this._radarSetup=new oc({hass:()=>t.hass,requestUpdate:()=>t.requestUpdate(),t:(e,s)=>t._t(e,s),configFromDraft:Da,apply:e=>{t._markerDialog&&(t._markerDialog={...t._markerDialog,radar:e,radarEligible:!0,radarTouched:!0,radarRemove:!1})},confirmDiscard:()=>t._confirmDanger((t=>({key:"discard-radar-setup",kind:"warning",title:t("radar.discard_setup_title"),message:t("radar.discard_setup"),confirmLabel:t("btn.close"),cancelLabel:t("btn.cancel")}))(e=>t._t(e)))}),t._editorSecondary=new ad({root:()=>t.renderRoot,requestUpdate:()=>t.requestUpdate(),updateComplete:()=>t.updateComplete,clearTip:()=>{t._tip=null}}),t._resize=new Jl}_routeLiveEditorUpdate(t,e){const s=Or(this.host,t,e);return!s&&this.host._resize.preview&&(this._resizeBaseFrameStable=!1),s}_commitLiveEditor(){!function(t){const e=t,s=Nr(t);s.raf&&"function"==typeof cancelAnimationFrame&&cancelAnimationFrame(s.raf),s.raf=0,Wr(s);const i=e.renderRoot?.querySelector("[data-hp-live-editor]");i&&St(d,i);const o=e.renderRoot?.querySelector("[data-hp-live-editor-html]");if(o){const t=e._viewOr(e._baseVb());St(e._renderLiveEditorMeasurements(t),o)}Ar(s,s.requestedRevision)}(this.host)}_disposeLiveEditor(){this._radarSetup.reset(),function(t){Lr(t);const e=Tr.get(t);e&&(e.raf&&"function"==typeof cancelAnimationFrame&&cancelAnimationFrame(e.raf),Wr(e),Ar(e,e.requestedRevision),Tr.delete(t))}(this.host)}_cancelRadarSetup(){this._radarSetup.interrupt()}async _whenLiveEditorSettled(){await this.host.updateComplete,await function(t){const e=Tr.get(t);if(!e||!e.raf||e.paintedRevision>=e.requestedRevision)return Promise.resolve();const s=e.requestedRevision;return new Promise(t=>e.waiters.push({revision:s,resolve:t}))}(this.host)}_queuePointerMove(t,e){Dr(this.host,t,e)}_flushPointerMove(t){Ir(this.host,t)}_cancelPointerMove(t){Lr(this.host,t)}_help(t){const e=`${t}.aria`,s=l(this.host.hass,this.host._config?.language);return Ne(s,t)&&Ne(s,e)?p``}}const yd=(t,e)=>t[0]*e[1]-t[1]*e[0],wd=(t,e)=>t[0]*e[0]+t[1]*e[1],$d=(t,e)=>[t[0]-e[0],t[1]-e[1]],kd=(t,e,s)=>[t[0]+e[0]*s,t[1]+e[1]*s];function xd(t,e,s){return Math.abs(yd(t,e))<=s}function Md(t,e,s){return Math.abs(yd($d(t,e),s))}function Cd(t,e,s,i,o){const a=e[0]-t[0],n=e[1]-t[1],r=Math.hypot(a,n);if(!(r>o&&s>0))return[];const l=[a/r,n/r];return function(t,e,s){const i=e.map(([e,s])=>[Math.max(0,Math.min(e,s)),Math.min(t,Math.max(e,s))]).filter(([t,e])=>e>t+s).sort((t,e)=>t[0]-e[0]||t[1]-e[1]),o=[];for(const t of i){const e=o[o.length-1];!e||t[0]>e[1]+s?o.push([...t]):e[1]=Math.max(e[1],t[1])}const a=[];let n=0;for(const[t,e]of o)t>n+s&&a.push([n,t]),n=Math.max(n,e);return t>n+s&&a.push([n,t]),a}(r,i.flatMap(e=>{const i=e.b[0]-e.a[0],a=e.b[1]-e.a[1],n=Math.hypot(i,a);if(!(n>o&&xd(l,[i/n,a/n],1e-6)))return[];if(Md(e.a,t,l)>1.1*Math.max(s,o)||Md(e.b,t,l)>1.1*Math.max(s,o))return[];return[[wd($d(e.a,t),l),wd($d(e.b,t),l)]]}),o).flatMap(([e,i])=>{const o=ke({a:kd(t,l,e),b:kd(t,l,i),halfDepth:s});return o?[o]:[]})}function Sd(t){const e=t.coordScale??1,s=Math.max(t.epsilon??2e-4*t.gridPitch,1e-9),i=[];for(const s of t.rooms||[]){if(!s?.id)continue;const o=vt(t.rooms,s.id,t.walls,t.openCuts,t.pitch,t.cellCm,t.gridPitch,e);if(!o||o.poly.length<3)continue;const a=we(o.poly,o.offsets);!a||a.length<3||i.push({roomId:s.id,profile:o,inner:a})}i.sort((t,e)=>t.roomId.localeCompare(e.roomId));const o=(t.roomOpenings||[]).map(t=>{const e=t.angle*Math.PI/180,s=[Math.cos(e),Math.sin(e)],i=Math.max(0,t.length)/2;return{a:kd([t.x,t.y],s,-i),b:kd([t.x,t.y],s,i)}}),a=[];for(const i of $e(t.rooms,t.walls,t.openCuts,t.pitch,t.cellCm,t.gridPitch,e))for(const t of Cd(i.a,i.b,i.depthUnits/2,o,s))a.push({body:t});const n=new Map;for(const e of t.partitionCuts||[]){const t=n.get(e.hostId)||[];t.push(e),n.set(e.hostId,t)}for(const e of t.partitions||[]){const i=V(e.cm,t.cellCm,t.gridPitch)/2;for(const t of Cd(e.a,e.b,i,n.get(e.id)||[],s))a.push({body:t,partitionId:e.id})}return{rooms:i,boundaries:a,epsilon:s}}function Pd(t,e,s,i){const o=t.profile.offsets[e];if(!(o>0))return null;const a=function(t,e){const s=t[e],i=t[(e+1)%t.length],o=i[0]-s[0],a=i[1]-s[1],n=Math.hypot(o,a)||1;return function(t){let e=0;for(let s=0;s=0?[-a/n,o/n]:[a/n,-o/n]}(t.profile.poly,e),n=kd(s.center,a,o),r=[];for(let e=0;ei&&xd(s.axis,[l[0]/h,l[1]/h],1e-6)))continue;if(Md(o,n,s.axis)>i||Md(a,n,s.axis)>i)continue;const c=wd($d(o,n),s.axis),d=wd($d(a,n),s.axis);r.push([Math.min(c,d),Math.max(c,d)])}const l=function(t,e){t.sort((t,e)=>t[0]-e[0]||t[1]-e[1]);const s=[];for(const i of t){const t=s[s.length-1];!t||i[0]>t[1]+e?s.push([...i]):t[1]=Math.max(t[1],i[1])}return s}(r,i).find(([t,e])=>t<=i&&e>=-i);if(!l)return null;const[h,c]=l,d=kd(n,s.axis,-s.half),p=kd(n,s.axis,s.half),u=Math.max(0,-s.half-h),_=Math.max(0,c-s.half),m=u>0?kd(n,s.axis,h):d,g=_>0?kd(n,s.axis,c):p,f=wd(a,s.normal)>=0?1:-1,b=(e,i,o)=>({from:e,to:i,label:[(e[0]+i[0])/2,(e[1]+i[1])/2],axis:s.axis,labelNormal:a,distance:o,roomId:t.roomId,roomSide:f,source:"room-face"});return{left:b(d,m,u),right:b(p,g,_)}}function Dd(t){const e=kd(t.center,t.axis,-t.half),s=kd(t.center,t.axis,t.half),i=kd(t.center,t.axis,Math.min(-t.half,t.targetLo)),o=kd(t.center,t.axis,Math.max(t.half,t.targetHi)),a=(e,s)=>({from:e,to:s,label:[(e[0]+s[0])/2,(e[1]+s[1])/2],axis:t.axis,labelNormal:t.normal,distance:Math.hypot(s[0]-e[0],s[1]-e[1]),source:"host-end"});return[a(e,i),a(s,o)]}function Id(t,e,s,i){const o=$d(s,e),a=wd(o,o);if(!(a>i*i))return Math.hypot(...$d(t,e))<=i;const n=wd($d(t,e),o)/a;if(n<-i||n>1+i)return!1;const r=kd(e,o,Math.max(0,Math.min(1,n)));return Math.hypot(...$d(t,r))<=i}function Ld(t,e,s){let i=!1;for(let o=0,a=e.length-1;ot[1]!=h>t[1]&&t[0]<(l-n)*(t[1]-r)/(h-r)+n&&(i=!i)}return i}function Td(t,e,s,i,o,a){const n=$d(i,s),r=yd(e,n);if(Math.abs(r)<=a)return null;const l=$d(s,t),h=yd(l,n)/r,c=yd(l,e)/r;return h<-a||h>o+a||c<-a||c>1+a?null:Math.max(0,Math.min(o,h))}function Rd(t,e,s){const i=Dd(s),o="partition"===t.host?.kind?t.host.id:void 0;return[{base:i[0],direction:[-s.axis[0],-s.axis[1]]},{base:i[1],direction:s.axis}].map(({base:t,direction:s})=>{const i=t.distance,a=function(t,e,s,i,o,a){let n=null;for(const r of i)if(!o||r.partitionId!==o){if(Ld(t,r.body,a))return 0;for(let i=0;iwd($d(t,o),s));return{center:o,axis:s,normal:i,half:Math.max(0,t.renderedLength)/2,targetLo:Math.min(...a),targetHi:Math.max(...a)}}(t),i=e.rooms.flatMap(t=>{const i=function(t,e,s){const{profile:i}=t;let o=null;for(let t=0;t0))continue;const a=i.poly[t],n=i.poly[(t+1)%i.poly.length],r=$d(n,a),l=Math.hypot(r[0],r[1]);if(!(l>s&&xd(e.axis,[r[0]/l,r[1]/l],1e-6)))continue;if(Md(a,e.center,e.axis)>s||Md(n,e.center,e.axis)>s)continue;const h=wd($d(a,e.center),e.axis),c=wd($d(n,e.center),e.axis),d=Math.min(h,c),p=Math.max(h,c);if(d>-e.half+s||p0?d:p<0?-p:0);(!o||u2)return Dd(s);if(i.length){const t=i.map(({room:t,edge:i})=>Pd(t,i,s,e.epsilon));if(t.some(t=>!t))return Dd(s);const o=t;return[...o.map(t=>t.left),...o.map(t=>t.right)]}return Rd(t,e,s)}function Fd(t,e,s,i,o){const a=(n=t,JSON.parse(JSON.stringify(n)));var n;const r=[...new Set(i.filter(t=>"string"==typeof t&&t))],l={partitionsMerged:0,partitionsReconciled:0,openingsRehosted:0,changed:!1};if(!r.length||!Array.isArray(a?.partitions))return{space:a,report:l};const h=JSON.stringify(a),c=Ja(a.partitions,{pitch:o.pitch,seedIds:r,geometry:Ya(a)});c.merged&&(a.partitions=c.partitions);const d=Array.isArray(a.openings)?a.openings:[];c.merged&&Za(d,c.partitions,c.openingMoves,{coordScale:o.coordScale,cellCm:o.cellCm,gridPitch:o.gridPitch});const p=function(t,e,s){const i=new Set(t.map(t=>t.id)),o=new Map(s.map(t=>[t.fromId,t.toId]));return[...new Set(e.map(t=>o.get(t)||t).filter(t=>i.has(t)))].sort((t,e)=>t.localeCompare(e))}(c.partitions,r,c.openingMoves),u=pn(a,{rooms:e.rooms,wall_columns:e.wall_columns,partitions:c.partitions.map(t=>({...t,a:[t.a[0]*o.coordScale,t.a[1]*o.coordScale],b:[t.b[0]*o.coordScale,t.b[1]*o.coordScale]}))},a.walls,s,{...o,partitionIds:p});return u.partitionsReconciled&&(u.walls.length?a.walls=u.walls:delete a.walls,u.partitions.length?a.partitions=u.partitions:delete a.partitions,u.openings.length?a.openings=u.openings:delete a.openings),{space:a,report:{partitionsMerged:c.merged,partitionsReconciled:u.partitionsReconciled,openingsRehosted:u.openingsRehosted,changed:JSON.stringify(a)!==h}}}const Nd=t=>void 0===t?t:JSON.parse(JSON.stringify(t)),Ad=(t,e)=>!!t&&"object"==typeof t&&Object.prototype.hasOwnProperty.call(t,e);function Ed(t,e){const s=e?new Set(e):null;return(t||[]).filter(t=>"string"==typeof t?.id&&(!s||s.has(t.id))).map(t=>{const e=t.vacuum;return{markerId:t.id,roomIdPresent:Ad(t,"room_id"),...Ad(t,"room_id")?{roomId:Nd(t.room_id)}:{},vacuumPresent:Ad(t,"vacuum"),segmentMapPresent:Ad(e,"segment_map"),...Ad(e,"segment_map")?{segmentMap:Nd(e?.segment_map)}:{}}}).sort((t,e)=>t.markerId.localeCompare(e.markerId))}function Od(t,e){const s=Nd([...t||[]]),i=new Set;for(const t of s){if("string"!=typeof t?.id)continue;let s=!1;"delete"===e.kind?t.room_id===e.roomId&&(delete t.room_id,s=!0):t.room_id===e.dropId&&(t.room_id=e.keepId,s=!0);const o=t.vacuum?.segment_map;if(o&&"object"==typeof o&&!Array.isArray(o)){for(const t of Object.keys(o))"delete"===e.kind&&o[t]===e.roomId?(delete o[t],s=!0):"merge"===e.kind&&o[t]===e.dropId&&(o[t]=e.keepId,s=!0);"delete"===e.kind&&0===Object.keys(o).length&&(t.vacuum&&delete t.vacuum.segment_map,t.vacuum&&0===Object.keys(t.vacuum).length&&delete t.vacuum)}s&&i.add(t.id)}const o=[...i].sort((t,e)=>t.localeCompare(e));return{markers:s,before:Ed(t,o),after:Ed(s,o),changed:o.length}}const Bd="1.77.0-beta.4";uo.adopt(ea,sa);const Hd=2e3,Wd=(t,e,s,i)=>{for(t.delete(e),t.set(e,s);t.size>i;){const e=t.keys().next().value;if(void 0===e)break;t.delete(e)}},jd=1e3,Gd=2e3,qd=t=>{try{t.target?.setPointerCapture?.(t.pointerId)}catch{}},Ud="44c8db0207714f5476f58cdacdfaae63754967422e492b7fadf3551ecaee4380";class Kd{constructor(t){this.host=t,this._junctionBaselineCache=new WeakMap,this._resizePreviewNodes=null,this._resizeBaselineLimits=[],this._resizeBaseFrameStable=!0,this._supportPreviewGeneration=0,this._decorAssetGuardReplace=null,this._undoGeometry=()=>{if(this.host._physicalDrag||this.host._physicalRotate)return void this._cancelPhysicalGesture();if(this.host._decorDraft)return this.host._decorDraft=null,void this.host.requestUpdate();if(this.host._decorMove||this.host._dtDrag||this.host._bdDrag)return void this._cancelDecorGesture();if(this.host._resize.dragging)return void this._rszCancelDrag();const t=this.host._geometryHistory.undo();t&&(this._applyGeometryState(t.before,!0)?this.host._showToast(this.host._t("history.undone",{name:t.name})):this.host._geometryHistory.clear())},this._redoGeometry=()=>{if(this.host._physicalDrag||this.host._physicalRotate)return void this._cancelPhysicalGesture();if(this.host._decorDraft)return this.host._decorDraft=null,void this.host.requestUpdate();if(this.host._decorMove||this.host._dtDrag||this.host._bdDrag)return void this._cancelDecorGesture();if(this.host._resize.dragging)return void this._rszCancelDrag();if(this.host._activeWallChainId&&this.host._wallChainRedo.length){const t=this.host._activeWallChainId,e=this.host._path.map(t=>[...t]),s=[...this.host._activeWallChainPartitionIds],i=[...this.host._wallChainSegmentCms],o=[...this.host._wallChainRedo],a=o[o.length-1],n=this.host._geometryHistory.redo();if(!n)return;return this._applyGeometryState(n.after,!0)?(this.host._activeWallChainId=t,this.host._path=[...e,[...a.point]],this.host._activeWallChainPartitionIds=[...s,a.id],this.host._wallChainSegmentCms=[...i,a.cm],this.host._wallChainRedo=o.slice(0,-1),this._clearPlanSnapHover(),void this.host._showToast(this.host._t("history.redone",{name:n.name}))):void this.host._geometryHistory.clear()}const t=this.host._geometryHistory.redo();t&&(this._applyGeometryState(t.after,!0)?this.host._showToast(this.host._t("history.redone",{name:t.name})):this.host._geometryHistory.clear())},this._savePhysicalDialog=()=>{const t=this.host._physicalDialog,e=this.host._curSpaceCfg,s=this.host._spaceModel();if(!t||!e||!s)return;const i=xt(t.cm);if(null==i)return void this._showPhysicalRange("column"===t.kind?xe:100,"column"===t.kind?1:0);const o=this.host._imperial?2.54*i:i,a="column"===t.kind?xe:100,n="column"===t.kind?1:0;if(!Number.isFinite(o)||oa)return void this._showPhysicalRange(a,n);if("column"===t.kind){const e=s.wall_columns.find(e=>e.id===t.id);if(!e)return;const i=xt(t.angle||"0");if("circle"!==t.shape&&(null==i||i<0||i>=90))return void this.host._showToast(this.host._t("toast.physical_angle"));const a="circle"===t.shape?{id:t.id,shape:"circle",center:e.center,cm:o}:{id:t.id,shape:"square",center:e.center,cm:o,angle:i};if(s.wall_columns.some(e=>e.id!==t.id&&Me(e,a,.02*this.host._gridPitch)))return void this.host._showToast(this.host._t("toast.column_duplicate"))}const r=this._geometrySnapshot();if("partition"===t.kind){const s=(e.partitions||[]).find(e=>e.id===t.id);if(s&&0===o&&Ce(e.openings,{kind:"partition",id:t.id}))return void this.host._showToast(this.host._t("toast.zero_wall_opening_conflict"));s&&(s.cm=o)}else if("column"===t.kind){const s=(e.wall_columns||[]).find(e=>e.id===t.id);s&&(s.cm=Se(o),s.shape="circle"===t.shape?"circle":"square","square"===s.shape?s.angle=xt(t.angle||"0"):delete s.angle)}const l=this._commitPhysicalGeometry(this.host._t("history.physical_edit"),r);this.host._physicalDialog=null,l||this.host.requestUpdate()},this._deletePhysicalSelection=async()=>{const t=this.host._physicalSel,e=this.host._curSpaceCfg;if(!t||!e)return;const s=this._geometrySnapshot();if("partition"===t.kind){const s=(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(s.length)return void(this.host._partitionDeleteDialog={id:t.id,openings:s.map(t=>JSON.parse(JSON.stringify(t)))})}const i="partition"===t.kind?"partitions":"wall_columns";e[i]=(e[i]||[]).filter(e=>e.id!==t.id),e[i].length||delete e[i],this.host._activeWallChainPartitionIds.includes(t.id)&&this._cancelPath(),this.host._physicalSel=null,this.host._physicalDialog=null,this._commitPhysicalGeometry(this.host._t("history.physical_delete"),s)},this._confirmPartitionDelete=()=>{const t=this.host._partitionDeleteDialog,e=this.host._curSpaceCfg;if(!t||!e)return;const s=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.host._partitionDeleteDialog=null,this.host._physicalSel=null,this.host._physicalDialog=null,this._commitPhysicalGeometry(this.host._t("history.physical_delete"),s)},this._furnShiftListener=t=>{if("Shift"!==t.key)return;const e=this.host._furnPreviewInput;if(!e)return;const s="keydown"===t.type;e.free!==s&&(this.host._furnPreviewInput={...e,free:s},this.host.requestUpdate())},this._furnShiftAttached=!1,this._confirmRoomDelete=t=>{const e=this.host._roomDeleteDialog,s=this.host._curSpaceCfg,i=this.host._spaceModel();if(!e||!s||!i)return;const o=i.rooms.find(t=>t.id===e.roomId);if(!o)return void(this.host._roomDeleteDialog=null);const a=this.host._openCuts(),n=Jc(O(i.rooms,this.host._spaceWalls,a,this.host._wallKeyPitch,this.host._cellCm,this.host._gridPitch,jd).filter(t=>t.roomId===o.id),i.partitions,this.host._openingsR.map(t=>({...t,x:t.rx,y:t.ry})),.02*this.host._gridPitch),r=new Set(n.materialize.filter(t=>!t.reusePartitionId).map(t=>t.interval.key)).size;if(t&&(s.partitions||[]).length+r>Gd)return void this.host._showToast(this.host._t("toast.physical_limit"));const l=this._geometrySnapshot(),h=Od(this.host._serverCfg?.markers||[],{kind:"delete",roomId:e.roomId});l&&h.changed&&(l.roomReferences=h.before);const c=Pe(i.rooms,this.host._spaceWalls,a,this.host._wallKeyPitch,this.host._cellCm,this.host._gridPitch,jd);if(t){s.partitions||=[];const t=new Map,e=new Map,i=t=>{const e=(s.wall_segments||[]).find(e=>{const s=[Number(e.a?.[0])*jd,Number(e.a?.[1])*jd],i=[Number(e.b?.[0])*jd,Number(e.b?.[1])*jd];return this._samePt(t.a,s)&&this._samePt(t.b,i)||this._samePt(t.a,i)&&this._samePt(t.b,s)});return"string"==typeof e?.id&&e.id?e.id:null},o=Date.now().toString(36);for(const a of n.materialize){let n=a.reusePartitionId?s.partitions.find(t=>t.id===a.reusePartitionId):e.get(a.interval.key);n||(n={id:i(a.interval)||`partition-room-${o}-${e.size}`,a:[a.interval.a[0]/jd,a.interval.a[1]/jd],b:[a.interval.b[0]/jd,a.interval.b[1]/jd],cm:a.interval.cm},s.partitions.push(n),e.set(a.interval.key,n)),t.set(a.interval.key,n)}for(const e of s.openings||[]){const s=n.openingIntervals.get(e.id),i=s?t.get(s):null,o=this.host._openingsR.find(t=>t.id===e.id);if(!i||!o)continue;const a={a:[i.a[0]*jd,i.a[1]*jd],b:[i.b[0]*jd,i.b[1]*jd]};e.host={kind:"partition",id:i.id,t:Zc([o.rx,o.ry],a)}}}else if(n.removeOpeningIds.length){const t=new Set(n.removeOpeningIds);s.openings=(s.openings||[]).filter(e=>!t.has(e.id)),s.openings.length||delete s.openings}s.rooms=s.rooms.filter(t=>t.id!==o.id),h.changed&&this.host._serverCfg&&(this.host._serverCfg.markers=h.markers),this.host._cfgEpoch++;const d=this.host._normalizeWalls(c,this.host._openCuts());d.length?s.walls=d:delete s.walls,this.host._roomDeleteDialog=null,this._commitPhysicalGeometry(this.host._t(t?"history.delete_room_keep_walls":"history.delete_room_with_walls"),l),this.host._regSignature="",this.host._maybeRebuildDevices(),this.host.requestUpdate()},this._rebindPartitionOpening=()=>{const t=this.host._openingDialog;if(!t?.id)return;const e=t.id;this._activateMarkupTool("opening"),"opening"===this.host._tool&&(this.host._openingRebindId=e,this.host._openingPreset={type:t.type,lengthCm:t.lengthCm,flipH:t.flipH,flipV:t.flipV,revision:++this.host._openingPresetRevision},this.host._openingDialog=null,this.host._openingHoverCandidate=null)},this._deviceInboxTabKey=t=>{if("ArrowLeft"!==t.key&&"ArrowRight"!==t.key)return;const e=this.host._deviceInbox;if(!e)return;const s=["on_plan","available","hidden","readd"],i="ArrowRight"===t.key?1:-1,o=(s.indexOf(e.tab)+i+s.length)%s.length;this.host._deviceInbox={...e,tab:s[o],limit:100,onlyNew:!1},t.preventDefault()},this._keepClosedAsPartitions=()=>{this.host._wallFaceBatch?this._decideWallFace(!1):this.host._contourClosed&&!this.host._pendingSplit&&this.host._curSpaceCfg&&this._finalizeWallChainPartitions(this.host._activeWallChainPartitionIds)&&(this.host._roomDialog=!1,this.host._path=[],this.host._activeWallChainId=null,this.host._activeWallChainPartitionIds=[],this.host._wallChainSegmentCms=[],this.host._wallChainRedo=[],this.host._closingWallCm=null,this.host.requestUpdate())},this._toggleServerPlans=async()=>{const t=this.host._spaceDialog;if(t)if(t.pickSaved)this.host._spaceDialog={...t,pickSaved:!1};else{this.host._spaceDialog={...t,pickSaved:!0,savedBusy:!0};try{const t=await this.host.hass.callWS({type:"houseplan/plans/list"}),e=this.host._spaceDialog;e&&(this.host._spaceDialog={...e,saved:t?.plans||[],savedBusy:!1})}catch(t){const e=this.host._spaceDialog;e&&(this.host._spaceDialog={...e,saved:[],savedBusy:!1}),this.host._showToast(this.host._t("toast.plans_list_failed",{err:this.host._errText(t)}))}}},this._openSettingsDialog=()=>{if(!this.host._norm)return;const t=this.host._glowRadiusCm,e=this.host._imperial?Math.round(t/30.48*10)/10:Math.round(t)/100;this.host._settingsDialog={colors:JSON.parse(JSON.stringify(this.host._fillColors)),glowRadius:e,bgColor:ze(this.host._settings,{bgColor:null})||null,northDeg:Re(this.host._settings,{}),bgMode:Te(this.host._settings,{}),sunRays:Le(this.host._settings,{}),sunRayOrigin:Ie(this.host._settings),radarShowLive:!1!==this.host._settings.radar?.show_live,showRoomTooltip:De(this.host._settings),zigbeeTopology:wt(this.host._settings),busy:!1},function(t,e){_o(t,"settings",$r(e))}(this.host,this.host._settingsDialog)},this._openSupportDialog=()=>{this.host._norm&&this.host._canEdit&&(clearTimeout(this._supportExpiryTimer),this._supportExpiryTimer=void 0,this._supportPreviewGeneration+=1,this.host._supportDialog={draftId:dd("draft"),idempotencyKey:dd("report"),submissionFingerprint:"",contact:"",message:"",attach:!1,status:"idle",preview:null,rawOpen:!1,errorCode:"",reportId:""})},this._openAlignDialog=()=>this._previewAlignDialog(!1),this._toggleOptimizeLivePositions=()=>{const t=this.host._alignDialog;t&&!t.busy&&t.report.liveMissingPositions.length&&this._previewAlignDialog(!t.removeLiveMissingPositions)},this._openBackupExport=()=>{this.host._settingsDialog=null,this.host._backupExportDialog={kind:"full",planOnly:!1,busy:!1,error:""}},this._decorStylePersistTimer=null,this._openRulesDialog=()=>{if(!this.host._norm)return;const t=this.host._settings.icon_rules,e=(t&&t.length?t:Fe).map(t=>({...t}));this.host._rulesDialog={rules:e,test:"",busy:!1}},this._discoveryPreviewMemo=null,this._decorImages=new vd(t,{decorSnap:(t,e)=>this._decorSnap(t,e),geometrySnapshot:()=>this._geometrySnapshot(),clearFurniturePreview:()=>this._clearFurniturePreview(),recordGeometry:(t,e)=>this._recordGeometry(t,e),saveConfig:()=>this._saveConfig(),saveShape:()=>this._decorSaveShape(),setGuardReplace:t=>{this._decorAssetGuardReplace=t},furnShiftDetach:()=>this._furnShiftDetach(),furnPick:t=>this._furnPick(t),furnFieldValue:t=>this._furnFieldValue(t),furnFieldToCm:t=>this._furnFieldToCm(t)}),this._radarSetup=new oc({hass:()=>t.hass,requestUpdate:()=>t.requestUpdate(),t:(e,s)=>t._t(e,s),configFromDraft:Da,apply:e=>{t._markerDialog&&(t._markerDialog={...t._markerDialog,radar:e,radarEligible:!0,radarTouched:!0,radarRemove:!1})},confirmDiscard:()=>t._confirmDanger((t=>({key:"discard-radar-setup",kind:"warning",title:t("radar.discard_setup_title"),message:t("radar.discard_setup"),confirmLabel:t("btn.close"),cancelLabel:t("btn.cancel")}))(e=>t._t(e)))}),t._editorSecondary=new ad({root:()=>t.renderRoot,requestUpdate:()=>t.requestUpdate(),updateComplete:()=>t.updateComplete,clearTip:()=>{t._tip=null}}),t._resize=new Jl}_routeLiveEditorUpdate(t,e){const s=Or(this.host,t,e);return!s&&this.host._resize.preview&&(this._resizeBaseFrameStable=!1),s}_commitLiveEditor(){!function(t){const e=t,s=Nr(t);s.raf&&"function"==typeof cancelAnimationFrame&&cancelAnimationFrame(s.raf),s.raf=0,Wr(s);const i=e.renderRoot?.querySelector("[data-hp-live-editor]");i&&St(d,i);const o=e.renderRoot?.querySelector("[data-hp-live-editor-html]");if(o){const t=e._viewOr(e._baseVb());St(e._renderLiveEditorMeasurements(t),o)}Ar(s,s.requestedRevision)}(this.host)}_disposeLiveEditor(){this._radarSetup.reset(),function(t){Lr(t);const e=Tr.get(t);e&&(e.raf&&"function"==typeof cancelAnimationFrame&&cancelAnimationFrame(e.raf),Wr(e),Ar(e,e.requestedRevision),Tr.delete(t))}(this.host)}_cancelRadarSetup(){this._radarSetup.interrupt()}async _whenLiveEditorSettled(){await this.host.updateComplete,await function(t){const e=Tr.get(t);if(!e||!e.raf||e.paintedRevision>=e.requestedRevision)return Promise.resolve();const s=e.requestedRevision;return new Promise(t=>e.waiters.push({revision:s,resolve:t}))}(this.host)}_queuePointerMove(t,e){Dr(this.host,t,e)}_flushPointerMove(t){Ir(this.host,t)}_cancelPointerMove(t){Lr(this.host,t)}_help(t){const e=`${t}.aria`,s=l(this.host.hass,this.host._config?.language);return Ne(s,t)&&Ne(s,e)?p` `:d}_setMode(t,e=!0){t!==this.host._mode&&this.host._cancelDangerConfirm(),this.host._endTabDrag(),this._clearFurniturePreview(),this.host._pendingNavMode=null;const s=this.host._spaceModel();if(!s)return this.host._cancelModeTransition(!1),void(this.host._mode="view");if(this.host._kiosk&&"view"!==t)return;if(this.host._mode===t){if(!e&&"view"===t&&this.host._modeTransitionBusy){const e=this.host._currentModeVisual(t),s=this.host._modeTransitionTargetZoom,i=this.host._modeTransitionTargetCenterX,o=this.host._modeTransitionTargetCenterY;this.host._cancelModeTransition(!1),this.host._commitViewModeAtomic(e,s,i,o)}return}if("devices"===this.host._mode&&this.host._cancelDeviceDrag(),this.host._bootSoftCancel(),("plan"===t||"decor"===t)&&!this.host._norm)return void this.host._showToast(this.host._t("toast.markup_needs_server"));if(this.host._wallFaceBatch&&this._roomDialogCancel(),"plan"===this.host._mode&&"draw"===this.host._tool&&!this._finishWallChain())return;this.host._clearTransientHover(!0),this.host._cancelDevicePressFeedback();const i=this.host._mode,o=this.host._effectiveProjection(),a=this.host._currentModeVisual(i),n=this.host._modeTransitionBusy,r=a&&"view"!==i&&"view"!==t?{...a,toolbarContentOpacity:this.host._reducedMotion?1:.35}:a;this.host._cancelModeTransition(!1),this.host._editorSecondary.closeForNavigation(),(this.host._decorMove||this.host._dtDrag||this.host._bdDrag)&&this._cancelDecorGesture();const l=!s.bg&&"view"===t!=("view"===i),h=n&&"view"===i&&"view"!==t?this.host._modeTransitionEditorCamera:null;let c=h?.zoom??(n?this.host._modeTransitionTargetZoom:this.host._zoom),d=h?h.centerX:n?this.host._modeTransitionTargetCenterX:r?.viewport.centerX,p=h?h.centerY:n?this.host._modeTransitionTargetCenterY:r?.viewport.centerY;if("view"===i&&"view"!==t&&!n){const e=this.host._view;if(this.host._viewModeSnap={space:this.host._space,zoom:this.host._zoom,cx:e?this.host._logicalViewCenter(o)?.x:void 0,cy:e?this.host._logicalViewCenter(o)?.y:void 0,w:"flat"===o?e?.w:void 0},"iso"===o){const e=this.host._logicalViewCenter("iso");d=e?.x,p=e?.y,this.host._view=null,this.host._mode=t,this.host._applyView(this.host._zoom,e?.x,e?.y)}l&&(c=1,d=void 0,p=void 0)}if(this.host._mode=t,"devices"===i&&"devices"!==t&&(this.host._showHidden=!1,this.host._deviceInbox=null,this.host._deviceInboxReturn=null,this.host._deviceInboxMemo=null),this.host._editorChromeMode="view"===t?i:t,"view"===t){"view"===i||n||(this.host._modeTransitionEditorCamera={zoom:this.host._zoom,centerX:r?.viewport.centerX,centerY:r?.viewport.centerY});const t=this.host._viewModeSnap;if(t&&t.space===this.host._space){c=t.zoom;const e=this.host._labsIso&&"iso"===this.host._viewPreference[this.host._space]?"iso":"flat",s=null!=t.cx&&null!=t.cy&&"iso"===e?Ae([t.cx,t.cy],0):null;d=s?.[0]??t.cx,p=s?.[1]??t.cy}else t&&(c=this.host._zoomBySpace[this.host._space]||1,d=void 0,p=void 0)}else this.host._modeTransitionEditorCamera={zoom:c,centerX:d,centerY:p};this.host._modeTransitionTargetZoom=c,this.host._modeTransitionTargetCenterX=d,this.host._modeTransitionTargetCenterY=p,("iso"===o||"view"===t&&this.host._labsIso&&"iso"===this.host._viewPreference[this.host._space])&&(this.host._modeTransitionForceAtomic=!0);const u=++this.host._modeTransitionRequest;e?r?(this.host._modeTransitionPreparing=!0,this.host._modeTransitionVisual=r,this.host._prepareModeTransition(u,r,t,c,d,p)):(this.host._modeTransitionPreparing=!1,this.host._modeTransitionVisual=null,this.host._zoom=c,this.host._view=null,requestAnimationFrame(()=>{this.host.isConnected&&u===this.host._modeTransitionRequest&&this.host._mode===t&&(this.host._applyView(c,d,p),"view"===t&&(this.host._viewModeSnap=null,this.host._modeTransitionEditorCamera=null),this.host.requestUpdate())})):"view"===t&&this.host._commitViewModeAtomic(r,c,d,p),this.host._path=[],this._clearPlanSnapHover(),this._clearOpeningPlacement(!0),this.host._tool="draw",this.host._mergeSel=null,this.host._mergeDialog=null,this.host._splitSel=null,this.host._pendingSplit=null,this.host._selId=null,this.host._physicalSel=null,this.host._physicalDialog=null,this.host._physicalDrag=null,this._rszResetController(),this.host._tip=null,this.host._hoverRoom=null,this.host._decorDraft=null,this.host._decorSel=null,this.host._decorMove=null,this.host._backdropDialog=null,this.host._decorTool="select",this.host._bdDrag=null,this.host._dtDrag=null,this.host._dtBox=null,"plan"===t&&this._primeDrawWallField(),this.host._saveNav()}_primeDrawWallField(){null===this.host._drawWallField&&(this.host._drawWallField=Ee(B,this.host._imperial))}_showPhysicalRange(t=this.host._drawWallMaxCm,e=0){this.host._showToast(this.host._t("toast.physical_range",{min:Ee(e,this.host._imperial),max:Ee(t,this.host._imperial),unit:this.host._t(this.host._imperial?"wallthick.unit_in":"wallthick.unit_cm")}))}_mergeSpacePartitions(t,e){const s=t?.partitions||[];if(s.length<2)return 0;const i=Ja(s,{pitch:z,seedIds:e,geometry:Ya(t)});return i.merged?(t.partitions=i.partitions,Za(t.openings,t.partitions,i.openingMoves,{coordScale:jd,cellCm:this.host._cellCm,gridPitch:this.host._gridPitch}),i.merged):0}_finalizeWallChainPartitions(t){if(!t.length)return!0;const e=this.host._curSpaceCfg,s=this.host._spaceModel(),i=this._geometrySnapshot();if(!e||!s||!i)return!1;const o=t.map(t=>fh(e,t)).find(Boolean)||null,a={path:this.host._path.map(t=>[...t]),chainId:this.host._activeWallChainId,ids:[...this.host._activeWallChainPartitionIds],cms:[...this.host._wallChainSegmentCms],redo:this.host._wallChainRedo.map(t=>({...t,point:[...t.point]})),closingCm:this.host._closingWallCm};let n;try{n=Fd(e,s,this.host._openCuts(),t,{pitch:this.host._wallKeyPitch,cellCm:this.host._cellCm,gridPitch:this.host._gridPitch,coordScale:jd})}catch{return this.host._showToast(this.host._t("toast.geometry_unsafe")),!1}if(!n.report.changed)return!0;const r=this.host._serverCfg,l=r?.spaces?.findIndex(t=>t.id===i.spaceId)??-1;if(l<0)return!1;r.spaces[l]=n.space;const h=function(t,e,s,i){const{host:o}=t,a=o._serverCfg,n=()=>t._commitPhysicalGeometry(e,s,[],!1);if(!s||!a||!i||10!==Number(a.model_version||0))return n();let r;try{r=Jn(a).config}catch(e){return t._clearGeometryGesture(),t._restoreGeometryStateLocal(s),t._showWallModelMigrationBlocked(e),!1}const l=r.spaces.find(t=>t.id===s.spaceId),h=JSON.parse(JSON.stringify(a));if(!l||!t._restoreGeometryStateInConfig(h,s))return n();const c=h.spaces.find(t=>t.id===s.spaceId),d=bh(l,i),p=bh(c,i);if(!d||!p)return n();const u={...r,spaces:[d.space]},_={...h,spaces:[p.space]};let m=null,g=!1;try{const t=o._path.length>=2?o._path.map(t=>[t[0]/vh,t[1]/vh]):[];g=Sn(l)<=Sn(s,t)&&o._checkSpacePhysicalGeometry(u,s.spaceId,t=>{m=t}).ok}catch{g=!1}if(!g)return yh(t,s);const f=t._junctionLimitsIntroduced(u,_,s.spaceId,m,d.roomIds);if(f.length)return t._clearGeometryGesture(),t._restoreGeometryStateLocal(s),o._showToast(t._junctionLimitLabel(f[0])),!1;Yn(a,r);const b=a.spaces.find(t=>t.id===s.spaceId),v=o._pendingPhysicalWrites.get(s.spaceId);return o._pendingPhysicalWrites.set(s.spaceId,{before:v?.before||s,fingerprint:Yt(b)}),t._saveConfig(),!0}(this,this.host._t("history.wall_segment"),i,o);return!!h||(this.host._path=a.path,this.host._activeWallChainId=a.chainId,this.host._activeWallChainPartitionIds=a.ids,this.host._wallChainSegmentCms=a.cms,this.host._wallChainRedo=a.redo,this.host._closingWallCm=a.closingCm,!1)}_finishWallChain(){return!("draw"===this.host._tool&&!this.host._wallFaceBatch&&!this.host._roomDialog)||!!this._finalizeWallChainPartitions(this.host._activeWallChainPartitionIds)&&(this.host._path=[],this.host._activeWallChainId=null,this.host._activeWallChainPartitionIds=[],this.host._wallChainSegmentCms=[],this.host._wallChainRedo=[],this.host._closingWallCm=null,this._clearPlanSnapHover(),!0)}_activateMarkupTool(t){t!==this.host._tool&&(this.host._wallFaceBatch&&this._roomDialogCancel(),("draw"!==this.host._tool||this._finishWallChain())&&(this._cancelPath(),"resize"===this.host._tool&&(this.host._resize.dragging?this._rszCancelDrag():this.host._resize.reset()),this.host._tool=t,"resize"===t&&this.host._resize.selectRoom(null),"wallthick"===t&&(this.host._wallDialog=null)))}_limitReached(t){const e=this.host._curSpaceCfg;if(!e)return!0;const s="partition"===t?(e.partitions||[]).length>=Gd:(e.wall_columns||[]).length>=500;return s&&this.host._showToast(this.host._t("toast.physical_limit")),s}_svgPoint(t){const e=this.host.renderRoot.querySelector(".stage").getBoundingClientRect();return this.host._screenToVb(t.clientX-e.left,t.clientY-e.top)}_snap(t){const e=this.host._gridPitch;return[Oe(Be(t[0],e)),Oe(Be(t[1],e))]}_snapDrawPoint(t,e=!1){const s=this.host._path[this.host._path.length-1],i=e&&s?He(s,t,this.host._gridPitch,po):t;return this._snap(i)}_planSnapOpeningCuts(t,e){if(!this.host._openingsR.length)return[];const s=this.host._openingWallIndexFor(t,e).value,i=[];for(const e of this.host._roomWallOpeningInputs(this.host._openingsR,t)){const t=K(s,e);if(!t.negative&&!t.positive)continue;const o=e.angle*Math.PI/180,a=Math.cos(o)*e.length/2,n=Math.sin(o)*e.length/2;i.push([e.x-a,e.y-n,e.x+a,e.y+n])}return i}_planSnapGeometrySnapshot(){const t=this.host._spaceModel();if(!t)return{key:`${this.host._space}|empty`,value:{segments:[],endpoints:[]}};const e=[this.host._space,this.host._cfgEpoch,t.rooms.length,t.partitions.length].join("|");if(this.host._planSnapGeometryCache?.key===e)return this.host._planSnapGeometryCache;const s=this.host._openCuts(),i=mc({space:t,roomCuts:this._planSnapOpeningCuts(t,s),partitionCuts:this._partitionOpeningCuts(t),epsilon:2e-4*this.host._gridPitch});return this.host._planSnapGeometryCache={key:e,value:i},this.host._planSnapGeometryCache}_hiddenWallDiagnosticSnapshot(){const t=this.host._spaceModel();if(!t)return{key:`${this.host._space}|hidden-empty`,value:{segments:[],endpoints:[]}};const e=["hidden",this.host._space,this.host._cfgEpoch,t.rooms.length,t.partitions.length].join("|");if(this.host._hiddenWallDiagnosticCache?.key===e)return this.host._hiddenWallDiagnosticCache;const s=_c({space:t,epsilon:2e-4*this.host._gridPitch});return this.host._hiddenWallDiagnosticCache={key:e,value:s},this.host._hiddenWallDiagnosticCache}_planStructuralGeometrySnapshot(){const t=this.host._spaceModel();if(!t)return{key:`${this.host._space}|structural-empty`,value:{segments:[],endpoints:[]}};const e=["structural",this.host._space,this.host._cfgEpoch,t.rooms.length,t.partitions.length].join("|");if(this.host._planStructuralGeometryCache?.key===e)return this.host._planStructuralGeometryCache;const s=mc({space:t,epsilon:2e-4*this.host._gridPitch});return this.host._planStructuralGeometryCache={key:e,value:s},this.host._planStructuralGeometryCache}_planSnapContextKey(t){const e=this.host._path[0],s=this.host._path[this.host._path.length-1];return[t,this.host._tool,this.host._path.length,e?`${e[0]},${e[1]}`:"",s?`${s[0]},${s[1]}`:""].join("|")}_resolvePlanDrawPoint(t,e){const s=this._planSnapGeometrySnapshot(),i=this.host._path[this.host._path.length-1],o="draw"===this.host._tool&&this.host._path.length>=3?[{point:this.host._path[0],key:"closure:first-point"}]:[],a=this.host._path.length>1?this.host._path.slice(1):i?[i]:[],n={tolerance:this._cssPxToRender(12),distinguishTolerance:this._cssPxToRender(8),gridStep:this.host._gridPitch,excludePoints:a,extraEndpoints:o,epsilon:2e-4*this.host._gridPitch},r=e&&i?wc(s.value,t,{...n,anchor:i}):function(t,e,s){if(!(nc(e)&&s.tolerance>=0))return{kind:"none",candidate:null,conflicts:[]};const i=s.epsilon??ac,o=s.excludePoints||[],a=vc(bc(t,e,s),s.distinguishTolerance||0);if(a)return a;let n=null;for(const a of t.segments){const t=[a.a[0],a.a[1],a.b[0],a.b[1]],r=de([e[0],e[1]],t);if(r>s.tolerance)continue;const l=yc(a,e,s.gridStep);!gc(l,o,i)&&fc(r,a.key,n)&&(n={kind:"line",point:l,key:a.key,distance:r,segment:a})}return n?{kind:"resolved",candidate:n,conflicts:[]}:{kind:"none",candidate:null,conflicts:[]}}(s.value,t,n),l="resolved"===r.kind?r.candidate:null,h=l?[...l.point]:this._snapDrawPoint(t,e),c=i?We(i,h):h;return{point:c,candidate:l&&st(c,l.point)?l:null,conflicts:"ambiguous"===r.kind?r.conflicts:[],ambiguous:"ambiguous"===r.kind,contextKey:this._planSnapContextKey(s.key)}}_clearPlanSnapHover(t=!0){this.host._planSnapHover=null,this._syncPlanSnapActiveMarker(null),this._syncPlanSnapConflictMarkers([]),t&&(this.host._cursorPt=null)}_samePt(t,e){return st(t,e)}_dropLegacySegments(t=this.host._serverCfg){for(const e of t?.markers||[])"ripple"===e.display&&(e.display="icon_ripple");for(const e of t?.spaces||[]){delete e.segments;const t=new Set,s=e=>"string"==typeof e&&e.length>=1&&e.length<=64&&!t.has(e),i=e=>(t.add(e),!0),o=t=>Array.isArray(t)&&2===t.length&&t.every(t=>Number.isFinite(Number(t))&&Math.abs(Number(t))<=be);if(Array.isArray(e.partitions)&&(e.partitions=e.partitions.filter(t=>t&&s(t.id)&&o(t.a)&&o(t.b)&&Math.hypot(t.a[0]-t.b[0],t.a[1]-t.b[1])>1e-9&&i(t.id)).map(t=>({...t,cm:Number.isFinite(Number(t.cm))?Math.max(0,Math.min(100,Number(t.cm))):15})),e.partitions.length||delete e.partitions),Array.isArray(e.wall_columns)&&(e.wall_columns=e.wall_columns.filter(t=>t&&s(t.id)&&o(t.center)&&i(t.id)).map(t=>({id:t.id,shape:"circle"===t.shape?"circle":"square",center:[Number(t.center[0]),Number(t.center[1])],cm:Se(Number(t.cm)||15),..."circle"===t.shape?{}:{angle:je(t.angle)}})),e.wall_columns.length||delete e.wall_columns),Array.isArray(e.walls)){const t=Ge(bt({spaces:[e]}),e.id),s=t?qe(e,t,jd,.02*ct).contour.map(t=>t.map(t=>t/jd)):Y(e.open_spans).map(t=>[t.a[0],t.a[1],t.b[0],t.b[1]]);e.walls=dt(e.walls,e.rooms||[],z,1,s),e.walls.length||delete e.walls}}}_rollbackRejectedPhysicalWrites(t){if(!this.host._serverCfg||!t.length)return!1;let e=!1;for(const[s]of t){const t=this.host._pendingPhysicalWrites.get(s);t&&(e=this._restoreGeometryStateInConfig(this.host._serverCfg,t.before)||e,this.host._pendingPhysicalWrites.delete(s))}return!!e&&(this._clearGeometryGesture(),this.host._geometryHistory.clear(),this.host._cfgEpoch++,this.host._modelCache=null,this.host._wallUnionCache=null,this.host._physicalBodiesCache=null,this.host._frame=null,this.host._regSignature="",this.host._adoption.refreshConfigFingerprint(),this.host._maybeRebuildDevices(),this.host.requestUpdate(),!0)}async _reloadRejectedPhysicalWrite(){const t=this.host._writeChain;await t.catch(()=>{}),await this.host._reloadConfigOnly(!0)}_prepareConfigCandidate(t){return this._dropLegacySegments(t),Ue(t)}_writeConfig(t=null){this.host._writesPending++,this.host._writeChain=Ke(this.host._writeChain,async()=>{if(!this.host._serverCfg)return;const e=yt(this.host._serverCfg),s=this._prepareConfigCandidate(this.host._serverCfg),i=yt(s);t&&e===t.attemptedFingerprint&&Object.assign(t,{revision:this.host._cfgRev,attempted:s,attemptedFingerprint:i});const o=[...this.host._pendingPhysicalWrites.entries()];for(const[t,e]of o){const i=s.spaces.find(e=>e.id===t),o=Yt(i);if(o===e.fingerprint)continue;let a=!1;try{a=this.host._checkSpacePhysicalGeometry(s,t).ok}catch{a=!1}if(!a)throw this._restoreGeometryStateLocal(e.before),this.host._pendingPhysicalWrites.delete(t),this.host._geometryHistory.clear(),this.host._showToast(this.host._t("toast.geometry_unsafe")),Object.assign(new Error("unsafe wall geometry"),{code:"geometry-unsafe"});e.fingerprint=o}this.host._adoption.stageConfigCandidate(s);try{await this.host._sendConfigCandidate(s)}catch(t){if(!this._rollbackRejectedPhysicalWrites(o))throw t;const e=t&&"object"==typeof t?t:Object.assign(new Error(String(t)),{cause:t});throw e.physicalGeometryRolledBack=!0,e}for(const[t,e]of o)this.host._pendingPhysicalWrites.get(t)?.fingerprint===e.fingerprint&&this.host._pendingPhysicalWrites.delete(t)});return this.host._writeChain.finally(()=>{this.host._writesPending--})}_saveConfig(){this.host._cfgEpoch++,this.host._saveConfigDebounced()}_geometrySnapshotFromConfig(t,e){const s=t?.spaces?.find(t=>t.id===e);if(!s)return null;const i=t=>JSON.parse(JSON.stringify(t)),o={};for(const t of["plan_x","plan_y","plan_scale","plan_scale_x","plan_scale_y","plan_angle"])void 0!==s[t]&&(o[t]=s[t]);return{spaceId:e,rooms:i(s.rooms||[]),...Array.isArray(s.openings)?{openings:i(s.openings)}:{},...Array.isArray(s.walls)?{walls:i(s.walls)}:{},...Array.isArray(s.wall_segments)?{wall_segments:i(s.wall_segments)}:{},...Array.isArray(s.open_spans)?{open_spans:i(s.open_spans)}:{},...Array.isArray(s.partitions)?{partitions:i(s.partitions)}:{},...Array.isArray(s.wall_columns)?{wall_columns:i(s.wall_columns)}:{},...Array.isArray(s.decor)?{decor:i(s.decor)}:{},plan_transform:o}}_geometrySnapshot(t=this.host._space){return this._geometrySnapshotFromConfig(this.host._serverCfg,t)}_recordGeometry(t,e){if(!e)return;const s=this._geometrySnapshot(e.spaceId);s&&JSON.stringify(e)!==JSON.stringify(s)&&(e.wallChainSeedIds&&(s.wallChainSeedIds=[...this.host._activeWallChainPartitionIds]),e.roomReferences&&(s.roomReferences=Ed(this.host._serverCfg?.markers||[],e.roomReferences.map(t=>t.markerId))),this.host._geometryHistory.push({name:t,before:e,after:s}),this.host.requestUpdate())}_restoreGeometryStateInConfig(t,e,s=!1){const i=t?.spaces?.find(t=>t.id===e.spaceId);if(!i)return!1;const o=t=>JSON.parse(JSON.stringify(t)),a=new Map((i.rooms||[]).map(t=>[t.id,t]));if(i.rooms=o(e.rooms),s)for(const t of i.rooms){const e=a.get(t.id);!Array.isArray(t.wall_ids)&&Array.isArray(e?.wall_ids)&&e.wall_ids.length===t.poly?.length&&(t.wall_ids=o(e.wall_ids))}const n=(t,e)=>{void 0!==e?i[t]=o(e):s&&"wall_segments"===t||delete i[t]},r=new Map((i.openings||[]).map(t=>[t.id,t]));if(n("openings",e.openings),n("walls",e.walls),n("wall_segments",e.wall_segments),n("open_spans",e.open_spans),n("partitions",e.partitions),n("wall_columns",e.wall_columns),n("decor",e.decor),s)for(const t of i.openings||[]){const e=r.get(t.id);t.host||"wall"!==e?.host?.kind||(t.host=o(e.host))}for(const t of["plan_x","plan_y","plan_scale","plan_scale_x","plan_scale_y","plan_angle"])delete i[t];return Object.assign(i,o(e.plan_transform||{})),e.roomReferences&&(t.markers||=[],function(t,e){const s=new Map((t||[]).map(t=>[t?.id,t]));for(const t of e){const e=s.get(t.markerId);e&&(t.roomIdPresent?e.room_id=Nd(t.roomId):delete e.room_id,t.segmentMapPresent?(e.vacuum&&"object"==typeof e.vacuum&&!Array.isArray(e.vacuum)||(e.vacuum={}),e.vacuum.segment_map=Nd(t.segmentMap)||{}):e.vacuum&&"object"==typeof e.vacuum&&!Array.isArray(e.vacuum)&&(delete e.vacuum.segment_map,t.vacuumPresent||0!==Object.keys(e.vacuum).length||delete e.vacuum))}}(t.markers,e.roomReferences)),!0}_canonicalWallChainHistoryState(t){if(this.host._activeWallChainId||!t.wallChainSeedIds?.length)return t;if(!this.host._serverCfg)return null;const e=JSON.parse(JSON.stringify(this.host._serverCfg));if(!this._restoreGeometryStateInConfig(e,t))return null;let s;try{s=Jn(e).config}catch{return null}const i=s.spaces?.find(e=>e.id===t.spaceId),o=Ge(bt(s),t.spaceId);if(!i||!o)return null;const a=Fd(i,o,Ve(i,o,ct,jd),t.wallChainSeedIds,{pitch:z,cellCm:Number(i.cell_cm)>0?Number(i.cell_cm):5,gridPitch:ct,coordScale:jd}),n=s.spaces.findIndex(e=>e.id===t.spaceId);let r;s.spaces[n]=a.space;try{r=Jn(s).config}catch{return null}const l=this._geometrySnapshotFromConfig(r,t.spaceId);return l?(l.wallChainSeedIds=[...t.wallChainSeedIds],t.roomReferences&&(l.roomReferences=JSON.parse(JSON.stringify(t.roomReferences))),l):null}_restoreGeometryStateLocal(t){return!!this._restoreGeometryStateInConfig(this.host._serverCfg,t)&&(this.host._cfgEpoch++,this.host._modelCache=null,this.host._wallUnionCache=null,this.host._physicalBodiesCache=null,this.host._frame=null,this.host.requestUpdate(),!0)}_wallModelBlockerLabel(t){const e=t instanceof vn?t.reason:"invalid-room";return this.host._t(`wall_model.reason.${e}`)}_hasLegacyZeroWallFields(t=this.host._serverCfg){return(t?.spaces||[]).some(t=>Array.isArray(t?.open_spans)&&t.open_spans.length>0||(t?.rooms||[]).some(t=>Array.isArray(t?.open_to)&&t.open_to.length>0))}_showWallModelMigrationBlocked(t){const e=this._hasLegacyZeroWallFields()?"toast.zero_wall_migration_blocked":"toast.wall_model_migration_blocked";this.host._showToast(this.host._t(e,{reason:this._wallModelBlockerLabel(t)}))}_limitSegmentsOf(t){const e=[];for(const s of t?.wall_segments||[])s?.a&&s?.b&&e.push({id:String(s.id||""),a:s.a,b:s.b,cm:Number(s.cm)});for(const s of t?.partitions||[])s?.a&&s?.b&&e.push({id:String(s.id||""),a:s.a,b:s.b,cm:Number(s.cm)});return e}_junctionLimitViolations(t,e,s,i){const o=(t?.spaces||[]).find(t=>t?.id===e);return o?function(t,e,s,i,o){const a=(t?.spaces||[]).find(t=>t?.id===e);if(!a)return[];const n=Number(a.cell_cm)>0?Number(a.cell_cm):5,r=[...Hh(s),...Uh(s,n,z),...Vh(s,n,z)];let l=i?.multiWallNodes||null;if(!l)try{l=ie(a.rooms||[],a.walls||[],[],z,n,z,1)}catch{l=null}const h=i&&"lightweight"!==i.status?i:null;let c="ok"===h?.status||"degraded-extra"===h?.status?h.roomGeom:null;const d=null===i||"lightweight"===i?.status;if(!c&&!d&&l?.nodes.length)try{const t=oe(a.rooms||[],a.walls||[],[],[],z,n,z,1);c="ok"===t?.status||"degraded-extra"===t?.status?t.roomGeom:null}catch{c=null}for(const t of a.rooms||[]){const e=String(t?.id||"");if(!e||o&&!o.has(e))continue;let s=null;try{s=ae(a.rooms||[],e,a.walls||[],[],z,n,z,1,d?null:c??void 0,l)}catch{s=null}r.push(...Jh(e,s,n,z))}return r}(t,e,this._limitSegmentsOf(o),s,i):[]}_junctionLimitLabel(t){const e=t=>String(Math.round(10*t)/10);return this.host._t(`junction.limit_${t.rule}`,{actual:e(t.actual),limit:e(t.limit)})}_junctionLimitsIntroduced(t,e,s,i,o){const a=o?.length?new Set(o):void 0;let n;const r=(e.spaces||[]).find(t=>t?.id===s);let l="";try{l=Yt(r)}catch{l=""}const h=!a&&e&&"object"==typeof e?this._junctionBaselineCache.get(e):void 0;if(h&&l&&h.fingerprint===l&&h.spaceId===s&&(n=h.violations),!n){try{const t=Number(e?.model_version||0)>=10?e:Jn(e).config;n=this.host._junctionLimitViolations(t,s,a?null:void 0,a)}catch{return[]}!a&&e&&"object"==typeof e&&l&&this._junctionBaselineCache.set(e,{spaceId:s,fingerprint:l,violations:n})}let c=[],d=n;try{c=this.host._junctionLimitViolations(t,s,i,a),a&&(d=n.filter(t=>"clearance"!==t.rule||a.has(t.subject)))}catch{return[{rule:"check_failed",subject:s,actual:0,limit:0}]}return Zh(c,d)}_commitPhysicalGeometry(t,e,s=[],i=!0){if(!e||!this.host._serverCfg)return!1;const o=this.host._serverCfg,a=t=>{const s=t?.spaces?.find(t=>t.id===e.spaceId);return s?{...t,spaces:[s]}:t},n=this._geometrySnapshotFromConfig(o,e.spaceId),r=o.spaces.find(t=>t.id===e.spaceId);if(!r||Yt(e)===Yt(r))return!1;let l,h=!1;try{h=this.host._checkSpacePhysicalGeometry(a(o),e.spaceId).ok}catch{h=!1}if(!h)return this._clearGeometryGesture(),this._restoreGeometryStateLocal(e),this.host._showToast(this.host._t("toast.geometry_unsafe")),!1;let c=e;try{if(Number(o.model_version||0)<9){const t=JSON.parse(JSON.stringify(o));if(!this._restoreGeometryStateInConfig(t,e))throw new vn("invalid-room",e.spaceId);const s=Jn(t).config;c=this._geometrySnapshotFromConfig(s,e.spaceId)||e,c.wallChainSeedIds=e.wallChainSeedIds,c.roomReferences=e.roomReferences;const i=JSON.parse(JSON.stringify(s));if(!n||!this._restoreGeometryStateInConfig(i,n,!0))throw new vn("invalid-room",e.spaceId);const a=s.spaces.find(t=>t.id===e.spaceId),r=i.spaces.find(t=>t.id===e.spaceId);if(!Array.isArray(n.wall_segments)&&JSON.stringify(e.rooms)===JSON.stringify(n.rooms))for(const t of r?.wall_segments||[])t.cm=it(n.walls,t.a,t.b,z,1);const h=((t,e,s)=>{const i=new Map,o=new Map((t?.rooms||[]).map(t=>[t.id,t])),a=new Map((e||[]).map(t=>[t.id,t])),{rooms:n}=En(s,Nn(t));for(const t of n){const e=a.get(t.id),n=o.get(t.id),r=N(e),l=(s.rooms||[]).find(e=>e.id===t.id),h=N(l),c=N(n);if(r&&h&&c&&r.length===h.length&&c.length===n?.wall_ids?.length&&t.poly.length===t.wall_ids.length)for(let e=0;e{const o=[];for(let a=0;abn||Dn(r,s,i)>bn)continue;const l=Pn(n,s,i),h=Pn(r,s,i);l<-1e-9||h>1+bn||h<=l+bn||o.push({start:l,id:e[a]})}return o.sort((t,e)=>t.start-e.start)},o=s(c,n.wall_ids,r[e],r[(e+1)%r.length]),a=s(t.poly,t.wall_ids,h[e],h[(e+1)%h.length]);if(o.length&&o.length===a.length)for(let t=0;tt.id===e.spaceId),i=this.host._path.length>=2?this.host._path.map(t=>[t[0]/jd,t[1]/jd]):[];i.push(...s.map(t=>[t[0],t[1]])),d=Sn(t)<=Sn(c,i)&&this.host._checkSpacePhysicalGeometry(a(l),e.spaceId).ok}catch{d=!1}if(!d)return this._clearGeometryGesture(),this._restoreGeometryStateLocal(e),this.host._showToast(this.host._t("toast.geometry_unsafe")),!1;const p=JSON.parse(JSON.stringify(o));this._restoreGeometryStateInConfig(p,e);const u=this._junctionLimitsIntroduced(l,p,e.spaceId);if(u.length)return this._clearGeometryGesture(),this._restoreGeometryStateLocal(e),this.host._showToast(this._junctionLimitLabel(u[0])),!1;Yn(o,l),i&&this._recordGeometry(t,c);const _=o.spaces.find(t=>t.id===e.spaceId),m=this.host._pendingPhysicalWrites.get(e.spaceId);return this.host._pendingPhysicalWrites.set(e.spaceId,{before:m?.before||c,fingerprint:Yt(_)}),this._saveConfig(),!0}_clearGeometryGesture(){this._clearFurniturePreview(),this.host._path=[],this._clearPlanSnapHover(),this._clearOpeningPlacement(!1),this.host._mergeSel=null,this.host._mergeDialog=null,this.host._splitSel=null,this.host._pendingSplit=null,this.host._wallFaceBatch=null,this.host._wallRepairDiagnostic=null,this.host._roomDeleteDialog=null,this.host._wallDialog=null,this.host._physicalDialog=null,this.host._physicalSel=null,this.host._physicalDrag=null,this.host._physicalRotate=null,this.host._activeWallChainId=null,this.host._activeWallChainPartitionIds=[],this.host._wallChainSegmentCms=[],this.host._wallChainRedo=[],this.host._closingWallCm=null,this.host._openingDialog=null,this._rszResetController(),this.host._decorDraft=null,this.host._decorMove=null,this.host._dtDrag=null,this.host._bdDrag=null}_stagePointerCancel(t){return clearTimeout(this.host._kioskHoldTimer),this.host._swipeStart?.id===t.pointerId&&(this.host._swipeStart=null),this.host._furnTouchPending?.pid===t.pointerId?(this._clearFurniturePreview(),this.host._pointers.delete(t.pointerId),void this.host.requestUpdate()):this.host._physicalDrag?.pid!==t.pointerId&&this.host._physicalRotate?.pid!==t.pointerId?this.host._decorDraft?.pid===t.pointerId?(this.host._decorDraft=null,void this.host.requestUpdate()):void(this.host._decorMove?.pid!==t.pointerId&&this.host._dtDrag?.pid!==t.pointerId&&this.host._bdDrag?.pid!==t.pointerId?("opening"===this.host._tool?(this.host._cursorPt=null,this._clearOpeningPlacement(!1)):"draw"===this.host._tool&&this._clearPlanSnapHover(),this.host._pointers.delete(t.pointerId),this.host._pointers.size<2&&(this.host._pinchStart=null),0===this.host._pointers.size&&(this.host._panStart=null,this.host._panLock=null),this.host._viewportGestureDirty&&0===this.host._pointers.size&&(this.host._viewportGestureDirty=!1,this.host.requestUpdate())):this._cancelDecorGesture()):void this._cancelPhysicalGesture()}_applyGeometryState(t,e=!1){const s=this._canonicalWallChainHistoryState(t);if(!s||!this.host._canCommitSpace(s.spaceId))return!1;const i=this._geometrySnapshot(s.spaceId);if(!i||!this._restoreGeometryStateLocal(s))return!1;const o=this.host._serverCfg,a=Yt(i)!==Yt(s);if(a){let t=!1;try{const i=o?this.host._checkSpacePhysicalGeometry(o,s.spaceId):null;t=!!i?.ok||!(!e||"wall-degraded-extra"!==i?.reason)}catch{t=!1}if(!t)return this._restoreGeometryStateLocal(i),this.host._showToast(this.host._t("toast.geometry_unsafe")),!1}let n;try{n=Jn(o).config}catch(t){return this._restoreGeometryStateLocal(i),this._showWallModelMigrationBlocked(t),!1}if(a){let t=!1;try{const i=n?this.host._checkSpacePhysicalGeometry(n,s.spaceId):null;t=!!i?.ok||!(!e||"wall-degraded-extra"!==i?.reason)}catch{t=!1}if(!t)return this._restoreGeometryStateLocal(i),this.host._showToast(this.host._t("toast.geometry_unsafe")),!1;Yn(o,n);const a=o?.spaces.find(t=>t.id===s.spaceId),r=this.host._pendingPhysicalWrites.get(s.spaceId);this.host._pendingPhysicalWrites.set(s.spaceId,{before:r?.before||i,fingerprint:Yt(a)})}else Yn(o,n);return this._clearGeometryGesture(),this.host._space!==s.spaceId&&(this.host._commitSpace(s.spaceId),this.host._saveNav(),this.host._restoreZoom()),this.host._modelCache=null,this.host._frame=null,this.host._regSignature="",this.host._maybeRebuildDevices(),this._saveConfig(),this.host.requestUpdate(),!0}_roomAt(t){return this.host._spaceModel()?.rooms.find(e=>{const s=N(e);return!!s&&Je(t,s)})}_overlapRoom(t){return this.host._spaceModel()?.rooms.find(e=>{const s=N(e);return!!s&&Vt(t,s)})}_pointInRoom(t,e){return e.poly?Ze(t,e.poly):null!=e.x&&t[0]>=e.x&&t[0]<=e.x+e.w&&t[1]>=e.y&&t[1]<=e.y+e.h}_contourSelfIntersects(t){if(!$l(t))return!0;const e=t.length,s=.001;for(let i=0;i=500)return this.host._showToast(this.host._t("toast.physical_limit")),!1;const t=this.host._curSpaceCfg;return!((t?.partitions||[]).length>=Gd)||(this.host._showToast(this.host._t("toast.physical_limit")),!1)}_markupClick(t){if(this.host._vacFit)return;if(!this.host._markup)return;const e=this.host._spaceModel();if(!e)return void this._clearGeometryGesture();if(this.host._suppressClick)return;if(this.host._drag||this.host._rlResize)return;const s=t.composedPath?.()||[];if(s.some(t=>t?.classList?.contains?.("roomlabel")||t?.classList?.contains?.("rlhandle")))return;if(s.some(t=>t?.classList?.contains?.("physical-hit")))return;const i=this._svgPoint(t);if("select"===this.host._tool)return void(this.host._physicalSel=null);if("resize"===this.host._tool){if(this.host._resize.dragging||s.some(t=>t?.classList?.contains?.("rszhandle")))return;const t=[...e.rooms].reverse().find(t=>this._pointInRoom(i,t));return this.host._resize.selectRoom(t?.id||null),void this.host.requestUpdate()}if("delroom"===this.host._tool)return void this._deleteRoomClick(i);if("opening"===this.host._tool)return void this._openingClick(i);if("merge"===this.host._tool)return void this._mergeClick(i);if("wallthick"===this.host._tool)return void this._wallThickClick(i);if("split"===this.host._tool)return void this._splitClick(i);if("column"===this.host._tool)return void this._columnClick(i);this.host._wallRepairDiagnostic=null;const o=this._resolvePlanDrawPoint(i,t.shiftKey);if(o.ambiguous)return this.host._planSnapHover={contextKey:o.contextKey,candidate:null,conflicts:o.conflicts},this._syncPlanSnapActiveMarker(null),this._syncPlanSnapConflictMarkers(o.conflicts),void this.host._showToast(this.host._t("toast.plan_snap_ambiguous"));let a=o.point;if(t.ctrlKey||t.metaKey){if(t.preventDefault(),this.host._path.length<3)return;a=We(this.host._path[this.host._path.length-1],this.host._path[0])}if(!this.host._path.length){if(!t.shiftKey&&!o.candidate&&this._offerExistingWallFace(i))return;return this.host._activeWallChainId=`chain-${Date.now().toString(36)}`,this.host._activeWallChainPartitionIds=[],this.host._wallChainSegmentCms=[],this.host._wallChainRedo=[],void(this.host._path=[a])}const n=this.host._path[this.host._path.length-1];if(this._samePt(a,n))return;if(!this._canAppendWallPoint())return;const r=this.host._drawWallCm;if(null==r)return void this._showPhysicalRange(100);const l=this.host._curSpaceCfg;if(!l)return;const h=this.host._path.map(t=>[...t]),c=this.host._activeWallChainId,d=[...this.host._activeWallChainPartitionIds],p=[...this.host._wallChainSegmentCms],u=this._wallGraphSources([]),_=this._geometrySnapshot();_&&(_.wallChainSeedIds=[...d]);const m=`partition-${crypto.randomUUID?.()||`${Date.now().toString(36)}-${Math.random().toString(36).slice(2)}`}`;if(l.partitions||=[],l.partitions.push({id:m,a:[n[0]/jd,n[1]/jd],b:[a[0]/jd,a[1]/jd],cm:r}),this.host._path=[...this.host._path,a],this.host._wallChainSegmentCms=[...this.host._wallChainSegmentCms,r],this.host._activeWallChainPartitionIds=[...d,m],this.host._wallChainRedo=[],!wh(this,this.host._t("history.wall_segment"),_))return this.host._activeWallChainId=c,this.host._activeWallChainPartitionIds=d,this.host._path=h,void(this.host._wallChainSegmentCms=p);this._offerWallFaces(h,h.length-1,u)}_activeWallSourceKey(t){const e=this.host._activeWallChainPartitionIds[t],s=e?this._planStructuralGeometrySnapshot().value.segments.find(t=>"partition"===t.sourceKind&&t.sourceId===e):null;return s?`static:${s.key}`:`active:${this.host._activeWallChainId||"session"}:${t}`}_wallGraphSources(t){return this._planStructuralGeometrySnapshot().value.segments.map(t=>({a:t.a,b:t.b,key:`static:${t.key}`}))}_wallFaceGraph(t,e){const s=`${this.host._space}|${e}|${JSON.stringify(t)}`,i=this.host._wallFaceGraphCache.findIndex(t=>t.key===s);if(i>=0){const[t]=this.host._wallFaceGraphCache.splice(i,1);return this.host._wallFaceGraphCache.push(t),t.value}const o=qc(t,e);return this.host._wallFaceGraphCache.push({key:s,value:o}),this.host._wallFaceGraphCache.length>4&&this.host._wallFaceGraphCache.shift(),o}_offerWallFaces(t,e=this.host._path.length-2,s){if(this.host._path.length<2||this.host._wallFaceBatch||this.host._roomDialog)return;const i=this.host._spaceModel();if(!i)return;const o=this._activeWallSourceKey(e),a=2e-4*this.host._gridPitch;let n,r;try{const e=s||this._wallGraphSources(t);r=this._wallGraphSources(this.host._path),n=function(t,e,s){const i=new Set(t.faces.map(t=>t.key));return e.faces.filter(t=>!i.has(t.key)&&t.sourceKeys.includes(s))}(this._wallFaceGraph(e,a),this._wallFaceGraph(r,a),o)}catch{return}if(!n.length){const t=id(r,{requiredSourceKey:o,maxDistance:V(2,this.host._cellCm,this.host._gridPitch),gridStep:this.host._gridPitch,epsilon:a});return"ambiguous"===t.kind?(this.host._wallRepairDiagnostic=t.proposals[0]||null,void this.host._showToast(this.host._t(0===this.host._drawWallCm?"toast.zero_wall_ambiguous":"toast.wall_repair_ambiguous"))):void("repair"!==t.kind||this._overlapRoom(t.face.ring)||this._beginWallFaceBatch([{...t.face,repair:t.proposal}]))}for(const t of i.rooms){const e=N(t);if(!t.id||!e)continue;const s=Ye(e,this.host._path,.02*this.host._gridPitch);if(!s)continue;const[i,o]=s,a=Zt(i)>=Zt(o)?i:o,r=a===i?o:i,l=[...n].sort((t,e)=>Math.abs(t.area-Zt(r))-Math.abs(e.area-Zt(r))||t.key.localeCompare(e.key))[0];if(!l)return;return void this._beginWallFaceBatch([{...l,ring:r.map(t=>[t[0],t[1]]),split:{roomId:t.id,mainPoly:a,newPoly:r},consumeAllActive:!0}])}const l=n.filter(t=>!(t.ring.length<3||this._contourSelfIntersects(t.ring))&&!this._overlapRoom(t.ring));l.length&&this._beginWallFaceBatch(l)}_beginWallFaceBatch(t){this.host._wallRepairDiagnostic=null,this.host._wallFaceBatch={candidates:[...t].sort((t,e)=>t.area-e.area||t.key.localeCompare(e.key)),index:0,decisions:[],activePath:this.host._path.map(t=>[...t]),activeCms:[...this.host._wallChainSegmentCms],activePartitionIds:[...this.host._activeWallChainPartitionIds]},this._clearPlanSnapHover(),this.host._nameSel="",this.host._areaSel="",this._resetRoomDialogFields(),this.host._roomDialog=!0}_offerExistingWallFace(t){if(this.host._path.length||this.host._wallFaceBatch||this.host._roomDialog)return!1;const e=2e-4*this.host._gridPitch;try{let s,i=Uc(this._wallFaceGraph(this._wallGraphSources([]),e),t,e);if(!i){const o=id(this._wallGraphSources([]),{point:t,maxDistance:V(2,this.host._cellCm,this.host._gridPitch),gridStep:this.host._gridPitch,epsilon:e});if("ambiguous"===o.kind)return this.host._wallRepairDiagnostic=o.proposals[0]||null,this.host._showToast(this.host._t(0===this.host._drawWallCm?"toast.zero_wall_ambiguous":"toast.wall_repair_ambiguous")),!0;if("repair"===o.kind)i=o.face,s=o.proposal;else if("none"===o.kind){const s=id(this._wallGraphSources([]),{point:t,maxDistance:this._cssPxToRender(12),gridStep:this.host._gridPitch,epsilon:e});if("repair"===s.kind)return this.host._wallRepairDiagnostic=s.proposal,this.host._showToast(this.host._t("toast.wall_repair_too_large")),!0}}return!(!i||i.ring.length<3||this._contourSelfIntersects(i.ring)||this._overlapRoom(i.ring))&&(this._beginWallFaceBatch([{...i,existing:!s,repair:s}]),!0)}catch{return!1}}_columnClick(t){const e=this._snap(t),s=this.host._drawWallCm;if(null==s)return void this._showPhysicalRange(xe,1);if(!this.host._curSpaceCfg||this._limitReached("column"))return;const i=this.host._spaceModel();if(!i)return;const o={id:"column-"+Date.now().toString(36),shape:"square",center:e,cm:Se(s),angle:0},a=(i.wall_columns||[]).find(t=>Me(t,o,.02*this.host._gridPitch));if(a)return clearTimeout(this.host._duplicateColumnTimer),this.host._duplicateColumnId=a.id,this.host._duplicateColumnTimer=window.setTimeout(()=>{this.host._duplicateColumnId=null},900),void this.host._showToast(this.host._t("toast.column_duplicate"));const n=this._geometrySnapshot(),r=this.host._curSpaceCfg;r.wall_columns||=[],r.wall_columns.push({...o,center:[e[0]/jd,e[1]/jd]}),this._commitPhysicalGeometry(this.host._t("history.column_add"),n)}_openPhysicalDialog(t,e){const s=this.host._spaceModel();if(s)if("partition"===t){const i=s.partitions.find(t=>t.id===e);i&&(this.host._physicalDialog={kind:t,id:e,cm:Ee(i.cm,this.host._imperial),length:this.host._fmtLen(i.a,i.b)})}else if("column"===t){const i=s.wall_columns.find(t=>t.id===e);i&&(this.host._physicalDialog={kind:t,id:e,cm:Ee(i.cm,this.host._imperial),shape:i.shape,angle:this.host._angleField("square"===i.shape?je(i.angle):0)})}}_physicalDown(t,e,s){const i=this.host._spaceModel();if(!i)return;t.stopPropagation(),qd(t);const o=this._svgPoint(t),a=[];for(const t of[...i.wall_columns].reverse())Xe(o,Qe(t,this.host._cellCm,this.host._gridPitch))&&a.push({kind:"column",id:t.id});for(const t of[...i.partitions].reverse()){const e=ts(t.a,t.b,t.cm,this.host._cellCm,this.host._gridPitch);e&&Xe(o,e)&&a.push({kind:"partition",id:t.id})}a.some(t=>t.kind===e&&t.id===s)||a.unshift({kind:e,id:s});const n=a.map(t=>`${t.kind}:${t.id}`).sort().join("|"),r=performance.now(),l=this.host._physicalPickCycle,h=a.length>1&&l?.signature===n&&r-l.at>380&&r-l.at<=1200&&Math.hypot(t.clientX-l.x,t.clientY-l.y)<=10?(l.index+1)%a.length:Math.max(0,a.findIndex(t=>t.kind===e&&t.id===s));this.host._physicalPickCycle={signature:n,index:h,x:t.clientX,y:t.clientY,at:r},e=a[h].kind,s=a[h].id;const c="partition"===e?i.partitions.find(t=>t.id===s):i.wall_columns.find(t=>t.id===s);c&&(this.host._physicalSel={kind:e,id:s},this.host._physicalDrag={pid:t.pointerId,kind:e,id:s,start:this._svgPoint(t),startClient:[t.clientX,t.clientY],before:this._geometrySnapshot(),moved:!1,base:JSON.parse(JSON.stringify(c)),delta:[0,0]})}_clampPhysicalDelta(t,e,s){const i="partition"===t?[e.a,e.b]:[e.center],o=i.map(t=>t[0]),a=i.map(t=>t[1]);return[Math.max(-be*jd-Math.min(...o),Math.min(be*jd-Math.max(...o),s[0])),Math.max(-be*jd-Math.min(...a),Math.min(be*jd-Math.max(...a),s[1]))]}_physicalMove(t){t.stopPropagation(),Dr(this.host,"physical",()=>this._physicalMoveNow(t))}_physicalMoveNow(t){const e=this.host._physicalDrag;if(!e||e.pid!==t.pointerId)return;t.stopPropagation();const s=this._svgPoint(t),i="partition"===e.kind?e.base.a:e.base.center,o=this._snap([i[0]+s[0]-e.start[0],i[1]+s[1]-e.start[1]]),a=this._clampPhysicalDelta(e.kind,e.base,[o[0]-i[0],o[1]-i[1]]);this.host._physicalDrag={...e,delta:a,moved:e.moved||Math.hypot(t.clientX-e.startClient[0],t.clientY-e.startClient[1])>=5}}_physicalUp(t){Ir(this.host,"physical");const e=this.host._physicalDrag;if(!e||e.pid!==t.pointerId)return;if(t.stopPropagation(),this.host._physicalDrag=null,!e.moved)return void this._registerPhysicalTap(e.kind,e.id);const s=this.host._spaceModel();if(!this.host._curSpaceCfg||!s)return;const i=this.host._curSpaceCfg;if("partition"===e.kind){const t=(i.partitions||[]).find(t=>t.id===e.id),s=e.base;if(t){const o={...s,a:[s.a[0]+e.delta[0],s.a[1]+e.delta[1]],b:[s.b[0]+e.delta[0],s.b[1]+e.delta[1]]};t.a=[o.a[0]/jd,o.a[1]/jd],t.b=[o.b[0]/jd,o.b[1]/jd];for(const t of i.openings||[]){if("partition"!==t.host?.kind||t.host.id!==e.id)continue;const s=A(t,[o],jd,this.host._cellCm,this.host._gridPitch).resolved;s&&Object.assign(t,E(t,s,jd))}}}else{const t=(i.wall_columns||[]).find(t=>t.id===e.id),o=e.base,a={...o,center:[o.center[0]+e.delta[0],o.center[1]+e.delta[1]]};if(s.wall_columns.some(t=>t.id!==e.id&&Me(t,a,.02*this.host._gridPitch)))return void this.host._showToast(this.host._t("toast.column_duplicate"));t&&(t.center=[(o.center[0]+e.delta[0])/jd,(o.center[1]+e.delta[1])/jd])}this._commitPhysicalGeometry(this.host._t("history.physical_move"),e.before)}_registerPhysicalTap(t,e){const s=performance.now(),i=this.host._physicalLastTap?.kind===t&&this.host._physicalLastTap.id===e&&s-this.host._physicalLastTap.at<=360;this.host._physicalLastTap={kind:t,id:e,at:s},i&&(this.host._physicalLastTap=null,this._openPhysicalDialog(t,e))}_cancelPhysicalGesture(){Lr(this.host,"physical"),Lr(this.host,"physical-rotate"),this.host._physicalDrag=null,this.host._physicalRotate=null,this.host.requestUpdate()}_physicalRotateDown(t,e){if("square"!==e.shape||!this.host._spaceModel())return;t.preventDefault(),t.stopPropagation(),qd(t);const s=this._svgPoint(t);this.host._physicalSel={kind:"column",id:e.id},this.host._physicalRotate={pid:t.pointerId,id:e.id,center:[...e.center],startAngle:180*Math.atan2(s[1]-e.center[1],s[0]-e.center[0])/Math.PI,baseAngle:je(e.angle),angle:je(e.angle),before:this._geometrySnapshot(),moved:!1}}_physicalRotateMove(t){t.preventDefault(),t.stopPropagation(),Dr(this.host,"physical-rotate",()=>this._physicalRotateMoveNow(t))}_physicalRotateMoveNow(t){const e=this.host._physicalRotate;if(!e||e.pid!==t.pointerId)return;t.preventDefault(),t.stopPropagation();const s=this._svgPoint(t),i=180*Math.atan2(s[1]-e.center[1],s[0]-e.center[0])/Math.PI,o=e.baseAngle+i-e.startAngle,a=je(t.shiftKey?o:5*Math.round(o/5));this.host._physicalRotate={...e,angle:a,moved:e.moved||Math.abs(o-e.baseAngle)>=.5}}_physicalRotateUp(t){Ir(this.host,"physical-rotate");const e=this.host._physicalRotate;if(!e||e.pid!==t.pointerId)return;t.preventDefault(),t.stopPropagation(),this.host._physicalRotate=null;const s=this.host._spaceModel();if(!e.moved||!this.host._curSpaceCfg||!s)return;const i=s.wall_columns.find(t=>t.id===e.id);if(!i||"square"!==i.shape)return;const o={...i,angle:e.angle};if(s.wall_columns.some(t=>t.id!==e.id&&Me(t,o,.02*this.host._gridPitch)))return void this.host._showToast(this.host._t("toast.column_duplicate"));const a=this.host._curSpaceCfg.wall_columns?.find(t=>t.id===e.id);a&&(a.angle=e.angle,this._commitPhysicalGeometry(this.host._t("history.physical_edit"),e.before))}_rszRooms(){const t=[],e=this.host._spaceModel();if(!e)return t;for(const s of e.rooms){const e=s.id?N(s):null;e&&t.push({id:s.id,poly:e,wall_ids:Array.isArray(s.wall_ids)?[...s.wall_ids]:void 0})}return s=t,i=Math.max(1e-12,1e-12*this.host._gridPitch),s.map(t=>{if(!Array.isArray(t.wall_ids)||t.wall_ids.length!==t.poly.length)return{...t,poly:t.poly.map(t=>[...t])};const e=t.poly.map(t=>[...t]);let s=!0;for(;s&&e.length>3;){s=!1;for(let t=0;t0){e.splice(t,1),s=!0;break}}}return{...t,poly:e}});var s,i}_rszOpenings(){return this.host._openingsR.map(t=>({id:t.id,x:t.rx,y:t.ry,length:t.rlen,hosted:!!t.host,angle:t.angle,type:t.type}))}_rszObstacles(){const t=this.host._spaceModel();if(!t)return[];const e=[];for(const s of t.partitions||[])e.push({kind:"segment",a:[...s.a],b:[...s.b],half:V(s.cm,this.host._cellCm,this.host._gridPitch)/2});for(const s of t.wall_columns||[]){const t=V(s.cm,this.host._cellCm,this.host._gridPitch)/2;e.push({kind:"circle",center:[...s.center],radius:"square"===s.shape?t*Math.SQRT2:t})}return e}_rszOptsFor(t,e){const s=it(this.host._spaceWalls,t,e,this.host._wallKeyPitch,jd),i=this.host._spaceWalls.filter(t=>Array.isArray(t.a)&&Array.isArray(t.b)&&t.a.length>=2&&t.b.length>=2).map(t=>({wall:t,a:[t.a[0]*jd,t.a[1]*this.host._spaceH],b:[t.b[0]*jd,t.b[1]*this.host._spaceH]})),o=Math.abs(t[0]-e[0])<=.05*this.host._gridPitch?"v":Math.abs(t[1]-e[1])<=.05*this.host._gridPitch?"h":null,a=i.filter(s=>!!o&&("h"===o?!(Math.abs(s.a[1]-t[1])>.05*this.host._gridPitch||Math.abs(s.b[1]-t[1])>.05*this.host._gridPitch)&&Math.min(Math.max(t[0],e[0]),Math.max(s.a[0],s.b[0]))-Math.max(Math.min(t[0],e[0]),Math.min(s.a[0],s.b[0]))>.05*this.host._gridPitch:!(Math.abs(s.a[0]-t[0])>.05*this.host._gridPitch||Math.abs(s.b[0]-t[0])>.05*this.host._gridPitch)&&Math.min(Math.max(t[1],e[1]),Math.max(s.a[1],s.b[1]))-Math.max(Math.min(t[1],e[1]),Math.min(s.a[1],s.b[1]))>.05*this.host._gridPitch)),n=new Set(a.map(t=>Number(t.wall.cm)).filter(t=>t>0));return{minDim:this.host._cmToUnits(30),eps:.05*this.host._gridPitch,step:this.host._gridPitch,movingHalf:s>0?V(s,this.host._cellCm,this.host._gridPitch)/2:0,obstacles:this._rszObstacles(),thicknessConflict:n.size>1}}_rszResolution(t,e,s){const i=this.host._resize.snapshotIdentity||s||this._rszSnapshot(),o=`${this.host._space}|${this.host._cellCm}|${this.host._gridPitch}|${i}`,a=`${t}:${e}`;return this.host._resize.resolve(o,a,()=>{const s=[...this.host._resize.rooms||this._rszRooms()],i=s.find(e=>e.id===t),o=i?.poly?.[e]||[0,0],a=i?.poly?.[(e+1)%(i?.poly?.length||1)]||[0,0];return function(t,e,s,i,o){const{eps:a}=o,n=t.find(t=>t.id===s);if(!n||i<0||i>=(n.poly?.length||0)||n.poly.length<4||!$l(n.poly))return{enabled:!1,reason:"invalid-geometry"};const r=n.poly[i],l=n.poly[(i+1)%n.poly.length],h=Cl(r,l,a);if(!h)return{enabled:!1,reason:"diagonal"};if(!Il(n.poly,i,h,a))return{enabled:!1,reason:"side-angle"};if(o.thicknessConflict)return{enabled:!1,reason:"thickness-conflict"};for(const t of o.obstacles||[])if(Rl(t,r,l,o))return{enabled:!1,reason:"duplicate-physical-wall"};const c=bl(ml(l,r)),d=[],p=new Set;let u=!1,_=!1;for(const e of t)if(e.id!==s)for(let t=0;t1||d.length>1)return{enabled:!1,reason:"multiple-rooms"};const m={[s]:i},g=[s];if(1===d.length){const t=d[0];if(!$l(t.room.poly))return{enabled:!1,reason:"invalid-geometry"};if(!Il(t.room.poly,t.edge,h,a))return{enabled:!1,reason:"side-angle"};g.push(t.room.id),m[t.room.id]=t.edge}const f=[];for(const t of e)if(!(yl([t.x,t.y],r,l)>2*a)){if(t.hosted||t.length>c+2*a)return{enabled:!1,reason:"opening-conflict"};f.push(t.id)}const b=Object.fromEntries(g.map(e=>[e,t.find(t=>t.id===e).poly.length])),v=[];for(const e of g){const s=t.find(t=>t.id===e),i=m[e],o=(i-1+s.poly.length)%s.poly.length,n=(i+1)%s.poly.length,r=Nl(t,e,o,1,a),l=Nl(t,e,n,0,a);if(!r||!l)return{enabled:!1,reason:"partial-shared"};v.push(r,l)}const y={roomId:s,edge:i,a:[...r],b:[...l],n:wl(n.poly,i),roomIds:g,edgeByRoom:m,topology:b,movingOpeningIds:f,sideOwnership:v};if(!jl(t,e,y,0,o))return{enabled:!1,reason:"invalid-geometry"};const w=Math.abs(Number(o.step));if(Number.isFinite(w)&&w>a){const s=[-w,w];if(!s.some(s=>jl(t,e,y,s,o))){if(!s.some(s=>Ol(Bl(t,e,y,s),y,a)))return{enabled:!1,reason:"partial-shared"};const i={...o,obstacles:[]};return s.some(s=>jl(t,e,y,s,i))?{enabled:!1,reason:"duplicate-physical-wall"}:e.length&&s.some(e=>jl(t,[],y,e,o))?{enabled:!1,reason:"opening-conflict"}:{enabled:!1,reason:"invalid-geometry"}}}return{enabled:!0,plan:y}}(s,[...this.host._resize.openings||this._rszOpenings()],t,e,this._rszOptsFor(o,a))})}_rszSnapshot(){return JSON.stringify(this._geometrySnapshot()||{spaceId:this.host._space,rooms:[],openings:[],walls:[],open_spans:[]})}_rszResetController(){const t=null!==this.host._resize.preview;this.host._resize.reset(),t&&this.host._cfgEpoch++}_rszProjectPreview(t,e,s,i,o){this.host._rszLimitViolation=null;const a=this.host._serverCfg?.spaces.find(t=>t.id===this.host._space);if(!a||!this.host._serverCfg)return{ok:!1,reason:"missing-context"};const n=JSON.parse(t),r={...a,rooms:n.rooms,openings:n.openings||[]};for(const t of["walls","wall_segments","open_spans","partitions","wall_columns","decor"])void 0!==n[t]?r[t]=n[t]:delete r[t];for(const t of["plan_x","plan_y","plan_scale","plan_scale_x","plan_scale_y","plan_angle"])void 0!==n.plan_transform?.[t]?r[t]=n.plan_transform[t]:delete r[t];const l=this.host._spaceH;for(const[t,s]of Object.entries(e)){const e=r.rooms.find(e=>e.id===t);e&&(e.poly=s.map(t=>[t[0]/jd,t[1]/l]),delete e.x,delete e.y,delete e.w,delete e.h)}for(const[t,e]of Object.entries(s)){const s=(r.openings||[]).find(e=>e.id===t);s&&(s.x=e[0]/jd,s.y=e[1]/l)}const h=[],c=[];for(const t of i){const e=o.find(e=>e.id===t),s=r.rooms.find(e=>e.id===t);if(!e||!s?.poly)continue;const i=s.poly.map(t=>[t[0]*jd,t[1]*l]);if(e.poly.length!==i.length)continue;const a=Array.isArray(e.wall_ids)?e.wall_ids:[];for(let t=0;tt.id===s):null;o&&(o.a=[i[t][0]/jd,i[t][1]/jd],o.b=[i[(t+1)%i.length][0]/jd,i[(t+1)%i.length][1]/jd])}}if(h.length&&Array.isArray(r.walls)&&r.walls.length){const t=es(r.walls,h,c,this.host._wallKeyPitch,jd,"fixed-topology");if(t.rejected)return{ok:!1,reason:"wall-metadata"};r.walls=t.walls}const d=[];for(const t of r.rooms||[]){const e=N(t);if(e&&!(e.length<2))for(let t=0;tJSON.stringify([t?.key,t?.cm,t?.a,t?.b]),u=new Map;for(const t of n.walls||[]){const e=p(t);u.set(e,(u.get(e)||0)+1)}const _=[];for(const t of r.walls||[]){const e=p(t),s=u.get(e)||0;s?u.set(e,s-1):_.push(t)}if(ss(_,d,this.host._wallKeyPitch,jd,n.walls||[]).length)return{ok:!1,reason:"wall-metadata"};const m=function(t,e,s=1e-8){const i=Yl(t),o=new Set(e),a=i.flatMap(t=>{if(!o.has(String(t.id||"")))return[];const e=th(Ql(t));return e?[e]:[]});return i.flatMap(t=>{const e=String(t.id||""),i=th(Ql(t)),n=!!i&&a.some(t=>i.minX<=t.maxX+s&&i.maxX+s>=t.minX&&i.minY<=t.maxY+s&&i.maxY+s>=t.minY);return e&&(o.has(e)||n)?[e]:[]})}(r.rooms||[],i),g=eh(r,m);if(!g||!this._rszSpaceCandidateGeometry(this.host._space,g).ok)return{ok:!1,reason:"physical-geometry"};const f={...this.host._serverCfg,spaces:(this.host._serverCfg?.spaces||[]).map(t=>t?.id===this.host._space?r:t)};try{this._resizePreviewNodes=ie(g.rooms,g.walls,[],z,this.host._cellCm,this.host._gridPitch,jd)}catch{this._resizePreviewNodes=null}let b;try{const t=new Set(i),e=this.host._junctionLimitViolations(f,this.host._space,{status:"lightweight",multiWallNodes:this._resizePreviewNodes},t);b=Zh(e,this._resizeBaselineLimits.filter(e=>"clearance"!==e.rule||t.has(e.subject)))}catch{b=[{rule:"check_failed",subject:this.host._space,actual:0,limit:0}]}return b.length?(this.host._rszLimitViolation=b[0],{ok:!1,reason:"junction-limit"}):{ok:!0,value:{preview:{space:this.host._space,sp:r},beforeWalls:n.walls||[],afterWalls:r.walls||[],artifact:null}}}_rszAcceptPreview(t,e){if(this.host._cfgEpoch++,this.host._physicalBodiesCache&&(this.host._physicalBodiesCache.key=`${this.host._space}|${this.host._cfgEpoch}|${this.host._cellCm}|${this.host._gridPitch}`),!t||!e)return;const s=is(e);if(!s)return;const i=`${this.host._space}|${this.host._cfgEpoch}|${t.sp.rooms.length}`;Object.defineProperty(s,"sourceFingerprint",{value:yt([t.sp,this.host._cellCm,this.host._gridPitch]),enumerable:!1});const o={key:i,value:s};Wd(this.host._wallUnionPool,i,o,8),this.host._wallUnionCache=o}_rszSpaceCandidateGeometry(t,e){if(!this.host._serverCfg)return{ok:!1,wallGeometry:null};const s={...this.host._serverCfg,spaces:this.host._serverCfg.spaces.map(s=>s.id===t?e:s)};let i=null;try{return{ok:this.host._checkSpacePhysicalGeometry(s,t,t=>{i=t}).ok,wallGeometry:i}}catch{return{ok:!1,wallGeometry:null}}}_rszSpaceCandidateRenderable(t,e){if(!this.host._serverCfg)return!1;try{const s={...this.host._serverCfg,spaces:this.host._serverCfg.spaces.map(s=>s.id===t?e:s)};return this.host._checkSpacePhysicalGeometry(s,t).ok}catch{return!1}}_rszCandidateRenderable(t){return!!t&&t.space===this.host._space&&this._rszSpaceCandidateRenderable(t.space,t.sp)}_rszEdgeDown(t,e,s){if("resize"!==this.host._tool||this.host._resize.dragging)return;this._resizeBaseFrameStable=!0,t.stopPropagation(),t.preventDefault();const i=this._rszRooms(),o=this._rszResolution(e,s);if(!o.enabled)return void this.host._showToast(this._rszReasonText(o.reason));qd(t);const a=o.plan;try{this._resizeBaselineLimits=this.host._junctionLimitViolations(this.host._serverCfg,this.host._space,null,new Set(a.roomIds))}catch{this._resizeBaselineLimits=[]}const n=this._svgPoint(t),r=`${this.host._space}|${this.host._cfgEpoch}|${i.length}`,l=this.host._wallUnionCache?.key===r?this.host._wallUnionCache.value:null,h=this._rszSnapshot();this.host._resize.begin({pointerId:t.pointerId,start:[n[0],n[1]],roomId:e,plan:a,options:this._rszOptsFor(a.a,a.b),rooms:i,openings:this._rszOpenings(),snapshotIdentity:h,before:JSON.parse(h),wallUnionBefore:l,epochBefore:this.host._cfgEpoch})}_rszReasonText(t){return this.host._t(`resize.disabled.${t}`)}_rszDisabledActivate(t,e){t.stopPropagation(),t.preventDefault(),this.host._showToast(this._rszReasonText(e))}_rszDisabledKey(t,e){"Enter"!==t.key&&" "!==t.key||this._rszDisabledActivate(t,e)}_rszMove(t){this.host._resize.ownsPointer(t.pointerId)&&(t.stopPropagation(),Dr(this.host,"resize",()=>this._rszMoveNow(t)))}_rszMoveNow(t){if(!this.host._resize.ownsPointer(t.pointerId))return;t.stopPropagation();const e=this._svgPoint(t),s=this.host._resize.move({pointerId:t.pointerId,point:[e[0],e[1]],step:this.host._gridPitch,snap:t=>{const e=this._snap(t);return[e[0],e[1]]},project:(t,e,s,i,o)=>this._rszProjectPreview(t,e,s,i,o),publish:(t,e)=>this._rszAcceptPreview(t,e),measure:(t,e)=>this._rszEdgeLabels(t,e)});if("rejected"===s.kind)return s.notify&&this.host._showToast(this.host._rszLimitViolation?`${this.host._t("resize.limit_stopped")} — `+this._junctionLimitLabel(this.host._rszLimitViolation):this.host._t("resize.preview_failed")),void this.host.requestUpdate();"accepted"===s.kind&&this.host.requestUpdate()}_rszUp(t){if(Ir(this.host,"resize"),!this.host._resize.ownsPointer(t.pointerId))return;t.stopPropagation();const e=this.host._resize.finish({pointerId:t.pointerId,currentSnapshotIdentity:this._rszSnapshot(),validatePreview:t=>this._rszCandidateRenderable(t)});if("no-op"===e.kind)return this.host._cfgEpoch++,void this.host.requestUpdate();if("rejected"===e.kind)return this.host._cfgEpoch++,this.host._showToast(this.host._t("resize.commit_failed")),void this.host.requestUpdate();const s=e.preview,i=this.host._serverCfg?.spaces.find(t=>t.id===s.space);i&&(i.rooms=s.sp.rooms,i.openings=s.sp.openings,Array.isArray(s.sp.walls)&&(s.sp.walls.length?i.walls=s.sp.walls:delete i.walls),Array.isArray(s.sp.wall_segments)&&(i.wall_segments=s.sp.wall_segments)),this.host._suppressClick=!0,setTimeout(()=>this.host._suppressClick=!1,0),this._commitPhysicalGeometry(this.host._t("history.resize_room"),e.before),this.host.requestUpdate()}_rszCancelDrag(t){Lr(this.host,"resize");const e=this.host._resize.cancel(this._rszSnapshot(),t);if("no-op"!==e.kind){if(null!==e.restoreEpoch?this.host._cfgEpoch=e.restoreEpoch:this.host._cfgEpoch++,this.host._physicalBodiesCache&&(this.host._physicalBodiesCache.key=`${this.host._space}|${this.host._cfgEpoch}|${this.host._cellCm}|${this.host._gridPitch}`),e.restoreWallUnion){const t=this.host._spaceModel();if(t){const s=`${this.host._space}|${this.host._cfgEpoch}|${t.rooms.length}`,i={key:s,value:e.restoreWallUnion};Wd(this.host._wallUnionPool,s,i,8),this.host._wallUnionCache=i}}null!==e.restoreEpoch&&"plan"===this.host._mode&&this._resizeBaseFrameStable&&(this.host._terminalFrame=1),this.host.requestUpdate()}}_rszPointerCancel(t){this.host._resize.ownsPointer(t.pointerId)&&(t.stopPropagation(),this._rszCancelDrag(t.pointerId))}_rszEdgeLabels(t,e,s=this.host._resize.rooms){const i=s,o=[],a=t.polys[e.roomId]||i?.find(t=>t.id===e.roomId).poly;if(!a||!i)return o;const n=a.length,r=this._rszInnerSpanCms(e.roomId,a,t.polys);for(const t of function(t,e){const s=t.length;return[(e-1+s)%s,(e+1)%s]}(a,e.edge)){const e=a[t],s=a[(t+1)%n],i=r?.[t];o.push({kind:"length",x:(e[0]+s[0])/2,y:(e[1]+s[1])/2,text:null==i?this.host._fmtLen(e,s):le(i,"mi"===this.host.hass?.config?.unit_system?.length),edge:{a:[e[0],e[1]],b:[s[0],s[1]]}})}const l="mi"===this.host.hass?.config?.unit_system?.length,h=e.roomIds,c=this.host._spaceWalls,d=this.host._physicalBodiesR(),p=this.host._baseVb(),u=this.host._view&&this.host._view.w>0&&this.host._view.h>0?this.host._view:{x:p[0],y:p[1],w:p[2],h:p[3]},[_,m]=this.host._lastValidStageSize||[u.w,u.h],g={...u,stageWidth:Math.max(1,_),stageHeight:Math.max(1,m)},f=this.host._spaceModel(),b=this.host._config?.icon_size??2.5,v=f?os(b>8?2.5:b,f,u.w,this.host._kiosk?this.host._kioskScale.icon:1)*g.stageWidth/100:24,y=Math.max(10,.77*v),w=this.host._t("room.settings_short"),$=y*(1.457+.66*Math.max(1,w.length)*.42);for(const s of h){const a=t.polys[s]||i.find(t=>t.id===s).poly,n=c.length&&f&&ae(f.rooms,s,c,this.host._openCuts(),this.host._wallKeyPitch,this.host._cellCm,this.host._gridPitch,jd,null,this._resizePreviewNodes)||a,r=d.length?as(ns(n,d))*Math.pow(this.host._cellCm/this.host._gridPitch,2)/1e4:rs(n,this.host._gridPitch,this.host._cellCm),h=ls(r,l),p=kh({poly:a,edge:e.edgeByRoom[s],text:h,view:g,gearCenter:hs(a),gearWidthPx:$,gearHeightPx:y});o.push({kind:"area",roomId:s,x:p.anchor[0],y:p.anchor[1],text:h,placement:p})}return o}_rszInnerSpanCms(t,e,s){const i=Object.keys(s).length?Object.entries(s).map(([t,e])=>({id:t,poly:e})):this.host._spaceModel()?.rooms;if(!i?.length)return null;const o=this.host._spaceWalls;if(!o.length)return null;const a=this.host._openCuts(),n=cs(i,t,o,a,this.host._wallKeyPitch,this.host._cellCm,this.host._gridPitch,jd);if(!n||n.length!==e.length)return null;const r=this.host._cellCm/this.host._gridPitch;return e.map((t,s)=>ds(e,s,n)*r)}_renderResizeMeasurements(){const t=this.host._resize.liveLabels;if(!t?.length)return d;const e=t.filter(t=>"length"===t.kind),s=t.filter(t=>"area"===t.kind);return Pt`
${e.map((t,e)=>Pt`
diff --git a/custom_components/houseplan/frontend/houseplan-assets/houseplan-onboarding-runtime-D690jAGU.js b/custom_components/houseplan/frontend/houseplan-assets/houseplan-onboarding-runtime-CNBlGqTW.js
similarity index 95%
rename from custom_components/houseplan/frontend/houseplan-assets/houseplan-onboarding-runtime-D690jAGU.js
rename to custom_components/houseplan/frontend/houseplan-assets/houseplan-onboarding-runtime-CNBlGqTW.js
index a7f7bbd6..fd2a9181 100644
--- a/custom_components/houseplan/frontend/houseplan-assets/houseplan-onboarding-runtime-D690jAGU.js
+++ b/custom_components/houseplan/frontend/houseplan-assets/houseplan-onboarding-runtime-CNBlGqTW.js
@@ -1,5 +1,5 @@
-globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="33e3bf530b13e01b6cc86d437770676c16441418afa14b0324be617fc2d3bb22";import{l as t,bq as s,A as e,aC as o,c as a,g as i,cE as l,cF as h,cG as n,bn as r,cH as c,cM as p,cI as d,cJ as _,cK as u,cL as g,cN as m,cO as b}from"./houseplan-card-B1GLwcbS.js";import{D as f,C as v,E as y,G as w,H as D,I as $,J as S,v as C}from"./backdrop-pick-CpXppwyK.js";import"./form-kit.styles-B2L2lNpH.js";const k="33e3bf530b13e01b6cc86d437770676c16441418afa14b0324be617fc2d3bb22";class F{constructor(t){this.host=t,this._toggleServerPlans=async()=>{const t=this.host._spaceDialog;if(t)if(t.pickSaved)this.host._spaceDialog={...t,pickSaved:!1};else{this.host._spaceDialog={...t,pickSaved:!0,savedBusy:!0};try{const t=await this.host.hass.callWS({type:"houseplan/plans/list"}),s=this.host._spaceDialog;s&&(this.host._spaceDialog={...s,saved:t?.plans||[],savedBusy:!1})}catch(t){const s=this.host._spaceDialog;s&&(this.host._spaceDialog={...s,saved:[],savedBusy:!1}),this.host._showToast(this.host._t("toast.plans_list_failed",{err:this.host._errText(t)}))}}}}_help(i){const l=`${i}.aria`,h=t(this.host.hass,this.host._config?.language);return s(h,i)&&s(h,l)?a` `:e}_openSpaceDialog(t,s){if(!this.host._serverStorage||!this.host._serverCfg)return void this.host._showToast(this.host._t("toast.integration_missing"));if("edit"===t){const e=this.host._serverCfg.spaces.find(t=>t.id===s);if(!e)return;const o=i(e),a=e.settings?.custom_fill&&"object"==typeof e.settings.custom_fill?l(e.settings.custom_fill):null,p="none"===o.fill?{...a||h,a:0}:a;return void(this.host._spaceDialog={mode:t,spaceId:s,title:e.title,planUrl:e.plan_url||null,planFile:null,source:e.plan_url?"file":"draw",showBorders:o.showBorders,showNames:o.showNames,zeroWallStyle:c(e),displayTouched:!0,hideDecor:o.hideDecor,hideOpenings:o.hideOpenings,roomColor:o.color,roomOpacity:o.opacity,fillMode:"none"===o.fill?"custom":o.fill,customFill:p,glowEnabled:o.glow,bgColor:o.bgColor,bgMode:"static"===e.settings?.bg_mode||"daynight"===e.settings?.bg_mode?e.settings.bg_mode:null,northDeg:r({},e.settings),sunRays:"boolean"==typeof e.settings?.sun_rays?e.settings.sun_rays:null,tempMin:o.tempMin,tempMax:o.tempMax,showLqi:o.showLqi??this.host._config?.show_signal??!0,cardFontScale:o.cardFontScale,labelTemp:o.labelTemp,labelHum:o.labelHum,labelLqi:o.labelLqi,labelLight:o.labelLight,cellCm:Number(e.cell_cm)>0?Number(e.cell_cm):5,cellCmInput:n(Number(e.cell_cm)>0?Number(e.cell_cm):5,this.host._imperial),cellCmTouched:!1,busy:!1})}const e=p(this.host._imperial);this.host._spaceDialog={mode:t,title:"",planUrl:null,planFile:null,...m(),hideDecor:!1,hideOpenings:!1,zeroWallStyle:"dashed",roomColor:g,roomOpacity:u,fillMode:"custom",customFill:{...h,a:0},glowEnabled:!0,bgColor:null,bgMode:"daynight",northDeg:null,sunRays:null,tempMin:_,tempMax:d,showLqi:this.host._config?.show_signal??!0,cardFontScale:1,labelTemp:!1,labelHum:!1,labelLqi:!1,labelLight:!1,cellCm:e,cellCmInput:n(e,this.host._imperial),cellCmTouched:!1,busy:!1},f(this.host,this.host._spaceDialog)}async _pickPlanFile(t){const s=t.target,e=s.files?.[0];if(!e||!this.host._spaceDialog)return;s.value="";const o=await v(e);if("reject"===o.kind)return void this.host._showToast(this.host._t("toast.plan_formats"));if("guard"===o.kind)return void(this.host._backdropGuard=o.state);const a=await y(e,o.ext,e.name);this.host._spaceDialog&&(this.host._spaceDialog={...this.host._spaceDialog,planFile:a})}_renderBackdropGuard(){return w(this.host,t=>{this.host._spaceDialog&&(this.host._spaceDialog={...this.host._spaceDialog,planFile:t})},()=>{this.host._backdropGuard=null},this.host.hass)??e}_useServerPlan(t){const s=this.host._spaceDialog;s&&(this.host._spaceDialog={...s,planUrl:t,planFile:null,pickSaved:!1,savedAspect:void 0},this.host._aspectJob=this._readPlanAspect(t))}async _readPlanAspect(t){for(let s=0;s<40;s++){const s=this.host._display(t);if(s){const e=await new Promise(t=>{const e=new Image;e.onload=()=>t(e.naturalWidth&&e.naturalHeight?e.naturalWidth/e.naturalHeight:0),e.onerror=()=>t(0),e.src=s}),o=this.host._spaceDialog;return o&&o.planUrl===t&&Number.isFinite(e)&&e>0?(this.host._spaceDialog={...o,savedAspect:e},e):0}if(await new Promise(t=>setTimeout(t,150)),this.host._spaceDialog?.planUrl!==t)return 0}return 0}async _deleteServerPlan(t){const s=this.host._spaceDialog,e=s?.saved?.find(s=>s.name===t);if(!s||!e||e.used_by.length||e.url===s.planUrl)return;const o=await this.host._confirmDanger({key:"delete-plan",kind:"destructive",title:this.host._t("confirm.delete_plan_title"),message:this.host._t("confirm.delete_plan_body"),objectName:t,confirmLabel:this.host._t("btn.delete"),cancelLabel:this.host._t("btn.cancel")}),a=this.host._spaceDialog,i=a?.saved?.find(s=>s.name===t);if(o&&a&&i&&i.url===e.url&&i.modified===e.modified&&!i.used_by.length&&i.url!==a.planUrl)try{await this.host.hass.callWS({type:"houseplan/plans/delete",name:t});const s=this.host._spaceDialog;s?.saved&&(this.host._spaceDialog={...s,saved:s.saved.filter(s=>s.name!==t)})}catch(t){this.host._showToast(this.host._t("toast.plan_delete_failed",{err:this.host._errText(t)}))}}_renderServerPlans(t){if(t.savedBusy)return a`${this.host._t("space.loading")}
`;const s=t.saved||[];if(!s.length)return a`${this.host._t("space.no_saved")}
`;return a`
+globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="44c8db0207714f5476f58cdacdfaae63754967422e492b7fadf3551ecaee4380";import{l as t,bq as s,A as e,aC as o,c as a,g as i,cE as l,cF as h,cG as n,bn as r,cH as c,cM as p,cI as d,cJ as _,cK as u,cL as g,cN as m,cO as f}from"./houseplan-card-BQWwo3i7.js";import{D as b,C as v,E as y,G as w,H as D,I as $,J as S,v as C}from"./backdrop-pick-D57BQQbo.js";import"./form-kit.styles-BqBbEnaz.js";const k="44c8db0207714f5476f58cdacdfaae63754967422e492b7fadf3551ecaee4380";class F{constructor(t){this.host=t,this._toggleServerPlans=async()=>{const t=this.host._spaceDialog;if(t)if(t.pickSaved)this.host._spaceDialog={...t,pickSaved:!1};else{this.host._spaceDialog={...t,pickSaved:!0,savedBusy:!0};try{const t=await this.host.hass.callWS({type:"houseplan/plans/list"}),s=this.host._spaceDialog;s&&(this.host._spaceDialog={...s,saved:t?.plans||[],savedBusy:!1})}catch(t){const s=this.host._spaceDialog;s&&(this.host._spaceDialog={...s,saved:[],savedBusy:!1}),this.host._showToast(this.host._t("toast.plans_list_failed",{err:this.host._errText(t)}))}}}}_help(i){const l=`${i}.aria`,h=t(this.host.hass,this.host._config?.language);return s(h,i)&&s(h,l)?a`
`:e}_openSpaceDialog(t,s){if(!this.host._serverStorage||!this.host._serverCfg)return void this.host._showToast(this.host._t("toast.integration_missing"));if("edit"===t){const e=this.host._serverCfg.spaces.find(t=>t.id===s);if(!e)return;const o=i(e),a=e.settings?.custom_fill&&"object"==typeof e.settings.custom_fill?l(e.settings.custom_fill):null,p="none"===o.fill?{...a||h,a:0}:a;return void(this.host._spaceDialog={mode:t,spaceId:s,title:e.title,planUrl:e.plan_url||null,planFile:null,source:e.plan_url?"file":"draw",showBorders:o.showBorders,showNames:o.showNames,zeroWallStyle:c(e),displayTouched:!0,hideDecor:o.hideDecor,hideOpenings:o.hideOpenings,roomColor:o.color,roomOpacity:o.opacity,fillMode:"none"===o.fill?"custom":o.fill,customFill:p,glowEnabled:o.glow,bgColor:o.bgColor,bgMode:"static"===e.settings?.bg_mode||"daynight"===e.settings?.bg_mode?e.settings.bg_mode:null,northDeg:r({},e.settings),sunRays:"boolean"==typeof e.settings?.sun_rays?e.settings.sun_rays:null,tempMin:o.tempMin,tempMax:o.tempMax,showLqi:o.showLqi??this.host._config?.show_signal??!0,cardFontScale:o.cardFontScale,labelTemp:o.labelTemp,labelHum:o.labelHum,labelLqi:o.labelLqi,labelLight:o.labelLight,cellCm:Number(e.cell_cm)>0?Number(e.cell_cm):5,cellCmInput:n(Number(e.cell_cm)>0?Number(e.cell_cm):5,this.host._imperial),cellCmTouched:!1,busy:!1})}const e=p(this.host._imperial);this.host._spaceDialog={mode:t,title:"",planUrl:null,planFile:null,...m(),hideDecor:!1,hideOpenings:!1,zeroWallStyle:"dashed",roomColor:g,roomOpacity:u,fillMode:"custom",customFill:{...h,a:0},glowEnabled:!0,bgColor:null,bgMode:"daynight",northDeg:null,sunRays:null,tempMin:_,tempMax:d,showLqi:this.host._config?.show_signal??!0,cardFontScale:1,labelTemp:!1,labelHum:!1,labelLqi:!1,labelLight:!1,cellCm:e,cellCmInput:n(e,this.host._imperial),cellCmTouched:!1,busy:!1},b(this.host,this.host._spaceDialog)}async _pickPlanFile(t){const s=t.target,e=s.files?.[0];if(!e||!this.host._spaceDialog)return;s.value="";const o=await v(e);if("reject"===o.kind)return void this.host._showToast(this.host._t("toast.plan_formats"));if("guard"===o.kind)return void(this.host._backdropGuard=o.state);const a=await y(e,o.ext,e.name);this.host._spaceDialog&&(this.host._spaceDialog={...this.host._spaceDialog,planFile:a})}_renderBackdropGuard(){return w(this.host,t=>{this.host._spaceDialog&&(this.host._spaceDialog={...this.host._spaceDialog,planFile:t})},()=>{this.host._backdropGuard=null},this.host.hass)??e}_useServerPlan(t){const s=this.host._spaceDialog;s&&(this.host._spaceDialog={...s,planUrl:t,planFile:null,pickSaved:!1,savedAspect:void 0},this.host._aspectJob=this._readPlanAspect(t))}async _readPlanAspect(t){for(let s=0;s<40;s++){const s=this.host._display(t);if(s){const e=await new Promise(t=>{const e=new Image;e.onload=()=>t(e.naturalWidth&&e.naturalHeight?e.naturalWidth/e.naturalHeight:0),e.onerror=()=>t(0),e.src=s}),o=this.host._spaceDialog;return o&&o.planUrl===t&&Number.isFinite(e)&&e>0?(this.host._spaceDialog={...o,savedAspect:e},e):0}if(await new Promise(t=>setTimeout(t,150)),this.host._spaceDialog?.planUrl!==t)return 0}return 0}async _deleteServerPlan(t){const s=this.host._spaceDialog,e=s?.saved?.find(s=>s.name===t);if(!s||!e||e.used_by.length||e.url===s.planUrl)return;const o=await this.host._confirmDanger({key:"delete-plan",kind:"destructive",title:this.host._t("confirm.delete_plan_title"),message:this.host._t("confirm.delete_plan_body"),objectName:t,confirmLabel:this.host._t("btn.delete"),cancelLabel:this.host._t("btn.cancel")}),a=this.host._spaceDialog,i=a?.saved?.find(s=>s.name===t);if(o&&a&&i&&i.url===e.url&&i.modified===e.modified&&!i.used_by.length&&i.url!==a.planUrl)try{await this.host.hass.callWS({type:"houseplan/plans/delete",name:t});const s=this.host._spaceDialog;s?.saved&&(this.host._spaceDialog={...s,saved:s.saved.filter(s=>s.name!==t)})}catch(t){this.host._showToast(this.host._t("toast.plan_delete_failed",{err:this.host._errText(t)}))}}_renderServerPlans(t){if(t.savedBusy)return a`
${this.host._t("space.loading")}
`;const s=t.saved||[];if(!s.length)return a`
${this.host._t("space.no_saved")}
`;return a`
${s.map(s=>{return a`
@@ -16,7 +16,7 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="33e3bf530b13e01b6cc86d437770676c1644
`;var e})}
-
`}async _saveConfigNow(){this.host._cfgEpoch++;try{await this.host._writeConfig()}catch(t){const s=t;throw s?.physicalGeometryRolledBack?await this.host._reloadRejectedPhysicalWrite():"conflict"===s?.code&&await this.host._reloadConfigOnly(),t}}async _saveSpaceDialog(){const t=this.host._spaceDialog;if(!t||t.busy||!t.title.trim())return;if("file"===t.source&&!t.planFile&&!t.planUrl)return void this.host._showToast(this.host._t("toast.plan_required"));const s="create"===t.mode&&0===(this.host._serverCfg?.spaces.length||0);this.host._spaceDialog={...t,busy:!0};try{const e="create"===t.mode?`s${Date.now().toString(36)}`:t.spaceId;let o=null;if("file"===t.source&&t.planFile){o={url:(await this.host.hass.callWS({type:"houseplan/plan/set",space_id:e,ext:t.planFile.ext,data:t.planFile.b64})).url,aspect:t.planFile.aspect}}let a=t.savedAspect||null;!o&&"file"===t.source&&t.planUrl&&!a&&this.host._aspectJob&&(a=await this.host._aspectJob||null);const i=this.host._serverCfg;let l=i.spaces.find(t=>t.id===e);if("create"===t.mode)l=b(e,t.title.trim()),i.spaces.push(l);else{if(!l)throw new Error(`space ${e} is gone from the config`);l.title=t.title.trim()}if(!l)throw new Error(`space ${e} is unavailable`);if(o?(l.plan_url=o.url,l.plan_aspect=o.aspect):"file"===t.source&&t.planUrl&&t.planUrl!==l.plan_url&&(l.plan_url=t.planUrl,l.plan_aspect=a),"draw"===t.source&&(l.plan_url=null,l.plan_aspect=null,delete l.plan_x,delete l.plan_y,delete l.plan_scale,delete l.plan_scale_x,delete l.plan_scale_y,delete l.plan_angle),l.settings={...l.settings||{},show_borders:t.showBorders,show_names:t.showNames,hide_decor:t.hideDecor||void 0,hide_openings:t.hideOpenings||void 0,room_color:t.roomColor,room_opacity:t.roomOpacity,bg_color:t.bgColor||void 0,bg_mode:t.bgMode||void 0,north_deg:t.northDeg??void 0,sun_rays:t.sunRays??void 0,fill_mode:t.fillMode,custom_fill:t.customFill||void 0,glow_enabled:t.glowEnabled,temp_min:Number.isFinite(t.tempMin)?Math.min(t.tempMin,t.tempMax):_,temp_max:Number.isFinite(t.tempMax)?Math.max(t.tempMin,t.tempMax):d,show_lqi:t.showLqi,card_font_scale:1!==t.cardFontScale?t.cardFontScale:void 0,label_temp:t.labelTemp,label_hum:t.labelHum,label_lqi:t.labelLqi,label_light:t.labelLight},l.zero_wall_style=t.zeroWallStyle,l.cell_cm=Number.isFinite(t.cellCm)&&t.cellCm>0?Math.max(D,Math.min($,t.cellCm)):5,await this._saveConfigNow(),this.host._spaceDialog=null,"create"===t.mode&&this.host._commitSpace(l.id),this.host._regSignature="",this.host._maybeRebuildDevices(),this.host._importQueue.length)this._openNextImport();else if(s||this.host._importTotal>0){const t=this.host._importTotal>0;this.host._importTotal=0,this.host._commitSpace(this.host._serverCfg.spaces[0]?.id||this.host._space),await this.host._requestMode("plan"),this.host._tool="draw",this.host._path=[],this.host._cursorPt=null,this.host._primeDrawWallField(),this.host._showToast(this.host._t(s&&!t?"toast.space_added_onboard":"import.done"))}else this.host._showToast(this.host._t("create"===t.mode?"toast.space_added":"toast.space_saved")),"create"===t.mode&&("plan"!==this.host._mode?await this.host._requestMode("plan"):(this.host._tool="draw",this.host._path=[],this.host._cursorPt=null,this.host._primeDrawWallField(),this.host._saveNav()))}catch(t){const s=t;"conflict"!==s?.code&&await this.host._reloadConfigOnly(!0),this.host._spaceDialog&&(this.host._spaceDialog={...this.host._spaceDialog,busy:!1}),this.host._showToast(this.host._t("toast.error",{err:this.host._errText(t)}))}}async _deleteSpace(){const t=this.host._spaceDialog;if(!t||"edit"!==t.mode)return;const s=this.host._serverCfg;if(!s)return;const e=s.spaces.find(s=>s.id===t.spaceId);if(!e)return;const o=S(s,this.host._layout||{},t.spaceId||""),a=1===s.spaces.length&&s.spaces[0]?.id===t.spaceId;if(o.count&&!a)return void(this.host._spaceDialog={...t,deleteBlockers:o.count});const i=t.spaceId,l=await this.host._confirmDanger({key:"delete-space",kind:"destructive",title:this.host._t("confirm.delete_space_title"),message:this.host._t("confirm.delete_space_body"),objectName:e.title,confirmLabel:this.host._t("btn.delete"),cancelLabel:this.host._t("btn.cancel")}),h=this.host._spaceDialog,n=this.host._serverCfg;if(!l||!h||"edit"!==h.mode||h.busy||h.spaceId!==i||!n)return;if(!n.spaces.find(t=>t.id===i))return;const r=S(n,this.host._layout||{},i),c=1===n.spaces.length&&n.spaces[0]?.id===i;if(!r.count||c){this.host._spaceDialog={...h,deleteBlockers:0,busy:!0};try{this.host._saveConfigDebounced.pending()&&this.host._saveConfigDebounced.flush(),this.host._persistLayout.pending()&&this.host._persistLayout.flush(),await this.host._writeChain,await this.host.hass.callWS({type:"houseplan/space/delete",space_id:i,expected_config_rev:this.host._cfgRev,expected_layout_rev:this.host._layoutRev});const[t,s]=await Promise.all([this.host._getAuthoritativeConfig(),this.host.hass.callWS({type:"houseplan/layout/get"})]);if("adopted"!==(await this.host._adoptAuthoritative({cfgResp:t,layResp:s,reason:"space-delete",profile:"post-write"})).status)return this.host._spaceDialog={...h,busy:!1},void this.host.requestUpdate();this.host._spaceDialog=null,this.host._space===i&&this.host._commitSpace(this.host._serverCfg.spaces[0]?.id||""),this.host._regSignature="",this.host._maybeRebuildDevices(),this.host._showToast(this.host._t("toast.space_deleted"))}catch(t){const s=t;"conflict"!==s?.code&&"space_in_use"!==s?.code||await Promise.all([this.host._reloadConfigOnly(!0),this.host._reloadLayoutOnly()]);const e=this.host._serverCfg;if(this.host._spaceDialog&&e){const t=S(e,this.host._layout||{},i),s=1===e.spaces.length&&e.spaces[0]?.id===i;this.host._spaceDialog={...this.host._spaceDialog,busy:!1,deleteBlockers:s?0:t.count}}this.host._showToast(this.host._t("toast.delete_failed",{err:this.host._errText(t)}))}}else this.host._spaceDialog={...h,deleteBlockers:r.count}}_startImport(){const t=this.host._importDialog;if(!t)return;const s=t.floors.filter(t=>t.checked).map(t=>t.name);this.host._importDialog=null,s.length?(this.host._importQueue=s,this.host._importTotal=s.length,this._openNextImport()):this._openSpaceDialog("create")}_openNextImport(){const t=this.host._importQueue.shift();if(void 0===t)return;const s=p(this.host._imperial);this.host._spaceDialog={mode:"create",title:t,planUrl:null,planFile:null,...m(),hideDecor:!1,hideOpenings:!1,zeroWallStyle:"dashed",roomColor:g,roomOpacity:u,fillMode:"custom",customFill:null,glowEnabled:!0,bgColor:null,bgMode:"daynight",northDeg:null,sunRays:null,tempMin:_,tempMax:d,showLqi:this.host._config?.show_signal??!0,cardFontScale:1,labelTemp:!1,labelHum:!1,labelLqi:!1,labelLight:!1,cellCm:s,cellCmInput:n(s,this.host._imperial),cellCmTouched:!1,busy:!1},f(this.host,this.host._spaceDialog)}_skipImport(){this.host._spaceDialog=null,this.host._importQueue.length?this._openNextImport():this.host._importTotal>0&&this.host._model.length&&(this.host._importTotal=0,this.host._commitSpace(this.host._serverCfg.spaces[0]?.id||this.host._space),this.host._requestMode("plan").then(()=>{this.host._showToast(this.host._t("import.done"))}))}_renderImportDialog(){const t=this.host._importDialog,s=t.floors.filter(t=>t.checked).length;return a`
`}async _saveConfigNow(){this.host._cfgEpoch++;try{await this.host._writeConfig()}catch(t){const s=t;throw s?.physicalGeometryRolledBack?await this.host._reloadRejectedPhysicalWrite():"conflict"===s?.code&&await this.host._reloadConfigOnly(),t}}async _saveSpaceDialog(){const t=this.host._spaceDialog;if(!t||t.busy||!t.title.trim())return;if("file"===t.source&&!t.planFile&&!t.planUrl)return void this.host._showToast(this.host._t("toast.plan_required"));const s="create"===t.mode&&0===(this.host._serverCfg?.spaces.length||0);this.host._spaceDialog={...t,busy:!0};try{const e="create"===t.mode?`s${Date.now().toString(36)}`:t.spaceId;let o=null;if("file"===t.source&&t.planFile){o={url:(await this.host.hass.callWS({type:"houseplan/plan/set",space_id:e,ext:t.planFile.ext,data:t.planFile.b64})).url,aspect:t.planFile.aspect}}let a=t.savedAspect||null;!o&&"file"===t.source&&t.planUrl&&!a&&this.host._aspectJob&&(a=await this.host._aspectJob||null);const i=this.host._serverCfg;let l=i.spaces.find(t=>t.id===e);if("create"===t.mode)l=f(e,t.title.trim()),i.spaces.push(l);else{if(!l)throw new Error(`space ${e} is gone from the config`);l.title=t.title.trim()}if(!l)throw new Error(`space ${e} is unavailable`);if(o?(l.plan_url=o.url,l.plan_aspect=o.aspect):"file"===t.source&&t.planUrl&&t.planUrl!==l.plan_url&&(l.plan_url=t.planUrl,l.plan_aspect=a),"draw"===t.source&&(l.plan_url=null,l.plan_aspect=null,delete l.plan_x,delete l.plan_y,delete l.plan_scale,delete l.plan_scale_x,delete l.plan_scale_y,delete l.plan_angle),l.settings={...l.settings||{},show_borders:t.showBorders,show_names:t.showNames,hide_decor:t.hideDecor||void 0,hide_openings:t.hideOpenings||void 0,room_color:t.roomColor,room_opacity:t.roomOpacity,bg_color:t.bgColor||void 0,bg_mode:t.bgMode||void 0,north_deg:t.northDeg??void 0,sun_rays:t.sunRays??void 0,fill_mode:t.fillMode,custom_fill:t.customFill||void 0,glow_enabled:t.glowEnabled,temp_min:Number.isFinite(t.tempMin)?Math.min(t.tempMin,t.tempMax):_,temp_max:Number.isFinite(t.tempMax)?Math.max(t.tempMin,t.tempMax):d,show_lqi:t.showLqi,card_font_scale:1!==t.cardFontScale?t.cardFontScale:void 0,label_temp:t.labelTemp,label_hum:t.labelHum,label_lqi:t.labelLqi,label_light:t.labelLight},l.zero_wall_style=t.zeroWallStyle,l.cell_cm=Number.isFinite(t.cellCm)&&t.cellCm>0?Math.max(D,Math.min($,t.cellCm)):5,await this._saveConfigNow(),this.host._spaceDialog=null,"create"===t.mode&&this.host._commitSpace(l.id),this.host._regSignature="",this.host._maybeRebuildDevices(),this.host._importQueue.length)this._openNextImport();else if(s||this.host._importTotal>0){const t=this.host._importTotal>0;this.host._importTotal=0,this.host._commitSpace(this.host._serverCfg.spaces[0]?.id||this.host._space),await this.host._requestMode("plan"),this.host._tool="draw",this.host._path=[],this.host._cursorPt=null,this.host._primeDrawWallField(),this.host._showToast(this.host._t(s&&!t?"toast.space_added_onboard":"import.done"))}else this.host._showToast(this.host._t("create"===t.mode?"toast.space_added":"toast.space_saved")),"create"===t.mode&&("plan"!==this.host._mode?await this.host._requestMode("plan"):(this.host._tool="draw",this.host._path=[],this.host._cursorPt=null,this.host._primeDrawWallField(),this.host._saveNav()))}catch(t){const s=t;"conflict"!==s?.code&&await this.host._reloadConfigOnly(!0),this.host._spaceDialog&&(this.host._spaceDialog={...this.host._spaceDialog,busy:!1}),this.host._showToast(this.host._t("toast.error",{err:this.host._errText(t)}))}}async _deleteSpace(){const t=this.host._spaceDialog;if(!t||"edit"!==t.mode)return;const s=this.host._serverCfg;if(!s)return;const e=s.spaces.find(s=>s.id===t.spaceId);if(!e)return;const o=S(s,this.host._layout||{},t.spaceId||""),a=1===s.spaces.length&&s.spaces[0]?.id===t.spaceId;if(o.count&&!a)return void(this.host._spaceDialog={...t,deleteBlockers:o.count});const i=t.spaceId,l=await this.host._confirmDanger({key:"delete-space",kind:"destructive",title:this.host._t("confirm.delete_space_title"),message:this.host._t("confirm.delete_space_body"),objectName:e.title,confirmLabel:this.host._t("btn.delete"),cancelLabel:this.host._t("btn.cancel")}),h=this.host._spaceDialog,n=this.host._serverCfg;if(!l||!h||"edit"!==h.mode||h.busy||h.spaceId!==i||!n)return;if(!n.spaces.find(t=>t.id===i))return;const r=S(n,this.host._layout||{},i),c=1===n.spaces.length&&n.spaces[0]?.id===i;if(!r.count||c){this.host._spaceDialog={...h,deleteBlockers:0,busy:!0};try{this.host._saveConfigDebounced.pending()&&this.host._saveConfigDebounced.flush(),this.host._persistLayout.pending()&&this.host._persistLayout.flush(),await this.host._writeChain,await this.host.hass.callWS({type:"houseplan/space/delete",space_id:i,expected_config_rev:this.host._cfgRev,expected_layout_rev:this.host._layoutRev});const[t,s]=await Promise.all([this.host._getAuthoritativeConfig(),this.host.hass.callWS({type:"houseplan/layout/get"})]);if("adopted"!==(await this.host._adoptAuthoritative({cfgResp:t,layResp:s,reason:"space-delete",profile:"post-write"})).status)return this.host._spaceDialog={...h,busy:!1},void this.host.requestUpdate();this.host._spaceDialog=null,this.host._space===i&&this.host._commitSpace(this.host._serverCfg.spaces[0]?.id||""),this.host._regSignature="",this.host._maybeRebuildDevices(),this.host._showToast(this.host._t("toast.space_deleted"))}catch(t){const s=t;"conflict"!==s?.code&&"space_in_use"!==s?.code||await Promise.all([this.host._reloadConfigOnly(!0),this.host._reloadLayoutOnly()]);const e=this.host._serverCfg;if(this.host._spaceDialog&&e){const t=S(e,this.host._layout||{},i),s=1===e.spaces.length&&e.spaces[0]?.id===i;this.host._spaceDialog={...this.host._spaceDialog,busy:!1,deleteBlockers:s?0:t.count}}this.host._showToast(this.host._t("toast.delete_failed",{err:this.host._errText(t)}))}}else this.host._spaceDialog={...h,deleteBlockers:r.count}}_startImport(){const t=this.host._importDialog;if(!t)return;const s=t.floors.filter(t=>t.checked).map(t=>t.name);this.host._importDialog=null,s.length?(this.host._importQueue=s,this.host._importTotal=s.length,this._openNextImport()):this._openSpaceDialog("create")}_openNextImport(){const t=this.host._importQueue.shift();if(void 0===t)return;const s=p(this.host._imperial);this.host._spaceDialog={mode:"create",title:t,planUrl:null,planFile:null,...m(),hideDecor:!1,hideOpenings:!1,zeroWallStyle:"dashed",roomColor:g,roomOpacity:u,fillMode:"custom",customFill:null,glowEnabled:!0,bgColor:null,bgMode:"daynight",northDeg:null,sunRays:null,tempMin:_,tempMax:d,showLqi:this.host._config?.show_signal??!0,cardFontScale:1,labelTemp:!1,labelHum:!1,labelLqi:!1,labelLight:!1,cellCm:s,cellCmInput:n(s,this.host._imperial),cellCmTouched:!1,busy:!1},b(this.host,this.host._spaceDialog)}_skipImport(){this.host._spaceDialog=null,this.host._importQueue.length?this._openNextImport():this.host._importTotal>0&&this.host._model.length&&(this.host._importTotal=0,this.host._commitSpace(this.host._serverCfg.spaces[0]?.id||this.host._space),this.host._requestMode("plan").then(()=>{this.host._showToast(this.host._t("import.done"))}))}_renderImportDialog(){const t=this.host._importDialog,s=t.floors.filter(t=>t.checked).length;return a`this.host._importDialog=null}>
diff --git a/custom_components/houseplan/frontend/houseplan-assets/hp-zigbee-topology-overlay-B-TXG5n3.js b/custom_components/houseplan/frontend/houseplan-assets/hp-zigbee-topology-overlay-fe_knnXY.js
similarity index 87%
rename from custom_components/houseplan/frontend/houseplan-assets/hp-zigbee-topology-overlay-B-TXG5n3.js
rename to custom_components/houseplan/frontend/houseplan-assets/hp-zigbee-topology-overlay-fe_knnXY.js
index e766c264..74a58300 100644
--- a/custom_components/houseplan/frontend/houseplan-assets/hp-zigbee-topology-overlay-B-TXG5n3.js
+++ b/custom_components/houseplan/frontend/houseplan-assets/hp-zigbee-topology-overlay-fe_knnXY.js
@@ -1,7 +1,7 @@
-globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="33e3bf530b13e01b6cc86d437770676c16441418afa14b0324be617fc2d3bb22";import{az as e,l as t,A as i,eb as r,as as o,c as s,ay as n}from"./houseplan-card-B1GLwcbS.js";import{t as a,a as h,r as d}from"./zigbee-topology-0vQ1r_Y7.js";import{zigbeeTopologyRuntimeSnapshot as p,subscribeZigbeeTopology as l}from"./zigbee-topology-runtime-DtATTFz4.js";function c(e,t,i,r,o,s=9,n=4.5){const a=t.x-e.x,h=t.y-e.y,d=Math.hypot(a,h),p=d-Math.max(0,i)-Math.max(0,r);if(!Number.isFinite(d)||d<=0||p<4)return null;const l=a/d,c=h/d,_="toward-neighbor"===o,u=_?{x:t.x-l*Math.max(0,r),y:t.y-c*Math.max(0,r)}:{x:e.x+l*Math.max(0,i),y:e.y+c*Math.max(0,i)},b=Math.min(s,Math.max(4,.45*p)),m=Math.min(n,.5*b),v=_?-1:1,g=u.x+l*b*v,y=u.y+c*b*v,x=-c;return{tip:u,points:[u,{x:g+x*m,y:y+l*m},{x:g-x*m,y:y-l*m}]}}const _={revision:0,topologies:[],states:{}},u="data-hp-zigbee-topology-endpoint";class b extends e{constructor(){super(...arguments),this.devices=[],this.currentSpace="",this._runtime=_,this._hovered="",this._desiredEndpointIds=new Set,this._endpointSetDirty=!1,this._endpointElements=new Set,this._pointerOver=e=>{if(!this._mouseAllowed(e))return void this._clear();const t=this._deviceFromEvent(e),i=t?.dataset.id||"";i&&i!==this._hovered&&(this._hovered=i,this.requestUpdate())},this._pointerOut=e=>{const t=this._deviceFromEvent(e);if(!t||t.dataset.id!==this._hovered)return;const i=e.relatedTarget instanceof Element?e.relatedTarget.closest('[data-hp="device"]'):null;i?.dataset.id!==this._hovered&&this._clear()},this._pointerDown=e=>{"mouse"!==e.pointerType&&this._clear()}}connectedCallback(){super.connectedCallback();const e=this.getRootNode();e.host&&"undefined"!=typeof MutationObserver&&(this._hoverGateObserver=new MutationObserver(()=>{e.host.hasAttribute("data-pointer-hover")||this._clear()}),this._hoverGateObserver.observe(e.host,{attributes:!0,attributeFilter:["data-pointer-hover"]})),queueMicrotask(()=>this._connectParent())}disconnectedCallback(){this._release?.(),this._release=void 0,this._disconnectParent(),this._hoverGateObserver?.disconnect(),this._hoverGateObserver=void 0,this._hovered="",this._desiredEndpointIds.clear(),super.disconnectedCallback()}updated(e){e.has("hass")&&(this._release?.(),this._acceptRuntime(p(this.hass)),this._release=l(this.hass,()=>{this._acceptRuntime(p(this.hass))}));const t=e.has("currentSpace")||e.has("devices")||e.has("registry");t&&(this._mappedMemo=void 0,this.devices.some(e=>e.id===this._hovered&&e.space===this.currentSpace)||this._clear()),this._connectParent(),(this._endpointSetDirty||t)&&this._syncEndpointOwnership()}_acceptRuntime(e){e.revision===this._runtime.revision&&e.topologies===this._runtime.topologies&&e.states===this._runtime.states||(this._setDesiredEndpointIds([]),this._clearEndpointOwnership(),this._endpointSetDirty=!1,this._runtime=e,this._mappedMemo=void 0,this.requestUpdate())}_connectParent(){const e=this.parentElement;e&&e!==this._parent&&(this._disconnectParent(),this._parent=e,e.addEventListener("pointerover",this._pointerOver),e.addEventListener("pointerout",this._pointerOut),e.addEventListener("pointerdown",this._pointerDown,!0),"undefined"!=typeof MutationObserver&&(this._markerObserver=new MutationObserver(()=>this._syncEndpointOwnership()),this._markerObserver.observe(e,{childList:!0})),this._syncEndpointOwnership())}_disconnectParent(){this._parent?.removeEventListener("pointerover",this._pointerOver),this._parent?.removeEventListener("pointerout",this._pointerOut),this._parent?.removeEventListener("pointerdown",this._pointerDown,!0),this._markerObserver?.disconnect(),this._markerObserver=void 0,this._clearEndpointOwnership(),this._parent=void 0}_deviceFromEvent(e){for(const t of e.composedPath())if(t instanceof HTMLElement&&"device"===t.dataset.hp)return t;return null}_mouseAllowed(e){const t=this.getRootNode();return"mouse"===e.pointerType&&t.host?.hasAttribute?.("data-pointer-hover")}_clear(){this._setDesiredEndpointIds([]),this._clearEndpointOwnership(),this._endpointSetDirty=!1,this._hovered&&(this._hovered="",this.requestUpdate())}_setDesiredEndpointIds(e){const t=new Set(e);t.size===this._desiredEndpointIds.size&&[...t].every(e=>this._desiredEndpointIds.has(e))||(this._desiredEndpointIds=t,this._endpointSetDirty=!0)}_marker(e){return[...this._parent?.querySelectorAll('.dev[data-hp="device"][data-id]')||[]].find(t=>t.dataset.id===e)||null}_clearEndpointOwnership(){for(const e of this._endpointElements)e.removeAttribute(u);for(const e of this._parent?.querySelectorAll(`[${u}]`)||[])e.removeAttribute(u);this._endpointElements.clear()}_syncEndpointOwnership(){const e=new Set;for(const t of this._desiredEndpointIds){const i=this._marker(t);i&&e.add(i)}for(const t of this._endpointElements)e.has(t)||t.removeAttribute(u);for(const t of this._parent?.querySelectorAll(`[${u}]`)||[])e.has(t)||t.removeAttribute(u);for(const t of e)this._endpointElements.has(t)&&t.hasAttribute(u)||t.setAttribute(u,"");this._endpointElements=e,this._endpointSetDirty=!1}_position(e,t,i){const r=this._marker(e);if(!r)return null;const o=Number.parseFloat(r.style.left),s=Number.parseFloat(r.style.top),n=r.getBoundingClientRect();return Number.isFinite(o)&&Number.isFinite(s)?{x:o*t/100,y:s*i/100,width:n.width,height:n.height}:null}_targetText(e){if("remote-space"===e.kind){const i=this.spaces?.find(t=>t.id===e.spaceId)?.title;return"string"==typeof i&&i.trim()||a(t(this.hass),"route_other_space")}return a(t(this.hass),"unplaced-coordinator"===e.kind?"route_coordinator_not_on_plan":"route_device_not_on_plan")}_markerClearance(e){return.61*Math.max(e.width,e.height)+3}_points(e){return e.map(e=>`${e.x.toFixed(2)},${e.y.toFixed(2)}`).join(" ")}render(){if(!this._hovered||!this.registry||!this._runtime.topologies.length)return this._setDesiredEndpointIds([]),i;const e=this._mappedMemo,n=e&&e.runtime===this._runtime&&e.devices===this.devices&&e.registry===this.registry?e.mapped:h(this._runtime.topologies,this.devices,this.registry);e&&n===e.mapped||(this._mappedMemo={runtime:this._runtime,devices:this.devices,registry:this.registry,mapped:n});const p=d(n,this.currentSpace,this._hovered),l=this.clientWidth||this._parent?.clientWidth||1,_=this.clientHeight||this._parent?.clientHeight||1,u=this._position(this._hovered,l,_);if(!u)return this._setDesiredEndpointIds([]),i;const b=p.lines.map(e=>({...e,point:this._position(e.neighborMarkerId,l,_)})).filter(e=>!!e.point).map(e=>{const t=void 0===e.lqi?"rgba(145,155,165,.85)":r(e.lqi),i=e.routeDirection?c(u,e.point,this._markerClearance(u),this._markerClearance(e.point),e.routeDirection):null;return{...e,color:t,arrow:i}}),m=u.x>l/2,v=this._markerClearance(u)+18,g=p.parentTargets.map((e,t)=>{const i=30*(t-(p.parentTargets.length-1)/2),r={x:u.x+(m?-v:v),y:Math.max(14,Math.min(_-14,u.y+i))};return{target:e,point:r,arrow:c(u,r,this._markerClearance(u),0,"toward-neighbor")}});return this._setDesiredEndpointIds(b.length||g.length||p.remoteCount?[this._hovered,...b.map(e=>e.neighborMarkerId)]:[]),s`
- ${b.length||g.length?o`
{if(!this._mouseAllowed(e))return void this._clear();const t=this._deviceFromEvent(e),i=t?.dataset.id||"";i&&i!==this._hovered&&(this._hovered=i,this.requestUpdate())},this._pointerOut=e=>{const t=this._deviceFromEvent(e);if(!t||t.dataset.id!==this._hovered)return;const i=e.relatedTarget instanceof Element?e.relatedTarget.closest('[data-hp="device"]'):null;i?.dataset.id!==this._hovered&&this._clear()},this._pointerDown=e=>{"mouse"!==e.pointerType&&this._clear()}}connectedCallback(){super.connectedCallback();const e=this.getRootNode();e.host&&"undefined"!=typeof MutationObserver&&(this._hoverGateObserver=new MutationObserver(()=>{e.host.hasAttribute("data-pointer-hover")||this._clear()}),this._hoverGateObserver.observe(e.host,{attributes:!0,attributeFilter:["data-pointer-hover"]})),queueMicrotask(()=>this._connectParent())}disconnectedCallback(){this._release?.(),this._release=void 0,this._disconnectParent(),this._hoverGateObserver?.disconnect(),this._hoverGateObserver=void 0,this._hovered="",this._desiredEndpointIds.clear(),super.disconnectedCallback()}updated(e){e.has("hass")&&(this._release?.(),this._acceptRuntime(p(this.hass)),this._release=l(this.hass,()=>{this._acceptRuntime(p(this.hass))}));const t=e.has("currentSpace")||e.has("devices")||e.has("registry");t&&(this._mappedMemo=void 0,this.devices.some(e=>e.id===this._hovered&&e.space===this.currentSpace)||this._clear()),this._connectParent(),(this._endpointSetDirty||t)&&this._syncEndpointOwnership()}_acceptRuntime(e){e.revision===this._runtime.revision&&e.topologies===this._runtime.topologies&&e.states===this._runtime.states||(this._setDesiredEndpointIds([]),this._clearEndpointOwnership(),this._endpointSetDirty=!1,this._runtime=e,this._mappedMemo=void 0,this.requestUpdate())}_connectParent(){const e=this.parentElement;e&&e!==this._parent&&(this._disconnectParent(),this._parent=e,e.addEventListener("pointerover",this._pointerOver),e.addEventListener("pointerout",this._pointerOut),e.addEventListener("pointerdown",this._pointerDown,!0),"undefined"!=typeof MutationObserver&&(this._markerObserver=new MutationObserver(()=>this._syncEndpointOwnership()),this._markerObserver.observe(e,{childList:!0})),this._syncEndpointOwnership())}_disconnectParent(){this._parent?.removeEventListener("pointerover",this._pointerOver),this._parent?.removeEventListener("pointerout",this._pointerOut),this._parent?.removeEventListener("pointerdown",this._pointerDown,!0),this._markerObserver?.disconnect(),this._markerObserver=void 0,this._clearEndpointOwnership(),this._parent=void 0}_deviceFromEvent(e){for(const t of e.composedPath())if(t instanceof HTMLElement&&"device"===t.dataset.hp)return t;return null}_mouseAllowed(e){const t=this.getRootNode();return"mouse"===e.pointerType&&t.host?.hasAttribute?.("data-pointer-hover")}_clear(){this._setDesiredEndpointIds([]),this._clearEndpointOwnership(),this._endpointSetDirty=!1,this._hovered&&(this._hovered="",this.requestUpdate())}_setDesiredEndpointIds(e){const t=new Set(e);t.size===this._desiredEndpointIds.size&&[...t].every(e=>this._desiredEndpointIds.has(e))||(this._desiredEndpointIds=t,this._endpointSetDirty=!0)}_marker(e){return[...this._parent?.querySelectorAll('.dev[data-hp="device"][data-id]')||[]].find(t=>t.dataset.id===e)||null}_clearEndpointOwnership(){for(const e of this._endpointElements)e.removeAttribute(u);for(const e of this._parent?.querySelectorAll(`[${u}]`)||[])e.removeAttribute(u);this._endpointElements.clear()}_syncEndpointOwnership(){const e=new Set;for(const t of this._desiredEndpointIds){const i=this._marker(t);i&&e.add(i)}for(const t of this._endpointElements)e.has(t)||t.removeAttribute(u);for(const t of this._parent?.querySelectorAll(`[${u}]`)||[])e.has(t)||t.removeAttribute(u);for(const t of e)this._endpointElements.has(t)&&t.hasAttribute(u)||t.setAttribute(u,"");this._endpointElements=e,this._endpointSetDirty=!1}_position(e,t,i){const r=this._marker(e);if(!r)return null;const o=Number.parseFloat(r.style.left),s=Number.parseFloat(r.style.top),n=r.getBoundingClientRect();return Number.isFinite(o)&&Number.isFinite(s)?{x:o*t/100,y:s*i/100,width:n.width,height:n.height}:null}_targetText(e){if("remote-space"===e.kind){const i=this.spaces?.find(t=>t.id===e.spaceId)?.title;return"string"==typeof i&&i.trim()||a(t(this.hass),"route_other_space")}return a(t(this.hass),"unplaced-coordinator"===e.kind?"route_coordinator_not_on_plan":"route_device_not_on_plan")}_markerClearance(e){return.61*Math.max(e.width,e.height)+3}_points(e){return e.map(e=>`${e.x.toFixed(2)},${e.y.toFixed(2)}`).join(" ")}render(){if(!this._hovered||!this.registry||!this._runtime.topologies.length)return this._setDesiredEndpointIds([]),i;const e=this._mappedMemo,n=e&&e.runtime===this._runtime&&e.devices===this.devices&&e.registry===this.registry?e.mapped:h(this._runtime.topologies,this.devices,this.registry);e&&n===e.mapped||(this._mappedMemo={runtime:this._runtime,devices:this.devices,registry:this.registry,mapped:n});const p=d(n,this.currentSpace,this._hovered),l=this.clientWidth||this._parent?.clientWidth||1,_=this.clientHeight||this._parent?.clientHeight||1,u=this._position(this._hovered,l,_);if(!u)return this._setDesiredEndpointIds([]),i;const m=p.lines.map(e=>({...e,point:this._position(e.neighborMarkerId,l,_)})).filter(e=>!!e.point).map(e=>{const t=void 0===e.lqi?"rgba(145,155,165,.85)":r(e.lqi),i=e.routeDirection?c(u,e.point,this._markerClearance(u),this._markerClearance(e.point),e.routeDirection):null;return{...e,color:t,arrow:i}}),v=u.x>l/2,b=this._markerClearance(u)+18,g=p.parentTargets.map((e,t)=>{const i=30*(t-(p.parentTargets.length-1)/2),r={x:u.x+(v?-b:b),y:Math.max(14,Math.min(_-14,u.y+i))};return{target:e,point:r,arrow:c(u,r,this._markerClearance(u),0,"toward-neighbor")}});return this._setDesiredEndpointIds(m.length||g.length||p.remoteCount?[this._hovered,...m.map(e=>e.neighborMarkerId)]:[]),s`
+ ${m.length||g.length?o`
- ${b.map(e=>o`${void 0===e.lqi?o`o`${void 0===e.lqi?o``:i}`)}
`:i}
- ${b.map(e=>s`s`
`)}
- ${g.map(e=>s`
s`
${this._targetText(e.target)}
`)}
${p.remoteCount?s`
${a(t(this.hass),"remote_count",{n:p.remoteCount})}
`:i}
- `}}b.properties={hass:{attribute:!1},devices:{attribute:!1},registry:{attribute:!1},currentSpace:{type:String,attribute:"current-space"},spaces:{attribute:!1},viewKey:{attribute:!1}},b.styles=n`:host{position:absolute;inset:0;z-index:7;display:block;pointer-events:none;}svg{position:absolute;inset:0;width:100%;height:100%;overflow:visible;}line{vector-effect:non-scaling-stroke;stroke-linecap:round;}.route-arrow{vector-effect:non-scaling-stroke;}svg,line,polygon,.halo,.remote,.parent-bubble{pointer-events:none;}.halo{position:absolute;width:calc(var(--device-base-size,4cqw) * 1.22);height:calc(var(--device-base-size,4cqw) * 1.22);transform:translate(-50%,-50%);box-sizing:border-box;border:2px solid rgba(120,190,220,.82);border-radius:50%;box-shadow:0 0 0 4px rgba(120,190,220,.16);}.remote,.parent-bubble{position:absolute;transform:translate(12px,calc(-100% - 12px));border:1px solid rgba(255,255,255,.7);border-radius:999px;padding:3px 7px;color:#fff;background:rgba(28,31,36,.88);box-shadow:0 2px 7px rgba(0,0,0,.28);white-space:nowrap;font:600 11px/1.2 system-ui,sans-serif;}.parent-bubble.right{transform:translate(0,-50%);}.parent-bubble.left{transform:translate(-100%,-50%);}@media (forced-colors:active){line{stroke:Highlight !important;}.route-arrow{fill:Highlight !important;}.halo{border-color:Highlight;box-shadow:none;}.remote,.parent-bubble{color:CanvasText;background:Canvas;border-color:CanvasText;}}`,customElements.get("hp-zigbee-topology-overlay")||customElements.define("hp-zigbee-topology-overlay",b);export{b as HpZigbeeTopologyOverlay};
+ `}}m.properties={hass:{attribute:!1},devices:{attribute:!1},registry:{attribute:!1},currentSpace:{type:String,attribute:"current-space"},spaces:{attribute:!1},viewKey:{attribute:!1}},m.styles=n`:host{position:absolute;inset:0;z-index:7;display:block;pointer-events:none;}svg{position:absolute;inset:0;width:100%;height:100%;overflow:visible;}line{vector-effect:non-scaling-stroke;stroke-linecap:round;}.route-arrow{vector-effect:non-scaling-stroke;}svg,line,polygon,.halo,.remote,.parent-bubble{pointer-events:none;}.halo{position:absolute;width:calc(var(--device-base-size,4cqw) * 1.22);height:calc(var(--device-base-size,4cqw) * 1.22);transform:translate(-50%,-50%);box-sizing:border-box;border:2px solid rgba(120,190,220,.82);border-radius:50%;box-shadow:0 0 0 4px rgba(120,190,220,.16);}.remote,.parent-bubble{position:absolute;transform:translate(12px,calc(-100% - 12px));border:1px solid rgba(255,255,255,.7);border-radius:999px;padding:3px 7px;color:#fff;background:rgba(28,31,36,.88);box-shadow:0 2px 7px rgba(0,0,0,.28);white-space:nowrap;font:600 11px/1.2 system-ui,sans-serif;}.parent-bubble.right{transform:translate(0,-50%);}.parent-bubble.left{transform:translate(-100%,-50%);}@media (forced-colors:active){line{stroke:Highlight !important;}.route-arrow{fill:Highlight !important;}.halo{border-color:Highlight;box-shadow:none;}.remote,.parent-bubble{color:CanvasText;background:Canvas;border-color:CanvasText;}}`,customElements.get("hp-zigbee-topology-overlay")||customElements.define("hp-zigbee-topology-overlay",m);export{m as HpZigbeeTopologyOverlay};
diff --git a/dist/houseplan-assets/iso-scene-render-DkVCyTYN.js b/custom_components/houseplan/frontend/houseplan-assets/iso-scene-render-sNAJFXBj.js
similarity index 99%
rename from dist/houseplan-assets/iso-scene-render-DkVCyTYN.js
rename to custom_components/houseplan/frontend/houseplan-assets/iso-scene-render-sNAJFXBj.js
index aa9680a7..9448c6dd 100644
--- a/dist/houseplan-assets/iso-scene-render-DkVCyTYN.js
+++ b/custom_components/houseplan/frontend/houseplan-assets/iso-scene-render-sNAJFXBj.js
@@ -1,4 +1,4 @@
-globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="33e3bf530b13e01b6cc86d437770676c16441418afa14b0324be617fc2d3bb22";import{dH as e,dI as t,br as n,dJ as o,dK as i,dL as a,ax as r,dM as s,dN as l,dO as c,dP as f,aW as d,dQ as u,U as h,ci as p,ch as m,dR as g,V as w,J as M,dS as y,d7 as b,dT as S,A as x,as as v,dU as $,dV as k,dW as z,dX as P,dY as C}from"./houseplan-card-B1GLwcbS.js";const I=e=>`${Number(e[0].toFixed(4))} ${Number(e[1].toFixed(4))}`;function T(e){let t=0;for(let n=0;n
Array.isArray(e)&&Number.isFinite(e[0])&&Number.isFinite(e[1])).map(e=>[Number(e[0]),Number(e[1])]),n=t[t.length-1];return t.length>1&&t[0][0]===n[0]&&t[0][1]===n[1]&&t.pop(),t}(e);if(n.length<3)return[];const o=!t;return T(n)>0===o?n:[...n].reverse()}function j(e,t,o){return e.length?`M ${e.map(e=>I(n(e,o,t))).join(" L ")} Z`:""}function O(e,t,n){const o=t[1]-e[1],i=-(t[0]-e[0]),a=n.rotDeg*Math.PI/180;return o*Math.sin(a)+i*Math.cos(a)}function N(t,o,i=e){if(!Number.isFinite(o)||o<0)throw new Error("invalid floor edge height");const a=(t||[]).map(e=>(e||[]).map((e,t)=>function(e,t){const n=H(e,t);if(!n.length)return n;let o=0;for(let e=1;e0)).filter(e=>e.length>=3&&Math.abs(T(e))>=1e-9)).filter(e=>e.length&&T(e[0])>0);a.sort((e,t)=>{const n=e[0][0],o=t[0][0];return n[0]-o[0]||n[1]-o[1]||Math.abs(T(t[0]))-Math.abs(T(e[0]))});const r=[],s=[];let l=0;for(let e=0;ee.depth-t.depth||e.component-t.component||e.edge-t.edge),{footprintPath:r.join(" "),sides:s,componentCount:a.length,edgeCount:l}}function B(e,t){return e^=Math.round(64*(Number.isFinite(t)?t:0)),Math.imul(e,16777619)>>>0}const A=Object.freeze({revision:3,leafThicknessRatio:.04,frameThicknessRatio:.05,doorTurnDeg:50,windowTurnDeg:65,gateTurnDeg:10,gateTopRatio:.88,windowFrameBottomRatio:.38,windowFrameTopRatio:1,windowSashBottomRatio:.4,windowSashTopRatio:.98,windowGlassBottomRatio:.45,windowGlassTopRatio:.93,doorTopRatio:.92});A.leafThicknessRatio,A.frameThicknessRatio;const R=e=>e.every(Number.isFinite);function F(e,t){return Object.freeze([Object.is(e,-0)?0:e,Object.is(t,-0)?0:t])}function V(e,t){return[e[0]+t[0],e[1]+t[1]]}function L(e,t){return[e[0]-t[0],e[1]-t[1]]}function D(e,t){return[e[0]*t,e[1]*t]}function G(e,t,n,o){const i=e[0]*n,a=e[1]*o,r=t*Math.PI/180;return[i*Math.cos(r)-a*Math.sin(r),i*Math.sin(r)+a*Math.cos(r)]}function W(e,t,n,i,a,r,s){const l=e.flipH?-1:1,c="gate"===e.type?1:e.flipV?-1:1,f="door"===e.type||"gate"===e.type?e.face:o(e.type,e.flipV,e.angle,e.face);return{leaf:t,hinge:V([e.x+f.ox,e.y+f.oy],G(n,e.angle,l,c)),closedVector:G(i,e.angle,l,c),quarterVector:G([-i[1],i[0]],e.angle,l,c),turnDeg:a,bottom:r,top:s}}const E=e=>`${Number(e[0].toFixed(4))} ${Number(e[1].toFixed(4))}`;function q(e,t,o,i,a={}){const r=o.map(e=>n(e.point,e.z,i)),s=i.rotDeg*Math.PI/180,l=i.tiltDeg*Math.PI/180,c=o.reduce((e,t)=>e+(t.point[0]*Math.sin(s)+t.point[1]*Math.cos(s))*Math.sin(l)+t.z*Math.cos(l),0)/o.length;return Object.freeze({kind:e,material:t,d:`M ${r.map(E).join(" L ")} Z`,cameraDepth:c,depth:Math.max(...r.map(e=>e[1])),...a})}function _(e,t,n,o,i,a,r,s={}){return q(e,t,[{point:n,z:i},{point:o,z:i},{point:o,z:a},{point:n,z:a}],r,s)}function U(t,o,i=e){const a=Math.max(0,Math.min(1,Number.isFinite(o)?o:0));return t.leaves.map(e=>{const o=function(e,t){const n=e.turnDeg*t*Math.PI/180;return[e.hinge[0]+e.closedVector[0]*Math.cos(n)+e.quarterVector[0]*Math.sin(n),e.hinge[1]+e.closedVector[1]*Math.cos(n)+e.quarterVector[1]*Math.sin(n)]}(e,a),r=n(e.hinge,e.bottom,i),s=n(o,e.bottom,i),l=n(o,e.top,i),c=n(e.hinge,e.top,i),f="window"===t.type?"light-window":"matte-leaf",d="window"===t.type?function(e,t,n,o){const i=e.windowProfile;if(!i)throw new Error("missing isometric window profile");const a=L(n,t.hinge),r=Math.hypot(a[0],a[1]);if(!(r>1e-9))return Object.freeze([]);const s=F(a[0]/r,a[1]/r),l=Math.min(i.member,r/4,(i.sashTop-i.sashBottom)/4),c=V(t.hinge,D(s,l)),f=L(n,D(s,l)),d=Math.min(.35*e.frameThickness,.02*r),u=F(-s[1]*d/2,s[0]*d/2),h=V(c,u),p=V(f,u),m=L(c,u),g=L(f,u),w=[_("window-sash-side","light-frame",t.hinge,c,i.sashBottom,i.sashTop,o,{edge:"hinge"}),_("window-sash-side","light-frame",f,n,i.sashBottom,i.sashTop,o,{edge:"tip"}),_("window-sash-bottom","light-frame",t.hinge,n,i.sashBottom,i.sashBottom+l,o),_("window-sash-top","light-frame",t.hinge,n,i.sashTop-l,i.sashTop,o),_("window-glass","glass-side",h,p,i.glassBottom,i.glassTop,o),_("window-glass","glass-side",g,m,i.glassBottom,i.glassTop,o),q("window-glass-top","glass-top",[{point:h,z:i.glassTop},{point:p,z:i.glassTop},{point:g,z:i.glassTop},{point:m,z:i.glassTop}],o)];return Object.freeze(w.sort((e,t)=>e.depth-t.depth||e.kind.localeCompare(t.kind)||String(e.edge||"").localeCompare(String(t.edge||""))))}(t,e,o,i):function(e,t,n,o){const i=L(t,e.hinge),a=Math.hypot(i[0],i[1]);if(!(a>1e-9&&n>0))return Object.freeze([]);const r=F(-i[1]*n/(2*a),i[0]*n/(2*a)),s=V(e.hinge,r),l=V(t,r),c=L(e.hinge,r),f=L(t,r),d=[_("leaf-back","matte-leaf",f,c,e.bottom,e.top,o),_("leaf-front","matte-leaf",s,l,e.bottom,e.top,o),_("leaf-edge","matte-leaf",c,s,e.bottom,e.top,o,{edge:"hinge"}),_("leaf-edge","matte-leaf",l,f,e.bottom,e.top,o,{edge:"tip"}),q("leaf-top","matte-leaf",[{point:s,z:e.top},{point:c,z:e.top},{point:f,z:e.top},{point:l,z:e.top}],o)];return Object.freeze(d.sort((e,t)=>e.depth-t.depth||e.kind.localeCompare(t.kind)||String(e.edge||"").localeCompare(String(t.edge||""))))}(e,o,t.leafThickness,i);return Object.freeze({id:t.id,sourceIndex:t.sourceIndex,type:t.type,leaf:e.leaf,d:`M ${E(r)} L ${E(s)} L ${E(l)} L ${E(c)} Z`,shadowD:`M ${E(n(e.hinge,0,i))} L ${E(n(o,0,i))}`,depth:Math.max(r[1],s[1]),material:f,thickness:"window"===t.type?0:t.leafThickness,surfaces:d})})}const K=1e-9,Z=(e,t)=>`${e}\0${t}`,J=e=>e.length>=2&&Number.isFinite(e[0])&&Number.isFinite(e[1]);function Q(e){let t=0;for(let n=0;n=3&&e.every(J)&&Math.abs(Q(e))>K}function Y(e,t,n){const o=n[0]-t[0],i=n[1]-t[1],a=o*o+i*i,r=a?Math.max(0,Math.min(1,((e[0]-t[0])*o+(e[1]-t[1])*i)/a)):0;return Math.hypot(e[0]-t[0]-r*o,e[1]-t[1]-r*i)}function ee(e,t,n=1e-7){for(let o=0;oe[1]!=r[1]>e[1]&&e[0]<(r[0]-a[0])*(e[1]-a[1])/(r[1]-a[1])+a[0]&&(n=!n)}return n}function ne(e){return Math.max(0,Math.abs(Q(e.outer))-(e.holes||[]).reduce((e,t)=>e+Math.abs(Q(t)),0))}function oe(e){return!!e.id&&X(e.outer)&&(e.holes||[]).every(X)&&ne(e)>K}function ie(e,t){if(ee(e,t.outer)||!te(e,t.outer))return!1;for(const n of t.holes||[])if(ee(e,n)||te(e,n))return!1;return!0}function ae(e,t){return oe(t)&&ie(e,t)}function re(e){if(!oe(e))return null;if(e.safePoint&&ae(e.safePoint,e))return[e.safePoint[0],e.safePoint[1]];const t=e.outer.map(e=>e[0]),n=e.outer.map(e=>e[1]),o=Math.min(...t),i=Math.max(...t),a=Math.min(...n),r=Math.max(...n),s=[[(o+i)/2,(a+r)/2],[t.reduce((e,t)=>e+t,0)/t.length,n.reduce((e,t)=>e+t,0)/n.length]];for(let t=0;t{if(!ae(t,e))return;const n=function(e,t){let n=1/0;for(const o of[t.outer,...t.holes||[]])for(let t=0;tc+K&&(l=t,c=n)};s.forEach(f);for(let e=1;e<16;e++)for(let t=1;t<16;t++)f([o+(i-o)*e/16,a+(r-a)*t/16]);return l}function se(e){if(!J(e.floorAnchor))return null;const t=e.roomsValidated?e.rooms:e.rooms.filter(oe),n=e.preferredRoomId&&t.find(t=>t.id===e.preferredRoomId)||null;let o=null;return"device"===e.kind?(n&&ae(e.floorAnchor,n)&&(o=n),o||(o=t.filter(t=>ae(e.floorAnchor,t)).sort((e,t)=>ne(e)-ne(t)||((e,t)=>et?1:0)(e.id,t.id))[0]||null)):o=n,o?{id:o.id,area:ne(o),safePoint:e.roomsValidated&&o.safePoint?[o.safePoint[0],o.safePoint[1]]:re(o)}:null}function le(t,o,i,a=e,r=[0,0]){if(!J(t)||!J(o)||o[0]<0||o[1]<0||!Number.isFinite(i)||!J(r))throw new Error("invalid isometric overlay footprint");return[[t[0]-o[0],t[1]-o[1]],[t[0]+o[0],t[1]-o[1]],[t[0]+o[0],t[1]+o[1]],[t[0]-o[0],t[1]+o[1]]].map(e=>{const t=n(e,i,a);return[t[0]+r[0],t[1]+r[1]]})}function ce(e,t,n){return(t[0]-e[0])*(n[1]-e[1])-(t[1]-e[1])*(n[0]-e[0])}function fe(e,t,n,o){const i=ce(e,t,n),a=ce(e,t,o),r=ce(n,o,e),s=ce(n,o,t);return(i>K&&a<-K||i<-K&&a>K)&&(r>K&&s<-K||r<-K&&s>K)||(Math.abs(i)<=K&&Y(n,e,t)<=K||Math.abs(a)<=K&&Y(o,e,t)<=K||Math.abs(r)<=K&&Y(e,n,o)<=K||Math.abs(s)<=K&&Y(t,n,o)<=K)}function de(e,t,n,o){return fe(e,t,n,o)?0:Math.min(Y(e,n,o),Y(t,n,o),Y(n,e,t),Y(o,e,t))}const ue=new WeakMap;function he(e){if(!e.length)return null;let t=1/0,n=1/0,o=-1/0,i=-1/0;for(const a of e){if(!J(a))return null;t=Math.min(t,a[0]),n=Math.min(n,a[1]),o=Math.max(o,a[0]),i=Math.max(i,a[1])}return[t,n,o,i]}function pe(e,t){if(!t)return he(e.outer);if(ue.has(e))return ue.get(e)??null;const n=he(e.outer);return ue.set(e,n),n}function me(e,t,n){return e[0]<=t[2]+n&&e[2]>=t[0]-n&&e[1]<=t[3]+n&&e[3]>=t[1]-n}function ge(e,t,n,o){return Math.min(t[0],n[0])<=e[2]+o&&Math.max(t[0],n[0])>=e[0]-o&&Math.min(t[1],n[1])<=e[3]+o&&Math.max(t[1],n[1])>=e[1]-o}function we(e,t,n,o,i){const a=pe(n,i);if(!a||!me(t,a,o))return!1;if(e.some(e=>function(e,t){return!!te(e,t.outer)&&!(t.holes||[]).some(t=>te(e,t))}(e,n)))return!0;if(n.outer.some(n=>n[0]>=t[0]&&n[0]<=t[2]&&n[1]>=t[1]&&n[1]<=t[3]&&te(n,e)))return!0;for(const i of[n.outer,...n.holes||[]])for(let n=0;n=-32768&&e<=32767&&t>=-32768&&t<=32767?65536*(e+32768)+t+32768:`${e}:${t}`}function $e(e,t,n){const o=e=>{const t=Math.floor(e),n=Math.ceil(e);return t===n?[t-1,t,t+1]:[t,n]},i=o(t[0]),a=o(t[1]);for(const t of a)for(const o of i){if(o*o+t*t>n*n+K)continue;const i=ve(o,t);if(!e.points.has(i)){const n=[o,t];e.points.set(i,n),e.pending.push(n)}}}function ke(e,t,n){const o=t[0]-e[0],i=t[1]-e[1];let a=0,r=1;const s=(e,t)=>{if(Math.abs(e)<=K)return t>=0;const n=t/e;if(e<0){if(n>r)return!1;n>a&&(a=n)}else{if(n{for(const i of[t[0],t[2]])if(!(in[2]+K))for(const a of[n[1],n[3]])a>=t[1]-K&&a<=t[3]+K&&$e(e,[i,a],o)};i(t,n),i(n,t)}function Ce(e,t,n){for(const o of t)ze(e,o,n);for(let o=0;oK?Math.max(0,Math.min(1,-(i[0][0]*a+i[0][1]*r)/s)):0;$e(e,i[0],o),$e(e,i[1],o),$e(e,[i[0][0]+a*l,i[0][1]+r*l],o)}function Te(e,t,n){const o=[[t[0],t[1]],[t[2],t[1]],[t[2],t[3]],[t[0],t[3]]];for(let t=0;tK)for(const t of[n[0],n[2]]){const a=(t-i[0])/r;if(a<-K||a>1+K)continue;const l=i[1]+s*a;l>=n[1]-K&&l<=n[3]+K&&$e(e,[t,l],o)}if(Math.abs(s)>K)for(const t of[n[1],n[3]]){const a=(t-i[1])/s;if(a<-K||a>1+K)continue;const l=i[0]+r*a;l>=n[0]-K&&l<=n[2]+K&&$e(e,[l,t],o)}}function je(e,t,n,o){for(const i of n)He(e,t,i,o)}function Oe(e,t,n,o){const[i,a]=t,[r,s]=n,l=[a[0]-i[0],a[1]-i[1]],c=[s[0]-r[0],s[1]-r[1]],f=l[0]*c[1]-l[1]*c[0];if(Math.abs(f)<=K)return;const d=[r[0]-i[0],r[1]-i[1]],u=(d[0]*c[1]-d[1]*c[0])/f,h=(d[0]*l[1]-d[1]*l[0])/f;if(u<-K||u>1+K||h<-K||h>1+K)return;const p=[i[0]+l[0]*u,i[1]+l[1]*u];Math.hypot(p[0],p[1])<=o+2&&$e(e,p,o)}const Ne=new WeakMap;function Be(e,t,n,o,i,a,r,s){for(const l of function(e){const t=Ne.get(e);if(t)return t;const n=[];for(const t of[e.outer,...e.holes||[]])for(let e=0;ee[0]*t[0]+e[1]*t[1];let d=1/0,u=-1/0,h=1/0,p=-1/0;for(const e of n){const n=f(e,t),o=f(e,c);d=Math.min(d,n),u=Math.max(u,n),h=Math.min(h,o),p=Math.max(p,o)}const m=l.tangentMin-u-o,g=l.tangentMax-d+o,w=[l.normalOffset-o-p,l.normalOffset+o-h];for(const n of w){const o=e=>[(t[0]*e+c[0]*n)/i,(t[1]*e+c[1]*n)/i],l=ke(o(m),o(g),a+2);l&&(s?.push(l),Ie(e,l[0],l[1],a),je(e,l,r,a))}}}function Ae(e,t){if(t<=K)$e(e,[0,0],t);else for(let n=Math.ceil(-t);n<=Math.floor(t);n++){const o=Math.sqrt(Math.max(0,t*t-n*n));$e(e,[n,o],t),$e(e,[n,-o],t)}}function Re(e,t,n=4){const o=[];for(let i=Math.floor(e[1]-n);i<=Math.ceil(e[1]+n);i++)for(let a=Math.floor(e[0]-n);a<=Math.ceil(e[0]+n);a++){const e=Math.hypot(a,i);e<=t+K&&o.push({offset:[a,i],distance:e})}return o.sort((e,t)=>e.distance-t.distance||e.offset[1]-t.offset[1]||e.offset[0]-t.offset[0]),o}function Fe(e,t){return[t[0]-e.screenHalfSize[0],t[1]-e.screenHalfSize[1],t[0]+e.screenHalfSize[0],t[1]+e.screenHalfSize[1]]}function Ve(e,t){return[e[0]-t,e[1]-t,e[2]+t,e[3]+t]}function Le(e,t,n){const o=Math.min(e[2],t[2])-Math.max(e[0],t[0])+n,i=Math.min(e[3],t[3])-Math.max(e[1],t[1])+n;return o>K&&i>K?o*i:0}function De(e,t,n){const o=n.tiltDeg*Math.PI/180;return a([e[0],e[1]+t*n.zScale*Math.sin(o)],n)}function Ge(e,t,n,o){const i=[t[0]*n,t[1]*n];if(!o&&Math.abs(i[0]-e.nudgeScene[0])<=K&&Math.abs(i[1]-e.nudgeScene[1])<=K)return e;const a=[i[0]-e.nudgeScene[0],i[1]-e.nudgeScene[1]],r=[e.raisedScene[0]+i[0],e.raisedScene[1]+i[1]],s=Math.hypot(t[0],t[1]);return{...e,visualScene:r,footprint:e.footprint.map(e=>[e[0]+a[0],e[1]+a[1]]),nudgeScene:i,nudgeCss:t,nudgeDistanceCss:s,nudged:s>K,capped:e.capped||o,status:o?"degraded":e.status,reason:o?"overlay-collision":e.reason,tether:Se(e.floorScene,r,!1)}}function We(t){const o=t.sceneUnitsPerCssPixel,a=t.maxNudgeCssPx??48,r=t.safetyGapCssPx??4,s=t.visualOffset??i,l=t.camera||e;if(!(o>0&&Number.isFinite(o)&&a>=0&&Number.isFinite(a)&&r>=0&&Number.isFinite(r)))throw new Error("invalid isometric overlay collision input");const c=r*o,f=64*o,d=new Map(t.rooms.filter(oe).map(e=>[e.id,e])),u=new Map([...d].map(([e,t])=>[e,he(t.outer)])),h=new Map([...d].flatMap(([e,t])=>{const n=function(e){if(4!==e.outer.length||0!==(e.holes?.length||0))return null;const t=he(e.outer);if(!t)return null;const n=new Set(e.outer.map(e=>{const n=Math.abs(e[0]-t[0])<=K?0:Math.abs(e[0]-t[2])<=K?1:-1,o=Math.abs(e[1]-t[1])<=K?0:Math.abs(e[1]-t[3])<=K?1:-1;return n<0||o<0?"":`${n}:${o}`}));return 4!==n.size||n.has("")?null:t}(t);return n?[[e,n]]:[]})),p=t.wallSilhouettes.every(Me),m=t.wallSilhouettes.map(e=>({wall:e,bounds:pe(e,!0)})),g=[],w=new Map,M=new Map,y=[],b=[...t.items].sort((e,t)=>e.placement.nudgeDistanceCss-t.placement.nudgeDistanceCss||Z(e.kind,e.id).localeCompare(Z(t.kind,t.id))),S=l.rotDeg*Math.PI/180,x=l.tiltDeg*Math.PI/180,v=1/l.xyScale,$=1/(l.xyScale*Math.cos(x)),k=Math.cos(S),z=Math.sin(S),P=e=>[Math.floor(e[0]/f),Math.floor(e[1]/f),Math.floor(e[2]/f),Math.floor(e[3]/f)],C=e=>{const[t,n,o,i]=P(Ve(e,c)),a=new Set;for(let e=n;e<=i;e++)for(let n=t;n<=o;n++)for(const t of w.get(ve(n,e))||[])a.add(t);return[...a].sort((e,t)=>e-t)},I=e=>{const t=g.push(e)-1,[n,o,i,a]=P(e.bounds);for(let e=o;e<=a;e++)for(let o=n;o<=i;o++){const n=ve(o,e),i=w.get(n)||[];i.push(t),w.set(n,i)}};for(const e of b){const t=Z(e.kind,e.id),i=e.placement,r=[i.nudgeScene[0]/o,i.nudgeScene[1]/o],w=i.footprint.map(e=>[e[0]-i.nudgeScene[0],e[1]-i.nudgeScene[1]]),b=i.owner&&d.get(i.owner.id)||null,S=De(i.visualScene,s,l),x=he(w),T=p&&w.length?m.filter(({bounds:e})=>{if(!e)return!1;return!!x&&me(Ve(x,a*o),e,c)}):m,H=C(Ve(Fe(e,i.raisedScene),a*o)),j=e=>{const t=[];let n=0;for(const o of H){const i=Le(e,g[o].bounds,c);i>K&&(t.push(o),n+=i)}return{conflicts:t,penalty:n}},O=t=>{if(Math.hypot(t[0],t[1])>a+K)return null;const n=[t[0]*o,t[1]*o],r=Math.abs(n[0]-i.nudgeScene[0])<=K&&Math.abs(n[1]-i.nudgeScene[1])<=K,s=[i.raisedScene[0]+n[0],i.raisedScene[1]+n[1]],l=Fe(e,s),{conflicts:c,penalty:f}=j(l);return{offsetScene:n,sameAsBase:r,visualScene:s,bounds:l,conflicts:c,penalty:f}},N=b&&u.get(b.id)||null,B=b&&h.get(b.id)||null,A=!!b&&(B?S[0]>B[0]+K&&S[0]B[1]+K&&S[1][0,0]),D=e=>{for(let t=0;t{const n=Math.floor((e[0]-c)/f),o=Math.floor((e[1]-c)/f),i=Math.floor((e[2]+c)/f),a=Math.floor((e[3]+c)/f);V+=1;for(let r=o;r<=a;r++)for(let o=n;o<=i;o++)for(const n of R.get(ve(o,r))||[])if(F[n]!==V&&(F[n]=V,we(t(),e,T[n].wall,c,!0)))return n},W=-2,E=-1,q=e=>{if(e.sameAsBase)return W;if(!p||!b)return E;const t=e.visualScene[0]-i.visualScene[0],n=e.visualScene[1]-i.visualScene[1],o=t*v,a=n*$,r=S[0]+o*k+a*z,s=S[1]-o*z+a*k;if(N&&(rN[2]||sN[3]))return E;if(B){if(!(r>B[0]+K&&rB[1]+K&&sc||=D(e.offsetScene));return void 0===f?W:f},_=e=>q(e)===W,U=e=>{const t=O(e);return t&&_(t)?{placement:Ge(i,e,o,!1),bounds:t.bounds,conflicts:t.conflicts,penalty:t.penalty}:null},J=U(r);let Q=J,X=!1;if(!Q||Q.conflicts.length){const t=e.nudgeHintCss?U(e.nudgeHintCss):null;t&&!t.conflicts.length&&(Q=t,X=!0)}if(!J||J.conflicts.length){const t=xe(),f=[],d=[],u=[],h=new Set,p=new Set(J?.conflicts||[]),m=t=>{if(h.has(t))return;h.add(t);const n=g[t].bounds,a=[(n[0]-e.screenHalfSize[0]-c-i.raisedScene[0])/o,(n[1]-e.screenHalfSize[1]-c-i.raisedScene[1])/o,(n[2]+e.screenHalfSize[0]+c-i.raisedScene[0])/o,(n[3]+e.screenHalfSize[1]+c-i.raisedScene[1])/o];f.push(a),d.push(a)},M=x,y=new Set,S=new Set,v=e=>{if(y.has(e)||!M)return;y.add(e);const{wall:n,bounds:i}=T[e];if(i){const e=[(i[0]-c-M[2])/o,(i[1]-c-M[3])/o,(i[2]+c-M[0])/o,(i[3]+c-M[1])/o];d.push(e),Te(t,e,a)}Be(t,n,w,c,o,a,f,u)};let $=!1,k=!1;const z=()=>{if(!$&&($=!0,Ae(t,a),b))for(const e of[b.outer,...b.holes||[]])for(let r=0;r{for(let e=P;e{const e=t.pending.splice(0).map(e=>({offset:e,distance:Math.hypot(e[0],e[1])})).sort((e,t)=>e.distance-t.distance||e.offset[1]-t.offset[1]||e.offset[0]-t.offset[0]);let n=null;for(const t of e){const e=Q&&!Q.conflicts.length?Q.placement.nudgeDistanceCss:1/0;if(t.distance>a+K||t.distance>e+K)break;const s=t.offset;if(Math.abs(s[0]-r[0])<=K&&Math.abs(s[1]-r[1])<=K)continue;const l=O(s);if(!l)continue;for(const e of l.conflicts)h.has(e)||p.add(e);if(!(!Q||!l.conflicts.length||Q.conflicts.length&&l.penalty=0){const e=c;if(y.has(e))continue;const o={index:e,freePriority:l.conflicts.length?1:0,score:l.conflicts.length?l.penalty:t.distance,distance:t.distance};(!n||o.freePrioritye-t);p.clear(),t.forEach(m),e=!0}if(S.size){const t=[...S].sort((e,t)=>e-t);S.clear(),t.forEach(v),e=!0}if(!e&&Q&&!Q.conflicts.length&&(!X||$||!k))break;if(e||$||(z(),e=!0),!e)break;H(),j()}if(Q&&!Q.conflicts.length){const e=Q.placement.nudgeCss;for(const t of Re(e,a)){if(t.distance>=Q.placement.nudgeDistanceCss-K)break;const e=O(t.offset);e&&!e.conflicts.length&&_(e)&&(Q={placement:Ge(i,t.offset,o,!1),bounds:e.bounds,conflicts:e.conflicts,penalty:e.penalty})}}}if(Q)Q.conflicts.length&&(Q={...Q,placement:Ge(i,Q.placement.nudgeCss,o,!0)});else{const t=Ge(i,r,o,!0),n=Fe(e,t.visualScene);Q={placement:t,bounds:n,conflicts:C(n),penalty:1/0}}for(const e of Q.conflicts)Le(Q.bounds,g[e].bounds,c)>K&&y.push(Object.freeze([g[e].key,t]));M.set(t,Q.placement),I({key:t,bounds:Q.bounds})}return{placements:M,residualPairs:Object.freeze(y)}}const Ee="33e3bf530b13e01b6cc86d437770676c16441418afa14b0324be617fc2d3bb22",qe=e=>"wall-side"===e.layer?0:"wall-top"===e.layer?1:2,_e=e=>{if("wall-side"===e.layer)return`${e.face.polygon}:${e.face.ring}:${e.face.edge}`;if("wall-top"===e.layer)return String(e.face.component);const t=e.surface;return`${t.sourceIndex}:${t.leaf??-1}:${t.kind}:${t.jamb??-1}:${t.edge??""}:${t.id}:${t.material}`};function Ue(e,t){const n=[...e.sides.map(e=>({layer:"wall-side",depth:e.depth,face:e})),...e.topFaces.map(e=>({layer:"wall-top",depth:e.depth,face:e})),...t.map(e=>({layer:"opening",depth:e.depth,surface:e}))];n.sort((e,t)=>e.depth-t.depth||qe(e)-qe(t)||_e(e).localeCompare(_e(t)));const o=new Map;for(const e of n){if("opening"!==e.layer)continue;const t=`${e.surface.type}\0${e.surface.id}`,n=o.get(t)||[];n.push(e),o.set(t,n)}for(const e of o.values())e.sort((e,t)=>{const n="opening"===e.layer?e.surface:null,o="opening"===t.layer?t.surface:null;return(n?.cameraDepth??n?.depth??0)-(o?.cameraDepth??o?.depth??0)||_e(e).localeCompare(_e(t))});const i=new Map;return Object.freeze(n.map(e=>{if("opening"!==e.layer)return e;const t=`${e.surface.type}\0${e.surface.id}`,n=i.get(t)||0;return i.set(t,n+1),o.get(t)?.[n]||e}))}const Ke=Object.freeze({textLatinAdvance:.72,textWideAsciiAdvance:1,textWideAdvance:1.1,textSpaceAdvance:.4,textWidthSafety:1.08,deviceShellInset:.134375,deviceShellGap:.1,deviceSectionGap:.08,deviceBadgeMinWidth:.7875,deviceBadgeHeight:.7875,deviceBadgeInlinePadding:.28,deviceValueInlinePadding:.32,deviceAuxiliaryExtent:.7,deviceLqiFontSize:.38,deviceLqiTop:.734375,deviceLqiBelowBottomBadgeTop:1.571875,devicePadding:.08,roomNameLineHeight:1.25,roomAreaLinkWidth:1.1,roomMetricsTopGap:.15,roomMetricFontSize:.75,roomMetricLineHeight:1.25,roomMetricIconWidth:1.05,roomMetricInnerGap:.12,roomMetricRowGap:.55,roomMetricMinWidth:11,roomPadding:.4,openingLockHalfSize:.62,roomMetricTextCharacters:Object.freeze({temperature:10,humidity:8,lqi:6,light:24})});function Ze(e){return[...String(e)].reduce((e,t)=>/\s/.test(t)?e+Ke.textSpaceAdvance:/[MW@#%&]/.test(t)?e+Ke.textWideAsciiAdvance:e+(t.codePointAt(0)>255?Ke.textWideAdvance:Ke.textLatinAdvance),0)*Ke.textWidthSafety}function Je(e,t){return Ze(e)*P(t||e)}function Qe(e,t){return[Math.max(Math.abs(e.left),Math.abs(e.right))+t,Math.max(Math.abs(e.top),Math.abs(e.bottom))+t]}function Xe(e){if("opening-lock"===e.kind){const t=(Number.isFinite(e.size)&&e.size>0?e.size:0)*Ke.openingLockHalfSize;return[t,t]}if("room-label"===e.kind){const t=Number.isFinite(e.font)&&e.font>0?e.font:0,n=b(e.room.settings?.name_scale),o=b(e.room.settings?.label_scale),i=(Ze(e.room.name||"")+(e.room.area?Ke.roomAreaLinkWidth:0))*n,a=Ke.roomNameLineHeight*n,r=[e.display.labelTemp?Ke.roomMetricTextCharacters.temperature:0,e.display.labelHum?Ke.roomMetricTextCharacters.humidity:0,e.display.labelLqi&&e.room.area?Ke.roomMetricTextCharacters.lqi:0,e.display.labelLight?Ke.roomMetricTextCharacters.light:0].filter(e=>e>0),s=Ke.roomMetricFontSize*o,l=r.length?Math.max(Ke.roomMetricMinWidth,r.reduce((e,t)=>e+Ke.roomMetricIconWidth+Ke.roomMetricInnerGap+t*Ke.textLatinAdvance*Ke.textWidthSafety,0)+(r.length-1)*Ke.roomMetricRowGap)*s:0,c=r.length?s*Ke.roomMetricLineHeight:0,f=Qe({left:-Math.max(i,l)/2,right:Math.max(i,l)/2,top:-a/2,bottom:r.length?a/2+Ke.roomMetricsTopGap+c:a/2},Ke.roomPadding);return[f[0]*t,f[1]*t]}const t=Number.isFinite(e.core)&&e.core>0?e.core:0,n=e.presentation,o=null==n.valueText?1:Math.max(1,Je(n.valueText,n.valueFullText||n.valueText)+Ke.deviceValueInlinePadding),i=[];n.valueBadge&&i.push(Math.max(Ke.deviceBadgeMinWidth,Je(n.valueBadge.text,n.valueBadge.fullText||n.valueBadge.text)+Ke.deviceBadgeInlinePadding));for(const e of S(n)){const t=e.text+e.suffix;i.push(Math.max(Ke.deviceBadgeMinWidth,Je(t,t)+Ke.deviceBadgeInlinePadding))}const a=n.valueBadge?.position||"right";let r;if(!i.length||"left"!==a&&"right"!==a)if(i.length){const e=i.reduce((e,t)=>e+t,0)+(i.length-1)*Ke.deviceSectionGap,t=Math.max(o,e),n=1+Ke.deviceShellGap+Ke.deviceBadgeHeight;r="bottom"===a?{left:-t/2-Ke.deviceShellInset,right:t/2+Ke.deviceShellInset,top:-.5-Ke.deviceShellInset,bottom:-.5+n+Ke.deviceShellInset}:{left:-t/2-Ke.deviceShellInset,right:t/2+Ke.deviceShellInset,top:.5-n-Ke.deviceShellInset,bottom:.5+Ke.deviceShellInset}}else r={left:-.5-Ke.deviceShellInset,right:-.5+o+Ke.deviceShellInset,top:-.5-Ke.deviceShellInset,bottom:.5+Ke.deviceShellInset};else{const e=Math.max(...i),t=i.length*Ke.deviceBadgeHeight+(i.length-1)*Ke.deviceSectionGap,n=o+Ke.deviceShellGap+e,s=Math.max(1,t);r="right"===a?{left:-.5-Ke.deviceShellInset,right:-.5+n+Ke.deviceShellInset,top:-s/2-Ke.deviceShellInset,bottom:s/2+Ke.deviceShellInset}:{left:.5-n-Ke.deviceShellInset,right:.5+Ke.deviceShellInset,top:-s/2-Ke.deviceShellInset,bottom:s/2+Ke.deviceShellInset}}const s=Ke.deviceAuxiliaryExtent;if(r.left=Math.min(r.left,-s),r.right=Math.max(r.right,s),r.top=Math.min(r.top,-s),r.bottom=Math.max(r.bottom,s),n.pulse.animated){const e=Math.max(1,n.pulse.diameterScale)/2;r.left=Math.min(r.left,-e),r.right=Math.max(r.right,e),r.top=Math.min(r.top,-e),r.bottom=Math.max(r.bottom,e)}if(null!=n.lqiText){const e="bottom"===n.valueBadge?.position?Ke.deviceLqiBelowBottomBadgeTop:Ke.deviceLqiTop,t=Ze(n.lqiText)*Ke.deviceLqiFontSize/2;r.left=Math.min(r.left,-t),r.right=Math.max(r.right,t),r.bottom=Math.max(r.bottom,e+Ke.deviceLqiFontSize)}const l=Qe(r,Ke.devicePadding);return[l[0]*t,l[1]*t]}function Ye(e,t){return e.flatMap((e,n)=>e.orphanReason?[]:[{id:String(e.id||n),sourceIndex:n,type:e.type,x:e.rx,y:e.ry,angle:Number(e.angle)||0,length:e.rlen>0?e.rlen:.9*t,flipH:!!e.flip_h,flipV:!!e.flip_v}])}function et(e){return{id:e.id,x:e.x,y:e.y,w:e.w,h:e.h,poly:e.poly,wall_ids:e.wall_ids}}function tt(e,t){const n=e?.partitionHost;if(!n)return null;const o="gate"===t.type?!t.flipV:t.flipV;return{sourceIndex:t.sourceIndex,hostId:n.host.id,t:n.t,depth:n.depth,face:m(n,o)}}function nt(n,o=A){const i=Ye(n.openings,n.coordinateScale),a=i.map(e=>tt(n.openings[e.sourceIndex],e)),s=r(t,n.cellCm),m=r(l,n.cellCm),g=r(c,n.cellCm);return{key:`${n.space.id}|${function(e){let t=2166136261;const n=e=>{if("number"!=typeof e)if("string"!=typeof e)if("boolean"!=typeof e)if(Array.isArray(e)){t=B(t,e.length);for(const t of e)n(t)}else{if(e&&"object"==typeof e){const t=e;for(const e of Object.keys(t).sort())n(e),n(t[e]);return}t=B(t,-1)}else t=B(t,e?1:0);else for(const n of e)t=B(t,n.codePointAt(0)||0);else t=B(t,e)};return n(e),t.toString(36)}({rooms:n.space.rooms.map(et),walls:n.walls,openCuts:n.openCuts,openings:i,openingHosts:a,openingGeometryPolicy:o,partitions:n.space.partitions,columns:n.space.wall_columns,cellCm:n.cellCm,gridPitch:n.gridPitch,wallKeyPitch:n.wallKeyPitch,camera:e,wallHeight:s,raisedHeight:g,floorEdgeHeight:m,algorithm:5})}`,build:()=>{n.onBuild();const r=f(n.space,n.cellCm,n.gridPitch,2e-4*n.gridPitch,n.partitionCuts()).all,l=n.roomOpenings(),c=n.walls.length||r.length?d(n.space.rooms,n.walls,n.openCuts,l,n.wallKeyPitch,n.cellCm,n.gridPitch,n.coordinateScale,r):null;if(c&&("failed-core"===c.status||"not-applicable"===c.status))throw new Error("wall boolean geometry failed");const m=c?.paperGeom??u(n.space.rooms,n.walls,n.openCuts,n.wallKeyPitch,n.cellCm,n.gridPitch,n.coordinateScale);if(!m)throw new Error("floor boolean geometry failed");const g=c?.openingIndex||h(n.space.rooms,n.walls,n.openCuts,n.wallKeyPitch,n.cellCm,n.gridPitch,n.coordinateScale),w=i.map((e,i)=>{const r=a[i],l="gate"===e.type?!e.flipV:e.flipV,c=r?r.face:n.walls.length||"gate"===e.type?p(g,{x:e.x,y:e.y,angle:e.angle,length:e.length,flip_v:l}):{ox:0,oy:0,cm:0,side:-1};return function(e,n=t,o=A){const i=e.face.cm??0;if(!R([e.x,e.y,e.angle,e.length,e.face.ox,e.face.oy,i,n])||!(e.length>0)||!(n>0)||-1!==e.face.side&&1!==e.face.side||i<0)throw new Error("invalid isometric opening input");const a=e.length/2,r=e.angle*Math.PI/180,s=F(Math.cos(r),Math.sin(r)),l=F(-Math.sin(r),Math.cos(r)),c=F(e.x,e.y),f=F(e.x-s[0]*a,e.y-s[1]*a),d=F(e.x+s[0]*a,e.y+s[1]*a),u=F(e.face.ox,e.face.oy),h=F(f[0]+u[0],f[1]+u[1]),p=F(d[0]+u[0],d[1]+u[1]),m=F(f[0]-u[0],f[1]-u[1]),g=F(d[0]-u[0],d[1]-u[1]),w=Object.freeze({center:c,tangent:s,normal:l,start:f,end:d}),M=Object.freeze({side:e.face.side,cm:i,depth:2*Math.hypot(e.face.ox,e.face.oy),offset:u,selectedStart:h,selectedEnd:p,oppositeStart:m,oppositeEnd:g}),y="passage"===e.type?[]:[Object.freeze({jamb:0,center:f,selected:h,opposite:m}),Object.freeze({jamb:1,center:d,selected:p,opposite:g})];let b;if("passage"===e.type)b=[];else if("gate"===e.type){const t=e.face.side*o.gateTurnDeg;b=[W(e,0,[-a,0],[a,0],t,0,n*o.gateTopRatio),W(e,1,[a,0],[-a,0],-t,0,n*o.gateTopRatio)]}else b="window"===e.type?[W(e,0,[-a,0],[a,0],-o.windowTurnDeg,n*o.windowSashBottomRatio,n*o.windowSashTopRatio),W(e,1,[a,0],[-a,0],o.windowTurnDeg,n*o.windowSashBottomRatio,n*o.windowSashTopRatio)]:[W(e,0,[-a,0],[e.length,0],-o.doorTurnDeg,0,n*o.doorTopRatio)];const S="window"===e.type?Object.freeze({frameBottom:n*o.windowFrameBottomRatio,frameTop:n*o.windowFrameTopRatio,sashBottom:n*o.windowSashBottomRatio,sashTop:n*o.windowSashTopRatio,glassBottom:n*o.windowGlassBottomRatio,glassTop:n*o.windowGlassTopRatio,member:n*o.frameThicknessRatio}):null;return Object.freeze({id:e.id,sourceIndex:e.sourceIndex,type:e.type,wallHeight:n,leafThickness:n*o.leafThicknessRatio,frameThickness:n*o.frameThicknessRatio,windowProfile:S,axis:w,face:M,reveals:Object.freeze(y),leaves:Object.freeze(b.map(e=>Object.freeze({...e,hinge:F(e.hinge[0],e.hinge[1]),closedVector:F(e.closedVector[0],e.closedVector[1]),quarterVector:F(e.quarterVector[0],e.quarterVector[1])})))})}({...e,face:c},s,o)}),M=Object.freeze(w);return{walls:c?.components.flatMap(e=>e.geom)||[],floor:m,openings:M,openingSurfaces:Object.freeze(M.flatMap(t=>function(t,n=e){if("passage"===t.type)return Object.freeze([]);const o=[];if(t.face.depth>1e-9)for(const e of t.reveals)o.push(_("jamb-reveal","reveal",e.selected,e.opposite,0,t.wallHeight,n,{jamb:e.jamb}));if("window"!==t.type||!t.leaves.length)return Object.freeze(o.sort((e,t)=>e.depth-t.depth||e.kind.localeCompare(t.kind)||(e.jamb??0)-(t.jamb??0)));const i=t.windowProfile;if(!i)throw new Error("missing isometric window profile");const a=i.frameBottom,r=i.frameTop,s=Math.min(t.frameThickness,Math.hypot(t.axis.end[0]-t.axis.start[0],t.axis.end[1]-t.axis.start[1])/4,(r-a)/4),l=V(t.axis.start,D(t.axis.tangent,s)),c=L(t.axis.end,D(t.axis.tangent,s)),f=t.face.depth>1e-9?[t.face.offset,F(-t.face.offset[0],-t.face.offset[1])]:[t.face.offset];for(const e of f){const i=V(t.axis.start,e),f=V(t.axis.end,e),d=V(l,e),u=V(c,e);o.push(_("window-frame-side","light-frame",i,d,a,r,n,{jamb:0}),_("window-frame-side","light-frame",u,f,a,r,n,{jamb:1}),_("window-frame-top","light-frame",d,u,Math.max(a,r-s),r,n))}return t.face.depth>1e-9&&o.push(q("window-sill","light-sill",[{point:t.face.selectedStart,z:a},{point:t.face.selectedEnd,z:a},{point:t.face.oppositeEnd,z:a},{point:t.face.oppositeStart,z:a}],n)),Object.freeze(o.sort((e,t)=>e.depth-t.depth||e.kind.localeCompare(t.kind)||(e.jamb??0)-(t.jamb??0)))}(t).map(e=>Object.freeze({...e,id:t.id,sourceIndex:t.sourceIndex,type:t.type}))))}}}}const ot=e=>Array.isArray(e)?e:[];function it(e,t){const o=e=>ot(e).flatMap(e=>Array.isArray(e)&&Number.isFinite(e[0])&&Number.isFinite(e[1])?[n([Number(e[0]),Number(e[1])],t)]:[]);return ot(e).flatMap(e=>{const t=ot(e);if(!t.length)return[];const n=o(t[0]);if(n.length<3)return[];return[{outer:n,holes:t.slice(1).map(o).filter(e=>e.length>=3)}]})}function at(o){const i=r(t,o.cellCm),a=r(l,o.cellCm),s=r(c,o.cellCm),f=$(o.cache,o.source.key);let d=f.hit?f.value:void 0;if(!d){const r=o.source.build(),s=function(o,i=e,a=t){if(!Number.isFinite(a)||a<0)throw new Error("invalid wall height");const r=[],s=[],l=[],c=[];let f=0;for(let e=0;e<(o||[]).length;e++){const t=o[e],d=[];let u=-1/0;for(let o=0;o<(t||[]).length;o++){const s=H(t[o],o>0);if(s.length<3||Math.abs(T(s))<1e-9)continue;const h=j(s,i,a);r.push(h),d.push(h),u=Math.max(u,...s.map(e=>n(e,a,i)[1])),f+=s.length;for(let t=0;te.depth-t.depth||e.polygon-t.polygon||e.ring-t.ring||e.edge-t.edge),s.sort((e,t)=>e.depth-t.depth||e.component-t.component),{topPath:r.join(" "),topFaces:s,sides:l,contactPath:c.join(" "),edgeCount:f}}(r.walls,e,i),l=it(r.walls,i);d={geometry:s,floor:N(r.floor,a),wallSilhouettes:Object.freeze([...l,...s.sides.map(e=>({outer:e.points}))]),openings:r.openings,openingSurfaces:r.openingSurfaces},k(o.cache,o.source.key,d,8)}const u=function(e){let t=1/0,n=1/0,o=-1/0,i=-1/0;const a=(e,a=0)=>{t=Math.min(t,e[0]-a),n=Math.min(n,e[1]-a),o=Math.max(o,e[0]+a),i=Math.max(i,e[1]+a)};for(const t of e)if("passage"!==t.type){a(t.axis.start),a(t.axis.end),a(t.face.selectedStart),a(t.face.selectedEnd),a(t.face.oppositeStart),a(t.face.oppositeEnd);for(const e of t.leaves){const n=Math.hypot(e.closedVector[0],e.closedVector[1])+t.leafThickness/2;a(e.hinge,n)}}return R([t,n,o,i])?{x:t,y:n,w:o-t,h:i-n}:null}(d.openings),h=u?rt(o.liveFrame,u):o.liveFrame,p=z({rect:h,wallHeight:i,openingHeight:i,floorDepth:a,raisedHeight:s});return{key:o.source.key,...d,frame:p}}const rt=(e,t)=>{const n=Math.min(e.x,t.x),o=Math.min(e.y,t.y);return{x:n,y:o,w:Math.max(e.x+e.w,t.x+t.w)-n,h:Math.max(e.y+e.h,t.y+t.h)-o}},st=e=>{if(!e.length||!e.every(e=>Number.isFinite(e[0])&&Number.isFinite(e[1])))return null;const t=e.map(e=>e[0]),n=e.map(e=>e[1]),o=Math.min(...t),i=Math.min(...n);return{x:o,y:i,w:Math.max(...t)-o,h:Math.max(...n)-i}},lt=(e,t)=>{const n=e.placement,o=t?n.visualScene:n.raisedScene,[i,a]=e.screenHalfSize,r=t?n.footprint:n.footprint.map(e=>[e[0]-n.nudgeScene[0],e[1]-n.nudgeScene[1]]);return[n.floorScene,...r,[o[0]-i,o[1]-a],[o[0]+i,o[1]-a],[o[0]+i,o[1]+a],[o[0]-i,o[1]+a]]},ct=(e,t)=>void 0===t?e:e.filter(e=>e.placement.owner?.id===t);function ft(e,t){return e?st(ct(e.entries,t).flatMap(e=>lt(e,!0))):null}function dt(e){const t=ct(e.entries,e.ownerId),n=st(t.flatMap(e=>lt(e,!1))),o=n?rt(e.baseBounds,n):e.baseBounds,i=e.targetView(o);if(!(i&&i.w>0&&i.h>0&&[i.x,i.y,i.w,i.h].every(Number.isFinite)))return null;const a=e.stageSize;if(!(n&&a&&a.width>0&&a.height>0))return{bounds:o,view:i};const r=e=>Math.max(e.w/a.width,e.h/a.height),s=t=>{const o=48*t,i={x:n.x-o,y:n.y-o,w:n.w+2*o,h:n.h+2*o},a=rt(e.baseBounds,i),r=e.targetView(a);return r&&[r.x,r.y,r.w,r.h].every(Number.isFinite)&&r.w>0&&r.h>0?{bounds:a,view:r}:null};let l=0,c=Math.max(r(i),Number.EPSILON),f=s(c);for(let e=0;f&&r(f.view)>c*(1+1e-10)&&e<24;e++)l=c,c*=2,f=s(c);if(!f)return null;for(let e=0;e<40;e++){const e=(l+c)/2,t=s(e);if(!t)return null;r(t.view)<=e?(c=e,f=t):l=e}return f}const ut=new WeakMap,ht=2048,pt=new WeakMap,mt=new WeakMap,gt=new WeakMap;function wt(e,t){if(e.size!==t.size)return!1;for(const[n,o]of t)if(e.get(n)!==o)return!1;return!0}function Mt(e){const t=ut.get(e.rooms);if(t)return t;const n=e.rooms.flatMap((e,t)=>{const n=M(e);return n&&n.length>=3?[{room:e,index:t,poly:n}]:[]}),o=Object.freeze(n.map(({room:e,index:t,poly:o})=>{const i=y(o,n.filter(e=>e.index!==t).map(e=>e.poly)),a={id:e.id||`room-index-${t}`,outer:o.map(e=>[e[0],e[1]]),holes:i.map(e=>e.map(e=>[e[0],e[1]]))};return{room:e,overlayRoom:{...a,safePoint:re(a)||void 0}}}));return ut.set(e.rooms,o),o}function yt(o){const a=o.stageSize&&o.stageSize.width>0&&o.stageSize.height>0?Math.max(o.view.w/o.stageSize.width,o.view.h/o.stageSize.height):Math.max(o.view.w,o.view.h)/1e3,l=Mt(o.space),c=l.map(e=>e.overlayRoom),f=r(t,o.cellCm),d=r(i,o.cellCm),u=new Map,h=new Map,p=new Map,m=[];let g=pt.get(o.wallSilhouettes);g||(g=new Map,pt.set(o.wallSilhouettes,g));let w=mt.get(l);w||(w=new Map,mt.set(l,w));const M=o.iconPct*s(o.space)*o.kioskIconScale/100,y=o.deviceBasePct*s(o.space)*o.kioskIconScale/100,b=(r,s,l,u,h)=>{const p=`${!1===o.resolveCollisions?"fit":"live"}\0${r}\0${s}`,m=[l[0],l[1],u[0],u[1],h||"",f,d].join("|"),M=`${m}|${a}`,y=$(g,p);if(y.hit&&y.value.signature===M)return y.value.placement;if(y.hit&&y.value.shapeSignature===m&&a<=y.value.unitsPerPixel){const e=y.value.placement,t=e.nudgeDistanceCss*y.value.unitsPerPixel/a;if(!e.nearWallBefore||e.cleared&&t<=48)return e}const b=`${r}\0${s}`,S=[l[0],l[1],h||""].join("|"),x=$(w,b),v=x.hit&&x.value.signature===S?x.value.owner:se({kind:r,floorAnchor:l,rooms:c,roomsValidated:!0,preferredRoomId:h});x.hit&&x.value.signature===S||k(w,b,{signature:S,owner:v},ht);const z=function(o){const a=o.camera||e,r=o.wallHeight??t,s=o.visualOffset??i,l=o.sceneUnitsPerCssPixel??1,c=o.safetyGapCssPx??4,f=o.maxNudgeCssPx??48;if(!J(o.floorAnchor)||!J(o.footprintHalfSize)||o.footprintHalfSize[0]<0||o.footprintHalfSize[1]<0||!Number.isFinite(r)||r<0||!Number.isFinite(s)||s<0||!Number.isFinite(l)||l<=0||!Number.isFinite(c)||c<0||!Number.isFinite(f)||f<0)throw new Error("invalid isometric overlay input");const d=[o.floorAnchor[0],o.floorAnchor[1]],u=n(d,0,a),h=(p=o.kind,!o.showBorders||"device"!==p&&"room-label"!==p&&"opening-lock"!==p?"floor":"raised");var p;if("floor"===h)return{plane:h,owner:null,floorAnchor:d,floorScene:u,raisedScene:u,visualScene:u,footprint:[],nudgeScene:[0,0],nudgeCss:[0,0],nudgeDistanceCss:0,nudged:!1,nearWallBefore:!1,nearWallAfter:!1,cleared:!0,capped:!1,grounding:{center:u,visible:!1},tether:Se(u,u,!1),status:"ok",reason:null};const m=s,g=n(d,m,a),w=o.ownerAlreadyResolved?o.resolvedOwner??null:se(o),M=o.wallGeometryValidated??o.wallSilhouettes.every(Me),y=c*l,b=le(d,o.footprintHalfSize,m,a),S=e=>{const t=he(e);return!!t&&o.wallSilhouettes.some(n=>we(e,t,n,y,!0===o.wallGeometryValidated))},x=!M||S(b);let v=0,$=[0,0],k=null,z=!1,P=M?"ok":"degraded",C=M?null:"invalid-wall-geometry";if(M&&x)if(w)if(w.safePoint){const e=o.rooms.find(e=>e.id===w.id)||null,t=n(w.safePoint,m,a),i=t[0]-g[0],r=t[1]-g[1],s=Math.hypot(i,r);if(s<=K)P="degraded",C="invalid-safe-point";else{const t=i/s,n=r/s,a=Math.min(f,s/l),c=a*l/s,u=[d[0]+(w.safePoint[0]-d[0])*c,d[1]+(w.safePoint[1]-d[1])*c],h=[t*a*l,n*a*l],p=he([...b,...b.map(e=>[e[0]+h[0],e[1]+h[1]])]),m=p?o.wallSilhouettes.filter(e=>{const t=pe(e,!0===o.wallGeometryValidated);return!!t&&me(p,t,y)}):o.wallSilhouettes,g=!!e&&ye(d,u,e),M=e=>{const i=[t*e*l,n*e*l],a=b.map(e=>[e[0]+i[0],e[1]+i[1]]),r=he(a);return!!r&&m.some(e=>we(a,r,e,y,!0===o.wallGeometryValidated))},S=o.nudgeHintCss;if(Number.isFinite(S)&&S>=0&&S<=a){const t=S*l/s,n=[d[0]+(w.safePoint[0]-d[0])*t,d[1]+(w.safePoint[1]-d[1])*t];(g||e&&ye(d,n,e))&&!M(S)&&(v=S,k=!1)}if(null===k){let t=null,n=0,o=!1;const i=Math.ceil(a);for(let r=1;r<=i;r++){const i=Math.min(a,r),c=i*l/s,f=[d[0]+(w.safePoint[0]-d[0])*c,d[1]+(w.safePoint[1]-d[1])*c];if(!(g||e&&ye(d,f,e))){o=!0;break}if(!M(i)){t=i;break}n=i}if(null!==t){let e=n,o=t;for(let t=0;t<14;t++){const t=(e+o)/2;M(t)?e=t:o=t}v=o}else v=n,z=!0,P="degraded",C=o?"owner-boundary":"nudge-cap"}$=[t*v*l,n*v*l]}}else P="degraded",C="invalid-safe-point";else P="degraded",C="missing-owner";const I=[g[0]+$[0],g[1]+$[1]],T=le(d,o.footprintHalfSize,m,a,$),H=!M||(k??S(T)),j=v>K;return{plane:h,owner:w,floorAnchor:d,floorScene:u,raisedScene:g,visualScene:I,footprint:T,nudgeScene:$,nudgeCss:[$[0]/l,$[1]/l],nudgeDistanceCss:v,nudged:j,nearWallBefore:x,nearWallAfter:H,cleared:!H,capped:z,grounding:{center:u,visible:!1},tether:Se(u,I,!1),status:P,reason:C}}({kind:r,floorAnchor:l,rooms:c,roomsValidated:!0,preferredRoomId:h,ownerAlreadyResolved:!0,resolvedOwner:v,nudgeHintCss:y.hit&&y.value.shapeSignature===m?y.value.placement.nudgeDistanceCss*y.value.unitsPerPixel/a:void 0,showBorders:!0,wallSilhouettes:!1===o.resolveCollisions?[]:o.wallSilhouettes,wallGeometryValidated:!0,footprintHalfSize:u,wallHeight:f,visualOffset:d,sceneUnitsPerCssPixel:a});return k(g,p,{signature:M,shapeSignature:m,unitsPerPixel:a,placement:z},ht),z};for(const e of o.devices){const t=o.positionOf(e),n=o.presentationOf(e,o.showLqi),i=y*n.scale,a=Xe({kind:"device",core:i,presentation:n}),r=e.marker?.room_id||l.find(t=>!!e.area&&t.room.area===e.area)?.overlayRoom.id||null,s=b("device",e.id,[t.x,t.y],a,r);u.set(e.id,s),m.push({id:e.id,kind:"device",placement:s,groundRadius:Math.max(.32*i,2),screenHalfSize:a})}for(const{room:e,overlayRoom:t}of l){if(!o.display.showNames||!e.name)continue;const n=o.labelPositionOf(e,o.space.id),i=.5*M*(o.labelScaleOf(e)*o.kioskFontScale*o.display.cardFontScale),a=Xe({kind:"room-label",font:i,room:e,display:o.display}),r=b("room-label",t.id,[n.x,n.y],a,t.id);h.set(e,r),m.push({id:t.id,kind:"room-label",placement:r,groundRadius:Math.max(.75*i,2),screenHalfSize:a})}const S=o.openings.filter(e=>!e.orphanReason&&("door"===e.type||"gate"===e.type)&&"string"==typeof e.lock&&!!e.lock&&o.openingEntityAvailable(e.lock));if(S.length){const e=o.openingWallIndex();for(const t of S){const n=St(t,e,o.cellCm),i=n.floorAnchor,a=.62*M,r=Xe({kind:"opening-lock",size:a}),s=b("opening-lock",String(t.id),i,r,n.preferredRoomId);p.set(String(t.id),s),m.push({id:String(t.id),kind:"opening-lock",placement:s,groundRadius:Math.max(.28*a,2),screenHalfSize:r})}}const x=!1===o.resolveCollisions?"fit":"live";let v=gt.get(o.wallSilhouettes);v||(v=new Map,gt.set(o.wallSilhouettes,v));const z=v.get(x),P=m.map(e=>{const t=e.placement;return[e.kind,e.id,t.floorAnchor[0],t.floorAnchor[1],t.raisedScene[0],t.raisedScene[1],t.nudgeScene[0],t.nudgeScene[1],t.owner?.id||"",t.status,t.reason||"",e.screenHalfSize[0],e.screenHalfSize[1],a].join("|")}).sort().join("");if(z?.collisionSignature===P&&wt(z.rooms,h))return z;const C=new Map(z?.entries.map(e=>[`${e.kind}\0${e.id}`,e])||[]),I="live"===x?We({items:m.flatMap(e=>{if("room-label"===e.kind)return[];const t=C.get(`${e.kind}\0${e.id}`),n=!!t&&t.screenHalfSize[0]===e.screenHalfSize[0]&&t.screenHalfSize[1]===e.screenHalfSize[1]&&t.placement.floorAnchor[0]===e.placement.floorAnchor[0]&&t.placement.floorAnchor[1]===e.placement.floorAnchor[1]&&(t.placement.owner?.id||"")===(e.placement.owner?.id||"");return[{id:e.id,kind:e.kind,placement:e.placement,screenHalfSize:e.screenHalfSize,...n?{nudgeHintCss:[t.placement.nudgeScene[0]/a,t.placement.nudgeScene[1]/a]}:{}}]}),rooms:c,wallSilhouettes:o.wallSilhouettes,sceneUnitsPerCssPixel:a,visualOffset:d}):{placements:new Map,residualPairs:[]},T=Object.freeze(m.map(e=>{if("room-label"===e.kind)return e;const t=I.placements.get(Z(e.kind,e.id))||e.placement;return t===e.placement?e:{...e,placement:t}})),H=new Map,j=new Map;for(const e of T)"device"===e.kind?H.set(e.id,e.placement):"opening-lock"===e.kind&&j.set(e.id,e.placement);const O={devices:H,rooms:h,locks:j,entries:T,collisionSignature:P,residualPairs:Object.freeze([...I.residualPairs])};return z&&function(e,t){return e.length===t.length&&t.every((t,n)=>{const o=e[n];return o.id===t.id&&o.kind===t.kind&&o.placement===t.placement&&o.groundRadius===t.groundRadius&&o.screenHalfSize[0]===t.screenHalfSize[0]&&o.screenHalfSize[1]===t.screenHalfSize[1]})}(z.entries,O.entries)&&wt(z.devices,O.devices)&&wt(z.rooms,O.rooms)&&wt(z.locks,O.locks)?z:(v.set(x,O),O)}function bt(e,t,n){return St(e,t,n).floorAnchor}function St(e,t,n){const o=!e.flip_v,i="gate"===e.type?e.partitionHost?m(e.partitionHost,o):p(t,{x:e.rx,y:e.ry,angle:e.angle,length:e.rlen,flip_v:o}):null,[a,r]=g({x:e.rx,y:e.ry,angle:e.angle,flipV:!!e.flip_v,gateFace:i},n);if(e.partitionHost)return{floorAnchor:a,preferredRoomId:null};const s=w(t,{x:e.rx,y:e.ry,angle:e.angle,length:e.rlen},!0),l=r?"negative":"positive";return{floorAnchor:a,preferredRoomId:s[l]?.roomId||null}}function xt(e){let t=!1;try{t="undefined"!=typeof CSS&&"function"==typeof CSS.supports&&CSS.supports("filter","blur(1px)")}catch{t=!1}let n=!1;try{n="function"==typeof matchMedia&&matchMedia("(forced-colors: active)").matches}catch{n=!0}return function(e){const t=!!e.showBorders;return{structural:t,panels:t&&!e.hideOpenings,shadows:t&&e.filtersSupported&&!e.forcedColors,materialNuance:t&&e.filtersSupported&&!e.forcedColors,floorSymbols:!e.hideOpenings&&!t}}({showBorders:e.showBorders,hideOpenings:e.hideOpenings,filtersSupported:t,forcedColors:n})}function vt(e,t,n,o){if(!e.panels||!t)return[];return t.openings.flatMap(e=>{const t=n[e.sourceIndex];return t?U(e,o(t)):[]}).sort((e,t)=>e.depth-t.depth||e.sourceIndex-t.sourceIndex||e.leaf-t.leaf)}function $t(e){const t=xt(e.display),n=t.panels?vt(t,e.scene,e.openings,e.amountOf):[],o=e.overlays(t),i=t=>({layers:t,panels:n,overlays:o,underlay:Tt(t,e.scene?.floor,e.cellCm),shadows:Ht(t,n,e.scene?.geometry,e.cellCm),walls:jt(e.projection,t,e.scene,n,e.cellCm),grounds:Ct(o,t,e.cellCm),raised:It()});try{return i(t)}catch(e){if(!t.shadows&&!t.materialNuance)throw e;return i({...t,shadows:!1,materialNuance:!1})}}const kt=()=>v``;function zt(e){return`translate(${r(4,e)} ${r(8,e)})`}function Pt(e,t,n){const o=C(n);return v`
+globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="44c8db0207714f5476f58cdacdfaae63754967422e492b7fadf3551ecaee4380";import{dH as e,dI as t,br as n,dJ as o,dK as i,dL as a,ax as r,dM as s,dN as l,dO as c,dP as f,aW as d,dQ as u,U as h,ci as p,ch as m,dR as g,V as w,J as M,dS as y,d7 as b,dT as S,A as x,as as v,dU as $,dV as k,dW as z,dX as P,dY as C}from"./houseplan-card-BQWwo3i7.js";const I=e=>`${Number(e[0].toFixed(4))} ${Number(e[1].toFixed(4))}`;function T(e){let t=0;for(let n=0;nArray.isArray(e)&&Number.isFinite(e[0])&&Number.isFinite(e[1])).map(e=>[Number(e[0]),Number(e[1])]),n=t[t.length-1];return t.length>1&&t[0][0]===n[0]&&t[0][1]===n[1]&&t.pop(),t}(e);if(n.length<3)return[];const o=!t;return T(n)>0===o?n:[...n].reverse()}function j(e,t,o){return e.length?`M ${e.map(e=>I(n(e,o,t))).join(" L ")} Z`:""}function O(e,t,n){const o=t[1]-e[1],i=-(t[0]-e[0]),a=n.rotDeg*Math.PI/180;return o*Math.sin(a)+i*Math.cos(a)}function N(t,o,i=e){if(!Number.isFinite(o)||o<0)throw new Error("invalid floor edge height");const a=(t||[]).map(e=>(e||[]).map((e,t)=>function(e,t){const n=H(e,t);if(!n.length)return n;let o=0;for(let e=1;e0)).filter(e=>e.length>=3&&Math.abs(T(e))>=1e-9)).filter(e=>e.length&&T(e[0])>0);a.sort((e,t)=>{const n=e[0][0],o=t[0][0];return n[0]-o[0]||n[1]-o[1]||Math.abs(T(t[0]))-Math.abs(T(e[0]))});const r=[],s=[];let l=0;for(let e=0;ee.depth-t.depth||e.component-t.component||e.edge-t.edge),{footprintPath:r.join(" "),sides:s,componentCount:a.length,edgeCount:l}}function B(e,t){return e^=Math.round(64*(Number.isFinite(t)?t:0)),Math.imul(e,16777619)>>>0}const A=Object.freeze({revision:3,leafThicknessRatio:.04,frameThicknessRatio:.05,doorTurnDeg:50,windowTurnDeg:65,gateTurnDeg:10,gateTopRatio:.88,windowFrameBottomRatio:.38,windowFrameTopRatio:1,windowSashBottomRatio:.4,windowSashTopRatio:.98,windowGlassBottomRatio:.45,windowGlassTopRatio:.93,doorTopRatio:.92});A.leafThicknessRatio,A.frameThicknessRatio;const R=e=>e.every(Number.isFinite);function F(e,t){return Object.freeze([Object.is(e,-0)?0:e,Object.is(t,-0)?0:t])}function V(e,t){return[e[0]+t[0],e[1]+t[1]]}function L(e,t){return[e[0]-t[0],e[1]-t[1]]}function D(e,t){return[e[0]*t,e[1]*t]}function G(e,t,n,o){const i=e[0]*n,a=e[1]*o,r=t*Math.PI/180;return[i*Math.cos(r)-a*Math.sin(r),i*Math.sin(r)+a*Math.cos(r)]}function W(e,t,n,i,a,r,s){const l=e.flipH?-1:1,c="gate"===e.type?1:e.flipV?-1:1,f="door"===e.type||"gate"===e.type?e.face:o(e.type,e.flipV,e.angle,e.face);return{leaf:t,hinge:V([e.x+f.ox,e.y+f.oy],G(n,e.angle,l,c)),closedVector:G(i,e.angle,l,c),quarterVector:G([-i[1],i[0]],e.angle,l,c),turnDeg:a,bottom:r,top:s}}const E=e=>`${Number(e[0].toFixed(4))} ${Number(e[1].toFixed(4))}`;function q(e,t,o,i,a={}){const r=o.map(e=>n(e.point,e.z,i)),s=i.rotDeg*Math.PI/180,l=i.tiltDeg*Math.PI/180,c=o.reduce((e,t)=>e+(t.point[0]*Math.sin(s)+t.point[1]*Math.cos(s))*Math.sin(l)+t.z*Math.cos(l),0)/o.length;return Object.freeze({kind:e,material:t,d:`M ${r.map(E).join(" L ")} Z`,cameraDepth:c,depth:Math.max(...r.map(e=>e[1])),...a})}function _(e,t,n,o,i,a,r,s={}){return q(e,t,[{point:n,z:i},{point:o,z:i},{point:o,z:a},{point:n,z:a}],r,s)}function U(t,o,i=e){const a=Math.max(0,Math.min(1,Number.isFinite(o)?o:0));return t.leaves.map(e=>{const o=function(e,t){const n=e.turnDeg*t*Math.PI/180;return[e.hinge[0]+e.closedVector[0]*Math.cos(n)+e.quarterVector[0]*Math.sin(n),e.hinge[1]+e.closedVector[1]*Math.cos(n)+e.quarterVector[1]*Math.sin(n)]}(e,a),r=n(e.hinge,e.bottom,i),s=n(o,e.bottom,i),l=n(o,e.top,i),c=n(e.hinge,e.top,i),f="window"===t.type?"light-window":"matte-leaf",d="window"===t.type?function(e,t,n,o){const i=e.windowProfile;if(!i)throw new Error("missing isometric window profile");const a=L(n,t.hinge),r=Math.hypot(a[0],a[1]);if(!(r>1e-9))return Object.freeze([]);const s=F(a[0]/r,a[1]/r),l=Math.min(i.member,r/4,(i.sashTop-i.sashBottom)/4),c=V(t.hinge,D(s,l)),f=L(n,D(s,l)),d=Math.min(.35*e.frameThickness,.02*r),u=F(-s[1]*d/2,s[0]*d/2),h=V(c,u),p=V(f,u),m=L(c,u),g=L(f,u),w=[_("window-sash-side","light-frame",t.hinge,c,i.sashBottom,i.sashTop,o,{edge:"hinge"}),_("window-sash-side","light-frame",f,n,i.sashBottom,i.sashTop,o,{edge:"tip"}),_("window-sash-bottom","light-frame",t.hinge,n,i.sashBottom,i.sashBottom+l,o),_("window-sash-top","light-frame",t.hinge,n,i.sashTop-l,i.sashTop,o),_("window-glass","glass-side",h,p,i.glassBottom,i.glassTop,o),_("window-glass","glass-side",g,m,i.glassBottom,i.glassTop,o),q("window-glass-top","glass-top",[{point:h,z:i.glassTop},{point:p,z:i.glassTop},{point:g,z:i.glassTop},{point:m,z:i.glassTop}],o)];return Object.freeze(w.sort((e,t)=>e.depth-t.depth||e.kind.localeCompare(t.kind)||String(e.edge||"").localeCompare(String(t.edge||""))))}(t,e,o,i):function(e,t,n,o){const i=L(t,e.hinge),a=Math.hypot(i[0],i[1]);if(!(a>1e-9&&n>0))return Object.freeze([]);const r=F(-i[1]*n/(2*a),i[0]*n/(2*a)),s=V(e.hinge,r),l=V(t,r),c=L(e.hinge,r),f=L(t,r),d=[_("leaf-back","matte-leaf",f,c,e.bottom,e.top,o),_("leaf-front","matte-leaf",s,l,e.bottom,e.top,o),_("leaf-edge","matte-leaf",c,s,e.bottom,e.top,o,{edge:"hinge"}),_("leaf-edge","matte-leaf",l,f,e.bottom,e.top,o,{edge:"tip"}),q("leaf-top","matte-leaf",[{point:s,z:e.top},{point:c,z:e.top},{point:f,z:e.top},{point:l,z:e.top}],o)];return Object.freeze(d.sort((e,t)=>e.depth-t.depth||e.kind.localeCompare(t.kind)||String(e.edge||"").localeCompare(String(t.edge||""))))}(e,o,t.leafThickness,i);return Object.freeze({id:t.id,sourceIndex:t.sourceIndex,type:t.type,leaf:e.leaf,d:`M ${E(r)} L ${E(s)} L ${E(l)} L ${E(c)} Z`,shadowD:`M ${E(n(e.hinge,0,i))} L ${E(n(o,0,i))}`,depth:Math.max(r[1],s[1]),material:f,thickness:"window"===t.type?0:t.leafThickness,surfaces:d})})}const K=1e-9,Z=(e,t)=>`${e}\0${t}`,J=e=>e.length>=2&&Number.isFinite(e[0])&&Number.isFinite(e[1]);function Q(e){let t=0;for(let n=0;n