e)continue;if(Math.abs((h[0]-r[0])*n+(h[1]-r[1])*o)>e)continue;const d=(c[0]-r[0])*i+(c[1]-r[1])*s,p=(h[0]-r[0])*i+(h[1]-r[1])*s;Math.abs(p-d)<=e||l.push(dt[0]-e[0]);const c=[];for(const t of l){const i=c[c.length-1];i&&t[0]<=i[1]+e?i[1]=Math.max(i[1],t[1]):c.push([t[0],t[1]])}for(const[t,e]of c)a.push([[r[0]+i*t,r[1]+s*t],[r[0]+i*e,r[1]+s*e]])}return a}(t))}}const c=this._sunRaysCache.rays,h=this._sunRaysCache.rims;if(!c.length)return e;const d=(p=function(t){const e=Math.min(90,Math.max(-90,Number(t)||0));let i=gr[gr.length-1][1];for(let t=1;t
${c.map((t,e)=>{const i=(t.a[0]+t.b[0])/2,s=(t.a[1]+t.b[1])/2,n=i+t.normal[0]*t.depth,o=s+t.normal[1]*t.depth;return j`
${u.map(([t,e])=>j` `)}
${_.map(([t,e])=>j` `)}
`})}
${c.map((t,e)=>t.paths?.length?t.paths.map(t=>j` `):t.polys.map(t=>j` `))}
${c.map((t,e)=>(h[e]||[]).map(t=>j` `))}
`}_sunFadeReset(){this._sunOutTimer&&(clearTimeout(this._sunOutTimer),this._sunOutTimer=0),this._sunShown=!1,this._sunOut=!1}_compassPoint(t){const e=t.currentTarget.getBoundingClientRect(),i=t.clientX-(e.left+e.width/2),s=t.clientY-(e.top+e.height/2);if(Math.hypot(i,s)<5)return;let n=Math.round(180*Math.atan2(i,-s)/Math.PI);t.shiftKey&&(n=15*Math.round(n/15)),n=(n%360+360)%360,this._settingsDialog={...this._settingsDialog,northDeg:n}}_renderCompass(){const t=this._settingsDialog.northDeg;return W`{t.currentTarget.setPointerCapture(t.pointerId),this._compassDrag=!0,this._compassPoint(t)}}
@pointermove=${t=>{this._compassDrag&&this._compassPoint(t)}}
@pointerup=${()=>this._compassDrag=!1}
@pointercancel=${()=>this._compassDrag=!1}>
${[0,45,90,135,180,225,270,315].map(t=>j` `)}
${this._t("gs.north_letter")}
${null===t?"—":t+"°"}
`}_stageBg(t){const e=this._settingsDialog,i=this._spaceDialog,s=e?e.bgColor||"":hs(this._settings,{bgColor:null});return(i&&"edit"===i.mode&&i.spaceId===this._space?i.bgColor||"":t.bgColor||"")||s}_stageBgHex(){const t=this._stageEl;if(t){const e=getComputedStyle(t).backgroundColor.match(/rgba?\((\d+),\s*(\d+),\s*(\d+)/);if(e)return"#"+e.slice(1,4).map(t=>(+t).toString(16).padStart(2,"0")).join("")}return"#111111"}_preflightDiagnostics(t,e){const i=new Map((e?.spaces||[]).map(t=>[String(t?.id||""),t]));return{kind:"houseplan-optimize-preflight",origin:"runtime",cardVersion:Ff,checkedAt:(new Date).toISOString(),preflightFingerprint:t.fingerprint,failures:t.failures.map(t=>({spaceId:t.spaceId,displayName:t.displayName,reason:t.reason,detail:t.detail??null,spaceGeometryFingerprint:i.has(t.spaceId)?lg(i.get(t.spaceId)):null}))}}_reportPreflightFailure(t,e){t.ok||t.fingerprint===this._reportedPreflightFingerprint||(this._reportedPreflightFingerprint=t.fingerprint,console.warn("[houseplan] optimize preflight failed",this._preflightDiagnostics(t,e)))}_preflightVersionsDiffer(){const t=this._haIntegrationVersion;return"string"==typeof t&&t.length>0&&t!==Ff}async _copyPreflightDiagnostics(){const t=this._alignDialog?.preflight;if(!t||t.ok)return;const e=JSON.stringify(this._preflightDiagnostics(t,this._alignDialog?.config??null),null,2);try{await navigator.clipboard.writeText(e),this._preflightClipboardFallback=null,this._showToast(this._t("gs.preflight_copied"))}catch{this._preflightClipboardFallback=e}}_checkOptimizeGeometry(t){return _g(t,{fallbackSpaceName:t=>this._t("gs.align_preflight_space",{n:String(t)})})}_checkSpacePhysicalGeometry(t,e){return function(t,e,i={}){const s=(Array.isArray(t?.spaces)?t.spaces:[]).find(t=>String(t?.id||"")===String(e||"")),n=lg(s);if(!s)return{spaceId:String(e||""),displayName:"",status:"failed",reason:"prepare-exception",fingerprint:n,ok:!1};const o=_g({...t,spaces:[s]},{...i,fingerprint:()=>n}).spaces[0]||{spaceId:String(e||""),displayName:"",status:"failed",reason:"prepare-exception"};return{...o,fingerprint:n,ok:"failed"!==o.status}}(t,e,{fallbackSpaceName:t=>this._t("gs.align_preflight_space",{n:String(t)})})}_optimizeReferenceContext(t){const e=this._haRegistry,i=this._fullRegistryHass,s={},n=(...t)=>{for(const e of t){const t=String(e||"").trim();if(t)return t}return""};for(const[t,i]of Object.entries(e.devices||{}))s[t]=n(i?.name_by_user,i?.name,i?.model);for(const[t,i]of Object.entries(e.entities||{}))s[`lg_${t}`]=n(this.hass?.states?.[t]?.attributes?.friendly_name,i?.name,i?.original_name);for(const t of this._devices)s[t.id]=n(t.name,s[t.id]);for(const t of this._serverCfg?.markers||[]){const e=String(t.binding||"").indexOf(":"),o=e>0?t.binding.slice(0,e):"",a=e>0?t.binding.slice(e+1):"",r="device"===o?i?.devices?.[a]:"entity"===o?i?.entities?.[a]:null;s[t.id]=n(t.name,"device"===o?r?.name_by_user:null,r?.name,"entity"===o?this.hass?.states?.[a]?.attributes?.friendly_name:null,s[t.id])}return{effectiveAreaByMarker:Object.fromEntries(this._devices.filter(t=>!t.virtual&&!!t.area).map(t=>[t.id,t.area])),ownerRoster:{authoritative:e.authoritative,deviceIds:Object.keys(e.devices||{}),entityIds:[...new Set([...Object.keys(e.entities||{}),...Object.keys(this.hass?.states||{})])],names:s},removeLiveMissingPositions:t}}_previewAlignDialog(t){if(!this._norm||!this._serverCfg)return;const e=this._serverCfg.spaces||[];let i;try{i=og(this._serverCfg,this._layout||{},this._optimizeReferenceContext(t))}catch(t){return void this._showWallModelMigrationBlocked(t)}const s=i.changed?this._checkOptimizeGeometry(i.config):null;s&&this._reportPreflightFailure(s,i.config);const n=Math.ceil(10*i.report.maxShiftCm)/10,o=e.find(t=>null!=t?.id&&String(t.id)===i.report.maxSpace),a=e.length>1&&o?String(o.title||o.id):"";this._preflightClipboardFallback=null,this._alignDialog={report:i.report,config:i.config,layout:i.layout,cm:n,where:a,preflight:s,changed:i.changed,busy:!1,removeLiveMissingPositions:t}}async _runAlignToGrid(){let t=this._alignDialog;if(!t||t.busy||!this._serverCfg||!t.changed||!t.preflight?.ok)return;const e=bd(t.config);if(t.preflight.fingerprint!==e){const e=this._checkOptimizeGeometry(t.config);if(this._reportPreflightFailure(e,t.config),t={...t,preflight:e},this._alignDialog=t,!e.ok)return}this._clearGeometryGesture(),this._alignDialog={...t,busy:!0};try{this._saveConfigDebounced.pending()&&this._saveConfigDebounced.flush(),await this._writeChain;const e=await this.hass.callWS({type:"houseplan/plan/optimize",config:t.config,layout:t.layout,expected_config_rev:this._cfgRev,expected_layout_rev:this._layoutRev});this._serverCfg=t.config,this._layout=t.layout,this._geometryHistory.clear(),this._cfgRev=e?.config_rev??this._cfgRev+1,this._layoutRev=e?.layout_rev??this._layoutRev+1,this._canOptimizeUndo=!!e?.can_undo,this._undoKind=e?.can_undo?"optimize":null,this._dirtyPos.clear(),this._sentPos.clear(),this._cfgEpoch++,this._modelCache=null,this._frame=null,this._regSignature="",this._maybeRebuildDevices(),this._cacheSnapshot(),this._alignDialog=null,this._preflightClipboardFallback=null,this.requestUpdate(),this._showToast(this._t("gs.align_done",{n:String(t.report.moved),m:String(t.report.migrated+t.report.canonicalized+t.report.coordsCanonicalized+t.report.latticeCoordinatesCanonicalized+t.report.wallsMerged+t.report.spansMerged+t.report.partitionsMerged+t.report.partitionsReconciled+t.report.openingsRehosted+t.report.wallsStraightened),r:String(t.report.spaceRefsRemapped+t.report.roomRefsRemapped+t.report.positionsRemapped+t.report.markersDetached+t.report.orphanRoomLabelsRemoved+t.report.orphanDevicePositionsRemoved+t.report.orphanGroupPositionsRemoved)}))}catch(t){if(this._alignDialog&&(this._alignDialog={...this._alignDialog,busy:!1}),"wall_model_client_outdated"===t?.code)return void this._showToast(this._t("toast.wall_model_client_outdated"));"conflict"===t?.code&&await Promise.all([this._reloadConfigOnly(!0),this._reloadLayoutOnly()]),this._showToast(this._t("toast.error",{err:this._errText(t)}))}}async _undoPlanOptimization(){if(!this._canOptimizeUndo||this._optimizeUndoBusy)return;const t=this._undoKind;this._clearGeometryGesture(),this._optimizeUndoBusy=!0,this.requestUpdate();try{await this.hass.callWS({type:"houseplan/plan/optimize_undo",expected_config_rev:this._cfgRev,expected_layout_rev:this._layoutRev});const[e,i]=await Promise.all([this.hass.callWS({type:"houseplan/config/get"}),this.hass.callWS({type:"houseplan/layout/get"})]);this._serverCfg=e?.config||this._serverCfg,this._cfgRev=e?.rev??this._cfgRev,this._layout=i?.layout||this._layout,this._geometryHistory.clear(),this._layoutRev=i?.rev??this._layoutRev,this._canOptimizeUndo=!1,this._undoKind=null,this._cfgEpoch++,this._modelCache=null,this._frame=null,this._regSignature="",this._maybeRebuildDevices(),this._cacheSnapshot(),this.requestUpdate(),this._showToast(this._t("import"===t?"backup.import_undone":"gs.optimize_undone"))}catch(t){this._canOptimizeUndo=!1,this._undoKind=null,this._showToast(this._t("toast.error",{err:this._errText(t)}))}finally{this._optimizeUndoBusy=!1,this.requestUpdate()}}async _runBackupExport(){const t=this._backupExportDialog;if(t&&!t.busy){this._backupExportDialog={...t,busy:!0,error:""};try{const e=await this.hass.callWS({type:"houseplan/export/create",kind:t.kind,space_id:"space"===t.kind?this._space:void 0,..."space"===t.kind&&t.planOnly?{plan_only:!0}:{},card_version:Ff}),i=new Blob([JSON.stringify(e.document,null,2)+"\n"],{type:"application/json;charset=utf-8"}),s=URL.createObjectURL(i),n=document.createElement("a");n.href=s,n.download=e.filename||`houseplan-${t.kind}.json`,n.style.display="none",document.body.append(n),n.click(),n.remove(),window.setTimeout(()=>URL.revokeObjectURL(s),0),this._backupExportDialog=null,this._showToast(this._t("backup.export_done"))}catch(t){this._backupExportDialog&&(this._backupExportDialog={...this._backupExportDialog,busy:!1,error:this._backupErrorText(t)})}}}async _pickBackupImport(t){const e=t.target,i=e.files?.[0];if(e.value="",i){this._settingsDialog=null,this._backupImportDialog={filename:i.name,size:i.size,token:"",preview:null,expectedConfigRev:this._cfgRev,expectedLayoutRev:this._layoutRev,duplicatePolicy:"skip",confirmMissing:!1,busy:!0,error:""};try{this._saveConfigDebounced.pending()&&this._saveConfigDebounced.flush(),await this._writeChain,this._persistLayout.pending()&&this._persistLayout.flush();const t="/api/houseplan/import/preview?duplicate_policy=skip",e={method:"POST",body:i,headers:{"content-type":"application/json"}},s=this.hass?.fetchWithAuth?await this.hass.fetchWithAuth(t,e):await fetch(t,{...e,headers:{...e.headers,...this.hass?.auth?.data?.access_token?{authorization:`Bearer ${this.hass.auth.data.access_token}`}:{}}}),n=await s.json().catch(()=>({}));if(!s.ok||n.error)throw Object.assign(new Error(n.message||n.error||`HTTP ${s.status}`),{code:n.error});this._backupImportDialog&&(this._backupImportDialog={...this._backupImportDialog,token:n.token,preview:n.preview,expectedConfigRev:n.expected_config_rev,expectedLayoutRev:n.expected_layout_rev,busy:!1})}catch(t){this._backupImportDialog&&(this._backupImportDialog={...this._backupImportDialog,busy:!1,error:this._backupErrorText(t)})}}}async _setBackupDuplicatePolicy(t){const e=this._backupImportDialog;if(e&&!e.busy&&e.token&&t!==e.duplicatePolicy){this._backupImportDialog={...e,duplicatePolicy:t,busy:!0,error:""};try{const i=await this.hass.callWS({type:"houseplan/import/revalidate",token:e.token,duplicate_policy:t});this._backupImportDialog&&(this._backupImportDialog={...this._backupImportDialog,preview:{...e.preview,...i.preview},expectedConfigRev:i.expected_config_rev,expectedLayoutRev:i.expected_layout_rev,confirmMissing:!1,busy:!1})}catch(t){this._backupImportDialog&&(this._backupImportDialog={...this._backupImportDialog,duplicatePolicy:e.duplicatePolicy,preview:e.preview,confirmMissing:e.confirmMissing,busy:!1,error:this._backupErrorText(t)})}}}async _applyBackupImport(){const t=this._backupImportDialog;if(!t||t.busy||!t.token||!t.preview)return;if(t.preview.confirmation_required&&!t.confirmMissing)return;this._backupImportDialog={...t,busy:!0,error:""};const e=this._space;try{const i=await this.hass.callWS({type:"houseplan/import/apply",token:t.token,expected_config_rev:t.expectedConfigRev,expected_layout_rev:t.expectedLayoutRev,duplicate_policy:t.duplicatePolicy,confirm_missing_content:t.confirmMissing}),[s,n]=await Promise.all([this.hass.callWS({type:"houseplan/config/get"}),this.hass.callWS({type:"houseplan/layout/get"})]);this._adoptStructuralResponses(s,n),this._geometryHistory.clear(),this._dirtyPos.clear(),this._sentPos.clear(),this._defPos={},this._cfgEpoch++,this._modelCache=null,this._frame=null,this._visibleDeviceSnapshot=null,this._candidateDeviceSnapshot=null,this._stagedDeviceSnapshotToken=-1,this._capturedSnapshotConfigEpoch=-1,this._regSignature="",this._signer.invalidate(this.hass),this._resign(),this._maybeRebuildDevices();const o=this._serverCfg?.spaces||[],a="space"===i.kind&&i.space_id?i.space_id:o.some(t=>t.id===e)?e:o[0]?.id||this._space;this._hasFixedFloor?this._adoptInitialSpace(this._model,!0):this._commitSpace(a),this._backupImportDialog=null,this._cacheSnapshot(),this.requestUpdate();const r="space"===i.kind?t.preview.counts:i.counts;this._showToast(this._t("space"===i.kind?"backup.space_done":"backup.full_done",{spaces:String(r?.spaces||0),rooms:String(r?.rooms||0),markers:String(r?.markers||0),refs:String(i.repaired_target_refs||0)}))}catch(t){if("conflict"===t?.code&&this._backupImportDialog?.token)try{const t=this._backupImportDialog,e=await this.hass.callWS({type:"houseplan/import/revalidate",token:t.token,duplicate_policy:t.duplicatePolicy});return void(this._backupImportDialog={...t,preview:{...t.preview,...e.preview},expectedConfigRev:e.expected_config_rev,expectedLayoutRev:e.expected_layout_rev,confirmMissing:!1,busy:!1,error:this._t("backup.revalidated")})}catch(e){t=e}this._backupImportDialog&&(this._backupImportDialog={...this._backupImportDialog,busy:!1,error:this._backupErrorText(t)})}}_renderBackupExportDialog(){const t=this._backupExportDialog,e=(this._serverCfg?.spaces||[]).find(t=>t.id===this._space);return W`this._backupExportDialog=null}>
this._backupExportDialog=null}>${this._t("btn.cancel")}
${t.busy?"…":this._t("backup.download")}
`}_renderBackupImportDialog(){const t=this._backupImportDialog,e=t.preview,i=e?.counts||{},s=e?.reference_report||{},n=t=>Object.values(t||{}).reduce((t,e)=>t+(Number(e)||0),0),o=[["incoming_remapped",n(s.remapped?.incoming)],["target_repaired",n(s.remapped?.target)],["preserved_unresolved",n(s.preservedUnresolved)],["collisions",n(s.collisions)],["dropped_links",n(s.droppedIncomingLinks)],["bounded_lineages",Number(s.boundedLineages)||0]].filter(([,t])=>t>0);return W`this._backupImportDialog=null}>
${t.filename} ${(t.size/1024).toFixed(1)} KB
${t.busy&&!e?W`
${this._t("backup.reading")}
`:G}
${t.error?W`
${t.error}
`:G}
${e?W`
${this._t("full"===e.kind?"backup.full":"backup.current_space")}
${e.plan_only?W`${this._t("backup.plan_only_preview")} `:G}
${this._t("same"===e.source?"backup.same_source":"backup.foreign_source")}
${this._t("backup.created",{value:e.created_at||"—"})}
${this._t("backup.versions",{card:e.card_version||"—",integration:e.integration_version||"—",model:String(e.model_version??"—")})}
${this._t("backup.count_spaces",{n:"full"===e.kind?`${e.current_counts?.spaces||0} → ${i.spaces||0}`:String(i.spaces||0)})}
${this._t("backup.count_rooms",{n:"full"===e.kind?`${e.current_counts?.rooms||0} → ${i.rooms||0}`:String(i.rooms||0)})}
${this._t("backup.count_walls",{n:"full"===e.kind?`${e.current_counts?.walls||0} → ${i.walls||0}`:String(i.walls||0)})}
${this._t("backup.count_openings",{n:"full"===e.kind?`${e.current_counts?.openings||0} → ${i.openings||0}`:String(i.openings||0)})}
${this._t("backup.count_decor",{n:"full"===e.kind?`${e.current_counts?.decor||0} → ${i.decor||0}`:String(i.decor||0)})}
${this._t("backup.count_markers",{n:"full"===e.kind?`${e.current_counts?.markers||0} → ${i.markers||0}`:String(i.markers||0)})}
${this._t("backup.count_layout",{n:"full"===e.kind?`${e.current_counts?.layout||0} → ${i.layout||0}`:String(i.layout||0)})}
${e.bindings?W`
${this._t("backup.bindings",{device:String(e.bindings.device||0),entity:String(e.bindings.entity||0),virtual:String(e.bindings.virtual||0),legacy:String(e.legacy_positions||0)})}
${this._t("backup.binding_status",{active:String(e.bindings.active||0),disabled:String(e.bindings.disabled||0),missing:String(e.bindings.missing||0)})}
`:G}
${e.missing_areas?.length?W`
${this._t("backup.missing_areas",{areas:e.missing_areas.join(", ")})}
`:G}
${e.dropped_marker_links?W`
${this._t("backup.dropped_marker_links",{n:String(e.dropped_marker_links)})}
`:G}
${e.repaired_target_refs?W`
${this._t("backup.repaired_target_refs",{n:String(e.repaired_target_refs)})}
`:G}
${e.preserved_unresolved_refs?W`
${this._t("backup.preserved_unresolved_refs",{n:String(e.preserved_unresolved_refs)})} ${this._t("backup.preserved_unresolved_hint")}
`:G}
${o.length?W`
${this._t("backup.import_details")}
${o.map(([t,e])=>W`${this._t(`backup.import_detail.${t}`,{n:String(e)})} `)}
${(s.examples||[]).slice(0,8).map(t=>W`
${t.owner} → ${t.reference}
`)}
`:G}
${"full"===e.kind?W`
${this._t("backup.replace_warning")}
${"foreign"===e.source?W`
${this._t("backup.foreign_bookkeeping")}
`:G}`:W`
${this._t("backup.final_name")} ${e.space_title}
${this._t("backup.target_settings")}
${e.duplicates?W`
${this._t("backup.duplicates",{n:String(e.duplicates)})}
this._setBackupDuplicatePolicy("skip")} />${this._t("backup.skip")}
this._setBackupDuplicatePolicy("virtual")} />${this._t("backup.virtual_copy")}
`:G}`}
${e.content?.length?W`
${this._t("backup.content")}
${e.content.map(t=>W`${t.url} · ${this._t("available"===t.state?"backup.content_available":"external"===t.state?"backup.content_external":"backup.content_detach_required")} `)}
`:G}
${e.confirmation_required?W`
this._backupImportDialog={...t,confirmMissing:e.target.checked}} />
${this._t("backup.confirm_detach")}
`:G}
`:G}
this._backupImportDialog=null}>${this._t("btn.cancel")}
${e?W`
${t.busy?"…":this._t("full"===e.kind?"backup.replace":"backup.add")}
`:G}
`}_setFillColor(t,e){const i=this._settingsDialog;this._settingsDialog={...i,colors:{...i.colors,[t]:{...i.colors[t],...e}}}}async _saveSettingsDialog(){const t=this._settingsDialog;if(t&&!t.busy){this._settingsDialog={...t,busy:!0};try{const e=this._serverCfg,i=JSON.stringify(t.colors)===JSON.stringify(ds),s={...e.settings};i?delete s.fill_colors:s.fill_colors=t.colors;const n=this._imperial?30.48*t.glowRadius:100*t.glowRadius;Number.isFinite(n)&&n>0&&300!==Math.round(n)?s.glow_radius_cm=Math.round(n):delete s.glow_radius_cm,t.bgColor?s.bg_color=t.bgColor:delete s.bg_color,null!==t.northDeg&&Number.isInteger(t.northDeg)&&t.northDeg>=0&&t.northDeg<=359?s.north_deg=t.northDeg:delete s.north_deg,s.bg_mode=t.bgMode,t.sunRays?s.sun_rays=!0:delete s.sun_rays,delete s.weather_entity,this._serverCfg={...e,settings:s},await this._saveConfigNow(),this._settingsDialog=null,this.requestUpdate(),this._showToast(this._t("gs.saved"))}catch(t){this._settingsDialog&&(this._settingsDialog={...this._settingsDialog,busy:!1}),this._showToast(this._t("toast.error",{err:this._errText(t)}))}}}_boolInput(t,e,i=!1){const s=t=>e(!!t.target.checked);return customElements.get("ha-switch")?W` `:W` `}_rangeInput(t,e,i,s,n,o=!1,a){const r=t=>{const e=Number(t.target.value);Number.isFinite(e)&&n(e)};return customElements.get("ha-slider")?W` `:W` `}_renderColorRow(t,e){const i=this._settingsDialog.colors[t];return W`
{this._setFillColor(t,{c:e.detail.color,a:e.detail.opacity})}}>
`}get _glowRadiusCm(){const t=Number(this._settings.glow_radius_cm);return Number.isFinite(t)&&t>0?t:300}get _imperial(){return"mi"===this.hass?.config?.unit_system?.length}get _glowRadiusPlaceholder(){const t=this._glowRadiusCm;return this._imperial?String(Math.round(t/30.48*10)/10):String(t/100)}_glowTransition(t,e){let i=this._glowRenderedSources.get(t);if(e){const e=this._glowFadeTimers.get(t);if(null!=e&&(clearTimeout(e),this._glowFadeTimers.delete(t)),null==i){this._suspendGlowFeatherForTransition(),i=++this._glowSourceSeq,this._glowRenderedSources.set(t,i),this._glowEnteringSources.add(t);const e=requestAnimationFrame(()=>{this._glowEnterRafs.get(t)===e&&(this._glowEnterRafs.delete(t),this._glowEnteringSources.delete(t),this.isConnected&&this.requestUpdate())});this._glowEnterRafs.set(t,e)}return{domId:i,entering:this._glowEnteringSources.has(t),leaving:!1}}if(null==i)return null;const s=this._glowEnterRafs.get(t);if(null!=s&&cancelAnimationFrame(s),this._glowEnterRafs.delete(t),this._glowEnteringSources.delete(t),!this._glowFadeTimers.has(t)){this._suspendGlowFeatherForTransition();const e=window.setTimeout(()=>{this._glowFadeTimers.get(t)===e&&(this._glowFadeTimers.delete(t),this._glowRenderedSources.delete(t),this._glowLastAppearance.delete(t),this.isConnected&&this.requestUpdate())},534);this._glowFadeTimers.set(t,e)}return{domId:i,entering:!1,leaving:!0}}_suspendGlowFeatherForTransition(){if(window.matchMedia?.("(prefers-reduced-motion: reduce)").matches)return;this._glowFeatherSuspendUntil=Math.max(this._glowFeatherSuspendUntil,Date.now()+500),clearTimeout(this._glowFeatherResumeTimer);const t=Math.max(0,this._glowFeatherSuspendUntil-Date.now())+17,e=()=>{this._glowFeatherResumeTimer=0,Date.now()=128){const t=this._glowGeometryWarnings.values().next().value;t&&this._glowGeometryWarnings.delete(t)}this._glowGeometryWarnings.add(n),console.warn(`HOUSEPLAN GLOW GEOMETRY FALLBACK: #218, space ${t}, room ${i}, phase ${s}`)}}_lightBarriers(t,e){const i=this._zeroWalls(),s=this._openCuts(),n=[...i.transmissive],o=Math.max(this._cmToUnits(10),.5*this._gridPitch),a=t=>e.some(e=>this._pointInRoom(t,e.r)),r=this._openingsR.filter(t=>{if("door"!==(e=String(t.type))&&"gate"!==e&&"passage"!==e)return!1;var e;const i=t.angle*Math.PI/180,s=-Math.sin(i),n=Math.cos(i);return a([t.rx+s*o,t.ry+n*o])&&a([t.rx-s*o,t.ry-n*o])}),l=this._roomWallOpeningInputs(r,t);for(const t of l){const e=t.angle*Math.PI/180,i=Math.cos(e)*t.length/2,s=Math.sin(e)*t.length/2;n.push([t.x-i,t.y-s,t.x+i,t.y+s])}const c=new Set(r.filter(t=>t.partitionHost).map(t=>t.id)),h=[t.id,this._cfgEpoch,this._cellCm,this._gridPitch,[...c].sort().join(",")].join("|");this._lightPhysicalBodiesCache?.key!==h&&(this._lightPhysicalBodiesCache={key:h,all:eh(t,this._cellCm,this._gridPitch,2e-4*this._gridPitch,this._partitionOpeningCuts(t,t=>c.has(t.id))).all});const d=this._lightPhysicalBodiesCache.all;let p=2166136261;const u=t=>{p^=Math.round(64*(Number.isFinite(t)?t:0)),p=Math.imul(p,16777619)>>>0},_=this._spaceWalls;u(this._cellCm),u(this._gridPitch),u(this._wallKeyPitch);for(const{poly:t}of e){u(t.length);for(const e of t)u(e[0]),u(e[1])}for(const t of n)for(const e of t)u(e);u("solid"===i.style?1:0);for(const t of i.barriers)for(const e of t)u(e);for(const t of d){u(t.length);for(const e of t)u(e[0]),u(e[1])}for(const t of _)u(t.cm),u(t.a?.[0]??0),u(t.a?.[1]??0),u(t.b?.[0]??0),u(t.b?.[1]??0);const m=p.toString(36),g=`${t.id}|${m}`;if(this._lightBarrierCache?.key===g)return this._lightBarrierCache.value;const f=.02*this._gridPitch,v=[],y=_.length||d.length?Rc(t.rooms,_,s,l,this._wallKeyPitch,this._cellCm,this._gridPitch,ev,d):null;if(!y||"ok"!==y.status&&"degraded-extra"!==y.status)for(const t of d)v.push(...zu(t));else for(const t of y.components)for(const e of lh(t.geom))v.push(...zu(e));for(const{poly:t}of e)for(const e of n.length?Ps(t,n,f):zu(t))v.push(e);for(const t of i.barriers)v.push(t);const b={occluders:Au(v),floor:e.map(t=>t.poly),fingerprint:m,masonryGeometry:!y||"ok"!==y.status&&"degraded-extra"!==y.status?[]:y.components.flatMap(t=>t.geom),opaqueBodies:d};return this._lightBarrierCache={key:g,value:b},b}_renderGlowLayer(t,e){const i=this._fillColors,s=this._glowRadiusCm/this._cellCm*this._gridPitch,n=t.rooms.map(t=>({r:t,poly:hi(t)})).filter(t=>!!t.poly),o=n.filter(({r:t})=>Fs(e.glow,t));if(!o.length)return this._forgetGlowSpace(t.id),j``;const{occluders:a,floor:r,fingerprint:l,masonryGeometry:c,opaqueBodies:h}=this._lightBarriers(t,n),d=ho(this._renderPlanHass,this._renderDevices,null,this._virtualLights).filter(e=>e.device.space===t.id),p=new Map;for(const t of d){if(!t.device.id)continue;const e=p.get(t.device.id)||[];e.push(t),p.set(t.device.id,e)}const u=[],_=new Set;for(const e of this._renderDevices){if(e.space!==t.id)continue;const o=po(p.get(e.id)||[]);if(!o)continue;const d=`${t.id}|${e.id}`;_.add(d);const m=$s(o.passive?{state:o.on?"on":"off",attributes:{}}:this._renderPlanHass.states[o.eid],e.marker?.glow_color,i.glow_light.c),g=Number(e.marker?.glow_radius_cm),f=Number.isFinite(g)&&g>0?g/this._cellCm*this._gridPitch:s,v=this._pos(e);if(dh([v.x,v.y],c,h)){this._forgetGlowSource(d);continue}const y=this._glowTransition(d,!!m);if(!y)continue;m&&this._glowLastAppearance.set(d,{c:m.c,alpha:Ss(m.bri,i.glow_light.a)});const b=this._glowLastAppearance.get(d);if(!b)continue;let w=null;const k=`${t.id}|${l}|${v.x.toFixed(4)},${v.y.toFixed(4)}|${f.toFixed(4)}`,x=qf(this._glowClipCache,k);if(x.hit)w=x.value;else{const e=Nu([v.x,v.y],f,a,96);w={lit:e.length>=3?oh([e],r,{onBoundsFailure:({boundIndex:e,phase:i})=>{const s=n[e]?.r;this._warnGlowGeometryFallback(t.id,l,s?.id||`#${e}`,i)}}):[]},Wf(this._glowClipCache,k,w,256)}u.push({key:d,sourceEid:o.eid,domId:y.domId,entering:y.entering,leaving:y.leaving,pos:v,c:b.c,alpha:b.alpha,geometry:w,r:f})}const m=`${t.id}|`;for(const t of this._glowRenderedSources.keys())t.startsWith(m)&&!_.has(t)&&this._forgetGlowSource(t);if(!u.length)return j``;const g=this._spaceWalls,f=o.length===n.length?[]:this._openCuts(),v=this._wallUnionGeometry()?.roomGeom,y=o.length===n.length?null:o.map(({r:e,poly:i})=>{const s=g.length&&e.id&&fc(t.rooms,e.id,g,f,this._wallKeyPitch,this._cellCm,this._gridPitch,ev,v)||i,o=this._cleanFloor(e,s,t).path,a=Pi(s,n.filter(t=>t.r!==e).map(t=>t.poly)),r=t=>"M "+t.map(t=>t[0]+" "+t[1]).join(" L ")+" Z";return[o||r(s),...a.map(r)].join(" ")}),b=this._viewOr(this._baseVb()),w=this._stageEl?.clientWidth&&b.w?this._stageEl.clientWidth/b.w:1,k=1/(w>0?w:1),x=!this._pinchStart&&!this._panStart&&Date.now()>=this._glowFeatherSuspendUntil;(null==this._glowFeatherUnits||x)&&(this._glowFeatherUnits=k);const $=this._glowFeatherUnits??k,S=4*$,M=u.reduce((t,e)=>({x:Math.min(t.x,e.pos.x-e.r-S),y:Math.min(t.y,e.pos.y-e.r-S),maxX:Math.max(t.maxX,e.pos.x+e.r+S),maxY:Math.max(t.maxY,e.pos.y+e.r+S),w:0,h:0}),{x:1/0,y:1/0,maxX:-1/0,maxY:-1/0,w:0,h:0});return M.w=M.maxX-M.x,M.h=M.maxY-M.y,j`
${Mt(u,t=>t.key,t=>{const e=t.domId,i=t.geometry;return j`
${""}
${iv.map(([e,i])=>j`
`)}
${""}
${i?j`
`:G}`})}
${y?j`${y.map(t=>j` `)} `:G}
${""}
${""}
${Mt(u,t=>t.key,t=>{const e=t.domId;return j`
`})}
`}_renderAlignDialog(){const t=this._alignDialog,e=t.report,i=t.changed&&!t.preflight?.ok,s=t.preflight?.failures||[],n=s.slice(0,3).map(t=>t.displayName),o=n.length?n.join(", "):this._t("gs.align_preflight_space",{n:"1"}),a=Math.max(0,s.length-n.length),r=a?this._t("gs.align_preflight_more",{n:String(a)}):"",l=e.spaceRefsRemapped+e.roomRefsRemapped+e.positionsRemapped+e.markersDetached,c=e.migrated+e.canonicalized+e.coordsCanonicalized+e.wallSegmentsMigrated+e.wallsMerged+e.spansMerged+e.partitionsMerged+e.partitionsReconciled+e.openingsRehosted+e.redundantDraftsRemoved,h=e.moved+e.rotated+e.removedDrafts+e.coordsCanonicalized+e.wallsStraightened,d=Math.ceil(10*e.maxStraightenShiftCm)/10,p=(this._serverCfg?.spaces||[]).find(t=>String(t?.id||"")===e.maxStraightenSpace),u=(this._serverCfg?.spaces||[]).length>1&&p?String(p.title||p.id):"",_=e.orphanRoomLabelsRemoved+e.orphanDevicePositionsRemoved+e.orphanGroupPositionsRemoved,m=e.liveMissingPositions.map(t=>t.name).filter(Boolean),g=m.slice(0,3).join(", "),f=Math.max(0,m.length-3),v=g?this._t("gs.optimize_live_names",{names:g,more:f?this._t("gs.optimize_reference_more",{n:String(f)}):""}):"",y=e.unverifiedPositions.some(t=>"registry_unavailable"===t.reason),b=t=>e.removedPositions.some(e=>e.id===t.id)?this._t("gs.optimize_detail_removed"):e.liveMissingPositions.some(e=>e.id===t.id)?this._t("gs.optimize_detail_live"):this._t("gs.optimize_detail_unverified"),w=t=>this._t("room_label"===t?"gs.optimize_detail_room_label":"group"===t?"gs.optimize_detail_group":"device"===t?"gs.optimize_detail_device":"gs.optimize_detail_unknown"),k=[...e.removedPositions,...e.liveMissingPositions.filter(t=>!e.removedPositions.some(e=>e.id===t.id)),...e.unverifiedPositions],x=k.slice(0,10),$=Math.max(0,k.length-x.length);return W`{this._alignDialog=null,this._preflightClipboardFallback=null}}>
${i?W`
${this._t("gs.align_preflight_failed",{spaces:o,more:r})}
${s.slice(0,10).map(t=>W`
${t.displayName}: ${this._t(`gs.preflight_reason_${t.reason}`)}
`)}
${s.length>10?W`
${this._t("gs.align_preflight_more",{n:String(s.length-10)})}
`:G}
${this._t("gs.align_preflight_hint")}
${this._preflightVersionsDiffer()?W`
${this._t("gs.preflight_update_hint")}
`:G}
this._copyPreflightDiagnostics()}>
${this._t("gs.preflight_copy")}
${this._preflightClipboardFallback?W`
${this._t("gs.preflight_copy")}
${this._preflightClipboardFallback}
`:G}`:t.changed?W`
${e.moved?W`
${this._t("gs.align_count",{n:String(e.moved),total:String(e.total),cm:String(t.cm)})}
`:G}
${e.latticeCoordinatesCanonicalized?W`
${this._t("gs.optimize_lattice_summary",{n:String(e.latticeCoordinatesCanonicalized),cm:Yr(e.latticeMaxShiftCm)})}
${e.latticeSpaces.map(t=>W`
${this._t("gs.optimize_lattice_space",{space:t.space,n:String(t.canonicalized),far:String(t.far)})}
`)}
`:G}
${t.where?W`
${this._t("gs.align_where",{s:t.where})}
`:G}
${e.rotated?W`
${this._t("gs.align_turned",{n:String(e.rotated)})}
`:G}
${e.removedDrafts?W`
${this._t("gs.align_removed_drafts",{n:String(e.removedDrafts)})}
`:G}
${e.redundantDraftsRemoved?W`
${this._t("gs.optimize_redundant_drafts",{n:String(e.redundantDraftsRemoved)})}
`:G}
${e.wallSegmentsMigrated?W`
${this._t("gs.wall_segments_migrated",{n:String(e.wallSegmentsMigrated)})}
`:G}
${e.legacyZeroWallsMigrated?W`
${this._t("gs.zero_walls_migrated",{n:String(e.legacyZeroWallsMigrated)})}
`:G}
${c?W`
${this._t("gs.optimize_changes",{m:String(e.migrated),c:String(e.canonicalized),p:String(e.coordsCanonicalized),w:String(e.wallsMerged),s:String(e.spansMerged),i:String(e.partitionsMerged)})}
`:G}
${e.partitionsReconciled?W`
${this._t("gs.optimize_coincident_partitions",{n:String(e.partitionsReconciled)})}
`:G}
${e.openingsRehosted?W`
${this._t("gs.optimize_openings_rehosted",{n:String(e.openingsRehosted)})}
`:G}
${e.wallsStraightened?W`
${this._t("gs.optimize_walls_straightened",{n:String(e.wallsStraightened),cm:String(d)})}
`:G}
${u?W`
${this._t("gs.optimize_walls_straightened_where",{s:u})}
`:G}
${e.glowSpacesMigrated||e.glowRoomsMigrated?W`
${this._t("gs.optimize_glow_migration",{spaces:String(e.glowSpacesMigrated),rooms:String(e.glowRoomsMigrated)})}
`:G}
${h?W`
${this._t("gs.align_warn")}
`:G}`:W`
${this._t(e.liveMissingPositions.length||e.unverifiedPositions.length||e.nestedRefsUnresolved?"gs.optimize_no_automatic_changes":"gs.align_none")}
`}
${!i&&e.wallsStraightenSkipped?W`
${this._t("gs.optimize_walls_straighten_skipped",{n:String(e.wallsStraightenSkipped)})}
`:G}
${l?W`
${this._t("gs.optimize_references",{spaces:String(e.spaceRefsRemapped),rooms:String(e.roomRefsRemapped),positions:String(e.positionsRemapped),detached:String(e.markersDetached)})}
`:G}
${_?W`
${this._t("gs.optimize_orphans_removed",{total:String(_),rooms:String(e.orphanRoomLabelsRemoved),devices:String(e.orphanDevicePositionsRemoved),groups:String(e.orphanGroupPositionsRemoved)})}
`:G}
${e.liveMissingPositions.length?W`
${this._t(t.removeLiveMissingPositions?"gs.optimize_live_positions_remove":"gs.optimize_live_positions",{n:String(e.liveMissingPositions.length),names:v})}
${this._t(t.removeLiveMissingPositions?"gs.optimize_live_keep":"gs.optimize_live_remove")}
${t.removeLiveMissingPositions?W`
${this._t("gs.optimize_live_selected")}
`:G}
`:G}
${e.unverifiedPositions.length?W`
${this._t("gs.optimize_unverified",{n:String(e.unverifiedPositions.length)})}
${y?` ${this._t("gs.optimize_registry_limited")}`:""}
`:G}
${e.nestedRefsUnresolved?W`
${this._t("gs.optimize_vacuum_warning",{n:String(e.nestedRefsUnresolved)})}
`:G}
${k.length?W`
${this._t("gs.optimize_details")}
${x.map(t=>W`${this._t("gs.optimize_detail_item",{status:b(t),kind:w(t.kind),id:t.id,space:t.spaceId})} `)}
${$?W`${this._t("gs.optimize_details_more",{n:String($)})}
`:G}
`:G}
{this._alignDialog=null,this._preflightClipboardFallback=null}}>${this._t("btn.cancel")}
${t.changed&&t.preflight?.ok?W`
${t.busy?"…":this._t("gs.align_run")}
`:G}
`}_renderSettingsDialog(){return W`this._settingsDialog=null}>
${this._t("gs.hint")}
${this._t("gs.light_group")}
${this._renderColorRow("light_on","gs.light_on")}
${this._renderColorRow("light_off","gs.light_off")}
${this._renderColorRow("light_none","gs.light_none")}
${this._t("gs.temp_group")}
${this._renderColorRow("temp_cold","gs.temp_cold")}
${this._renderColorRow("temp_ok","gs.temp_ok")}
${this._renderColorRow("temp_hot","gs.temp_hot")}
${this._t("gs.lqi_group")}
${this._renderColorRow("lqi_low","gs.lqi_low")}
${this._renderColorRow("lqi_high","gs.lqi_high")}
${this._t("gs.glow_group")}
${this._renderColorRow("glow_base","gs.glow_base")}
${this._renderColorRow("glow_light","gs.glow_light")}
${this._t("gs.glow_radius")}
{const e=Bf(t.target.value);null!=e&&e>0&&(this._settingsDialog={...this._settingsDialog,glowRadius:e})}} />
${this._imperial?this._t("gs.unit_ft"):this._t("gs.unit_m")}
${this._t("gs.wall_group")}
${this._renderColorRow("wall_fill","gs.wall_fill")}
${this._t("gs.bg_group")}
${this._t("gs.bg_mode")}
this._settingsDialog={...this._settingsDialog,bgMode:"daynight"===t.target.value?"daynight":"static"}}>
${this._t("gs.bg_static")}
${this._t("gs.bg_daynight")}
${"static"===this._settingsDialog.bgMode?W`
{this._settingsDialog={...this._settingsDialog,bgColor:t.detail.color}}}>
${this._settingsDialog.bgColor?W`this._settingsDialog={...this._settingsDialog,bgColor:null}}>${this._t("gs.bg_default")} `:W`${this._t("gs.bg_theme")} `}
`:W`
${this._t("gs.bg_daynight_hint")}
`}
${this._t("gs.sun_group")}
${Cr(this.hass)?G:W`
${this._t("gs.sun_missing")}
`}
${this._renderCompass()}
${this._t("gs.north")}
{const e=t.target.value.trim(),i=""===e?null:Math.round(Number(e));this._settingsDialog={...this._settingsDialog,northDeg:null!==i&&Number.isFinite(i)?Math.min(359,Math.max(0,i)):null}}} />
${null!==this._settingsDialog.northDeg?W`this._settingsDialog={...this._settingsDialog,northDeg:null}}>${this._t("gs.north_clear")} `:G}
${null===this._settingsDialog.northDeg?W`
${this._t("gs.north_hint")}
`:G}
${this._boolInput(this._settingsDialog.sunRays,t=>this._settingsDialog={...this._settingsDialog,sunRays:t})}
${this._t("gs.sun_rays")}
${this._canEdit?W`
${this._t("gs.backup_group")}
${this._t("gs.backup_hint")}
${this._t("backup.export_open")}
t.currentTarget.nextElementSibling?.click()}>
${this._t("backup.import_open")}
${this._canOptimizeUndo&&"import"===this._undoKind?W`
${this._t("backup.undo_import")}
`:G}
`:G}
${this._t("gs.grid_group")}
${this._t("gs.grid_hint")}
${this._t("gs.align_all")}
${this._canOptimizeUndo&&"import"!==this._undoKind?W`
${this._t("gs.optimize_undo")}
`:G}
${this._t("gs.about_group")}
${this._t("gs.about_version",{v:Ff})}
${this._t("gs.about_github")}
${this._t("gs.about_telegram")}
this._settingsDialog={...this._settingsDialog,colors:JSON.parse(JSON.stringify(ds)),glowRadius:this._imperial?9.8:3,bgColor:null,northDeg:null,bgMode:"daynight",sunRays:!1}}>
${this._t("gs.reset")}
this._settingsDialog=null}>${this._t("btn.cancel")}
${this._settingsDialog.busy?"…":this._t("btn.save")}
`}_rulesSet(t){this._rulesDialog={...this._rulesDialog,rules:t}}async _saveRules(){const t=this._rulesDialog;if(!t||t.busy)return;const e=t.rules.filter(t=>t.pattern.trim()&&t.icon.trim());this._rulesDialog={...t,busy:!0};try{const t=this._serverCfg,i=JSON.stringify(e)===JSON.stringify(Jt),s={...t.settings};i?delete s.icon_rules:s.icon_rules=e,this._serverCfg={...t,settings:s},await this._saveConfigNow(),this._rulesDialog=null,this._regSignature="",this._maybeRebuildDevices(),this._showToast(this._t("rules.saved"))}catch(t){this._rulesDialog&&(this._rulesDialog={...this._rulesDialog,busy:!1}),this._showToast(this._t("toast.error",{err:this._errText(t)}))}}_renderRulesDialog(){const t=this._rulesDialog,e=Xt(t.rules),i=t.test.trim()?ee(t.test,"",e):null,s=(e,i)=>{const s=[...t.rules],n=e+i;n<0||n>=s.length||([s[e],s[n]]=[s[n],s[e]],this._rulesSet(s))};return W`this._rulesDialog=null}>
${this._t("rules.hint")}
this._rulesDialog={...t,test:e.target.value}} />
${i?W`${i} `:G}
${t.rules.map((e,i)=>{const n=""!==e.pattern.trim()&&!function(t){try{return new RegExp(t,"i"),!0}catch{return!1}}(e.pattern);return W`
{const n=[...t.rules];n[i]={...e,pattern:s.target.value},this._rulesSet(n)}} />
{const n=[...t.rules];n[i]={...e,icon:s.target.value},this._rulesSet(n)}} />
s(i,-1)}>
s(i,1)}>
this._rulesSet(t.rules.filter((t,e)=>e!==i))}>
`})}
this._rulesSet([...t.rules,{pattern:"",icon:""}])}>
${this._t("rules.add")}
this._rulesSet(Jt.map(t=>({...t})))}>
${this._t("rules.reset")}
this._rulesDialog=null}>${this._t("btn.cancel")}
${t.busy?"…":this._t("btn.save")}
`}_saveKioskScale(t){this._kioskScale={...this._kioskScale,...t};try{localStorage.setItem(Zf,JSON.stringify(this._kioskScale))}catch{}this.requestUpdate()}_renderKioskDialog(){const t=this._kioskScale,e=(e,i)=>W`${i}
${this._rangeInput(50,300,5,Math.round(100*t[e]),t=>this._saveKioskScale({[e]:t/100}))}
${Math.round(100*t[e])}%
`;return W`this._kioskDialog=!1}>
${this._t("kiosk.hint")}
${e("icon",this._t("kiosk.icon_scale"))}
${e("font",this._t("kiosk.font_scale"))}
this._saveKioskScale({icon:1,font:1})}>${this._t("gs.reset")}
this._kioskDialog=!1}>${this._t("btn.close")}
`}_fixedFloorValue(t){if("string"==typeof t)return t||"''";try{const e=JSON.stringify(t);return(void 0===e?String(t):e).slice(0,160)}catch{return String(t).slice(0,160)}}render(){if(!this._config||!this.hass)return G;const t=this._model,e=this.houseplanDiagnostics(),i=this._fixedFloorState(t);if("pending"===i.kind)return W`
${this._config.title||this._t("card.title")}
${this._t("fixed_floor.loading")}
`;if("invalid"===i.kind)return W`
${this._config.title||this._t("card.title")}
${this._t("fixed_floor.invalid_title")}
${this._t("fixed_floor.invalid_body",{value:this._fixedFloorValue(i.value)})}
`;if(!t.length)return W`
${this._config.title||this._t("card.title")}
${this._t("empty.no_spaces")}
${this._serverStorage?W`
${this._t("empty.add_first")}
this._openSpaceDialog("create")}>
${this._t("btn.add_space")}
`:W`
${this._t("empty.install")}
`}
${this._spaceDialog?this._renderSpaceDialog():G}
${this._importDialog?this._renderImportDialog():G}
${this._toast?W`${this._toast}
`:G}
`;const s=this._spaceModel();if(!s)return G;const n="valid"===i.kind?[s]:t,o=s.vb,a=this._effectiveProjection();this._renderProjection=a,this._labs.active.length&&function(t){Hg||Gg(t);const e=Lg,i=e.active.join(",");if(!i||i===qg)return;qg=i;const s=new Map(Tg.map(t=>[t.id,t])),n=e.active.map(t=>{const e=s.get(t);return`${t} (#${e.issue}, expires ${e.expires})`}).join(", ");console.info(`HOUSEPLAN LABS: ${n}`)}(Ff);const r="iso"===a,l="devices"===this._mode&&this._showAll,c=this._renderDevices.filter(t=>t.space===s.id&&(!t.hidden||l)),h=this._renderDeviceSnapshot,d=this._spaceDisplayForRender(),p=r?this._isoDecorationLayers(d):null,u=p?this._isoOpeningPanels(p):[],_=this._resolvedRoomFills(s,d),m=this._resolvedGlowBase(s,d,_),g=d.showLqi??this._config.show_signal??!0,f=this._config.icon_size??2.5,v=f>8?2.5:f,y=o_(v),b=this._viewOr(this._baseVb()),w=this._floorView(b),k=this._editing?"":this._stageBg(d),x=this._opMeasureView,$=this._decorMeasure,S=this._bdLive,M=this._furnLive,C="view"===this._mode?this._editorChromeMode:this._mode,D=this._roomHoverPaths(s),P=s.bg?this._display(s.bg.href):"",T=this._continuity.overlayVisible||"recovery-error"===this._continuity.state?this._continuity.recoveryReason:null,R=this._modeTransitionVisual,I=this._dayCycleState(),A=R?.viewWeight??("view"===this._mode?1:0),z=this._modeTransition.state?.from.presentedMode,F=!this._markup||!!R&&("view"===R.presentedMode||"devices"===R.presentedMode||"view"===z||"devices"===z),E=R?.stageColor||k,N=R?.sceneBrightness??1;return W`
this._notePointer(t)}
@pointerdown=${this._touchGestureGuard}
@pointermove=${this._touchGestureGuard}
@pointerup=${this._touchGestureGuard}
@pointercancel=${this._touchGestureGuard}
@lostpointercapture=${this._touchGestureGuard}
@click=${this._touchGestureGuard}>
${this._config.title||this._t("card.title")}
this._tabPointerMove(t)}>
${n.map(t=>W`this._tabPointerDown(e,t.id)}
@pointerup=${t=>this._tabPointerUp(t)}
@pointercancel=${()=>this._endTabDrag()}
@click=${()=>this._tabClick(t.id)}
>
${t.title}${this._norm&&this._canEdit?W`{e.stopPropagation(),this._openSpaceDialog("edit",t.id)}}> `:G}
`)}
${""}
${!this._canEdit||this._kiosk||this._hasFixedFloor?G:W`this._openSpaceDialog("create")}>
`}
${this._canEdit?W`
${[["plan","mdi:floor-plan"],["devices","mdi:tune-variant"],["decor","mdi:draw"]].map(([t,e])=>W`this._setMode(t)}>
${this._t("mode."+t)}
${this._mode===t?W`{t.stopPropagation(),this._setMode("view")}}> `:G}
`)}
`:G}
${this._t("count.devices",{n:c.filter(t=>!t.hidden).length})}
${this._labsIso&&"view"===this._mode&&!this._kiosk?W`
this._setProjection(r?"flat":"iso")}>
`:G}
this._stepZoom(-1)} title=${this._t("title.zoom_out")}>
${""}
this._fitAll()}
title=${this._t("title.zoom_fit")}>
this._stepZoom(1)} title=${this._t("title.zoom_in")}>
${this._norm&&this._canEdit?W`
`:G}
${this._canEdit&&!this._kiosk?W`
${"plan"===C?this._renderMarkupBar():"devices"===C?this._renderDevicesBar():this._renderDecorBar()}
`:G}
this._markupClick(t)}
@wheel=${t=>this._onWheel(t)}
@pointerdown=${t=>{this._notePointer(t),this._stagePointerDown(t)}}
@pointermove=${t=>this._stagePointerMove(t)}
@pointerleave=${t=>this._stagePointerLeave(t)}
@pointerup=${t=>this._stagePointerUp(t)}
@pointercancel=${t=>this._stagePointerCancel(t)}>
${Tr(I,A)}
${this._renderEditorSecondary()}
${r&&p?.structural?j`
${this._renderIsoUnderlay(p)}
`:G}
${""}
${this._wallHatchDefs(d.color)}${j`${this._paperShapes(s.rooms).map(t=>"path"in t?j` `:"poly"in t?j` `:j` `)} `}
${this._editing?this._renderMarkupDefs(o):G}
${""}
${this._editing&&!this._markup&&this._gridLevels()?j` `:G}
${s.bg&&P?j`this._onBackdropLoaded(s.bg.href,P)}
transform=${s.bg.angle?`rotate(${s.bg.angle} ${s.bg.x+s.bg.w/2} ${s.bg.y+s.bg.h/2})`:G}
@dblclick=${t=>this._openBackdropDialog(t)}
preserveAspectRatio="none" />`:G}
${(()=>{const t=this._openCuts(),e=new Map,i=t=>(e.has(t)||e.set(t,hi(t)),e.get(t));return s.rooms.filter(t=>t.area||"view"===this._mode||this._markup||d.showBorders).map(e=>{let n="room "+(s.bg?"overlay":"yard")+(this._markup?" outlined":"");!this._markup||e.id!==this._mergeSel&&e.id!==this._splitSel?.roomId||(n+=" picked");let o="";const a=zs(d.fill,e);if(!this._markup&&(d.showBorders||"none"!==a)){n+=" styled";const t=[];t.push(`--room-stroke:${d.color}`,`--room-stroke-op:${d.showBorders?d.opacity:0}`);const i=_.byRoom.get(e)||null;i?(n+=" filled",t.push(`--room-fill:${i.color}`,`--room-fill-op:${i.opacity}`)):t.push("--room-fill:transparent","--room-fill-op:0"),o=t.join(";")}let r;const l=t=>{"view"===this._mode&&(void 0===r&&(r=this._roomArea(e)),this._showTip(t,e.name||this._t("room.unnamed"),r?this._t("tip.area",{value:r}):"",g?this._roomLqi(e.area):null,this._roomTemp(e),this._roomHum(e)))},c=i(e),h=this._markup&&(e.id===this._mergeSel||e.id===this._splitSel?.roomId),p=c&&!h?t.filter(t=>{const e=[(t[0]+t[2])/2,(t[1]+t[3])/2];return c.some((t,i)=>Ls(e,[t[0],t[1],...c[(i+1)%c.length]])<=.08*this._gridPitch)}):[],u=h?[]:this._thickWallCuts(),m=p.concat(u);m.length&&(n+=" noedge");const f=this._spaceWalls,v=f.length&&e.id&&c&&fc(s.rooms,e.id,f,t,this._wallKeyPitch,this._cellCm,this._gridPitch,ev,this._wallUnionGeometry()?.roomGeom)||c,y=v?Pi(v,(b=e,s.rooms.filter(t=>t!==b).map(i).filter(Boolean))):[];var b;const w=t=>"M "+t.map(t=>t[0]+" "+t[1]).join(" L ")+" Z",k=v?this._cleanFloor(e,v,s).path:"",x=e.id||G,$=e.area||G,S=k&&v?j`{this._notePointer(t),this._pointerModality.hoverEnabled&&(this._hoverRoom={space:s.id,room:e})}}
@pointermove=${l}
@pointerleave=${()=>this._clearTransientHover()}> `:y.length&&v?j`{this._notePointer(t),this._pointerModality.hoverEnabled&&(this._hoverRoom={space:s.id,room:e})}}
@pointermove=${l}
@pointerleave=${()=>this._clearTransientHover()}> `:v&&v!==c?j`{this._notePointer(t),this._pointerModality.hoverEnabled&&(this._hoverRoom={space:s.id,room:e})}}
@pointermove=${l}
@pointerleave=${()=>this._clearTransientHover()}> `:e.poly?j`{this._notePointer(t),this._pointerModality.hoverEnabled&&(this._hoverRoom={space:s.id,room:e})}}
@pointermove=${l}
@pointerleave=${()=>this._clearTransientHover()}> `:j`{this._notePointer(t),this._pointerModality.hoverEnabled&&(this._hoverRoom={space:s.id,room:e})}}
@pointermove=${l}
@pointerleave=${()=>this._clearTransientHover()}> `,M=m.length&&c?Ps(c,m,.02*this._gridPitch):null,C=M?j` `:G;return j`${S}${C}`})})()}
${this._renderRoomHoverFill(D)}
${this._renderOpeningTunnelFills(s,_)}
${this._renderGlowBaseRooms(s,m)}
${this._renderOpeningTunnelFills(s,m,"glow-base")}
${""}
${d.hideDecor&&"decor"!==this._mode?G:this._renderDecorLayer()}
${F?this._renderGlowLayer(s,d):G}
${this._renderSunRays(s)}
${this._editing?j`${this._renderAlignGuides()} `:G}
${this._markup?j`${this._renderMarkupLayer(o)} `:G}
${""}
${""}
${this._editing?G:this._renderZeroWalls(d)}
${this._renderWallBodies(d)}
${this._markup&&"resize"===this._tool?this._renderResizeMeasurements():G}
${this._renderRoomHoverOutline(D)}
${""}
${this._editing?this._renderZeroWalls(d):G}
${this._markup?j`${this._renderHiddenWallDiagnosticOverlay()} `:G}
${this._markup?j`${this._renderOpeningPlacementPreview()} `:G}
${x?this._renderOpeningDimensionGuides(x):G}
${x?.guide?this._renderOpeningCenterTick(x.guide):G}
${""}
${""}
${this._markup?j`${this._renderActiveChainInk()} `:G}
${this._markup?j`${this._renderPlanSnapOverlay()} `:G}
${d.hideOpenings&&!this._markup||p&&!p.floorSymbols?G:this._renderOpenings(d)}
${this._renderWallThickUi()}
${this._markup&&"resize"===this._tool?this._renderResizeLayer(b):G}
${""}
${this._renderBackdropFrame(b)}
${this._renderTextFrame(b)}
${r&&p?.structural?j`
${this._renderIsoShadows(p,u)}
${this._renderIsoWalls(p,u)}
`:G}
${""}
${c.map(t=>this._renderDevice(t,b,g))}
${this._renderVacuums(c,b)}
${this._renderVacFit(b)}
${this._renderOpeningLocks(b)}
${d.showNames||this._markup?s.rooms.map(t=>this._renderRoomLabel(t,s,b,d)):G}
${this._markup?s.rooms.map(t=>this._renderRoomGear(t,s,b)):G}
${this._measureAnchor?W`
${this._renderMeasureLabel(b)}
`:G}
${this._rszLive?W`
${this._rszLive.map(t=>W`
${t.text}
`)}
`:G}
${x?W`
${x.labels.map(t=>W`
${t.text}
`)}
`:G}
${this._wallDialog?W`
${this._renderWallThickDialog()}
`:G}
${$?W`
`:G}
${M?W`
${M.map(t=>W`
${t.text}
`)}
`:G}
${S?W`
`:G}
${this._zoom>1?W`
${Math.round(100*this._zoom)}%
`:G}
${this._renderFarHint()}
${this._renderHomeArrow()}
${this._renderRecoveryOverlay()}
${this._booting||this._bootFading?W`
`:G}
${this._roomDialog?this._renderRoomDialog():G}
${this._mergeDialog?this._renderMergeDialog():G}
${this._openingDialog?this._renderOpeningDialog():G}
${this._physicalDialog?this._renderPhysicalDialog():G}
${this._partitionDeleteDialog?this._renderPartitionDeleteDialog():G}
${this._roomDeleteDialog?this._renderRoomDeleteDialog():G}
${this._openingInfo?this._renderOpeningInfoCard():G}
${this._decorTextDialog?this._renderDecorTextDialog():G}
${this._decorShapeDialog?this._renderDecorShapeDialog():G}
${this._backdropDialog?this._renderBackdropDialog():G}
${this._decorEraseConfirm?this._renderDecorEraseConfirm():G}
${this._spaceDialog?this._renderSpaceDialog():G}
${this._markerDialog?this._renderMarkerDialog():G}
${this._vacCalConfirm?W`this._vacCalConfirm=null}>
${this._t("vac.residual_message",{error:this._vacCalConfirm.error})}
this._vacCalConfirm=null}>${this._t("btn.cancel")}
this._vacApplyCalibrationProposal(!0)}>${this._t("vac.fit")}
this._vacApplyCalibrationProposal(!1)}>
${this._t("vac.apply_proposal")}
`:G}
${this._infoCard?this._renderInfoCard():G}
${this._rulesDialog?this._renderRulesDialog():G}
${this._settingsDialog?this._renderSettingsDialog():G}
${this._alignDialog?this._renderAlignDialog():G}
${this._backupExportDialog?this._renderBackupExportDialog():G}
${this._backupImportDialog?this._renderBackupImportDialog():G}
${this._importDialog?this._renderImportDialog():G}
${this._tip?W`
${this._tip.title} ${this._tip.meta?W`${this._tip.meta} `:G}
${null!=this._tip.temp?W`${this._t("tip.temp_avg")} ${this._tip.temp}° `:G}
${null!=this._tip.hum?W`${this._t("tip.hum_avg")} ${this._tip.hum}% `:G}
${null!=this._tip.lqi?W`${this._t("tip.lqi")}
${this._tip.lqi} `:G}
`:G}
${this._kiosk&&!this._hasFixedFloor&&this._kioskDots&&this._model.length>1?W`
${this._model.map(t=>W` `)}
`:G}
${this._kioskDialog?this._renderKioskDialog():G}
${this._vacFit?W`
${this._t("vac.fit_hint")}
this._vacFitTurn({rot:(this._vacFit.p.rot+90)%360})}>${this._t("vac.fit_rotate")}
this._vacFitTurn({mir:!this._vacFit.p.mir})}>${this._t("vac.fit_mirror")}
this._vacFitSave()}>${this._t("btn.save")}
{this._vacFit=null}}>${this._t("btn.cancel")}
`:G}
${this._tapConfirm?W`this._tapConfirm=null}>
${"run"===this._tapConfirm.kind?W`
${this._tapConfirm.text}
`:this._tapConfirm.lines.map((t,e)=>W`
${t}
`)}
this._tapConfirm=null}>${this._t("btn.cancel")}
{const t=this._tapConfirm;this._tapConfirm=null,t.exec()}}>
${this._t("btn.run")}
`:G}
${this._toast?W`${this._toast}
`:G}
`}_vacCandidateStatus(t,e,i=this._planHass){const s=this._bindingStatus("entity:"+t);if("ha_disabled"===s.kind)return"disabled";if("orphaned"===s.kind)return"missing";if("unverified"===s.kind)return"unverified";const n=i?.states?.[t];return"unavailable"===n?.state?"unavailable":e?.hasPosition?"ok":"unsupported"}_vacOpenAllCameras(t){const e=this._haRegistry.entities||{},i=[];for(const[t,s]of Object.entries(this.hass?.states||{})){if(!t.startsWith("camera."))continue;const n=Od(t,s,e[t]);n&&i.push(n)}this._vacAllCameraCache={devId:t.id,candidates:i},this._vacAllCamerasFor=t.id}_vacSourceResolution(t,e=!1,i=this._planHass){const s=t.marker?.vacuum,n="string"==typeof s?.source&&!!s.source,o=new Set(t.entities||[]),a=new Set(o);n&&a.add(s.source);const r=i?.entities||{},l=[];for(const t of a){const e=i?.states?.[t],o=Od(t,e,r[t]);o?l.push(o):n&&t===s.source&&l.push({entityId:t,name:String(e?.attributes?.friendly_name||t),platform:r[t]?.platform?String(r[t].platform):null,category:t.startsWith("camera.")?"camera":"partial",hasPosition:!1,hasRooms:!1,hasPath:!1,hasMapId:!1,score:0})}if(e&&this._vacAllCameraCache?.devId===t.id){const t=new Set(l.map(t=>t.entityId));for(const e of this._vacAllCameraCache.candidates)t.has(e.entityId)||l.push(e)}const c={};for(const t of l)c[t.entityId]=this._vacCandidateStatus(t.entityId,t,i);return function(t,e,i,s){const n="string"==typeof t&&t.length>0,o=new Set(e),a=Array.from(i).sort((e,i)=>n&&e.entityId===t?-1:n&&i.entityId===t?1:i.score-e.score||e.entityId.localeCompare(i.entityId));if(n){const e=a.find(e=>e.entityId===t);return{entityId:t,status:s[t]||(e?.hasPosition?"ok":"unverified"),pinned:!0,candidates:a}}const r=a.find(t=>o.has(t.entityId)&&t.hasPosition&&"ok"===s[t.entityId]);return r?{entityId:r.entityId,status:"ok",pinned:!1,candidates:a}:{entityId:null,status:"none",pinned:!1,candidates:a}}(s?.source,o,l,c)}_vacSource(t,e=this._planHass){if(!1===t.marker?.vacuum?.live)return null;const i=this._vacSourceResolution(t,!1,e);return"ok"===i.status||"unsupported"===i.status?i.entityId:null}_vacEntity(t){return t.primary?.startsWith("vacuum.")?t.primary:(t.entities||[]).find(t=>t.startsWith("vacuum."))||null}_isVacDev(t){return!!this._vacEntity(t)}_activitySourceKey(t){return this._activitySnapshot(t).sourceKey}_activitySnapshot(t,e=ho(this._planHass,this._devices,null,this._virtualLights)){const i=Yu(this._planHass,t,this._devices,e,this._fullRegistryHass);return{samples:i.samples,sourceKey:Zu(this._planHass,t,i)}}_stampActivity(t,e,i){let s=this._activityRt.get(t);s||(s=I_(i||"",[]),this._activityRt.set(t,s)),null!=i&&(s.sources=i),z_(s,e,Date.now(),window.clearTimeout.bind(window),t=>window.setTimeout(()=>this.requestUpdate(),t))}_syncActivityRuntime(){const t=new Map;if(!this.hass)return t;if(!1===this._config?.live_states){for(const t of this._activityRt.values())clearTimeout(t.timer);return this._activityRt.clear(),t}const e=new Set,i=ho(this._planHass,this._devices,null,this._virtualLights);for(const s of this._devices){if(s.hidden)continue;if("icon_ripple"!==Bi(s.marker?.display))continue;e.add(s.id);const n=this._activitySnapshot(s,i);t.set(s.id,n);const{samples:o,sourceKey:a}=n;let r=this._activityRt.get(s.id);r?r.sources!==a&&A_(r,a,o,window.clearTimeout.bind(window)):(r=I_(a,o),this._activityRt.set(s.id,r))}for(const[t,i]of this._activityRt)e.has(t)||(clearTimeout(i.timer),this._activityRt.delete(t));return t}_activityTick(){if(!this.hass)return;const t=this._syncActivityRuntime();for(const e of this._devices){if(e.hidden)continue;if("icon_ripple"!==Bi(e.marker?.display))continue;const i=t.get(e.id)||this._activitySnapshot(e),{samples:s,sourceKey:n}=i,o=this._activityRt.get(e.id);if(!o||o.sources!==n)continue;const a=F_(o,s,window.clearTimeout.bind(window));a&&this._stampActivity(e.id,a,n)}}_vacTick(){if(this.hass)for(const t of this._devices){if(t.hidden||!this._isVacDev(t))continue;if("static_icon"===Bi(t.marker?.display)){this._vacRt.delete(t.id);continue}const e=this._vacSource(t);if(!e)continue;const i=this._vacEntity(t),s=qd(this.hass.states[i||""]?.state),n=Nd(this.hass.states[e]?.attributes);let o=this._vacRt.get(t.id);o||(o={trail:[],lastKey:"",lastTs:0,moving:!1,jump:!1,endedTs:0,lastPos:null},this._vacRt.set(t.id,o)),s&&!o.moving&&(o.trail=[],o.lastPos=null);const a="never"!==Vd(t.marker?.vacuum)&&!n?.path.length;!s&&o.moving&&(o.endedTs=Date.now(),a&&o.lastPos&&(o.trail=Bd(o.trail,o.lastPos,40)),o.lastPos=null),o.moving=s;const r=n?.pos;if(s&&r){const t=r.x+":"+r.y;if(t!==o.lastKey){const e=Date.now();o.jump=o.lastTs>0&&e-o.lastTs>1e4,o.lastKey=t,o.lastTs=e,a&&o.lastPos&&(o.trail=Bd(o.trail,o.lastPos,40)),o.lastPos=[r.x,r.y]}}}}_vacEnsureMarker(t){const e=this._serverCfg;if(!e)return null;e.markers=e.markers||[];const i=e.markers.find(e=>e.id===t.id);if(i)return i;if("device"!==t.bindingKind&&"entity"!==t.bindingKind||!t.bindingRef)return null;const s={id:t.id,binding:t.bindingKind+":"+t.bindingRef,space:t.space||null,area:t.area||null,hidden:!!t.hidden};return e.markers.push(s),s}_renderVacSection(t){const e=this._devices.find(e=>e.id===t.devId);if(!e||!this._isVacDev(e))return G;const i=e.marker?.vacuum||{},s=this._vacAllCamerasFor===e.id,n=this._vacSourceResolution(e,s),o=n.entityId,a=n.candidates.find(t=>t.entityId===o)||null,r=o?Nd(this.hass?.states[o]?.attributes):null,l=!1!==i.live&&("ok"===n.status||"unsupported"===n.status),c=this._vacPlanRoomAnchors(e.space),h=r?function(t,e){const i=new Set(e.map(Ld).filter(Boolean)),s=new Set;for(const e of t){const t=Ld(e.name||"");t&&i.has(t)&&s.add(t)}return s.size}(r.rooms,c.map(t=>t.name)):0,d=!!(l&&r&&h>=3),p=Object.keys(i.calibration||{}),u=t=>{const i=this._vacEnsureMarker(e);i&&(i.vacuum={...i.vacuum||{},...t},this._regSignature="",this._maybeRebuildDevices(),this._saveConfig(),this.requestUpdate())},_=new Set(e.entities||[]),m=n.candidates.filter(t=>_.has(t.entityId)||t.entityId===i.source),g=s?n.candidates.filter(t=>t.entityId.startsWith("camera.")&&!m.some(e=>e.entityId===t.entityId)):[],f=t=>[t.hasPosition?this._t("vac.cap_position"):"",t.hasRooms?this._t("vac.cap_rooms_short"):"",t.hasPath?this._t("vac.cap_path"):"",t.hasMapId?this._t("vac.cap_map"):""].filter(Boolean).join(" · ")||this._t("vac.cap_none"),v=t=>W`
u({source:t.entityId})}>
${t.name} ${t.entityId}
${t.platform||this._t("vac.platform_unknown")} · ${f(t)}
`,y=n.candidates.some(t=>_.has(t.entityId)&&"known_xcme_incomplete"===t.category)||!!n.pinned&&!!o?.startsWith("camera.")&&!a?.hasPosition;return W`
${this._t("vac.section")}
${this._t("vac.diag_source")} ${o||this._t("vac.source_none")}
${a?.platform?W`
${this._t("vac.diag_platform")} ${a.platform}
`:G}
${this._t("vac.diag_status")} ${this._t(`vac.source_status_${n.status}`)}
${this._t("vac.diag_position")} ${r?.pos?this._t("common.yes"):this._t("common.no")}
${this._t("vac.diag_rooms")} ${ss(this._t("vac.diag_rooms_value"),{total:String(r?.rooms.length||0),matched:String(h),readiness:this._t(h>=3?"vac.autocal_ready":"vac.autocal_not_ready")})}
${this._t("vac.diag_path")} ${r?.path.length?this._t("common.yes"):this._t("common.no")}
${this._t("vac.diag_map")} ${r?.mapId??"default"}
${"missing"===n.status||"disabled"===n.status||"unverified"===n.status?W`
${this._t(`vac.source_banner_${n.status}`)}
{const t=[...this.renderRoot.querySelectorAll("details.vacpicker")].find(t=>t.dataset.devId===e.id);t&&(t.open=!0,t.querySelector("summary")?.focus())}}>${this._t("vac.choose_source")}
`:G}
${y?W`
${this._t("vac.xcme_hint")}
attributes:
- vacuum_position
- rooms
- path
- map_name
`:G}
${this._t("vac.choose_source")}
u({source:null})}>
${this._t("vac.source_auto")} ${this._t("vac.source_auto_hint")}
${m.map(v)}
{t.currentTarget.open?this._vacOpenAllCameras(e):(this._vacAllCamerasFor=null,this._vacAllCameraCache=null)}}>
${this._t("vac.all_cameras")}
${this._t("vac.all_cameras_warn")}
${s?g.length?g.map(v):W`${this._t("vac.all_cameras_empty")}
`:G}
${r?W`
${this._boolInput(!1!==i.live,t=>u({live:!!t&&null}))}
${this._t("vac.live")}
${this._t("vac.trail")}
u({trail_mode:t.target.value,trail:null})}>
${["never","cleaning","always"].map(t=>W`
${this._t("vac.trail_"+t)} `)}
${p.length?W`
${ss(this._t("vac.cal_maps"),{maps:p.join(", ")})}
`:G}
`:G}
`}_vacMapId(t,e,i=this._planHass){const s=this._vacEntity(t),n=s?i?.states?.[s]?.attributes?.selected_map:null;return o=e.mapId,a=n,"default"!==o?o:null!=a?String(a):"default";var o,a}_vacSaveMatrix(t,e,i,s){const n=this._devices.find(e=>e.id===t),o=n?this._vacEnsureMarker(n):this._serverCfg?.markers?.find(e=>e.id===t);if(!o)return!1;const a={...o.vacuum||{}};return a.source=e,a.calibration={...a.calibration||{},[i]:s.map(t=>Number(t.toFixed(6)))},o.vacuum=a,this._regSignature="",this._maybeRebuildDevices(),this._saveConfig(),this.requestUpdate(),!0}_vacPlanRoomAnchors(t){return(this._spaceModelById(t)?.rooms||[]).map(t=>({room:t,poly:hi(t)})).filter(({room:t,poly:e})=>t.name&&e).map(({room:t,poly:e})=>{const i=Id(e);return i?{name:String(t.name),cx:i[0],cy:i[1]}:null}).filter(Boolean)}_vacAutoCalibrate(t){const e=this._vacSource(t),i=e?Nd(this.hass?.states[e]?.attributes):null;if(!e||!i||i.rooms.length<3)return void this._showToast(this._t("vac.autocal_no_rooms"));const s=this._vacPlanRoomAnchors(t.space),n=Hd(i.rooms,s);if(!n)return void this._showToast(this._t("vac.autocal_no_match"));const o=this._serverCfg?.spaces?.find(e=>e.id===t.space),a=Number(o?.cell_cm),r=Number.isFinite(a)&&a>0?a:5,l=function(t,e,i){return![t,e,i].every(Number.isFinite)||t<0||e<=0||i<=0?Number.POSITIVE_INFINITY:t/e*i}(n.residual,this._gridPitch,r),c=this._vacMapId(t,i);l>40?this._vacCalConfirm={markerId:t.id,source:e,mapId:c,matrix:n.matrix,rooms:n.matched.length,error:li(l,"mi"===this.hass?.config?.unit_system?.length)}:this._vacSaveMatrix(t.id,e,c,n.matrix)&&this._showToast(ss(this._t("vac.autocal_done"),{rooms:String(n.matched.length)}))}_vacApplyCalibrationProposal(t){const e=this._vacCalConfirm;if(e){if(this._vacCalConfirm=null,t){const t=this._devices.find(t=>t.id===e.markerId),i=Ud(e.matrix);if(!t||!i)return;if(this._markerDialog=null,t.space!==this._space&&!this._commitSpace(t.space))return;return void(this._vacFit={markerId:e.markerId,source:e.source,mapId:e.mapId,p:i,drag:null})}this._vacSaveMatrix(e.markerId,e.source,e.mapId,e.matrix)&&this._showToast(ss(this._t("vac.autocal_done"),{rooms:String(e.rooms)}))}}_vacStartFit(t){const e=this._vacSource(t),i=e?Nd(this.hass?.states[e]?.attributes):null;if(!e||!i)return void this._showToast(this._t("vac.cal_need_pos"));const s=this._vacMapId(t,i),n=t.marker?.vacuum?.calibration?.[s],o=this._spaceModelById(t.space);if(!o)return;const a=o.vb,r=n&&6===n.length&&Ud(n)||function(t,e){const i=[],s=[];for(const e of t)null!=e.x0?(i.push(e.x0,e.x1),s.push(e.y0,e.y1)):(i.push(e.cx),s.push(e.cy));if(!i.length)return{ox:e[0]+e[2]/2,oy:e[1]+e[3]/2,s:e[2]/1e4,rot:0,mir:!0};const n=Math.min(...i),o=Math.max(...i),a=Math.min(...s),r=Math.max(...s),l=Math.max(o-n,r-a)||1,c={ox:0,oy:0,s:.6*Math.min(e[2],e[3])/l,rot:0,mir:!0},h=jd(c),[d,p]=Dd(h,(n+o)/2,(a+r)/2);return c.ox=e[0]+e[2]/2-d,c.oy=e[1]+e[3]/2-p,c}(i.rooms,a);this._markerDialog=null,(t.space===this._space||this._commitSpace(t.space))&&(this._vacFit={markerId:t.id,source:e,mapId:s,p:r,drag:null})}_vacFitSave(){const t=this._vacFit;if(!t)return;const e=this._vacSaveMatrix(t.markerId,t.source,t.mapId,jd(t.p));this._vacFit=null,e&&this._showToast(this._t("vac.cal_done"))}_vacFitTurn(t){const e=this._vacFit;if(!e)return;const i=Nd(this.hass?.states[e.source]?.attributes),s=this._vacGhostCentre(i?.rooms||[]),n={...e.p,...t};this._vacFit={...e,p:Gd(n,e.p,s[0],s[1])}}_vacGhostCentre(t){const e=[],i=[];for(const s of t)e.push(s.x0??s.cx,s.x1??s.cx),i.push(s.y0??s.cy,s.y1??s.cy);return e.length?[(Math.min(...e)+Math.max(...e))/2,(Math.min(...i)+Math.max(...i))/2]:[0,0]}_vacDelta(t,e,i){const s=this._stageEl,n=s?.clientWidth||1,o=s?.clientHeight||1;return[e/n*t.w,i/o*t.h]}_vacFitPointer(t,e){const i=this._vacFit;if(!i)return;if(t.stopPropagation(),"pointerdown"===t.type){const e=t.target,s=e.getAttribute?.("data-corner");try{t.currentTarget.setPointerCapture?.(t.pointerId)}catch{}return void(this._vacFit={...i,drag:s?{kind:"scale",sx:t.clientX,sy:t.clientY,p0:{...i.p},fx:Number(s.split(",")[0]),fy:Number(s.split(",")[1])}:{kind:"move",sx:t.clientX,sy:t.clientY,p0:{...i.p},fx:0,fy:0}})}const s=i.drag;if(s){if("pointermove"===t.type){const[n,o]=this._vacDelta(e,t.clientX-s.sx,t.clientY-s.sy);if("move"===s.kind)this._vacFit={...i,p:{...s.p0,ox:s.p0.ox+n,oy:s.p0.oy+o}};else{const t=Nd(this.hass?.states[i.source]?.attributes),e=this._vacGhostCentre(t?.rooms||[]),a=jd(s.p0),[r,l]=Dd(a,e[0],e[1]),[c,h]=Dd(a,s.fx,s.fy),d=Math.hypot(r-c,l-h)||1,[p,u]=[2*r-c,2*l-h],_=Math.hypot(p+2*n-c,u+2*o-h)/2,m=Math.max(.05,_/d),g={...s.p0,s:s.p0.s*m};this._vacFit={...i,p:Gd(g,s.p0,s.fx,s.fy)}}return}"pointerup"!==t.type&&"pointercancel"!==t.type||(this._vacFit={...i,drag:null})}}_renderVacFit(t){const e=this._vacFit;if(!e)return G;const i=Nd(this._renderPlanHass?.states?.[e.source]?.attributes);if(!i)return G;const s=jd(e.p),n=[],o=[],a=[];for(const t of i.rooms){if(null==t.x0)continue;const e=[[t.x0,t.y0],[t.x1,t.y0],[t.x1,t.y1],[t.x0,t.y1]].map(([t,e])=>Dd(s,t,e));e.forEach(([t,e])=>{o.push(t),a.push(e)});const[i,r]=Dd(s,t.cx,t.cy);n.push(j`
${t.name} `)}let r=G;if(i.pos){const[e,n]=Dd(s,i.pos.x,i.pos.y);r=j` `}const l=[];if(o.length){const e=(()=>{const t=s[0]*s[4]-s[1]*s[3];return(e,i)=>[(s[4]*(e-s[2])-s[1]*(i-s[5]))/t,(-s[3]*(e-s[2])+s[0]*(i-s[5]))/t]})(),i=Math.min(...o),n=Math.max(...o),r=Math.min(...a),c=Math.max(...a),h=.022*t.w,d=h/4;for(const[t,s,o,a]of[[i,r,n,c],[n,r,i,c],[n,c,i,r],[i,c,n,r]]){const i=e(o,a);l.push(j`
`)}}return W`this._vacFitPointer(e,t)}
@pointermove=${e=>this._vacFitPointer(e,t)}
@pointerup=${e=>this._vacFitPointer(e,t)}
@pointercancel=${e=>this._vacFitPointer(e,t)}>${n}${r}${l} `}_vacRafLoop(){this._vacRaf=requestAnimationFrame(()=>{const t=this.renderRoot,e=this._stageEl,i=this._vacLastView,s=t?.querySelectorAll?.(".vacpuck")||[];if(!e||!i||!s.length)return void(this._vacRaf=0);const n=e.getBoundingClientRect();for(const e of s){const s=e.getAttribute("data-mid"),o=e.getBoundingClientRect(),a=i.x+(o.left+o.width/2-n.left)/n.width*i.w,r=i.y+(o.top+o.height/2-n.top)/n.height*i.h;for(const e of t.querySelectorAll(`line.tip[data-mid="${s}"]`))e.setAttribute("x2",a.toFixed(1)),e.setAttribute("y2",r.toFixed(1))}this._vacRafLoop()})}_renderVacuums(t,e){if(this._markup||"decor"===this._mode)return G;const i=this._space+"|"+e.x+"|"+e.y+"|"+e.w+"|"+e.h,s=this._vacJumpOnce||i!==this._vacViewKey;this._vacViewKey=i,this._vacJumpOnce=!1;const n=[],o=[];for(const i of t){if(i.hidden||!this._isVacDev(i))continue;if("static_icon"===Bi(i.marker?.display))continue;const t=this._renderDeviceSnapshot?.facts.get(`vacuum:${i.id}`),a=t?.source??this._vacSource(i,this._renderPlanHass);if(!a)continue;const r=t?.telemetry??Nd(this._renderPlanHass?.states[a]?.attributes);if(!r)continue;const l=String(t?.mapId??this._vacMapId(i,r,this._renderPlanHass)),c=i.marker?.vacuum?.calibration?.[l];if(!c||6!==c.length)continue;const h=t?.runtime??this._vacRt.get(i.id),d=h?.moving??!1,p=Vd(i.marker?.vacuum),u="always"===p||"cleaning"===p&&d,_=t?.server??this._vacSrvTrails[i.id],m=_?.current?.map_id===l&&Array.isArray(_.current.points)?_.current:null,g=_?.previous?.map_id===l&&Array.isArray(_.previous.points)?_.previous:null;if("always"===p&&g&&g.points.length>1){const t=g.points.map(([t,e])=>{const[i,s]=Dd(c,t,e),n=this._scenePoint([i,s]);return n[0].toFixed(1)+","+n[1].toFixed(1)}).join(" ");o.push(j` `)}if(u){const t=Fd(r,m,h?.trail||[]),e=!d||"integration"!==t.source&&"server"!==t.source?t.path:Ed(t.path);if(e.length){const t=e.map(t=>t.map(([t,e],i)=>{const[s,n]=Dd(c,t,e),o=this._scenePoint([s,n]);return`${i?"L":"M"} ${o[0].toFixed(1)} ${o[1].toFixed(1)}`}).join(" ")).join(" ");o.push(j` `);const s=e[e.length-1];if(d&&s?.length>=2){const t=s[s.length-1],[e,n]=Dd(c,t[0],t[1]),a=this._scenePoint([e,n]),r=a[0].toFixed(1),l=a[1].toFixed(1);o.push(j` `)}}}if(!d||!r.pos)continue;const[f,v]=Dd(c,r.pos.x,r.pos.y),y=this._scenePoint([f,v]),b=(y[0]-e.x)/e.w*100,w=(y[1]-e.y)/e.h*100,k=h&&h.lastTs>0&&Date.now()-h.lastTs>6e4,x=i.marker?.icon||i.icon||"mdi:robot-vacuum";n.push(W`{t.stopPropagation();const e=this._vacEntity(i);e&&this._openMoreInfo(e)}}>
`)}return this._vacLastView=e,n.length&&!this._vacRaf&&this._vacRafLoop(),n.length||o.length?W`
${o.length?j`${o} `:G}
${n}`:G}_renderDevice(t,e,i=!0){const s=this._pos(t),n=this._scenePoint([s.x,s.y]),o=(n[0]-e.x)/e.w*100,a=(n[1]-e.y)/e.h*100,r=this._devicePresentation(t,i),l=[`left:${o}%`,`top:${a}%`,...Go(r)],c=r.disabledReason,h=r.haDisabled?this._t(`marker.ha_disabled_${c}`):t.userHidden?this._t("marker.hidden_ghost"):t.name,d=Wu(r),p="view"===this._mode||"devices"===this._mode,u=[h,r.haDisabled?"":this._t(`marker.state_a11y_${d}`),"none"!==r.pulse.kind?this._t(`marker.pulse_a11y_${r.pulse.reason}`):"",r.valueFullText||r.valueText||"",Ro(r.valueBadge),null!=r.lqiText&&r.lqiBand?this._t(`marker.lqi_a11y_${r.lqiBand}`,{value:r.lqiText}):""].filter(Boolean).join(", "),_=[t.model,r.valueBadge?.fullText||"",null!=r.lqiText?"LQI "+r.lqiText:""].filter(Boolean).join(" · ");return W`this._clickDevice(e,t)}
@keydown=${e=>this._keyDevice(e,t)}
@contextmenu=${e=>this._ctxDevice(e,t)}
@pointerover=${e=>this._showTip(e,t.name,r.haDisabled?h:_)}
@pointerleave=${()=>this._clearTransientHover()}
@pointerdown=${e=>this._pointerDown(e,t)}
@pointermove=${e=>{this._pointerMove(e,t),this._showTip(e,t.name,r.haDisabled?h:_)}}
@pointerup=${e=>this._pointerUp(e,t)}
@pointercancel=${e=>this._pointerUp(e,t)}
>
${Ko(r,{newDevice:this._newIds.has(t.id),newDeviceTitle:this._t("device.new"),disabledTitle:r.haDisabled?h:""})}
`}_roomArea(t){const e=hi(t);if(!e)return null;const i=this._spaceModel();if(!i)return null;const s=this._spaceWalls,n=s.length&&t.id&&fc(i.rooms,t.id,s,this._openCuts(),this._wallKeyPitch,this._cellCm,this._gridPitch,ev,this._wallUnionGeometry()?.roomGeom)||e,o=this._cleanFloor(t,n),a=this._cellCm/this._gridPitch;return ir(o.area*a*a/1e4,"mi"===this._renderPlanHass?.config?.unit_system?.length)}_roomTemp(t){const e=t.settings?.temp_source;return e?Mo(this._renderPlanHass,e,"temp",this._markers):t.area?this._climate().get(t.area)?.temp??null:null}_roomHum(t){const e=t.settings?.hum_source;return e?Mo(this._renderPlanHass,e,"hum",this._markers):t.area?this._climate().get(t.area)?.hum??null:null}_climate(){const t=this._serverCfg?.markers,e=this._renderPlanHass,i=this._climateCache;if(i&&i.h===e&&i.r===this._iconRules&&i.mk===t)return i.m;const s=function(t,e,i){const s=new Map;if(!t?.entities)return s;const n=wo(i),o=new Set;for(const t of i||[]){if(t?.removed||!0!==t?.use_climate_temp)continue;const e=(t.binding||"").indexOf(":");e>0&&o.add(t.binding.slice(e+1))}const a=new Map;for(const[e,i]of Object.entries(t.entities)){if(i.device_id&&n.devices.has(i.device_id)&&!n.liveEntities.has(e)||!i.device_id&&n.entities.has(e)&&!n.liveEntities.has(e))continue;const s=i.device_id?t.devices?.[i.device_id]:null,r=i.area_id||s?.area_id||null;if(!r)continue;if(i.entity_category)continue;if(!(o.size>0&&e.startsWith("climate.")&&(o.has(e)||i.device_id&&o.has(i.device_id)))){if(Yt.has(i.platform))continue;if(Co.test(e))continue}let l=a.get(r);l||(l=new Map,a.set(r,l));const c=i.device_id||e;let h=l.get(c);if(!h){const n=t.states?.[e];h={name:(s?s.name_by_user||s.name:i.name||n?.attributes?.friendly_name||e)||e,model:s?.model,ents:[]},l.set(c,h)}h.ents.push(e)}for(const[i,n]of a){const a=[],r=[];for(const[i,s]of n){const n=bo(t,s.name,s.model,s.ents,e),l="mdi:thermometer"===n||"mdi:air-filter"===n;if(l){const e=mo(t,s.ents);null!=e&&a.push(e)}if(o.size>0&&(o.has(i)||s.ents.some(t=>o.has(t)))){const e=go(t,s.ents);null!=e&&a.push(e)}if(l||"mdi:water-percent"===n){const e=vo(t,s.ents);null!=e&&r.push(e)}}(a.length||r.length)&&s.set(i,{temp:a.length?Math.round(a.reduce((t,e)=>t+e,0)/a.length*10)/10:null,hum:r.length?Math.round(r.reduce((t,e)=>t+e,0)/r.length):null})}return s}(e,this._iconRules,t);return this._climateCache={h:e,r:this._iconRules,mk:t,m:s},s}_resetRoomDialogFields(){this._roomEditId=null,this._roomFill="",this._roomCustomFill=null,this._roomTempSrc="",this._roomHumSrc="",this._roomSrcOpen=null,this._roomSrcFilter="",this._roomNameScale=1,this._roomLabelScale=1}_openRoomEdit(t){if(!t.id)return;this._roomEditId=t.id,this._nameSel=t.name||"",this._areaSel=t.area||"",this._roomFill="glow"===t.settings?.fill_mode?"":t.settings?.fill_mode||"";const e=t.settings?.custom_fill;this._roomCustomFill=e&&"object"==typeof e?rs(e,cs(this._curSpaceCfg).customFill):null,this._roomTempSrc=t.settings?.temp_source||"",this._roomHumSrc=t.settings?.hum_source||"",this._roomNameScale=Es(t.settings?.name_scale),this._roomLabelScale=Es(t.settings?.label_scale),this._roomSrcOpen=null,this._roomSrcFilter="",this._roomDialog=!0}_roomSettingsFromDialog(){const t={};return this._roomFill&&(t.fill_mode=this._roomFill),this._roomCustomFill&&(t.custom_fill=this._roomCustomFill),this._roomTempSrc&&(t.temp_source=this._roomTempSrc),this._roomHumSrc&&(t.hum_source=this._roomHumSrc),1!==this._roomNameScale&&(t.name_scale=this._roomNameScale),1!==this._roomLabelScale&&(t.label_scale=this._roomLabelScale),Object.keys(t).length?t:null}_saveRoomEdit(){const t=this._curSpaceCfg,e=t?.rooms.find(t=>t.id===this._roomEditId);if(!e)return this._roomDialog=!1,void(this._roomEditId=null);e.name=this._nameSel.trim()||e.name,e.area=this._areaSel||null;const i=e.settings||{},s={...i};this._roomFill?s.fill_mode=this._roomFill:delete s.fill_mode,this._roomCustomFill?s.custom_fill=this._roomCustomFill:delete s.custom_fill,"glow"===i.fill_mode&&"boolean"!=typeof i.glow&&(s.glow=!0),this._roomTempSrc?s.temp_source=this._roomTempSrc:delete s.temp_source,this._roomHumSrc?s.hum_source=this._roomHumSrc:delete s.hum_source,1!==this._roomNameScale?s.name_scale=this._roomNameScale:delete s.name_scale,1!==this._roomLabelScale?s.label_scale=this._roomLabelScale:delete s.label_scale,Object.keys(s).length?e.settings=s:delete e.settings,this._saveConfig(),this._roomDialog=!1,this._roomEditId=null,this._nameSel="",this._areaSel="",this._regSignature="",this._maybeRebuildDevices(),this.requestUpdate(),this._showToast(this._t("toast.room_updated"))}_roomSrcCandidates(){const t=this._planHass,e=wo(this._markers),i=this._roomSrcFilter.trim().toLowerCase(),s=[];for(const n of Object.values(t.devices)){if("service"===n.entry_type)continue;if(e.devices.has(n.id))continue;const t=(n.name_by_user||n.name||n.id).trim();i&&!t.toLowerCase().includes(i)||s.push({value:"device:"+n.id,label:t,sub:n.model||this._t("marker.sub_device")})}for(const[n,o]of Object.entries(t.entities)){if(!n.startsWith("sensor.")||o.hidden)continue;if(ko(t,n,e))continue;const a=o.name||t.states[n]?.attributes?.friendly_name||n;i&&!(a+" "+n).toLowerCase().includes(i)||s.push({value:"entity:"+n,label:a,sub:n})}return s.sort((t,e)=>t.label.localeCompare(e.label)),s.slice(0,200)}_roomSrcLabel(t){const e=t.indexOf(":"),i=t.slice(0,e),s=t.slice(e+1);return"device"===i?this._fullRegistryHass.devices[s]?.name_by_user||this._fullRegistryHass.devices[s]?.name||s:this._fullRegistryHass.entities[s]?.name||this.hass.states[s]?.attributes?.friendly_name||s}_labelPos(t,e){const i=this._layout["rl_"+(t.id||"")];if(i&&i.s===e)return{x:i.x*ev,y:i.y*ev};const s=this._snap(this._roomCenter(t));return{x:s[0],y:s[1]}}_labelDown(t,e,i){if("plan"!==this._mode)return;t.preventDefault(),t.stopPropagation();const s=this._labelPos(e,i);this._drag={id:"rl_"+(e.id||""),sx:t.clientX,sy:t.clientY,ox:s.x,oy:s.y,moved:!1},cv(t),this._tip=null}_labelMove(t,e,i){const s="rl_"+(e.id||"");if(!this._drag||this._drag.id!==s)return;const n=this._stageEl;if(!n)return;const o=this._spaceModelById(i);if(!o)return;const a=o.vb,r=n.getBoundingClientRect(),l=this._viewOr(a),c=(t.clientX-this._drag.sx)/r.width*l.w,h=(t.clientY-this._drag.sy)/r.height*l.h;Math.abs(t.clientX-this._drag.sx)+Math.abs(t.clientY-this._drag.sy)>3&&(this._drag.moved=!0);const d=Ih(this._drag.ox+c),p=Ih(this._drag.oy+h);this._savePos({id:s,space:i},d,p)}_labelUp(t){const e="rl_"+(t.id||"");if(!this._drag||this._drag.id!==e)return;const i=this._drag.moved;this._drag=i?this._drag:null,i&&window.setTimeout(()=>this._drag=null,0)}_labelScale(t){const e=this._layout["rl_"+(t.id||"")]?.k;return"number"==typeof e&&Number.isFinite(e)?Math.min(3,Math.max(.5,e)):1}_rlResizeDown(t,e,i){if("plan"!==this._mode)return;t.preventDefault(),t.stopPropagation();const s=t.target.closest(".roomlabel");if(!s)return;const n=s.getBoundingClientRect(),o=n.left+n.width/2,a=n.top+n.height/2,r=Math.max(8,Math.hypot(t.clientX-o,t.clientY-a));this._rlResize={id:"rl_"+(e.id||""),space:i,k0:this._labelScale(e),cx:o,cy:a,d0:r},cv(t)}_rlResizeMove(t){const e=this._rlResize;if(!e)return;t.stopPropagation();const i=Math.max(8,Math.hypot(t.clientX-e.cx,t.clientY-e.cy)),s=Math.min(3,Math.max(.5,e.k0*(i/e.d0))),n=this._layout[e.id];if(n)this._layout={...this._layout,[e.id]:{...n,k:s}};else{const t=e.id.slice(3),i=this._spaceModelById(e.space);if(!i)return;const n=i.rooms.find(e=>e.id===t);if(!n)return;const o=this._labelPos(n,e.space);this._layout={...this._layout,[e.id]:{s:e.space,x:o.x/ev,y:o.y/ev,k:s}}}this._dirtyPos.add(e.id)}_rlResizeUp(){this._rlResize&&(this._rlResize=null,this._persistLayout())}_renderRoomGear(t,e,i){if(!t.id)return G;let s=null;if(t.poly?(s=this._gearPtCache.get(t.poly)||null,s||(s=$i(t.poly),this._gearPtCache.set(t.poly,s))):null!=t.x&&null!=t.y&&(s=[t.x+(t.w||0)/2,t.y+(t.h||0)/2]),!s)return G;const n=(s[0]-i.x)/i.w*100,o=(s[1]-i.y)/i.h*100;return W`t.stopPropagation()}
@click=${e=>{e.stopPropagation(),this._openRoomEdit(t)}}>
${this._t("room.settings_short")}
`}_renderRoomLabel(t,e,i,s){if(!t.name&&!this._markup)return G;const n=this._labelPos(t,e.id),o=this._scenePoint([n.x,n.y]),a=(o[0]-i.x)/i.w*100,r=(o[1]-i.y)/i.h*100,l=Math.min(1,s.opacity+.25),c=this._labelScale(t),h=[];if(t.area||t.settings?.temp_source||t.settings?.hum_source||s.labelLight){if(s.labelTemp){const e=this._roomTemp(t);null!=e&&h.push(W` ${e}° `)}if(s.labelHum){const e=this._roomHum(t);null!=e&&h.push(W` ${e}% `)}if(s.labelLqi&&t.area){const e=this._roomLqi(t.area);null!=e&&h.push(W` ${e} `)}if(s.labelLight){const e=(d=ho(this._renderPlanHass,this._renderDevices,t,this._virtualLights)).length?{on:d.filter(t=>t.on).length,total:d.length}:null;if(e){const t=0===e.on?this._t("roomcard.light_off"):e.on===e.total?this._t("roomcard.light_on"):this._t("roomcard.light_partial",{on:e.on,total:e.total});h.push(W` ${t} `)}}}var d;const p=!!t.area,u=!this._markup;return W`this._labelDown(i,t,e.id)}
@pointermove=${i=>this._labelMove(i,t,e.id)}
@pointerup=${()=>this._labelUp(t)}
@pointercancel=${()=>this._labelUp(t)}
>${t.name||(this._markup?this._t("room.unnamed"):"")}${p?W`{e.stopPropagation(),this._clickRoom(t)}:G}
@pointerdown=${u?t=>t.stopPropagation():G}> `:G}
${h.length?W`${h} `:G}
${"plan"===this._mode?["tl","tr","bl","br"].map(i=>W`this._rlResizeDown(i,t,e.id)}
@pointermove=${t=>this._rlResizeMove(t)}
@pointerup=${()=>this._rlResizeUp()}
@pointercancel=${()=>this._rlResizeUp()}> `):G}
`}get _measureAnchor(){return this._markup&&this._cursorPt?"draw"===this._tool&&this._path.length&&!this._contourClosed?this._path[this._path.length-1]:"split"===this._tool&&this._splitSel?.pts?.length?this._splitSel.pts[this._splitSel.pts.length-1]:null:null}_renderMeasureLabel(t){const e=this._measureAnchor,i=this._cursorPt,s=(i[0]-t.x)/t.w*100,n=(i[1]-t.y)/t.h*100,o=Ns(e,i),a=Math.round(10*o)/10,r=function(t,e,i=.001){if(t.length<2||e.length<2)return!1;const s=Math.abs(e[0]-t[0]),n=Math.abs(e[1]-t[1]);if(!Number.isFinite(s)||!Number.isFinite(n)||Math.hypot(s,n)<=i)return!1;const o=Math.max(s,n,1);return s<=i*o||n<=i*o||Math.abs(s-n)<=i*o}(e,i,2e-4*this._gridPitch);return W`
${this._fmtLen(e,i)} · ${a}°
`}get _decorMeasure(){const t=this._decorDraft;if(!t||"decor"!==this._mode)return null;const[e,i]=t.a,[s,n]=t.b;if(Math.abs(e-s)<1e-6&&Math.abs(i-n)<1e-6)return null;const o=(e+s)/2,a=(i+n)/2;if("line"===t.kind){const e=Ns(t.a,t.b);return{x:o,y:a,on45:Os(e),text:`${this._fmtLen(t.a,t.b)} · ${Math.round(10*e)/10}°`}}const r=this._fmtLen([e,i],[s,i]),l=this._fmtLen([s,i],[s,n]);if("ellipse"===t.kind){const t=this._fmtLen([0,0],[Math.abs(s-e)/2,0]),r=this._fmtLen([0,0],[0,Math.abs(n-i)/2]);return{x:o,y:a,on45:!1,text:Math.abs(Math.abs(s-e)-Math.abs(n-i))<1e-6?`R ${t}`:`Rx ${t} × Ry ${r}`}}return{x:o,y:a,on45:!1,text:`${r} × ${l} · ${ir(Er(Math.abs(s-e),this._cellCm,this._gridPitch)*Er(Math.abs(n-i),this._cellCm,this._gridPitch)/1e4,this._imperial)}`}}get _alignPoint(){if(this._markup){if("draw"===this._tool&&this._path.length&&!this._contourClosed&&this._cursorPt)return this._cursorPt;if("split"===this._tool&&this._splitSel?.pts?.length&&this._cursorPt)return this._cursorPt;if(this._drag?.id.startsWith("rl_")&&this._drag.moved){const t=this._drag.id.slice(3),e=this._spaceModel()?.rooms.find(e=>e.id===t);return e?(()=>{const t=this._labelPos(e,this._space);return[t.x,t.y]})():null}return null}if("devices"===this._mode&&this._drag?.moved){const t=this._devices.find(t=>t.id===this._drag.id);return t?(()=>{const e=this._pos(t);return[e.x,e.y]})():null}if("decor"===this._mode){if(this._decorDraft)return this._decorDraft.b;if(this._decorMove){const t=this._decorList.find(t=>t.id===this._decorMove.id);if(!t)return null;const e=ev,i=this._decorH;return"line"===t.kind?[t.x1*e,t.y1*i]:[t.x*e,t.y*i]}return null}return null}_alignCandidates(){const t=[],e=this._spaceModel();if(this._markup){if(!e)return t;if(this._drag?.id.startsWith("rl_")){const i=this._drag.id.slice(3);for(const s of e.rooms){if(!s.name||s.id===i)continue;const e=this._labelPos(s,this._space);t.push([e.x,e.y])}return t}for(const i of e.rooms){const e=hi(i);if(e)for(const i of e)t.push(i)}if("draw"===this._tool)for(const e of this._path)t.push(e);if("split"===this._tool&&this._splitSel?.pts)for(const e of this._splitSel.pts)t.push(e);return t}if("devices"===this._mode){for(const e of this._devices){if(e.space!==this._space||e.id===this._drag?.id||"ha_disabled"===e.bindingStatus?.kind)continue;const i=this._pos(e);t.push([i.x,i.y])}return t}if("decor"===this._mode){const e=this._decorMove?.id;return t.push(...this._decorSnapGeometry(e).points),this._decorDraft&&t.push(this._decorDraft.a),t}return t}_renderAlignGuides(){const t=this._alignPoint;if(!t)return j``;const e=this._drag?.id.startsWith("rl_")?.5*this._gridPitch:.05*this._gridPitch,i=function(t,e,i){let s=null,n=null;for(const o of e)if(!(Math.abs(o[0]-t[0])<1e-6&&Math.abs(o[1]-t[1])<1e-6)){if(Math.abs(o[0]-t[0])<=i){const e=Math.abs(o[1]-t[1]);e>1e-6&&(!s||e1e-6&&(!n||e
${i.map(e=>{const[i,o,a,r]="x"===e.axis?[e.at,e.from[1],e.at,t[1]+Math.sign(t[1]-e.from[1])*n]:[e.from[0],e.at,t[0]+Math.sign(t[0]-e.from[0])*n,e.at];return j`
`})}