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 r=this._sunRaysCache.rays,l=this._sunRaysCache.rims;if(!r.length)return e;const c=(h=function(t){const e=Math.min(90,Math.max(-90,Number(t)||0));let i=ja[ja.length-1][1];for(let t=1;t
- ${r.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`
- ${d.map(([t,e])=>j` `)}
-
-
- ${p.map(([t,e])=>j` `)}
- `})}
-
-
- ${r.map((t,e)=>t.paths?.length?t.paths.map(t=>j` `):t.polys.map(t=>j` `))}
- ${r.map((t,e)=>(l[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"}_checkOptimizeGeometry(t){return function(t,e={}){const i=(e.fingerprint||Dh)(t),s=Array.isArray(t?.spaces)?t.spaces:[],n=e.fallbackSpaceName||(t=>`Space ${t}`),o=e.prepareSpace||D_,a=e.wallPass||Dl,r=e.floorPass||Ml,l=[];for(let e=0;e0||h.physicalBodies.length>0;if(!h.space.rooms.length&&!d){l.push({...c,status:"not-applicable"});continue}let p=null;if(d){try{p=a(h.space.rooms,h.walls,h.openCuts,h.roomOpenings,h.wallKeyPitch,h.cellCm,h.gridPitch,h.coordScale,h.physicalBodies)}catch{l.push({...c,status:"failed",reason:"wall-exception"});continue}if(null==p){l.push({...c,status:"failed",reason:"wall-null"});continue}}if(h.space.rooms.length&&null==p?.paperGeom){let t;try{t=r(h.space.rooms,h.walls,h.openCuts,h.wallKeyPitch,h.cellCm,h.gridPitch,h.coordScale)}catch{l.push({...c,status:"failed",reason:"floor-exception"});continue}if(null==t){l.push({...c,status:"failed",reason:"floor-null"});continue}}l.push({...c,status:"ok"})}const c=l.filter(t=>"failed"===t.status);return{fingerprint:i,spaces:l,failures:c,ok:0===c.length}}(t,{fallbackSpaceName:t=>this._t("gs.align_preflight_space",{n:String(t)})})}async _runAlignToGrid(){let t=this._alignDialog;if(!t||t.busy||!this._serverCfg||!t.changed||!t.preflight?.ok)return;const e=Dh(t.config);if(t.preflight.fingerprint!==e){const e=this._checkOptimizeGeometry(t.config);if(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.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.wallsMerged+t.report.spansMerged+t.report.partitionsMerged),r:String(t.report.spaceRefsRemapped+t.report.roomRefsRemapped+t.report.positionsRemapped+t.report.markersDetached)}))}catch(t){this._alignDialog&&(this._alignDialog={...this._alignDialog,busy:!1}),"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:Yg}),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._t("backup.export_hint")}
-
this._backupExportDialog={...t,kind:"full",planOnly:!1}} />
- ${this._t("backup.full")}
-
this._backupExportDialog={...t,kind:"space"}} />
- ${e?this._t("backup.current_space_title",{title:e.title||e.id}):this._t("backup.no_current_space")}
- ${"space"===t.kind&&e?W`
- this._backupExportDialog={...t,planOnly:e.target.checked}} />
- ${this._t("backup.plan_only")} ${this._t("backup.plan_only_hint")}
- `:G}
-
${this._t("backup.privacy_warning")}
- ${t.error?W`
${t.error}
`:G}
-
-
- this._backupExportDialog=null}>${this._t("btn.cancel")}
-
-
- ${t.busy?"…":this._t("backup.download")}
-
-
- `}_renderBackupImportDialog(){const t=this._backupImportDialog,e=t.preview,i=e?.counts||{};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}
- ${"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._openPairs().flatMap(t=>t.segs),s=[...i],n=Math.max(this._cmToUnits(10),.5*this._gridPitch),o=t=>e.some(e=>this._pointInRoom(t,e.r)),a=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),a=Math.cos(i);return o([t.rx+s*n,t.ry+a*n])&&o([t.rx-s*n,t.ry-a*n])}),r=this._roomWallOpeningInputs(a,t);for(const t of r){const e=t.angle*Math.PI/180,i=Math.cos(e)*t.length/2,n=Math.sin(e)*t.length/2;s.push([t.x-i,t.y-n,t.x+i,t.y+n])}const l=new Set(a.filter(t=>t.partitionHost).map(t=>t.id)),c=[t.id,this._cfgEpoch,this._cellCm,this._gridPitch,[...l].sort().join(",")].join("|");this._lightPhysicalBodiesCache?.key!==c&&(this._lightPhysicalBodiesCache={key:c,all:Jl(t,this._cellCm,this._gridPitch,2e-4*this._gridPitch,this._partitionOpeningCuts(t,t=>l.has(t.id))).all});const h=this._lightPhysicalBodiesCache.all;let d=2166136261;const p=t=>{d^=Math.round(64*(Number.isFinite(t)?t:0)),d=Math.imul(d,16777619)>>>0},u=this._spaceWalls;p(this._cellCm),p(this._gridPitch),p(this._wallKeyPitch);for(const{poly:t}of e){p(t.length);for(const e of t)p(e[0]),p(e[1])}for(const t of s)for(const e of t)p(e);for(const t of h){p(t.length);for(const e of t)p(e[0]),p(e[1])}for(const t of u)p(t.cm),p(t.a?.[0]??0),p(t.a?.[1]??0),p(t.b?.[0]??0),p(t.b?.[1]??0);const _=d.toString(36),g=`${t.id}|${_}`;if(this._lightBarrierCache?.key===g)return this._lightBarrierCache.value;const m=.02*this._gridPitch,f=[],v=u.length||h.length?Dl(t.rooms,u,i,r,this._wallKeyPitch,this._cellCm,this._gridPitch,gm,h):null;if(v)for(const t of function(t){const e=[];for(const i of t||[])for(const t of i||[])t?.length>=4&&e.push(t.slice(0,-1).map(t=>[t[0],t[1]]));return e}(v.geom))f.push(...Hp(t));else for(const t of h)f.push(...Hp(t));for(const{poly:t}of e)for(const e of s.length?Ts(t,s,m):Hp(t))f.push(e);const y={occluders:Np(f),floor:e.map(t=>t.poly),fingerprint:_,masonryGeometry:v?.geom||[],opaqueBodies:h};return this._lightBarrierCache={key:g,value:y},y}_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})=>Es(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 g=$s(o.passive?{state:o.on?"on":"off",attributes:{}}:this._renderPlanHass.states[o.eid],e.marker?.glow_color,i.glow_light.c),m=Number(e.marker?.glow_radius_cm),f=Number.isFinite(m)&&m>0?m/this._cellCm*this._gridPitch:s,v=this._pos(e);if(ac([v.x,v.y],c,h)){this._forgetGlowSource(d);continue}const y=this._glowTransition(d,!!g);if(!y)continue;g&&this._glowLastAppearance.set(d,{c:g.c,alpha:Ss(g.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=im(this._glowClipCache,k);if(x.hit)w=x.value;else{const e=qp([v.x,v.y],f,a,96);w={lit:e.length>=3?ec([e],r,{onBoundsFailure:({boundIndex:e,phase:i})=>{const s=n[e]?.r;this._warnGlowGeometryFallback(t.id,l,s?.id||`#${e}`,i)}}):[]},sm(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 g=`${t.id}|`;for(const t of this._glowRenderedSources.keys())t.startsWith(g)&&!_.has(t)&&this._forgetGlowSource(t);if(!u.length)return j``;const m=this._spaceWalls,f=o.length===n.length?[]:this._openPairs().flatMap(t=>t.segs),v=this._wallUnionGeometry()?.roomGeom,y=o.length===n.length?null:o.map(({r:e,poly:i})=>{const s=m.length&&e.id&&fl(t.rooms,e.id,m,f,this._wallKeyPitch,this._cellCm,this._gridPitch,gm,v)||i,o=this._cleanFloor(e,s,t).path,a=Ti(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`
- ${""}
-
- ${mm.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.positionsUnresolved+e.nestedRefsUnresolved,h=e.deadSpaceIds.slice(0,10).join(", "),d=Math.max(0,e.deadSpaceIds.length-10);return W`this._alignDialog=null}>
-
- ${i?W`
-
${this._t("gs.align_preflight_failed",{spaces:o,more:r})}
-
${this._t("gs.align_preflight_hint")}
`:t.changed?W`
- ${e.moved?W`
${this._t("gs.align_count",{n:String(e.moved),total:String(e.total),cm:String(t.cm)})}
`: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}
-
${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)})}
- ${e.glowSpacesMigrated||e.glowRoomsMigrated?W`
${this._t("gs.optimize_glow_migration",{spaces:String(e.glowSpacesMigrated),rooms:String(e.glowRoomsMigrated)})}
`:G}
-
${this._t("gs.align_warn")}
`:W`
${this._t("gs.align_none")}
`}
- ${l?W`
${this._t("gs.optimize_references",{spaces:String(e.spaceRefsRemapped),rooms:String(e.roomRefsRemapped),positions:String(e.positionsRemapped),detached:String(e.markersDetached)})}
`:G}
- ${c||e.deadSpaceIds.length?W`
${this._t("gs.optimize_reference_warning",{positions:String(e.positionsUnresolved),nested:String(e.nestedRefsUnresolved),ids:h||"—",more:d?this._t("gs.optimize_reference_more",{n:String(d)}):""})}
`:G}
-
-
-
- this._alignDialog=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=em(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")}
- ${er(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:Yg})}
-
- ${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(Xt),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=Jt(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(Xt.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(pm,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){eg||rg(t);const e=tg,i=e.active.join(",");if(!i||i===sg)return;sg=i;const s=new Map(U_.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}`)}(Yg);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),g=this._resolvedGlowBase(s,d,_),m=d.showLqi??this._config.show_signal??!0,f=this._config.icon_size??2.5,v=f>8?2.5:f,y=hu(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),T=s.bg?this._display(s.bg.href):"",P=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),F=this._modeTransition.state?.from.presentedMode,E=!this._markup||!!R&&("view"===R.presentedMode||"devices"===R.presentedMode||"view"===F||"devices"===F),z=R?.stageColor||k,O=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)}>
- ${nr(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&&T?j`this._onBackdropLoaded(s.bg.href,T)}
- 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._openPairs(),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=Fs(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}):"",m?this._roomLqi(e.area):null,this._roomTemp(e),this._roomHum(e)))},c=this._markup&&(e.id===this._mergeSel||e.id===this._splitSel?.roomId),h=e.id&&!c?t.filter(t=>t.a.id===e.id||t.b.id===e.id).flatMap(t=>t.segs):[],p=c?[]:this._thickWallCuts(),u=h.concat(p);u.length&&(n+=" noedge");const g=i(e),f=this._spaceWalls,v=f.length&&e.id&&g&&fl(s.rooms,e.id,f,this._openPairs().flatMap(t=>t.segs),this._wallKeyPitch,this._cellCm,this._gridPitch,gm,this._wallUnionGeometry()?.roomGeom)||g,y=v?Ti(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!==g?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=u.length&&g?Ts(g,u,.02*this._gridPitch):null,C=M?j` `:G;return j`${S}${C}`})})()}
- ${this._renderRoomHoverFill(D)}
- ${this._renderOpeningTunnelFills(s,_)}
- ${this._renderGlowBaseRooms(s,g)}
- ${this._renderOpeningTunnelFills(s,g,"glow-base")}
- ${""}
- ${d.hideDecor&&"decor"!==this._mode?G:this._renderDecorLayer()}
- ${E?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._renderOpenWalls(d)}
- ${this._renderWallBodies(d)}
- ${this._markup?j`${this._renderPlanSnapOverlay()} `:G}
- ${this._markup?j`${this._renderOpeningPlacementPreview()} `:G}
- ${x?this._renderOpeningDimensionGuides(x):G}
- ${x?.guide?this._renderOpeningCenterTick(x.guide):G}
- ${this._renderRoomHoverOutline(D)}
- ${""}
- ${this._editing?this._renderOpenWalls(d):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,m))}
- ${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=Gh(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=Gh(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=tu(this._planHass,t,this._devices,e,this._fullRegistryHass);return{samples:i.samples,sourceKey:su(this._planHass,t,i)}}_stampActivity(t,e,i){let s=this._activityRt.get(t);s||(s=Cu(i||"",[]),this._activityRt.set(t,s)),null!=i&&(s.sources=i),Tu(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&&Du(r,a,o,window.clearTimeout.bind(window)):(r=Cu(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=Pu(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=Xh(this.hass.states[i||""]?.state),n=Uh(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"!==ed(t.marker?.vacuum)&&!n?.path.length;!s&&o.moving&&(o.endedTs=Date.now(),a&&o.lastPos&&(o.trail=Yh(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=Yh(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?Uh(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(Vh).filter(Boolean)),s=new Set;for(const e of t){const t=Vh(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||[]),g=n.candidates.filter(t=>_.has(t.entityId)||t.entityId===i.source),m=s?n.candidates.filter(t=>t.entityId.startsWith("camera.")&&!g.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")}
-
- ${g.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?m.length?m.map(v):W`${this._t("vac.all_cameras_empty")}
`:G}
-
-
-
-
- ${d?W`
this._vacAutoCalibrate(e)}>${this._t("vac.autocal")} `:G}
- ${l?W`
this._vacStartFit(e)}>${this._t("vac.fit")} `:G}
-
${this._t("vac.documentation")}
-
- ${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=Lh(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?Uh(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=Kh(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=Qh(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?Uh(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&&Qh(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=Zh(c),[d,p]=zh(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,Zh(t.p));this._vacFit=null,e&&this._showToast(this._t("vac.cal_done"))}_vacFitTurn(t){const e=this._vacFit;if(!e)return;const i=Uh(this.hass?.states[e.source]?.attributes),s=this._vacGhostCentre(i?.rooms||[]),n={...e.p,...t};this._vacFit={...e,p:td(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=Uh(this.hass?.states[i.source]?.attributes),e=this._vacGhostCentre(t?.rooms||[]),a=Zh(s.p0),[r,l]=zh(a,e[0],e[1]),[c,h]=zh(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,g=Math.max(.05,_/d),m={...s.p0,s:s.p0.s*g};this._vacFit={...i,p:td(m,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=Uh(this._renderPlanHass?.states?.[e.source]?.attributes);if(!i)return G;const s=Zh(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])=>zh(s,t,e));e.forEach(([t,e])=>{o.push(t),a.push(e)});const[i,r]=zh(s,t.cx,t.cy);n.push(j`
- ${t.name} `)}let r=G;if(i.pos){const[e,n]=zh(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??Uh(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=ed(i.marker?.vacuum),u="always"===p||"cleaning"===p&&d,_=t?.server??this._vacSrvTrails[i.id],g=_?.current?.map_id===l&&Array.isArray(_.current.points)?_.current:null,m=_?.previous?.map_id===l&&Array.isArray(_.previous.points)?_.previous:null;if("always"===p&&m&&m.points.length>1){const t=m.points.map(([t,e])=>{const[i,s]=zh(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=Wh(r,g,h?.trail||[]),e=!d||"integration"!==t.source&&"server"!==t.source?t.path:jh(t.path);if(e.length){const t=e.map(t=>t.map(([t,e],i)=>{const[s,n]=zh(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]=zh(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]=zh(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=Kp(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&&fl(i.rooms,t.id,s,this._openPairs().flatMap(t=>t.segs),this._wallKeyPitch,this._cellCm,this._gridPitch,gm,this._wallUnionGeometry()?.roomGeom)||e,o=this._cleanFloor(t,n),a=this._cellCm/this._gridPitch;return Ia(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)||!i.device_id&&n.entities.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=go(t,s.ents);null!=e&&a.push(e)}if(o.size>0&&(o.has(i)||s.ents.some(t=>o.has(t)))){const e=mo(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=zs(t.settings?.name_scale),this._roomLabelScale=zs(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*gm,y:i.y*gm};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},xm(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=Cc(this._drag.ox+c),p=Cc(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},xm(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/gm,y:o.y/gm,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=Os(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=Os(t.a,t.b);return{x:o,y:a,on45:Ns(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} · ${Ia(hr(Math.abs(s-e),this._cellCm,this._gridPitch)*hr(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=gm,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`
- `})}
- `}_renderOpeningCenterTick(t){const e=(t.angle+90)*Math.PI/180,i=hc(15,this._cellCm);return j` `}_renderOpeningDimensionGuides(t){const e=t.labels.flatMap(t=>t.dimension?[t.dimension]:[]);if(!e.length)return j``;const i=this._cssPxToRender(4);return j`
- ${e.map(t=>{const e=-t.axis[1],s=t.axis[0],n=(t,n)=>j` `;return j`
-
- ${n(t.from,"from")}${n(t.to,"to")}
- `})}
- `}_roomCenter(t){if(t.poly){const e=t.poly.length;return[t.poly.reduce((t,e)=>t+e[0],0)/e,t.poly.reduce((t,e)=>t+e[1],0)/e]}return[t.x+t.w/2,t.y+.1*Math.min(t.w,t.h)]}_openingAmt(t){const e=t.contact&&this._renderOpeningEntityAvailable(t.contact)?this._renderPlanHass.states[t.contact]?.state:null;return gi(t.type,e,!!t.invert)}_planEntityAvailable(t){return!!t&&(!ko(this._fullRegistryHass,t,wo(this._markers))&&"active"===this._bindingStatus("entity:"+t).kind)}_renderEntityAvailable(t){return!!t&&(!ko(this._renderPlanHass,t,wo(this._markers))&&(!!this._renderPlanHass.entities?.[t]&&!!this._renderPlanHass.states?.[t]))}_openingEntityAvailable(t){return function(t,e,i=An(t)){return!!e&&"active"===Bn(t,`entity:${e}`,i).kind}(this.hass,t,this._haRegistry)}_renderOpeningEntityAvailable(t){return e=this._renderPlanHass,!!(i=t)&&!!e?.states?.[i];var e,i}_renderOpeningPlacementPreview(){const t=this._openingPreview;if(!t)return j``;const e={type:t.type,length:t.renderedLength,angle:t.angle,amount:gi(t.type,null),flipH:t.flipH,flipV:t.flipV,base:"var(--hp-open)",tone:"var(--hp-open)",cellCm:this._cellCm,gridPitch:this._gridPitch,face:t.face},i="passage"===t.type?function(t,e){const i=Math.max(0,t.renderedLength)/2,s=Math.max(0,t.target.physicalHalfWidth),n=s+.18*Math.max(0,e),o=t=>({x1:t,y1:-n,x2:t,y2:n});return{rect:{x:-i,y:s?-s:0,width:2*i,height:2*s},boundaries:[o(-i),o(i)]}}(t,hc(this._gridPitch,this._cellCm)):null;return j`
- ${i?j`
-
- ${i.boundaries.map(t=>j`
- `)}
- `:Up(e)}
-
- `}_renderOpenings(t){const e=this._openingsR;if(!e.length)return j``;const i=this._spaceModel();if(!i)return j``;const s=t.color,n=this._spaceWalls,o=this._openPairs().flatMap(t=>t.segs),a=this._openingWallIndexFor(i,o).value;return j`${e.map(t=>{if(t.orphanReason)return j`{e.stopPropagation(),this._editOpening(t)}}>
-
- !
- `;const e=this._openingAmt(t),i=e>0&&!!t.contact&&this._renderOpeningEntityAvailable(t.contact)?"var(--hp-open)":s,o="gate"===t.type?!t.flip_v:t.flip_v,r=t.partitionHost||n.length||"gate"===t.type?this._openingFace(t,a,!!o):{ox:0,oy:0,cm:0,side:-1},l={type:t.type,length:t.rlen,angle:t.angle,amount:e,flipH:!!t.flip_h,flipV:!!t.flip_v,base:s,tone:i,cellCm:this._cellCm,gridPitch:this._gridPitch,face:r},{half:c,outlineHalf:h,hitHalf:d}=jp(l),p=hc(10,this._cellCm),u=hc(12,this._cellCm);return j`
- ${Up(l)}
-
- this._opClick(e,t)}
- @pointerdown=${e=>this._opPointerDown(e,t)}
- @pointermove=${e=>this._opPointerMove(e,t)}
- @pointerup=${e=>this._opPointerUp(e,t)}
- @pointercancel=${e=>this._opPointerUp(e,t)}>
- `})}`}_renderOpeningLocks(t){const e=this._openingsR.filter(t=>!t.orphanReason&&("door"===t.type||"gate"===t.type)&&t.lock&&this._renderOpeningEntityAvailable(t.lock));if(!e.length)return W``;const i=this._spaceModel();if(!i)return W``;const s=this._openPairs().flatMap(t=>t.segs),n=this._openingWallIndexFor(i,s).value;return W`${e.map(e=>{const i=this._renderPlanHass.states[e.lock]?.state,s="locked"===i,o=s||["unlocked","open","opening","unlocking","locking"].includes(String(i)),a=(e.angle+90)*Math.PI/180,r="gate"===e.type?this._openingFace(e,n,!e.flip_v):null,l=hc(16,this._cellCm),c=r?-l*r.side:l*(e.flip_v?-1:1),h=e.rx+Math.cos(a)*c,d=e.ry+Math.sin(a)*c,p=this._scenePoint([h,d]),u=(p[0]-t.x)/t.w*100,_=(p[1]-t.y)/t.h*100;return W`{t.stopPropagation(),"view"===this._mode&&(this._openingInfo=e)}}>
-
-
-
-
-
-
`})}`}_lockAction(t,e){if(this._openingEntityAvailable(t)){if("unlock"===e){const e=this.hass?.states?.[t]?.attributes?.friendly_name||t;if(!confirm(this._t("confirm.unlock",{name:e})))return}this.hass?.callService?.("lock",e,{entity_id:t})}}_renderOpeningInfoCard(){const t=this._openingInfo,e="passage"!==t.type&&t.contact&&this._openingEntityAvailable(t.contact)?t.contact:null,i=("door"===t.type||"gate"===t.type)&&t.lock&&this._openingEntityAvailable(t.lock)?t.lock:null,s=e?this.hass.states[e]?.state:null,n=this._openingAmt(t),o=i?this.hass.states[i]?.state:null,a="door"===t.type?"opening.door":"gate"===t.type?"opening.gate":"passage"===t.type?"opening.passage":"opening.window",r="door"===t.type?"mdi:door":"gate"===t.type?"mdi:gate":"passage"===t.type?"mdi:arch":"mdi:window-closed-variant",l="gate"===t.type?n>0?"mdi:gate-open":"mdi:gate":n>0?"mdi:door-open":"mdi:door-closed",c=(t,e,i,s="")=>W`${e} ${i}
`;return W`this._openingInfo=null}>
-
- ${e?c(l,this._t("opening.contact_label"),"unavailable"===s||null==s?this._t("opening.state_unknown"):this._t(n>0?"opening.open":"opening.closed"),n>0?"warn":"ok"):G}
- ${i?c("locked"===o?"mdi:lock":"mdi:lock-open-variant",this._t("opening.lock_label"),"locked"===o?this._t("opening.locked"):["unlocked","open"].includes(String(o))?this._t("opening.unlocked"):this._t("opening.state_unknown"),"locked"===o?"ok":"warn"):G}
- ${i&&("locked"===o||["unlocked","open"].includes(String(o)))?W`
this._lockAction(i,"locked"===o?"unlock":"lock")}>
-
- ${this._t("locked"===o?"opening.unlock_action":"opening.lock_action")}
- `:i&&["locking","unlocking"].includes(String(o))?W`
- ${this._t("opening.lock_pending")}
- `:G}
- ${e||i?G:W`
${this._t("opening.no_entities")}
`}
-
-
-
- this._openingInfo=null}>${this._t("btn.close")}
-
- `}_renderOpeningDialog(){const t=this._openingDialog,e=this._spaceModel()?.partitions||[],i=t.id?this._curSpaceCfg?.openings?.find(e=>e.id===t.id):null,s={id:t.id||"preview",type:t.type,x:t.x/gm,y:t.y/this._spaceH,angle:t.angle,length:i&&!t.lengthTouched?i.length:this._cmToUnits(Math.max(20,t.lengthCm))/gm,...t.host?{host:t.host}:{}},n=Fd(i,s),o=t.host?n?Ad(s,e,gm,this._cellCm,this._gridPitch):Id(s,e,gm,this._cellCm,this._gridPitch):null,a="does-not-fit-jamb"===o?.reason,r=t.host?e.find(e=>e.id===t.host.id):null,l=r?li(r.cm/2,this._imperial):"",c=!!t.host&&!o?.resolved&&!a,h="gate"===t.type?"mdi:gate":"window"===t.type?"mdi:window-closed-variant":"passage"===t.type?"mdi:arch":"mdi:door",d=(t,e,i)=>W`i(t.target.value)}>
- ${this._t("opening.none")}
- ${t.map(t=>W`${t.label} `)}
- `;return W`this._openingDialog=null}>
-
- ${t.host?W`
${this._t("opening.host_partition")}
-
- ${c||a?W` `:G}
- ${c?this._t("opening.partition_orphan"):a?this._t("opening.partition_jamb_margin",{distance:l}):this._t("opening.host_partition")}
-
`:G}
-
${this._t("opening.type_label")}
-
this._openingDialog={...t,type:"window",lengthCm:t.id?t.lengthCm:Cg("window")}} />
- ${this._t("opening.window")}
-
this._openingDialog={...t,type:"door",lengthCm:t.id?t.lengthCm:Cg("door")}} />
- ${this._t("opening.door")}
-
this._openingDialog={...t,type:"passage",lengthCm:t.id?t.lengthCm:Cg("passage")}} />
- ${this._t("opening.passage")}
-
this._openingDialog={...t,type:"gate",lengthCm:t.id?t.lengthCm:Cg("gate"),flipH:!1}} />
- ${this._t("opening.gate")}
-
-
${this._t("opening.length_label")}
-
{const i=em(e.target.value);null!=i&&(this._openingDialog={...t,lengthCm:i,lengthTouched:!0})}} />
-
- ${"passage"===t.type&&(t.contact||t.lock)?W`
-
- ${this._t("opening.passage_binding_warning")}
-
`:G}
-
- ${"passage"!==t.type?W`
${this._t("opening.contact_label")}
- ${d(this._contactCandidates(),t.contact,e=>this._openingDialog={...t,contact:e})}
- ${t.contact?W`
${this._boolInput(t.invert,e=>this._openingDialog={...t,invert:e})}
- ${this._t("opening.invert")} `:G}`:G}
-
- ${"door"===t.type||"gate"===t.type?W`
${this._t("opening.lock_label")}
- ${d(this._lockCandidates(),t.lock,e=>this._openingDialog={...t,lock:e})}`:G}
-
- ${"gate"!==t.type&&"passage"!==t.type?W`
${this._boolInput(t.flipH,e=>this._openingDialog={...t,flipH:e})}
- ${this._t("opening.flip_h")} `:G}
- ${"passage"!==t.type?W`
${this._boolInput(t.flipV,e=>this._openingDialog={...t,flipV:e})}
- ${this._t("opening.flip_v")} `:G}
-
-
- `}_gridLevels(){const t=this._stageEl,e=this._viewOr(this._baseVb()),i=t&&t.clientWidth&&e.w?t.clientWidth/e.w:1;return function(t,e,i=7){if(!(t>0&&e>0&&Number.isFinite(e)))return null;const s=qc.find(s=>t*s*e>=i);if(void 0===s)return null;const n=qc.find(t=>t>=5*s)??5*s;return{fine:s,coarse:n}}(this._gridPitch,i)}_renderMarkupDefs(t){const e=this._gridLevels();if(!e)return j` `;const i=this._gridPitch*e.fine,s=this._gridPitch*e.coarse,n=this._gridPitch*e.fine*.14;return j`
-
-
-
-
-
-
-
-
-
-
-
-
-
- `}_renderPhysicalEditorLayer(){const t=this._spaceModel();if(!t)return j``;const e=this._gridPitch,i=this._viewOr(this._baseVb()),s=this._stageEl,n=s?.clientWidth?i.w/s.clientWidth:e/8,o=Math.max(.22*e,8*n),a=Math.max(o,12*n),r=t=>`M ${t.map(t=>`${t[0]} ${t[1]}`).join(" L ")} Z`,l=(t,e)=>this._physicalSel?.kind===t&&this._physicalSel.id===e||"column"===t&&this._duplicateColumnId===e,c=(t.room_drafts||[]).flatMap(t=>t.points.slice(0,-1).map((e,i)=>{const s=t.points[i+1],o=xr(t.segments[i]?.cm||15,this._cellCm,this._gridPitch);return j`{this._physicalSel={kind:"draft",id:t.id,segment:i},this._registerPhysicalTap("draft",t.id,i)}}> `})),h=(t.partitions||[]).map(t=>{const e=Kl(t.a,t.b,t.cm,this._cellCm,this._gridPitch);return e?j`this._physicalDown(e,"partition",t.id)}
- @pointermove=${t=>this._physicalMove(t)}
- @pointerup=${t=>this._physicalUp(t)}> `:G}),d=(t.wall_columns||[]).map(t=>{const e=Yl(this._physicalRotate?.id===t.id?{...t,angle:this._physicalRotate.angle}:t,this._cellCm,this._gridPitch);return j`this._physicalDown(e,"column",t.id)}
- @pointermove=${t=>this._physicalMove(t)}
- @pointerup=${t=>this._physicalUp(t)}> `}),p=this._physicalDrag,u=(()=>{if(!p?.moved)return G;const t="partition"===p.kind?Kl(p.base.a,p.base.b,p.base.cm,this._cellCm,this._gridPitch):Yl(p.base,this._cellCm,this._gridPitch);return t?j` `:G})(),_=(()=>{const i=this._physicalSel;if(!i)return G;if("draft"===i.kind){const e=t.room_drafts.find(t=>t.id===i.id);return e?j`
- t.join(",")).join(" ")}>
- ${e.points.map(t=>j` `)}
- `:G}if("partition"===i.kind){const e=t.partitions.find(t=>t.id===i.id);if(!e)return G;const s=Kl(e.a,e.b,e.cm,this._cellCm,this._gridPitch);if(!s)return G;const n=(e.a[0]+e.b[0])/2,a=(e.a[1]+e.b[1])/2;return j`
-
-
-
-
- `}const s=t.wall_columns.find(t=>t.id===i.id);if(!s)return G;const l=this._physicalRotate?.id===s.id?{...s,angle:this._physicalRotate.angle}:s,c=Yl(l,this._cellCm,this._gridPitch);if("square"!==l.shape)return j`
-
-
- `;const h=xr(l.cm,this._cellCm,this._gridPitch),d=Wl(l.angle)*Math.PI/180,p=Math.sin(d),u=-Math.cos(d),_=[l.center[0]+p*h/2,l.center[1]+u*h/2],g=[_[0]+p*Math.max(e,24*n),_[1]+u*Math.max(e,24*n)];return j`
-
-
-
- this._physicalRotateDown(t,s)}
- @pointermove=${t=>this._physicalRotateMove(t)}
- @pointerup=${t=>this._physicalRotateUp(t)}>
- `})();return j`${c}${h}${d}${u}${_} `}_renderPlanSnapOverlay(){if(!this._markup||"draw"!==this._tool)return j``;const t=this._planSnapGeometrySnapshot().value,e=this._activePlanSnapCandidate,i=new Set(this._activePlanSnapConflicts.map(t=>t.key)),s=xr(5,this._cellCm,this._gridPitch),n=xr(10,this._cellCm,this._gridPitch);return j`
- ${mt([t,s,[...i].sort().join("|")],()=>j`
- ${t.segments.map(t=>j` `)}
- ${t.endpoints.map(t=>j` `)}
- `)}
-
- `}_syncPlanSnapActiveMarker(t){const e=this.renderRoot?.querySelector('[data-hp="plan-snap-active-marker"]');if(e){if(e.setAttribute("class",`plan-snap-node${t?" active":""}${"line"===t?.kind?" dynamic":""}`),e.setAttribute("data-active",t?"true":"false"),e.setAttribute("visibility",t?"visible":"hidden"),!t)return e.removeAttribute("data-kind"),void e.removeAttribute("data-key");e.setAttribute("data-kind",t.kind),e.setAttribute("data-key",t.key),e.setAttribute("cx",String(t.point[0])),e.setAttribute("cy",String(t.point[1])),e.setAttribute("r",String(xr(10,this._cellCm,this._gridPitch)))}}_syncPlanSnapConflictMarkers(t){const e=new Set(t.map(t=>t.key));for(const t of this.renderRoot?.querySelectorAll('.plan-snap-node[data-kind="endpoint"]')||[])t.setAttribute("class","plan-snap-node"+(e.has(t.dataset.key||"")?" conflict":""))}_planSnapPhysicalSegment(t){let e=0;const i=this._spaceModel();if(!i)return null;if("partition"===t.sourceKind)e=Number(i.partitions.find(e=>e.id===t.sourceId)?.cm)||0;else if("draft"===t.sourceKind){const s=/^(.*):(\d+)$/.exec(t.sourceId),n=s?i.room_drafts.find(t=>t.id===s[1]):null;e=n&&s&&Number(n.segments[Number(s[2])]?.cm)||0}else e=_l(i.rooms,this._spaceWalls,this._openCuts(),[t.a[0],t.a[1],t.b[0],t.b[1]],this._wallKeyPitch,this._cellCm,this._gridPitch,gm);return e>0?{a:[...t.a],b:[...t.b],halfDepth:xr(e,this._cellCm,this._gridPitch)/2}:null}_drawPreviewJoinPatchD(t,e){if(t.length<2)return"";const i=[];for(let s=0;s+10&&i.push({a:t[s],b:t[s+1],halfDepth:e[s]});if(!i.length)return"";const s=2e-4*this._gridPitch,n=this._planSnapGeometrySnapshot().value.segments.filter(e=>t.some(t=>Hs(t,[e.a[0],e.a[1],e.b[0],e.b[1]])<=s)).map(t=>this._planSnapPhysicalSegment(t)).filter(t=>!!t);return Ur([...i,...n],s).map(t=>`M ${t.map(t=>`${t[0]} ${t[1]}`).join(" L ")} Z`).join(" ")}_renderMarkupLayer(t){const e=this._openPairs().flatMap(t=>t.segs),i=this._thickWallCuts(),s=e.concat(i),n=s.length?Ds(this._segments,s,.02*this._gridPitch):this._segments,o=this._path,a=this._gridPitch,r=this._viewOr(this._baseVb()),l="draw"===this._tool?this._drawWallCm:null,c=(()=>"draw"===this._tool&&o.length&&null!=l&&l>0?this._contourClosed?o:this._cursorPt?[...o,this._cursorPt]:o.length>=2?o:null:null)(),h=c?ep(c.length-1,this._contourClosed?[...this._draftSegmentCms,this._closingWallCm??void 0]:this._draftSegmentCms,l,fr).map(t=>xr(t,this._cellCm,this._gridPitch)/2):[],d=c?Gr(c,xr(l,this._cellCm,this._gridPitch)/2,this._contourClosed,h):"",p=c?this._drawPreviewJoinPatchD(c,h):"",u=this._wallFaceBatch?.candidates[this._wallFaceBatch.index]?.repair||this._wallRepairDiagnostic;return j`
- ${this._gridLevels()?j` `:G}
- ${n.map(t=>j` `)}
- ${this._renderPhysicalEditorLayer()}
- ${"column"===this._tool&&this._cursorPt&&this._drawWallCm?j``M ${Yl({shape:"square",center:this._cursorPt,cm:this._drawWallCm},this._cellCm,this._gridPitch).map(t=>`${t[0]} ${t[1]}`).join(" L ")} Z`)()}> `:G}
- ${d?j`
- `:G}
- ${p?j`
- `:G}
- ${u?j` `:G}
- ${o.length>1?j` `:G}
- ${o.length&&this._cursorPt&&"draw"===this._tool&&!this._contourClosed?j`
- ${this._activePlanSnapCandidate||this._activePlanSnapConflicts.length?G:j` `}`:G}
- ${o.map((t,e)=>j` `)}
- ${"split"===this._tool&&this._splitSel?.pts?.length?j`${this._splitSel.pts.length>1?j` `:G}
- ${this._splitSel.pts.map((t,e)=>j` `)}
- ${this._cursorPt?j` `:G}`:G}
- `}_renderPartitionDeleteDialog(){const t=this._partitionDeleteDialog,e="mi"===this.hass?.config?.unit_system?.length;return W`this._partitionDeleteDialog=null}>
-
-
${this._t("confirm.delete_partition_openings_body",{count:t.openings.length})}
-
- ${t.openings.map(t=>W`${this._t("confirm.delete_partition_openings_item",{type:this._t(`opening.${t.type}`),length:li(t.length*gm/this._gridPitch*this._cellCm,e)})} `)}
-
-
-
- this._partitionDeleteDialog=null}>
- ${this._t("btn.cancel")}
-
-
-
- ${this._t("btn.delete")}
-
-
- `}_renderRoomDeleteDialog(){const t=this._roomDeleteDialog;return W`this._roomDeleteDialog=null}>
-
-
${this._t("confirm.delete_room_body")}
-
-
- this._roomDeleteDialog=null}>
- ${this._t("btn.cancel")}
-
-
- this._confirmRoomDelete(!0)}>
- ${this._t("btn.delete_room_keep_walls")}
-
- this._confirmRoomDelete(!1)}>
- ${this._t("btn.delete_room_with_walls")}
-
-
- `}_renderPhysicalDialog(){const t=this._physicalDialog,e="column"===t.kind;return W`this._physicalDialog=null}>
-
- ${e?W`
${this._t("physical.shape")}
-
{const i=e.target.value;this._physicalDialog={...t,shape:i}}}>
- ${this._t("physical.square")}
- ${this._t("physical.circle")}
- `:G}
-
${this._t(e?"circle"===t.shape?"physical.diameter":"physical.side":"wallthick.field")}
-
this._physicalDialog={...t,cm:e.target.value}} />
- ${this._t(this._imperial?"wallthick.unit_in":"wallthick.unit_cm")}
- ${e&&"square"===t.shape?W`
-
${this._t("physical.rotation")}
-
this._physicalDialog={...t,angle:e.target.value}} />`:G}
- ${t.length?W`
${this._t("physical.length")}: ${t.length}
`:G}
-
-
- `}_renderMarkupBar(){const t=this._geometryHistory.undoName,e=this._geometryHistory.redoName,i="boundary"===this._tool&&!!this._openWallAnchor,s=i?this._t("markup.boundary_cancel"):t?this._t("history.undo_named",{name:t}):this._t("history.undo_empty"),n=i?this._t("markup.boundary_cancel"):e?this._t("history.redo_named",{name:e}):this._t("history.redo_empty");return W`
-
-
-
- this._activateMarkupTool("select")}
- title=${this._t("title.markup_select")}>
- ${this._t("markup.select")}
-
- this._activateMarkupTool("draw")}
- title=${this._t("title.markup_add")}>
- ${this._t("markup.add")}
-
- this._activateMarkupTool("column")}
- title=${this._t("title.markup_column")}>
- ${this._t("markup.column")}
-
-
- this._activateMarkupTool("merge")}
- title=${this._t("title.markup_merge")}>
- ${this._t("markup.merge")}
-
- this._activateMarkupTool("split")}
- title=${this._t("title.markup_split")}>
- ${this._t("markup.split")}
-
- this._activateMarkupTool("resize")}
- title=${this._t("title.markup_resize")}>
- ${this._t("markup.resize")}
-
- ${this._editorToolbarGroups.map(t=>this._renderEditorGroupLauncher(t))}
- this._activateMarkupTool("boundary")}
- aria-pressed=${"boundary"===this._tool?"true":"false"}
- title=${this._t("title.markup_boundary")}>
- ${this._t("markup.boundary")}
-
- this._activateMarkupTool("wallthick")}
- title=${this._t("title.markup_wallthick")}>
- ${this._t("markup.wallthick")}
-
- this._activateMarkupTool("delroom")}
- title=${this._t("title.markup_delroom")}>
- ${this._t("markup.delete_room")}
-
-
-
-
-
-
-
-
-
- this._setMode("view")}>
-
-
-
-
`}_renderDevicesBar(){return W`
-
-
- this._openMarkerDialog()} title=${this._t("title.add_device")}>
- ${this._t("devbar.add")}
-
-
- ${this._t("devbar.show_all")}
-
-
- ${this._t("devbar.rules")}
-
- ${this._editorToolbarGroups.map(t=>this._renderEditorGroupLauncher(t))}
-
-
- this._setMode("view")}>
-
-
-
-
`}_cardEntities(t){const e=this._planHass,i=[],s=new Set,n=t=>{if(!t||s.has(t)||!e.states[t])return;const n=e.entities[t];if("config"===n?.entity_category||"diagnostic"===n?.entity_category)return;s.add(t);const o=t.split(".")[0];["light","switch","fan","humidifier","siren","input_boolean"].includes(o)?i.push({eid:t,kind:"toggle"}):["cover","valve","lock","climate","media_player","vacuum","water_heater"].includes(o)?i.push({eid:t,kind:"open"}):["sensor","binary_sensor","number","select"].includes(o)&&i.push({eid:t,kind:"value"})};for(const i of ho(e,this._devices,null,this._virtualLights))if(i.device.id===t.id)for(const t of[...i.serviceEids,...i.stateEids])n(t);t.primary&&n(t.primary);for(const e of t.entities)n(e);return i.slice(0,12)}_cardToggle(t){const e=t.split(".")[0];"lock"!==e&&"alarm_control_panel"!==e&&this._planEntityAvailable(t)&&this.hass.callService("homeassistant","toggle",{entity_id:t}).catch(t=>this._showToast(this._t("toast.error",{err:this._errText(t)})))}_renderInfoCard(){const t=this._infoCard,e=t.primary?this.hass.states[t.primary]:void 0,i=e?Ji(this.hass,t.primary)?.text??e.state:null,s=(t.controls??t.marker?.controls??[]).filter(Ms).filter(t=>this._planEntityAvailable(t));return W`
-
- ${(()=>{const e=this._cardEntities(t);return e.length?W`
- ${e.map(({eid:t,kind:e})=>{const i=this.hass.states[t],s=this.hass.entities[t]?.name||i?.attributes?.friendly_name||t,n=i?Ji(this.hass,t)?.text??i.state:"",o="on"===i?.state||["open","unlocked","playing","cleaning"].includes(i?.state);return W`
-
- ${s}
- ${"toggle"===e?W`this._cardToggle(t)}>${n} `:"open"===e?W`{this._closeInfoCard(),this._openMoreInfo(t)}}>${n} `:W`${n} `}
-
`})}
-
`:G})()}
- ${t.model?W`
${this._t("info.model")} ${t.model}
`:G}
- ${i&&!this._cardEntities(t).length?W`
${this._t("info.state")} ${i}
`:G}
- ${Hi(t.link)?W`
`:G}
- ${t.description?W`
${t.description}
`:G}
- ${t.pdfs&&t.pdfs.length?W`
${this._t("info.manuals")}
- ${t.pdfs.map(t=>W`
- ${t.name} `)} `:G}
- ${s.length?W`
${this._t("info.controls")}
-
- ${s.map(t=>{const e=this.hass.states[t],i="on"===e?.state;return W`
-
- ${e?.attributes?.friendly_name||t} `})}
-
`:G}
- ${t.model||i||t.link||t.description||t.pdfs&&t.pdfs.length||s.length?G:W`
${this._t("info.none")}
`}
-
-
- `}_markerValueBadgeFields(t){return(e={touched:t.valueBadgeTouched,originalHas:t.originalHasValueBadge,original:t.originalValueBadge,enabled:t.valueBadgeEnabled,source:t.valueBadgeSource,position:t.valueBadgePosition}).touched?{value_badge:{enabled:e.enabled,source:e.source,position:e.position}}:e.originalHas?{value_badge:e.original}:{};var e}_markerDraft(t){if("ha"===t.bindingMode&&(!t.binding||"virtual"===t.binding))return null;const e=qs(t.room),i=Ei(t.binding,t.devId,()=>"__hp_device_preview__"),s=this._markers.find(e=>e.id===i||e.id===t.devId),n=Zn(t.binding,t.controls,this._bindingEntities(t.binding)),o=this._effectiveStoredTapAction(t),a={id:i,binding:t.binding,name:t.name.trim()||null,icon:t.icon||null,display:"badge"!==t.display?t.display:null,ripple_color:"icon_ripple"===t.display&&t.rippleColor?t.rippleColor:null,ripple_size:"icon_ripple"===t.display&&1.5!==t.rippleSize?t.rippleSize:null,size:1!==t.size?t.size:null,angle:t.angle||null,...this._markerTapActionFields(t),...this._markerToggleEntityFields(t),tap_target:"run"===o&&t.tapTarget||null,tap_confirm:!!t.tapConfirm||null,controls:n.length?n:null,...this._markerLightFields(t),...this._markerValueBadgeFields(t),use_climate_temp:!!t.useClimateTemp||null,glow_radius_cm:(()=>{const e=em(t.glowRadius);return null==e||e<=0?null:Math.round(this._imperial?30.48*e:100*e)})(),model:t.model.trim()||null,link:t.link.trim()||null,description:t.description.trim()||null,pdfs:t.pdfs,hidden:t.hideFromPlan,vacuum:s?.vacuum||null};return("virtual"===t.binding||t.room)&&(a.space=e?.space||("virtual"===t.binding?this._space:null),a.area=e?.area||null,a.room_id=e?.roomId||null),a}_markerPreviewDevice(t){const e=this._markerDraft(t);if(!e)return null;const i=`${this._haRegistry.revision}\n${JSON.stringify(e)}`;if(this._markerPreviewMemo?.key===i)return this._markerPreviewMemo.device;const s=function(t){const{marker:e,...i}=t;return So({...i,markers:[e]}).find(t=>t.id===e.id)||null}({hass:this.hass,registry:this._haRegistry,areaToSpace:Object.fromEntries(Object.entries(this._areaToSpace).map(([t,e])=>[t,e.space])),marker:e,settings:this._settings,excluded:this._excluded,showAll:this._showAll,firstSpaceId:this._model[0]?.id||this._space,loc:t=>this._t(t),iconRules:this._iconRules});return this._markerPreviewMemo={key:i,device:s},s}_markerPreviewDevices(t){const e=this._markerPreviewDevicesMemo;if(e?.base===this._devices&&e.preview===t)return e.devices;const i=[...this._devices.filter(e=>e.id!==t.id),t];return this._markerPreviewDevicesMemo={base:this._devices,preview:t,devices:i},i}_toggleIntent(t,e=this._devices){return $d({hass:this._planHass,registryHass:this._fullRegistryHass,devices:e,device:t,virtualLights:this._virtualLights})}_toggleIntentForDialog(t){const e=this._markerPreviewDevice(t);if(!e)return null;const i=this._markerPreviewDevices(e);return this._toggleIntent(e,i)}_toggleStateText(t,e){const i=this._planHass?.states?.[t]||this.hass?.states?.[t];try{return i&&"function"==typeof this.hass?.formatEntityState?this.hass.formatEntityState(i):e}catch{return e}}_toggleConfirmationStateText(t){const e=String(t.state||"unknown"),i=t.entityId?this._toggleStateText(t.entityId,e):e;if(i.trim().toLocaleLowerCase()!==e.trim().toLocaleLowerCase())return i;const s={on:"confirm.state_on",off:"confirm.state_off",open:"confirm.state_open",closed:"confirm.state_closed",opening:"confirm.state_opening",closing:"confirm.state_closing",unknown:"confirm.state_unknown"}[e];return s?this._t(s):e.replaceAll("_"," ").replaceAll("-"," ")}_toggleConfirmationLines(t){const e={"turn-on":"confirm.state_on","turn-off":"confirm.state_off",open:"confirm.state_open",close:"confirm.state_closed",stop:"confirm.state_stopped"};return function(t,e){if(!Md(t)||!t.nextEffect||!t.targets.length)return[];const i="group"===t.kind,s=i?t.targets.filter(t=>"on"===t.state).length:0,n=i?0===s?e.groupAllOff():e.groupCurrent(s,t.targets.length):e.state(t.targets[0]);let o;return o="toggle"===t.nextEffect?e.expectedByHa():i&&"turn-on"===t.nextEffect?e.groupAllOn():i&&"turn-off"===t.nextEffect?e.groupAllOff():e.effect(t.nextEffect),[e.current(n),e.expected(o),...t.skippedTargets.length?[e.unavailable(t.skippedTargets.length)]:[]]}(t,{state:t=>this._toggleConfirmationStateText(t),current:t=>this._t("confirm.current_state",{state:t}),expected:t=>this._t("confirm.expected_state",{state:t}),groupCurrent:(t,e)=>this._t("confirm.group_current",{on:t,total:e}),groupAllOn:()=>this._t("confirm.group_all_on"),groupAllOff:()=>this._t("confirm.group_all_off"),unavailable:t=>this._t("confirm.unavailable_targets",{count:t}),effect:t=>this._t(e[t]),expectedByHa:()=>this._t("confirm.expected_by_ha")})}_toggleHintLines(t){if(!t)return[];const e=t=>this._t(`marker.toggle_effect_${t.replace("-","_")}`),i=t=>this._t(`marker.toggle_skip_${t.replace("-","_")}`);return function(t,e){const i=t.targets[0]||t.skippedTargets[0],s=[];return"group"===t.kind?t.targets.length&&s.push(e.group(t.targets)):i&&s.push(e.single(i)),t.nextEffect&&t.targets.length&&s.push("group"===t.kind?e.groupCurrentNext(t.targets,t.nextEffect):e.currentNext(t.targets[0],t.nextEffect)),t.skippedTargets.length&&s.push(e.skipped(t.skippedTargets)),!t.command&&t.noneReason&&s.push(e.none(t.noneReason)),s}(t,{single:t=>{if("via"in t&&"virtual-light"===t.via)return this._t("marker.virtual_light_target",{name:t.name});const e=t.entityId||("ref"in t?t.ref:""),i=t.name||e;return this._t("marker.toggle_hint_single",{name:i,id:e})},group:t=>this._t("marker.toggle_hint_group",{count:t.length,names:t.map(t=>`${t.name} (${t.entityId})`).join(", ")}),currentNext:(t,i)=>"virtual-light"===t.via?this._t("marker.virtual_light_current",{state:this._t("on"===t.state?"marker.virtual_light_state_on":"marker.virtual_light_state_off"),effect:e(i)}):this._t("marker.toggle_hint_current",{state:this._toggleStateText(t.entityId,t.state),effect:e(i)}),groupCurrentNext:(t,i)=>this._t("marker.toggle_hint_group_current",{on:t.filter(t=>"on"===t.state).length,count:t.length,effect:e(i)}),skipped:t=>this._t("marker.toggle_hint_skipped",{count:t.length,targets:t.map(t=>{const e=t.entityId||t.ref;return`${t.name||e} (${e}: ${i(t.reason)})`}).join(", ")}),none:t=>this._t(`marker.toggle_none_${t.replaceAll("-","_")}`)})}_effectiveStoredTapAction(t,e){return t.tapActionTouched?t.tapAction:bd(t.originalHasTapAction?t.originalTapAction:null,e)}_effectiveMarkerTapAction(t,e=this._markerPreviewDevice(t)){return this._effectiveStoredTapAction(t,e?.primary?.split(".")[0])}_announceToggleDraft(t){const e=this._markerPreviewDevice(t),i=t.tapActionTouched?t:{...t,tapAction:this._effectiveMarkerTapAction(t,e)},s="toggle"===i.tapAction?this._toggleHintLines(this._toggleIntentForDialog(i)).join(" "):"";return{...i,tapHintAnnouncement:s}}_valueBadgeForBinding(t,e){const i={...t,binding:e,valueBadgeEnabled:!1,valueBadgeSource:null,valueBadgeTouched:!0},s=this._markerPreviewDevice(i);if(!s)return{valueBadgeEnabled:!1,valueBadgeSource:null,valueBadgeTouched:!0};const n=[...this._devices.filter(t=>t.id!==s.id),s],o=Wo(this._planHass,s,n),a=jo(this._planHass,s,o);return{valueBadgeEnabled:t.valueBadgeEnabled&&!!a,valueBadgeSource:a,valueBadgeTouched:!0}}_markerSpatialSource(t){const e=this._markerPreviewDevice(t);if(!e)return null;const i={...e,hidden:!1};return po(ho(this._planHass,[...this._devices.filter(t=>t.id!==i.id),i],null,this._virtualLights).filter(t=>t.device.id===i.id))}_markerAutoHasSpatialSource(t){const e={...t,lightRole:"auto",lightRoleTouched:!0},i=this._markerPreviewDevice(e);return!!i&&lo(this._planHass,{...i})}_setMarkerLightRole(t){const e=this._markerDialog;e&&(this._markerDialog={...e,lightRole:t,lightRoleTouched:!0})}_controlRefInfo(t){if(!t.startsWith("marker:"))return{label:this.hass.states[t]?.attributes?.friendly_name||t,sub:t,icon:t.startsWith("light.")?"mdi:lightbulb":"mdi:toggle-switch",warning:!this._planEntityAvailable(t)};const e=t.slice(7),i=this._markers.find(t=>t.id===e),s=this._devices.find(t=>t.id===e);if(!i||i.removed||!0!==i.is_light)return{label:this._t("marker.control_missing_label"),sub:`${this._t("marker.control_broken")} (${t})`,icon:"mdi:alert-outline",warning:!0};const n=this._serverCfg?.spaces.find(t=>t.id===(s?.space||i.space)),o=!!s&&to(s).length>0;return{label:i.name||s?.name||e,sub:[n?.title||s?.space||i.space,i.room_id||s?.area,o?"":this._t("marker.control_passive")].filter(Boolean).join(" · "),icon:i.icon||s?.icon||"mdi:lightbulb-outline",warning:!0===i.hidden||!0===s?.hidden}}_valueBadgeCandidateLabel(t){const e=t.source;if("derived_lqi"===e.kind)return this._t("marker.value_badge_lqi");if("derived_marker_state"===e.kind)return this._t("marker.value_badge_marker_state",{name:t.label});if("entity_state"===e.kind)return this._t("marker.value_badge_state",{name:t.label});const i=this.hass.states[e.entity_id]?.attributes?.friendly_name||this._fullRegistryHass.entities[e.entity_id]?.name||e.entity_id;return this._t(`marker.value_badge_attr_${e.attribute}`,{name:i})}_controlCandidates(t){const e=this._markerDraft(t)?.id||t.devId||"",i=[],s=new Set;for(const t of this._markers){if(t.id===e||t.removed||t.hidden||!0!==t.is_light)continue;if("virtual"!==t.binding&&"active"!==this._bindingStatus(t.binding).kind)continue;const n=this._devices.find(e=>e.id===t.id);if(!n||n.hidden)continue;const o=this._controlRefInfo(`marker:${t.id}`);for(const t of to(n))s.add(t);i.push({value:`marker:${t.id}`,label:o.label,sub:o.sub,icon:o.icon,search:`${o.label} ${o.sub} ${t.id} ${to(n).join(" ")}`.toLowerCase()})}const n=Object.keys(this.hass.states||{}).filter(e=>Ms(e)&&!s.has(e)&&Jn(t.binding,[e],this._bindingEntities(t.binding)).length>0&&this._planEntityAvailable(e)).map(t=>{const e=this._controlRefInfo(t);return{value:t,label:e.label,sub:t,icon:e.icon,search:`${e.label} ${t}`.toLowerCase()}}),o=t.controlsFilter.trim().toLowerCase();return[...i,...n].filter(e=>!t.controls.includes(e.value)&&(!o||e.search.includes(o))).slice(0,12).map(({search:t,...e})=>e)}_addControlRef(t,e){if(e.startsWith("marker:")){const i=this._markerDraft(t)?.id||t.devId||"";if(!i)return void this._showToast(this._t("toast.marker_binding_required"));const s=e.slice(7),n=this._markerDraft(t);if(function(t,e,i){if(!e||e===i)return!0;const s=new Map;for(const e of t)s.set(e.id,(e.controls||[]).filter(t=>"string"==typeof t&&t.startsWith("marker:")).map(t=>t.slice(7)));const n=new Set,o=[i];for(;o.length;){const t=o.pop();if(t===e)return!0;n.has(t)||(n.add(t),o.push(...s.get(t)||[]))}return!1}(n?[...this._markers.filter(t=>t.id!==i),n]:this._markers,i,s))return void this._showToast(this._t("toast.marker_control_cycle"))}this._markerDialog=this._announceToggleDraft({...t,controls:[...t.controls,e],controlsFilter:""})}_setMarkerGlowMode(t){const e=this._markerDialog;if(!e)return;if("auto"===t)return void(this._markerDialog={...e,glowMode:t,glowTouched:!0});const i=this._markerSpatialSource(e),s=xs(i?this._planHass.states[i.eid]:void 0,null,this._fillColors.glow_light.c),n=!e.glowColorDrafted,o="fixed"===t&&!e.glowBrightnessDrafted;this._markerDialog={...e,glowMode:t,glowColor:n?s.c:e.glowColor,glowBrightness:o?Math.max(1,Math.round(100*s.bri)):e.glowBrightness,glowColorDrafted:!0,glowBrightnessDrafted:e.glowBrightnessDrafted||"fixed"===t,glowTouched:!0}}_renderMarkerDialog(){const t=this._markerDialog,e="virtual"===t.bindingMode,i=this._bindingCandidates();this._bindingEntities(t.binding);const s=e?null:this._bindingStatus(t.binding),n=!e&&this._bindingHasHaPage(t.binding),o=this._markerPreviewDevice(t),a=this._effectiveMarkerTapAction(t,o),r=o?cs(this._serverCfg?.spaces.find(t=>t.id===o.space)):null,l=o?this._markerPreviewDevices(o):this._devices,c="toggle"===a&&o?this._toggleIntent(o,l):null,h=this._toggleHintLines(c),d=o?ou(this._planHass,o,{liveStates:!1!==this._config?.live_states,showTemperature:!1!==this._config?.show_temperature,showSignal:r?.showLqi??!1!==this._config?.show_signal,designPreview:!0,activityRuntime:this._activityRt.get(o.id),lightDevices:l,registryHass:this._fullRegistryHass,reducedMotion:this._reducedMotion}):null,p=o?Wo(this._planHass,o,l):[],u=o?jo(this._planHass,o,p):null,_=t.valueBadgeTouched?t.valueBadgeEnabled:!!d?.valueBadge,g=t.valueBadgeTouched?t.valueBadgeSource:d?.valueBadge?.source||t.valueBadgeSource,m=t.valueBadgeTouched?t.valueBadgePosition:d?.valueBadge?.position||t.valueBadgePosition,f=Ao(g),v=!!g&&!p.some(t=>t.key===f),y=p.find(t=>t.key===f),b=d?.valueSource?d.valueSource.attribute?`attr:${d.valueSource.eid}:${d.valueSource.attribute}`:`state:${d.valueSource.eid}`:"",w=this._markerAutoHasSpatialSource(t),k=!!o&&function(t,e){return io(t,e).some(t=>!!t.eid)}(this._planHass,{...o}),x=function(t,e,i,s){const n="always"===t||"auto"===t&&e,o=n&&!i;return{sourceExists:n,fromSourceEnabled:n&&i,manualEnabled:n,radiusEnabled:n,passive:o,effectiveMode:o&&"auto"===s?"fixed":s}}(t.lightRole,w,k,t.glowMode),$=!x.sourceExists,S=!x.fromSourceEnabled,M=x.passive,C=x.effectiveMode,D="never"===t.lightRole?this._t("marker.glow_disabled_never"):"auto"!==t.lightRole||w?M?this._t("marker.glow_passive_hint"):this._t("marker.glow_disabled_no_entity"):this._t("marker.glow_disabled_auto"),T=o?to(o):[],P=o&&eo(o)||"",R=!!t.lightEntity&&!T.includes(t.lightEntity),I=o?gd(o):[],A=!!t.toggleEntity&&!I.includes(t.toggleEntity),F="toggle"===a?this._toggleIntentForDialog({...t,toggleEntity:"",toggleEntityTouched:!0}):null,E=F?[...F.targets,...F.skippedTargets].map(t=>t.entityId||("ref"in t?t.ref:"")).filter(Boolean).join(", "):"",z=(()=>{if(e)return null;const s=i.find(e=>e.value===t.binding);if(s)return s.label;const[n,o]=t.binding.split(":");return"device"===n?this._fullRegistryHass.devices[o]?.name_by_user||this._fullRegistryHass.devices[o]?.name||o:this._fullRegistryHass.entities[o]?.name||this.hass.states[o]?.attributes?.friendly_name||o})();return W`this._markerDialog=null}>
-
- ${"ha_disabled"===s?.kind?W`
-
- ${this._t(`marker.ha_disabled_${s.reason}`)}
- ${n?W`this._openBindingInHa(t.binding)}>
- ${this._t("btn.open_in_ha")}
- `:G}
-
`:"unverified"===s?.kind&&t.binding?W`
-
- ${this._t("marker.ha_registry_limited")}
-
`:G}
-
${this._t("marker.name_label")}
-
this._markerDialog={...t,name:e.target.value}} />
-
-
${this._t("marker.binding_label")}
-
-
- {const e={...t,bindingMode:"virtual",binding:"virtual",bindingOpen:!1,controls:Zn("virtual",t.controls),autoIcon:this._autoIconForBinding("virtual")};this._markerDialog=this._announceToggleDraft({...e,...this._valueBadgeForBinding(e,"virtual")})}} />
- ${this._t("marker.virtual_option")}
-
-
-
- this._markerDialog=this._announceToggleDraft({...t,bindingMode:"ha",binding:"virtual"===t.binding?"":t.binding,bindingOpen:"virtual"===t.binding||!t.binding})} />
- ${this._t("marker.from_ha_option")}
-
-
- ${this._boolInput(t.showEntities,e=>this._markerDialog={...t,showEntities:e},"ha"!==t.bindingMode)}
- ${this._t("marker.show_entities")}
-
-
- ${"ha"===t.bindingMode?W`
this._markerDialog={...t,bindingOpen:!t.bindingOpen}}>
- ${z?W`${z} ${t.binding}${"ha_disabled"===s?.kind?` · ${this._t("marker.binding_disabled")}`:""} `:W`${this._t("marker.pick_ph")} `}
-
-
- ${t.bindingOpen?W`
-
this._markerDialog={...t,bindingFilter:e.target.value}} />
-
- ${i.map(e=>W`
{const i={...t,binding:e.value,bindingOpen:!1,controls:Zn(e.value,t.controls,this._bindingEntities(e.value)),autoIcon:this._autoIconForBinding(e.value)};this._markerDialog=this._announceToggleDraft({...i,...this._valueBadgeForBinding(i,e.value)})}}>
- ${e.label} ${e.sub}
-
`)}
- ${i.length?G:W`
${this._t("marker.nothing_found")}
`}
-
-
`:G}`:G}
-
-
-
${this._t("marker.room_label")}${e?"":this._t("marker.room_override")}
-
this._markerDialog={...t,room:e.target.value}}>
-
- ${e?this._t("marker.room_choose"):this._t("marker.room_auto")}
-
- ${this._allRoomsFlat().map(e=>W`${e.label} `)}
-
-
- ${this._renderVacSection(t)}
-
-
${this._t("marker.tap_label")}
-
{const i={...t,tapAction:e.target.value,tapActionTouched:!0};this._markerDialog=this._announceToggleDraft(i)}}>
- ${qi.map(t=>[t,"tap."+t.replace("-","_")]).map(([t,e])=>W`
- ${this._t(e)}
- `)}
-
- ${"toggle"===a&&(I.length>1||A)?W`
-
- ${this._t("marker.toggle_entity_label")}
- ${this._help("marker.toggle_entity.help")}
-
-
{const i={...t,toggleEntity:e.target.value,toggleEntityTouched:!0};this._markerDialog=this._announceToggleDraft(i)}}>
-
- ${this._t("marker.toggle_entity_auto",{entity:E||this._t("marker.toggle_entity_none")})}
-
- ${I.map(e=>W`
- ${this.hass.states[e]?.attributes?.friendly_name||this._fullRegistryHass.entities[e]?.name||e} · ${e}
- `)}
-
- ${A?W`
-
- ${this._t("marker.toggle_entity_missing",{entity:t.toggleEntity,fallback:E||this._t("marker.toggle_entity_none")})}
-
`:G}
-
`:G}
- ${"toggle"===a?W`
-
${t.tapHintAnnouncement}
`:G}
- ${"run"===a?(()=>{const e=t.runFilter.trim().toLowerCase(),i=this._runCandidates().filter(t=>!e||t.label.toLowerCase().includes(e)||t.value.includes(e)),s=t.tapTarget?this._runCandidates().find(e=>e.value===t.tapTarget):null;return W`
-
${this._t("marker.run_target_label")}
- ${t.tapTarget&&!s?W`
${this._t("marker.run_target_gone",{id:t.tapTarget})}
`:G}
-
{t.target.select()}}
- @input=${e=>this._markerDialog={...t,runFilter:e.target.value,tapTarget:""}} />
- ${s?G:W`
- ${i.slice(0,40).map(e=>W`
this._markerDialog={...t,tapTarget:e.value,runFilter:""}}>
- ${e.label} ${e.sub}
-
`)}
- ${i.length?G:W`
${this._t("marker.nothing_found")}
`}
-
`}`})():G}
- ${"run"===a||"toggle"===a?W`
- ${this._boolInput(t.tapConfirm,e=>this._markerDialog={...t,tapConfirm:e})}
- ${this._t("marker.tap_confirm")}
- `:G}
-
-
${this._t("marker.controls_label")}
-
${this._t("marker.controls_hint")}
- ${t.controls.length?W`
- ${t.controls.map(e=>{const i=this._controlRefInfo(e);return W`
- ${i.label}
- this._markerDialog=this._announceToggleDraft({...t,controls:t.controls.filter(t=>t!==e)})}>
- `})}
-
`:G}
-
this._markerDialog={...t,controlsFilter:e.target.value}} />
- ${t.controlsFilter.trim()?W`
- ${this._controlCandidates(t).map(e=>W`this._addControlRef(t,e.value)}>
-
- ${e.label}
- ${e.sub}
- `)}
-
`:G}
-
- ${this._bindingHasClimate(t.binding)?W`
- ${this._boolInput(t.useClimateTemp,e=>this._markerDialog={...t,useClimateTemp:e})}
- ${this._t("marker.use_climate_temp")}
- `:G}
-
- ${this._t("marker.light_role_label")} ${this._help("marker.light_role.help")}
-
- this._setMarkerLightRole("auto")} />
- ${this._t(w?"marker.light_role_auto_yes":"marker.light_role_auto_no")}
- this._setMarkerLightRole("always")} />
- ${this._t("marker.light_role_always")}
- this._setMarkerLightRole("never")} />
- ${this._t("marker.light_role_never")}
-
-
-
- ${"always"===t.lightRole&&(T.length>1||R)?W`
-
- ${this._t("marker.light_entity_label")}
- ${this._help("marker.light_entity.help")}
-
-
this._markerDialog={...t,lightEntity:e.target.value,lightEntityTouched:!0}}>
-
- ${this._t("marker.light_entity_auto",{entity:P||this._t("marker.light_entity_none")})}
-
- ${T.map(e=>W`
- ${this.hass.states[e]?.attributes?.friendly_name||this._fullRegistryHass.entities[e]?.name||e} · ${e}
- `)}
-
- ${R?W`
-
- ${this._t("marker.light_entity_missing",{entity:t.lightEntity,fallback:P||"—"})}
-
`:G}
-
`:G}
-
-
- ${this._t("marker.glow_color_label")} ${this._help("marker.glow_mode.help")}
-
- this._setMarkerGlowMode("auto")} />
- ${this._t("marker.glow_mode_auto")}
- this._setMarkerGlowMode("color")} />
- ${this._t("marker.glow_mode_color")}
- this._setMarkerGlowMode("fixed")} />
- ${this._t("marker.glow_mode_fixed")}
-
- ${"auto"!==C?W`
- {this._markerDialog={...t,glowMode:C,glowColor:e.detail.color,glowColorDrafted:!0,glowTouched:!0}}}>
- ${"fixed"===C?W`
- ${this._t("marker.glow_brightness")}
- ${this._rangeInput(1,100,1,t.glowBrightness,e=>{this._markerDialog={...t,glowMode:C,glowBrightness:e,glowBrightnessDrafted:!0,glowTouched:!0}},$,this._t("marker.glow_brightness"))}
- ${Math.round(t.glowBrightness)}% `:G}
-
`:G}
-
-
-
- ${this._t("marker.glow_radius_label")}
- ${this._help("marker.glow_radius.help")}
-
-
- this._markerDialog={...t,glowRadius:e.target.value}} />
- ${this._imperial?this._t("gs.unit_ft"):this._t("gs.unit_m")}
-
-
- ${$||M?W`
- ${D}
-
`:G}
-
-
${this._t("marker.icon_label")}
- ${customElements.get("ha-icon-picker")?W`
{const i=e.detail.value||"";(t.icon||i!==t.autoIcon)&&(this._markerDialog={...t,icon:i})}}> `:W`
this._markerDialog={...t,icon:e.target.value}} />`}
- ${!t.icon&&t.autoIcon?W`
- ${this._t("marker.icon_auto",{icon:t.autoIcon})}
- this._markerDialog={...t,icon:t.autoIcon}}>
- ${this._t("marker.icon_pin_auto")}
-
`:G}
-
-
${this._t("marker.display_label")}
-
this._markerDialog={...t,display:Bi(e.target.value)}}>
- ${Li.map(e=>W`
- ${this._t(Xg[e])}
- `)}
-
-
${this._t(Jg[t.display])}
- ${"static_icon"===t.display&&this._bindingHasAlarm(t.binding)?W`
-
- ${this._t("marker.static_alarm_warning")}
-
`:G}
-
- ${this._t("marker.value_badge_title")} ${this._help("marker.value_badge.help")}
-
- ${this._boolInput(_,e=>{const i=g||u;this._markerDialog={...t,valueBadgeEnabled:e&&!!i,valueBadgeSource:i,valueBadgeTouched:!0}},"static_icon"===t.display||!p.length&&!t.valueBadgeSource)}
- ${this._t("marker.value_badge_enabled")}
-
- ${"static_icon"===t.display?W`
- ${this._t("marker.value_badge_static")}
-
`:p.length||t.valueBadgeSource?G:W`
- ${this._t("marker.value_badge_empty")}
-
`}
- ${_?W`
-
- ${this._t("marker.value_badge_source")}
- ${this._help("marker.value_badge_source.help")}
-
- this._markerDialog={...t,valueBadgeSource:Fo(e.target.value),valueBadgeEnabled:!0,valueBadgeTouched:!0}}>
- ${v?W`
- ${this._t("marker.value_badge_missing")}
- `:G}
- ${p.map(t=>W`
- ${this._valueBadgeCandidateLabel(t)} · ${t.value}
- `)}
-
- ${y?W`${y.technical}
`:G}
- ${v?W`
- ${this._t("marker.value_badge_missing_hint")}
-
`:G}
- ${"value"===t.display&&f===b?W`
- ${this._t("marker.value_badge_duplicate")}
-
`:G}
-
- ${this._t("marker.value_badge_position")}
- ${this._help("marker.value_badge_position.help")}
-
- this._markerDialog={...t,valueBadgeEnabled:_,valueBadgeSource:g,valueBadgePosition:e.target.value,valueBadgeTouched:!0}}>
- ${["right","bottom","left","top"].map(t=>W`
-
- ${this._t(`marker.value_badge_${t}`)}
- `)}
-
- `:G}
-
- ${d?W`
- `:W`
-
- ${this._t("marker.preview.select_source")}
-
`}
- ${"icon_ripple"===t.display?W`
- {this._markerDialog={...t,rippleColor:e.detail.color}}}>
-
-
- ${this._t("marker.ripple_size")}
- ${this._rangeInput(1,8,.5,t.rippleSize,e=>this._markerDialog={...t,rippleSize:e})}
- ×${t.rippleSize}
-
-
${this._t("marker.activity_alarm_note")}
`:G}
-
-
${this._t("marker.size_label")}
-
- ${this._rangeInput(.5,3,.1,t.size,e=>this._markerDialog={...t,size:e})}
- ×${t.size.toFixed(1)}
- ${this._t("marker.angle_label")}
- ${""}
- ${this._rangeInput(0,355,5,t.angle,e=>this._markerDialog={...t,angle:e})}
- ${t.angle}°
-
-
-
${this._t("marker.model_label")}
-
this._markerDialog={...t,model:e.target.value}} />
-
-
${this._t("marker.link_label")}
-
this._markerDialog={...t,link:e.target.value}} />
-
-
${this._t("marker.desc_label")}
-
-
-
${this._t("marker.manuals_label")}
-
- ${t.pdfs.map(t=>W`
- ${t.name}
- this._removeMarkerPdf(t.url)}> `)}
-
- t.currentTarget.nextElementSibling?.click()}>
- ${this._t("btn.attach")}
-
- this._pickMarkerFiles(t)} />
-
-
-
-
- `}_renderSpaceDialog(){const t=this._spaceDialog,e=this._importTotal>0&&"create"===t.mode?this._t("import.progress",{i:this._importTotal-this._importQueue.length,n:this._importTotal}):"",i=()=>{this._spaceDialog=null,this._importQueue=[],this._importTotal=0};return W`
-
-
${this._t("space.title_label")}
-
this._spaceDialog={...t,title:e.target.value}} />
-
${this._t("space.plan_label")}
-
- this._spaceDialog=Fh(t,"file")} />
- ${this._t("space.source_file")}
-
- ${"file"===t.source?W`
- ${t.planFile?W`
${t.planFile.name} `:t.planUrl?W`
`:W`
${this._t("space.no_plan")} `}
-
- t.currentTarget.nextElementSibling?.click()}>
- ${t.planUrl||t.planFile?this._t("btn.replace"):this._t("btn.upload")}
-
- this._pickPlanFile(t)} />
-
-
- ${this._t("space.pick_saved")}
-
-
- ${t.pickSaved?this._renderServerPlans(t):G}`:G}
-
- this._spaceDialog=Fh(t,"draw")} />
- ${this._t("space.source_draw")}
-
-
-
${this._t("space.scale_label")}
-
- {const i=e.target.value,s=em(i),n=null==s?null:(o=s,this._imperial?o*lc:o);var o;this._spaceDialog={...t,cellCmInput:i,cellCmTouched:!0,cellCm:null!=n&&n>0?Math.max(.1,Math.min(Qg,n)):t.cellCm}}} />
- ${this._t(this._imperial?"space.scale_unit_imperial":"space.scale_unit")}
-
-
-
${this._t("space.display_section")}
-
- ${this._boolInput(t.showBorders,e=>this._spaceDialog=Eh(t,"showBorders",e))}
- ${this._t("space.show_borders")}
-
-
- ${this._boolInput(t.showNames,e=>this._spaceDialog=Eh(t,"showNames",e))}
- ${this._t("space.show_names")}
-
-
- ${this._boolInput(t.showLqi,e=>this._spaceDialog={...t,showLqi:e})}
- ${this._t("space.show_lqi")}
-
- ${""}
-
- ${this._boolInput(t.hideDecor,e=>this._spaceDialog={...t,hideDecor:e})}
- ${this._t("space.hide_decor")}
-
-
${this._t("space.hide_decor_tip")}
-
- ${this._boolInput(t.hideOpenings,e=>this._spaceDialog={...t,hideOpenings:e})}
- ${this._t("space.hide_openings")}
-
-
${this._t("space.hide_openings_tip")}
-
${this._t("space.roomcard_section")}
- ${[["labelTemp","space.label_temp"],["labelHum","space.label_hum"],["labelLqi","space.label_lqi"],["labelLight","space.label_light"]].map(([e,i])=>W`
- ${this._boolInput(t[e],i=>this._spaceDialog={...t,[e]:i})}
- ${this._t(i)}
- `)}
-
${this._t("space.card_font")}
-
- ${this._rangeInput(50,300,5,Math.round(100*t.cardFontScale),e=>this._spaceDialog={...t,cardFontScale:e/100})}
- ${Math.round(100*t.cardFontScale)}%
-
- ${this._renderCardPreview(t.cardFontScale,1,1)}
-
- {this._spaceDialog={...t,roomColor:e.detail.color,roomOpacity:e.detail.opacity}}}>
-
-
${this._t("space.bg_mode")}
-
{const i=e.target.value;this._spaceDialog={...t,bgMode:"static"===i||"daynight"===i?i:null}}}>
- ${this._t("space.sun_inherit")}
- ${this._t("gs.bg_static")}
- ${this._t("gs.bg_daynight")}
-
- ${"static"===(t.bgMode??Qa(this._settings,{}))?W`
- {this._spaceDialog={...t,bgColor:e.detail.color}}}>
- ${t.bgColor?W`this._spaceDialog={...t,bgColor:null}}>
- ${this._t("space.bg_inherit")} `:W`${this._t("space.bg_inherited")} `}
-
`:G}
-
${this._t("space.north")}
-
- {const i=e.target.value.trim(),s=""===i?null:Math.round(Number(i));this._spaceDialog={...t,northDeg:null!==s&&Number.isFinite(s)?Math.min(359,Math.max(0,s)):null}}} />
- ${null===t.northDeg?this._t("space.north_inherited",{v:null===Za(this._settings,{})?"—":String(Za(this._settings,{}))+"°"}):"°"}
-
-
${this._t("space.sun_rays")}
-
{const i=e.target.value;this._spaceDialog={...t,sunRays:""===i?null:"1"===i}}}>
- ${this._t("space.sun_inherit")}
- ${this._t("space.sun_on")}
- ${this._t("space.sun_off")}
-
-
${this._t("space.fill_label")}
- ${Wi.map(t=>[t,"fill."+t]).map(([e,i])=>W`
- this._spaceDialog={...t,fillMode:e}} />
- ${this._t(i)}
- ${"temp"===e&&"temp"===t.fillMode?W`
- {const i=em(e.target.value);null!=i&&(this._spaceDialog={...t,tempMin:i})}} />
- –
- {const i=em(e.target.value);null!=i&&(this._spaceDialog={...t,tempMax:i})}} />
- °C
- `:G}
-
- ${"custom"===e&&"custom"===t.fillMode?W`
- ${this._t("space.custom_fill")}
- {this._spaceDialog={...t,customFill:{c:e.detail.color,a:e.detail.opacity}}}}>
- ${t.customFill?W`this._spaceDialog={...t,customFill:null}}>
- ${this._t("btn.reset")} `:G}
-
`:G}`)}
-
- ${this._boolInput(t.glowEnabled,e=>{this._spaceDialog={...t,glowEnabled:e}})}
- ${this._t("space.glow_enabled")}
-
- ${t.deleteBlockers?W`
${this._t("space.delete_blocked",{n:String(t.deleteBlockers)})}
`:G}
-
-
- `}_renderMergeDialog(){const t=this._mergeDialog,e=this._spaceModel()?.rooms||[],i=(i,s)=>{const n=e.find(t=>t.id===i),o=n?.area?this.hass.areas[n.area]?.name:null;return W`
- this._mergeDialog={...t,pick:s}} />
- ${n?.name||""} · ${o||this._t("merge.no_area")}
- `};return W`this._mergeDialog=null}>
-
-
${this._t("merge.hint")}
-
${this._t("merge.keep")}
- ${i(t.aId,"a")}
- ${i(t.bId,"b")}
-
-
-
- this._mergeDialog=null}>${this._t("btn.cancel")}
-
- ${this._t("btn.save")}
-
-
- `}_renderCardPreview(t,e,i){const s=18*t;return W`
-
- ${this._t("preview.room_name")}
-
- 22.4° ·
- 45% ·
- ${this._t("roomcard.light_partial",{on:1,total:3})}
-
-
`}_renderRoomSource(t){const e="temp"===t?this._roomTempSrc:this._roomHumSrc,i=e=>{"temp"===t?this._roomTempSrc=e:this._roomHumSrc=e,this.requestUpdate()},s=this._roomSrcOpen===t;return W`
- ${this._t("temp"===t?"room.temp_src_label":"room.hum_src_label")}
-
- {i(""),this._roomSrcOpen=null}} />
- ${this._t("room.src_average")}
-
-
- {this._roomSrcOpen=t,this._roomSrcFilter="",this.requestUpdate()}} />
- ${this._t("room.src_pick")}
-
- ${e||s?W`{this._roomSrcOpen=s?null:t,this._roomSrcFilter=""}}>
- ${e?W`${this._roomSrcLabel(e)} ${e} `:W`${this._t("room.src_ph")} `}
-
-
- ${s?W`
-
{this._roomSrcFilter=t.target.value,this.requestUpdate()}} />
-
- ${this._roomSrcCandidates().map(t=>W`
{i(t.value),this._roomSrcOpen=null}}>
- ${t.label} ${t.sub}
-
`)}
-
-
`:G}`:G}`}_renderRoomDialog(){const t=!!this._roomEditId,e=t?null:this._wallFaceBatch,i=e&&e.candidates.length>1?this._t("room.queue_progress",{current:e.index+1,total:e.candidates.length}):"",s=!!this._areaSel||!!this._nameSel.trim(),n=cs(this._curSpaceCfg),o=this._roomFill||n.fill,a=this._roomCustomFill||n.customFill,r=[...this._freeAreas];if(t&&this._areaSel&&!r.some(t=>t.area_id===this._areaSel)){const t=this.hass.areas[this._areaSel];t&&r.unshift(t)}return W`
-
- ${i?W`
- ${i}
-
`:G}
-
${this._t("room.name_label")}
-
this._nameSel=t.target.value} />
-
${this._t("room.area_label")}
-
{this._areaSel=t.target.value,!this._nameSel&&this._areaSel&&(this._nameSel=this.hass.areas[this._areaSel]?.name||""),this.requestUpdate()}}>
- ${this._t("room.no_area_option")}
- ${r.map(t=>W`${t.name} `)}
-
-
-
${this._t("room.settings_section")}
-
${this._t("room.fill_label")}
- ${[["","fill.inherit"],...ji.map(t=>[t,"fill."+t])].map(([t,e])=>W`
- {this._roomFill=t,this.requestUpdate()}} />
- ${this._t(e)}
- `)}
- ${"custom"===o?W`
- ${this._roomCustomFill?this._t("room.custom_fill_own"):this._t("room.custom_fill_space")}
- {this._roomCustomFill={c:t.detail.color,a:t.detail.opacity}}}>
- ${this._roomCustomFill?W`{this._roomCustomFill=null}}>${this._t("btn.reset")} `:G}
-
`:G}
- ${this._renderRoomSource("temp")}
- ${this._renderRoomSource("hum")}
-
-
${this._t("room.sizes_section")}
-
${this._t("room.name_scale")}
-
- ${this._rangeInput(50,300,5,Math.round(100*this._roomNameScale),t=>{this._roomNameScale=t/100,this.requestUpdate()})}
- ${Math.round(100*this._roomNameScale)}%
-
-
${this._t("room.label_scale")}
-
- ${this._rangeInput(50,300,5,Math.round(100*this._roomLabelScale),t=>{this._roomLabelScale=t/100,this.requestUpdate()})}
- ${Math.round(100*this._roomLabelScale)}%
-
- ${this._renderCardPreview(cs(this._curSpaceCfg).cardFontScale,this._roomNameScale,this._roomLabelScale)}
-
-
- `}}$m.properties={_tabDrag:{state:!0},_hdrH:{state:!0},_booting:{state:!0},_bootFading:{state:!0},_bootSoft:{state:!0},_continuityEpoch:{state:!0},_tapConfirm:{state:!0},hass:{attribute:!1},_config:{state:!0},_space:{state:!0},_layout:{state:!0},_devices:{state:!0},_tip:{state:!0},_hoverRoom:{state:!0},_selId:{state:!0},_toast:{state:!0},_serverCfg:{state:!0},_mode:{state:!0},_tool:{state:!0},_wallDialog:{state:!0},_drawWallField:{state:!0},_activeDraftId:{state:!0},_physicalSel:{state:!0},_physicalDialog:{state:!0},_partitionDeleteDialog:{state:!0},_roomDeleteDialog:{state:!0},_physicalDrag:{state:!0},_physicalRotate:{state:!0},_duplicateColumnId:{state:!0},_rszSel:{state:!0},_rszLive:{state:!0},_opMeasure:{state:!0},_path:{state:!0},_cursorPt:{state:!0},_mergeSel:{state:!0},_openingPreset:{state:!0},_openingDialog:{state:!0},_openingInfo:{state:!0},_mergeDialog:{state:!0},_openWallAnchor:{state:!0},_splitSel:{state:!0},_decorTool:{state:!0},_decorStyle:{state:!0},_decorDraft:{state:!0},_decorSel:{state:!0},_decorEraseConfirm:{state:!0},_decorTextDialog:{state:!0},_decorShapeDialog:{state:!0},_backdropDialog:{state:!0},_furnPalette:{state:!0},_bdDrag:{state:!0},_dtBox:{state:!0},_dtDrag:{state:!0},_kioskDialog:{state:!0},_vacFit:{state:!0},_vacAllCamerasFor:{state:!0},_vacCalConfirm:{state:!0},_kioskDots:{state:!0},_areaSel:{state:!0},_nameSel:{state:!0},_roomDialog:{state:!0},_roomEditId:{state:!0},_roomFill:{state:!0},_roomCustomFill:{state:!0},_roomTempSrc:{state:!0},_roomHumSrc:{state:!0},_roomSrcOpen:{state:!0},_roomSrcFilter:{state:!0},_roomNameScale:{state:!0},_roomLabelScale:{state:!0},_spaceDialog:{state:!0},_infoCard:{state:!0},_rulesDialog:{state:!0},_settingsDialog:{state:!0},_alignDialog:{state:!0},_backupExportDialog:{state:!0},_backupImportDialog:{state:!0},_importDialog:{state:!0},_markerDialog:{state:!0},_zoom:{state:!0},_view:{state:!0}},$m.ZOOM_MAX=8,$m.ZOOM_MIN=1/3,$m.styles=[Kt,Eu],customElements.get("houseplan-card")||customElements.define("houseplan-card",$m),window.customCards=window.customCards||[],window.customCards.find(t=>"houseplan-card"===t.type)||window.customCards.push({type:"houseplan-card",name:"House Plan Card",description:"Interactive house plan: spaces, rooms and devices with live states and drag layout."}),console.info(`%c HOUSEPLAN-CARD %c v${Yg} `,"background:#3ea6ff;color:#04121f;font-weight:700","");
diff --git a/dist/houseplan-card.js b/dist/houseplan-card.js
index ae6b67d1..a2b35b19 100755
--- a/dist/houseplan-card.js
+++ b/dist/houseplan-card.js
@@ -1,4 +1,4 @@
-globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="9f02bbdd4af8b4bb62b64b6c02b34185edd3d5072031d8adb6d54393ec7b7c54";const t=globalThis,e=t.ShadowRoot&&(void 0===t.ShadyCSS||t.ShadyCSS.nativeShadow)&&"adoptedStyleSheets"in Document.prototype&&"replace"in CSSStyleSheet.prototype,i=Symbol(),s=new WeakMap;let n=class{constructor(t,e,s){if(this._$cssResult$=!0,s!==i)throw Error("CSSResult is not constructable. Use `unsafeCSS` or `css` instead.");this.cssText=t,this.t=e}get styleSheet(){let t=this.o;const i=this.t;if(e&&void 0===t){const e=void 0!==i&&1===i.length;e&&(t=s.get(i)),void 0===t&&((this.o=t=new CSSStyleSheet).replaceSync(this.cssText),e&&s.set(i,t))}return t}toString(){return this.cssText}};const o=(t,...e)=>{const s=1===t.length?t[0]:e.reduce((e,i,s)=>e+(t=>{if(!0===t._$cssResult$)return t.cssText;if("number"==typeof t)return t;throw Error("Value passed to 'css' function must be a 'css' function result: "+t+". Use 'unsafeCSS' to pass non-literal values, but take care to ensure page security.")})(i)+t[s+1],t[0]);return new n(s,t,i)},a=e?t=>t:t=>t instanceof CSSStyleSheet?(t=>{let e="";for(const i of t.cssRules)e+=i.cssText;return(t=>new n("string"==typeof t?t:t+"",void 0,i))(e)})(t):t,{is:r,defineProperty:l,getOwnPropertyDescriptor:c,getOwnPropertyNames:h,getOwnPropertySymbols:d,getPrototypeOf:p}=Object,u=globalThis,_=u.trustedTypes,g=_?_.emptyScript:"",m=u.reactiveElementPolyfillSupport,f=(t,e)=>t,v={toAttribute(t,e){switch(e){case Boolean:t=t?g:null;break;case Object:case Array:t=null==t?t:JSON.stringify(t)}return t},fromAttribute(t,e){let i=t;switch(e){case Boolean:i=null!==t;break;case Number:i=null===t?null:Number(t);break;case Object:case Array:try{i=JSON.parse(t)}catch(t){i=null}}return i}},y=(t,e)=>!r(t,e),b={attribute:!0,type:String,converter:v,reflect:!1,useDefault:!1,hasChanged:y};Symbol.metadata??=Symbol("metadata"),u.litPropertyMetadata??=new WeakMap;let w=class extends HTMLElement{static addInitializer(t){this._$Ei(),(this.l??=[]).push(t)}static get observedAttributes(){return this.finalize(),this._$Eh&&[...this._$Eh.keys()]}static createProperty(t,e=b){if(e.state&&(e.attribute=!1),this._$Ei(),this.prototype.hasOwnProperty(t)&&((e=Object.create(e)).wrapped=!0),this.elementProperties.set(t,e),!e.noAccessor){const i=Symbol(),s=this.getPropertyDescriptor(t,i,e);void 0!==s&&l(this.prototype,t,s)}}static getPropertyDescriptor(t,e,i){const{get:s,set:n}=c(this.prototype,t)??{get(){return this[e]},set(t){this[e]=t}};return{get:s,set(e){const o=s?.call(this);n?.call(this,e),this.requestUpdate(t,o,i)},configurable:!0,enumerable:!0}}static getPropertyOptions(t){return this.elementProperties.get(t)??b}static _$Ei(){if(this.hasOwnProperty(f("elementProperties")))return;const t=p(this);t.finalize(),void 0!==t.l&&(this.l=[...t.l]),this.elementProperties=new Map(t.elementProperties)}static finalize(){if(this.hasOwnProperty(f("finalized")))return;if(this.finalized=!0,this._$Ei(),this.hasOwnProperty(f("properties"))){const t=this.properties,e=[...h(t),...d(t)];for(const i of e)this.createProperty(i,t[i])}const t=this[Symbol.metadata];if(null!==t){const e=litPropertyMetadata.get(t);if(void 0!==e)for(const[t,i]of e)this.elementProperties.set(t,i)}this._$Eh=new Map;for(const[t,e]of this.elementProperties){const i=this._$Eu(t,e);void 0!==i&&this._$Eh.set(i,t)}this.elementStyles=this.finalizeStyles(this.styles)}static finalizeStyles(t){const e=[];if(Array.isArray(t)){const i=new Set(t.flat(1/0).reverse());for(const t of i)e.unshift(a(t))}else void 0!==t&&e.push(a(t));return e}static _$Eu(t,e){const i=e.attribute;return!1===i?void 0:"string"==typeof i?i:"string"==typeof t?t.toLowerCase():void 0}constructor(){super(),this._$Ep=void 0,this.isUpdatePending=!1,this.hasUpdated=!1,this._$Em=null,this._$Ev()}_$Ev(){this._$ES=new Promise(t=>this.enableUpdating=t),this._$AL=new Map,this._$E_(),this.requestUpdate(),this.constructor.l?.forEach(t=>t(this))}addController(t){(this._$EO??=new Set).add(t),void 0!==this.renderRoot&&this.isConnected&&t.hostConnected?.()}removeController(t){this._$EO?.delete(t)}_$E_(){const t=new Map,e=this.constructor.elementProperties;for(const i of e.keys())this.hasOwnProperty(i)&&(t.set(i,this[i]),delete this[i]);t.size>0&&(this._$Ep=t)}createRenderRoot(){const i=this.shadowRoot??this.attachShadow(this.constructor.shadowRootOptions);return((i,s)=>{if(e)i.adoptedStyleSheets=s.map(t=>t instanceof CSSStyleSheet?t:t.styleSheet);else for(const e of s){const s=document.createElement("style"),n=t.litNonce;void 0!==n&&s.setAttribute("nonce",n),s.textContent=e.cssText,i.appendChild(s)}})(i,this.constructor.elementStyles),i}connectedCallback(){this.renderRoot??=this.createRenderRoot(),this.enableUpdating(!0),this._$EO?.forEach(t=>t.hostConnected?.())}enableUpdating(t){}disconnectedCallback(){this._$EO?.forEach(t=>t.hostDisconnected?.())}attributeChangedCallback(t,e,i){this._$AK(t,i)}_$ET(t,e){const i=this.constructor.elementProperties.get(t),s=this.constructor._$Eu(t,i);if(void 0!==s&&!0===i.reflect){const n=(void 0!==i.converter?.toAttribute?i.converter:v).toAttribute(e,i.type);this._$Em=t,null==n?this.removeAttribute(s):this.setAttribute(s,n),this._$Em=null}}_$AK(t,e){const i=this.constructor,s=i._$Eh.get(t);if(void 0!==s&&this._$Em!==s){const t=i.getPropertyOptions(s),n="function"==typeof t.converter?{fromAttribute:t.converter}:void 0!==t.converter?.fromAttribute?t.converter:v;this._$Em=s;const o=n.fromAttribute(e,t.type);this[s]=o??this._$Ej?.get(s)??o,this._$Em=null}}requestUpdate(t,e,i,s=!1,n){if(void 0!==t){const o=this.constructor;if(!1===s&&(n=this[t]),i??=o.getPropertyOptions(t),!((i.hasChanged??y)(n,e)||i.useDefault&&i.reflect&&n===this._$Ej?.get(t)&&!this.hasAttribute(o._$Eu(t,i))))return;this.C(t,e,i)}!1===this.isUpdatePending&&(this._$ES=this._$EP())}C(t,e,{useDefault:i,reflect:s,wrapped:n},o){i&&!(this._$Ej??=new Map).has(t)&&(this._$Ej.set(t,o??e??this[t]),!0!==n||void 0!==o)||(this._$AL.has(t)||(this.hasUpdated||i||(e=void 0),this._$AL.set(t,e)),!0===s&&this._$Em!==t&&(this._$Eq??=new Set).add(t))}async _$EP(){this.isUpdatePending=!0;try{await this._$ES}catch(t){Promise.reject(t)}const t=this.scheduleUpdate();return null!=t&&await t,!this.isUpdatePending}scheduleUpdate(){return this.performUpdate()}performUpdate(){if(!this.isUpdatePending)return;if(!this.hasUpdated){if(this.renderRoot??=this.createRenderRoot(),this._$Ep){for(const[t,e]of this._$Ep)this[t]=e;this._$Ep=void 0}const t=this.constructor.elementProperties;if(t.size>0)for(const[e,i]of t){const{wrapped:t}=i,s=this[e];!0!==t||this._$AL.has(e)||void 0===s||this.C(e,void 0,i,s)}}let t=!1;const e=this._$AL;try{t=this.shouldUpdate(e),t?(this.willUpdate(e),this._$EO?.forEach(t=>t.hostUpdate?.()),this.update(e)):this._$EM()}catch(e){throw t=!1,this._$EM(),e}t&&this._$AE(e)}willUpdate(t){}_$AE(t){this._$EO?.forEach(t=>t.hostUpdated?.()),this.hasUpdated||(this.hasUpdated=!0,this.firstUpdated(t)),this.updated(t)}_$EM(){this._$AL=new Map,this.isUpdatePending=!1}get updateComplete(){return this.getUpdateComplete()}getUpdateComplete(){return this._$ES}shouldUpdate(t){return!0}update(t){this._$Eq&&=this._$Eq.forEach(t=>this._$ET(t,this[t])),this._$EM()}updated(t){}firstUpdated(t){}};w.elementStyles=[],w.shadowRootOptions={mode:"open"},w[f("elementProperties")]=new Map,w[f("finalized")]=new Map,m?.({ReactiveElement:w}),(u.reactiveElementVersions??=[]).push("2.1.2");const k=globalThis,x=t=>t,$=k.trustedTypes,S=$?$.createPolicy("lit-html",{createHTML:t=>t}):void 0,M="$lit$",C=`lit$${Math.random().toFixed(9).slice(2)}$`,D="?"+C,T=`<${D}>`,P=document,R=()=>P.createComment(""),I=t=>null===t||"object"!=typeof t&&"function"!=typeof t,A=Array.isArray,F="[ \t\n\f\r]",E=/<(?:(!--|\/[^a-zA-Z])|(\/?[a-zA-Z][^>\s]*)|(\/?$))/g,z=/-->/g,O=/>/g,N=RegExp(`>|${F}(?:([^\\s"'>=/]+)(${F}*=${F}*(?:[^ \t\n\f\r"'\`<>=]|("|')|))|$)`,"g"),H=/'/g,L=/"/g,B=/^(?:script|style|textarea|title)$/i,q=t=>(e,...i)=>({_$litType$:t,strings:e,values:i}),W=q(1),j=q(2),U=Symbol.for("lit-noChange"),G=Symbol.for("lit-nothing"),V=new WeakMap,K=P.createTreeWalker(P,129);function Y(t,e){if(!A(t)||!t.hasOwnProperty("raw"))throw Error("invalid template strings array");return void 0!==S?S.createHTML(e):e}const X=(t,e)=>{const i=t.length-1,s=[];let n,o=2===e?"":3===e?"":"",a=E;for(let e=0;e"===l[0]?(a=n??E,c=-1):void 0===l[1]?c=-2:(c=a.lastIndex-l[2].length,r=l[1],a=void 0===l[3]?N:'"'===l[3]?L:H):a===L||a===H?a=N:a===z||a===O?a=E:(a=N,n=void 0);const d=a===N&&t[e+1].startsWith("/>")?" ":"";o+=a===E?i+T:c>=0?(s.push(r),i.slice(0,c)+M+i.slice(c)+C+d):i+C+(-2===c?e:d)}return[Y(t,o+(t[i]||">")+(2===e?" ":3===e?"":"")),s]};class J{constructor({strings:t,_$litType$:e},i){let s;this.parts=[];let n=0,o=0;const a=t.length-1,r=this.parts,[l,c]=X(t,e);if(this.el=J.createElement(l,i),K.currentNode=this.el.content,2===e||3===e){const t=this.el.content.firstChild;t.replaceWith(...t.childNodes)}for(;null!==(s=K.nextNode())&&r.length0){s.textContent=$?$.emptyScript:"";for(let i=0;iA(t)||"function"==typeof t?.[Symbol.iterator])(t)?this.k(t):this._(t)}O(t){return this._$AA.parentNode.insertBefore(t,this._$AB)}T(t){this._$AH!==t&&(this._$AR(),this._$AH=this.O(t))}_(t){this._$AH!==G&&I(this._$AH)?this._$AA.nextSibling.data=t:this.T(P.createTextNode(t)),this._$AH=t}$(t){const{values:e,_$litType$:i}=t,s="number"==typeof i?this._$AC(t):(void 0===i.el&&(i.el=J.createElement(Y(i.h,i.h[0]),this.options)),i);if(this._$AH?._$AD===s)this._$AH.p(e);else{const t=new Q(s,this),i=t.u(this.options);t.p(e),this.T(i),this._$AH=t}}_$AC(t){let e=V.get(t.strings);return void 0===e&&V.set(t.strings,e=new J(t)),e}k(t){A(this._$AH)||(this._$AH=[],this._$AR());const e=this._$AH;let i,s=0;for(const n of t)s===e.length?e.push(i=new tt(this.O(R()),this.O(R()),this,this.options)):i=e[s],i._$AI(n),s++;s2||""!==i[0]||""!==i[1]?(this._$AH=Array(i.length-1).fill(new String),this.strings=i):this._$AH=G}_$AI(t,e=this,i,s){const n=this.strings;let o=!1;if(void 0===n)t=Z(this,t,e,0),o=!I(t)||t!==this._$AH&&t!==U,o&&(this._$AH=t);else{const s=t;let a,r;for(t=n[0],a=0;a{const s=i?.renderBefore??e;let n=s._$litPart$;if(void 0===n){const t=i?.renderBefore??null;s._$litPart$=n=new tt(e.insertBefore(R(),t),t,void 0,i??{})}return n._$AI(t),n},ct=globalThis;let ht=class extends w{constructor(){super(...arguments),this.renderOptions={host:this},this._$Do=void 0}createRenderRoot(){const t=super.createRenderRoot();return this.renderOptions.renderBefore??=t.firstChild,t}update(t){const e=this.render();this.hasUpdated||(this.renderOptions.isConnected=this.isConnected),super.update(t),this._$Do=lt(e,this.renderRoot,this.renderOptions)}connectedCallback(){super.connectedCallback(),this._$Do?.setConnected(!0)}disconnectedCallback(){super.disconnectedCallback(),this._$Do?.setConnected(!1)}render(){return U}};ht._$litElement$=!0,ht.finalized=!0,ct.litElementHydrateSupport?.({LitElement:ht});const dt=ct.litElementPolyfillSupport;dt?.({LitElement:ht}),(ct.litElementVersions??=[]).push("4.2.2");const pt=2,ut=t=>(...e)=>({_$litDirective$:t,values:e});let _t=class{constructor(t){}get _$AU(){return this._$AM._$AU}_$AT(t,e,i){this._$Ct=t,this._$AM=e,this._$Ci=i}_$AS(t,e){return this.update(t,e)}update(t,e){return this.render(...e)}};const gt={},mt=ut(class extends _t{constructor(){super(...arguments),this.ot=gt}render(t,e){return e()}update(t,[e,i]){if(Array.isArray(e)){if(Array.isArray(this.ot)&&this.ot.length===e.length&&e.every((t,e)=>t===this.ot[e]))return U}else if(this.ot===e)return U;return this.ot=Array.isArray(e)?Array.from(e):e,this.render(e,i)}}),{I:ft}=at,vt=t=>t,yt=()=>document.createComment(""),bt=(t,e,i)=>{const s=t._$AA.parentNode,n=void 0===e?t._$AB:e._$AA;if(void 0===i){const e=s.insertBefore(yt(),n),o=s.insertBefore(yt(),n);i=new ft(e,o,t,t.options)}else{const e=i._$AB.nextSibling,o=i._$AM,a=o!==t;if(a){let e;i._$AQ?.(t),i._$AM=t,void 0!==i._$AP&&(e=t._$AU)!==o._$AU&&i._$AP(e)}if(e!==n||a){let t=i._$AA;for(;t!==e;){const e=vt(t).nextSibling;vt(s).insertBefore(t,n),t=e}}}return i},wt=(t,e,i=t)=>(t._$AI(e,i),t),kt={},xt=(t,e=kt)=>t._$AH=e,$t=t=>{t._$AR(),t._$AA.remove()},St=(t,e,i)=>{const s=new Map;for(let n=e;n<=i;n++)s.set(t[n],n);return s},Mt=ut(class extends _t{constructor(t){if(super(t),t.type!==pt)throw Error("repeat() can only be used in text expressions")}dt(t,e,i){let s;void 0===i?i=e:void 0!==e&&(s=e);const n=[],o=[];let a=0;for(const e of t)n[a]=s?s(e,a):a,o[a]=i(e,a),a++;return{values:o,keys:n}}render(t,e,i){return this.dt(t,e,i).values}update(t,[e,i,s]){const n=(t=>t._$AH)(t),{values:o,keys:a}=this.dt(e,i,s);if(!Array.isArray(n))return this.ut=a,o;const r=this.ut??=[],l=[];let c,h,d=0,p=n.length-1,u=0,_=o.length-1;for(;d<=p&&u<=_;)if(null===n[d])d++;else if(null===n[p])p--;else if(r[d]===a[u])l[u]=wt(n[d],o[u]),d++,u++;else if(r[p]===a[_])l[_]=wt(n[p],o[_]),p--,_--;else if(r[d]===a[_])l[_]=wt(n[d],o[_]),bt(t,l[_+1],n[d]),d++,_--;else if(r[p]===a[u])l[u]=wt(n[p],o[u]),bt(t,n[d],n[p]),p--,u++;else if(void 0===c&&(c=St(a,u,_),h=St(r,d,p)),c.has(r[d]))if(c.has(r[p])){const e=h.get(a[u]),i=void 0!==e?n[e]:null;if(null===i){const e=bt(t,n[d]);wt(e,o[u]),l[u]=e}else l[u]=wt(i,o[u]),bt(t,n[d],i),n[e]=null;u++}else $t(n[p]),p--;else $t(n[d]),d++;for(;u<=_;){const e=bt(t,l[_+1]);wt(e,o[u]),l[u++]=e}for(;d<=p;){const t=n[d++];null!==t&&$t(t)}return this.ut=a,xt(t,l),U}}),Ct=new WeakMap;let Dt=0;class Tt extends ht{constructor(){super(...arguments),this.title="",this.icon="",this.wide=!1,this.dismissOnScrim=!1,this.hass=null,this._opener=null,this._focusRoot=null,this._useHaDialog=!1,this._closing=!1,this._overlays=[],this._titleId="hp-dialog-title-"+ ++Dt,this._focusInitial=()=>{const t=this._focusableElements(),e=t.find(t=>t.hasAttribute("autofocus"))||t[0]||(this._useHaDialog?null:this.renderRoot.querySelector(".close"))||this.renderRoot.querySelector(".surface")||this.renderRoot.querySelector("ha-dialog");e?.focus({preventScroll:!0})},this._requestClose=()=>{this._closing||(this._closing=!0,this.dispatchEvent(new CustomEvent("hp-close",{bubbles:!0,composed:!0})))},this._onKeyDown=t=>{if("Escape"===t.key){t.preventDefault(),t.stopImmediatePropagation(),this._pruneOverlays();const e=this._overlays[this._overlays.length-1];return e?void this._closeOverlay(e,"escape"):void this._requestClose()}if("Tab"!==t.key||this._useHaDialog)return;const e=this.renderRoot.querySelector(".close"),i=e?[e,...this._focusableElements()]:this._focusableElements();if(!i.length)return t.preventDefault(),void this.renderRoot.querySelector(".surface")?.focus({preventScroll:!0});const s=this._deepActiveElement(),n=i[0],o=i[i.length-1];!t.shiftKey||s!==n&&i.includes(s)?t.shiftKey||s!==o||(t.preventDefault(),n.focus()):(t.preventDefault(),o.focus())},this._onFallbackCancel=t=>{t.preventDefault(),this._requestClose()},this._onFallbackClick=t=>{this.dismissOnScrim&&t.target===t.currentTarget&&this._requestClose()}}connectedCallback(){super.connectedCallback(),this._opener=this._deepActiveElement();const t=this.getRootNode();this._focusRoot=t;const e=Ct.get(t)||{dialogs:new Set,opener:this._opener};e.dialogs.add(this),Ct.set(t,e),this._useHaDialog=!!customElements.get("ha-dialog"),this.addEventListener("keydown",this._onKeyDown,!0)}disconnectedCallback(){this.removeEventListener("keydown",this._onKeyDown,!0);const t=[...this._overlays];this._overlays=[];for(const e of t.reverse())e.close("disconnect");const e=this._focusRoot,i=this._opener;this._opener=null,this._focusRoot=null;const s=e?Ct.get(e):void 0;s?.dialogs.delete(this),super.disconnectedCallback(),e&&s&&requestAnimationFrame(()=>{const t=Ct.get(e);if(!t)return;if(!t.dialogs.size)return t.opener?.isConnected&&t.opener.focus({preventScroll:!0}),void Ct.delete(e);const s=i?.closest("hp-dialog");i?.isConnected&&s&&t.dialogs.has(s)&&i.focus({preventScroll:!0})})}firstUpdated(t){if(super.firstUpdated(t),!this._useHaDialog){const t=this.renderRoot.querySelector("dialog");t&&!t.open&&t.showModal()}queueMicrotask(()=>this._focusInitial())}_deepActiveElement(){let t=document.activeElement;for(;t?.shadowRoot?.activeElement;)t=t.shadowRoot.activeElement;return t&&t!==document.body?t:null}_focusableElements(){const t=["[autofocus]","a[href]","button:not([disabled])",'input:not([disabled]):not([type="hidden"])',"select:not([disabled])","textarea:not([disabled])",'[contenteditable="true"]','[tabindex]:not([tabindex="-1"])'].join(","),e=[],i=new Set,s=n=>{if(!i.has(n)){if(i.add(n),n instanceof HTMLElement){if(n.matches(t)&&e.push(n),n instanceof HTMLSlotElement){for(const t of n.assignedNodes({flatten:!0}))s(t);return}if(n.shadowRoot){for(const t of n.shadowRoot.childNodes)s(t);return}}for(const t of n.childNodes)s(t)}};for(const t of this.childNodes)s(t);const n=this.overlayPortal();return n&&s(n),e.filter(t=>{let e=t;for(;e;){const t=getComputedStyle(e);if(e.hidden||e.inert||"true"===e.getAttribute("aria-hidden")||"none"===t.display||"hidden"===t.visibility)return!1;if(e=e.assignedSlot||e.parentElement||(e.getRootNode()instanceof ShadowRoot?e.getRootNode().host:null),e===this)break}return!0})}_pruneOverlays(){this._overlays=this._overlays.filter(t=>t.owner.isConnected)}_closeOverlay(t,e){const i=this._overlays.findIndex(e=>e.token===t.token);i>=0&&this._overlays.splice(i,1),t.close(e)}registerOverlay(t){this._pruneOverlays();const e=this._overlays.find(e=>e.owner===t.owner);e&&this._overlays.splice(this._overlays.indexOf(e),1);const i=t.group||"transient";for(const t of[...this._overlays].reverse())t.group===i&&this._closeOverlay(t,"exclusive");const s={...t,group:i,token:Symbol("hp-overlay")};this._overlays.push(s);let n=!1;return()=>{if(n)return;n=!0;const t=this._overlays.findIndex(t=>t.token===s.token);t>=0&&this._overlays.splice(t,1)}}closeTransientOverlays(t="outside"){this._pruneOverlays();const e=[...this._overlays].filter(t=>"transient"===(t.group||"transient"));for(const i of e.reverse())this._closeOverlay(i,t);return e.length>0}overlayPortal(){return this.renderRoot.querySelector(".overlay-portal")}render(){const t=W`
+globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="f527852beab243e7a346efae1c86117a1f36ed7d04cb2d13ca52f4955fef4106";const t=globalThis,e=t.ShadowRoot&&(void 0===t.ShadyCSS||t.ShadyCSS.nativeShadow)&&"adoptedStyleSheets"in Document.prototype&&"replace"in CSSStyleSheet.prototype,i=Symbol(),s=new WeakMap;let n=class{constructor(t,e,s){if(this._$cssResult$=!0,s!==i)throw Error("CSSResult is not constructable. Use `unsafeCSS` or `css` instead.");this.cssText=t,this.t=e}get styleSheet(){let t=this.o;const i=this.t;if(e&&void 0===t){const e=void 0!==i&&1===i.length;e&&(t=s.get(i)),void 0===t&&((this.o=t=new CSSStyleSheet).replaceSync(this.cssText),e&&s.set(i,t))}return t}toString(){return this.cssText}};const o=(t,...e)=>{const s=1===t.length?t[0]:e.reduce((e,i,s)=>e+(t=>{if(!0===t._$cssResult$)return t.cssText;if("number"==typeof t)return t;throw Error("Value passed to 'css' function must be a 'css' function result: "+t+". Use 'unsafeCSS' to pass non-literal values, but take care to ensure page security.")})(i)+t[s+1],t[0]);return new n(s,t,i)},a=e?t=>t:t=>t instanceof CSSStyleSheet?(t=>{let e="";for(const i of t.cssRules)e+=i.cssText;return(t=>new n("string"==typeof t?t:t+"",void 0,i))(e)})(t):t,{is:r,defineProperty:l,getOwnPropertyDescriptor:c,getOwnPropertyNames:h,getOwnPropertySymbols:d,getPrototypeOf:p}=Object,u=globalThis,_=u.trustedTypes,g=_?_.emptyScript:"",m=u.reactiveElementPolyfillSupport,f=(t,e)=>t,v={toAttribute(t,e){switch(e){case Boolean:t=t?g:null;break;case Object:case Array:t=null==t?t:JSON.stringify(t)}return t},fromAttribute(t,e){let i=t;switch(e){case Boolean:i=null!==t;break;case Number:i=null===t?null:Number(t);break;case Object:case Array:try{i=JSON.parse(t)}catch(t){i=null}}return i}},y=(t,e)=>!r(t,e),b={attribute:!0,type:String,converter:v,reflect:!1,useDefault:!1,hasChanged:y};Symbol.metadata??=Symbol("metadata"),u.litPropertyMetadata??=new WeakMap;let w=class extends HTMLElement{static addInitializer(t){this._$Ei(),(this.l??=[]).push(t)}static get observedAttributes(){return this.finalize(),this._$Eh&&[...this._$Eh.keys()]}static createProperty(t,e=b){if(e.state&&(e.attribute=!1),this._$Ei(),this.prototype.hasOwnProperty(t)&&((e=Object.create(e)).wrapped=!0),this.elementProperties.set(t,e),!e.noAccessor){const i=Symbol(),s=this.getPropertyDescriptor(t,i,e);void 0!==s&&l(this.prototype,t,s)}}static getPropertyDescriptor(t,e,i){const{get:s,set:n}=c(this.prototype,t)??{get(){return this[e]},set(t){this[e]=t}};return{get:s,set(e){const o=s?.call(this);n?.call(this,e),this.requestUpdate(t,o,i)},configurable:!0,enumerable:!0}}static getPropertyOptions(t){return this.elementProperties.get(t)??b}static _$Ei(){if(this.hasOwnProperty(f("elementProperties")))return;const t=p(this);t.finalize(),void 0!==t.l&&(this.l=[...t.l]),this.elementProperties=new Map(t.elementProperties)}static finalize(){if(this.hasOwnProperty(f("finalized")))return;if(this.finalized=!0,this._$Ei(),this.hasOwnProperty(f("properties"))){const t=this.properties,e=[...h(t),...d(t)];for(const i of e)this.createProperty(i,t[i])}const t=this[Symbol.metadata];if(null!==t){const e=litPropertyMetadata.get(t);if(void 0!==e)for(const[t,i]of e)this.elementProperties.set(t,i)}this._$Eh=new Map;for(const[t,e]of this.elementProperties){const i=this._$Eu(t,e);void 0!==i&&this._$Eh.set(i,t)}this.elementStyles=this.finalizeStyles(this.styles)}static finalizeStyles(t){const e=[];if(Array.isArray(t)){const i=new Set(t.flat(1/0).reverse());for(const t of i)e.unshift(a(t))}else void 0!==t&&e.push(a(t));return e}static _$Eu(t,e){const i=e.attribute;return!1===i?void 0:"string"==typeof i?i:"string"==typeof t?t.toLowerCase():void 0}constructor(){super(),this._$Ep=void 0,this.isUpdatePending=!1,this.hasUpdated=!1,this._$Em=null,this._$Ev()}_$Ev(){this._$ES=new Promise(t=>this.enableUpdating=t),this._$AL=new Map,this._$E_(),this.requestUpdate(),this.constructor.l?.forEach(t=>t(this))}addController(t){(this._$EO??=new Set).add(t),void 0!==this.renderRoot&&this.isConnected&&t.hostConnected?.()}removeController(t){this._$EO?.delete(t)}_$E_(){const t=new Map,e=this.constructor.elementProperties;for(const i of e.keys())this.hasOwnProperty(i)&&(t.set(i,this[i]),delete this[i]);t.size>0&&(this._$Ep=t)}createRenderRoot(){const i=this.shadowRoot??this.attachShadow(this.constructor.shadowRootOptions);return((i,s)=>{if(e)i.adoptedStyleSheets=s.map(t=>t instanceof CSSStyleSheet?t:t.styleSheet);else for(const e of s){const s=document.createElement("style"),n=t.litNonce;void 0!==n&&s.setAttribute("nonce",n),s.textContent=e.cssText,i.appendChild(s)}})(i,this.constructor.elementStyles),i}connectedCallback(){this.renderRoot??=this.createRenderRoot(),this.enableUpdating(!0),this._$EO?.forEach(t=>t.hostConnected?.())}enableUpdating(t){}disconnectedCallback(){this._$EO?.forEach(t=>t.hostDisconnected?.())}attributeChangedCallback(t,e,i){this._$AK(t,i)}_$ET(t,e){const i=this.constructor.elementProperties.get(t),s=this.constructor._$Eu(t,i);if(void 0!==s&&!0===i.reflect){const n=(void 0!==i.converter?.toAttribute?i.converter:v).toAttribute(e,i.type);this._$Em=t,null==n?this.removeAttribute(s):this.setAttribute(s,n),this._$Em=null}}_$AK(t,e){const i=this.constructor,s=i._$Eh.get(t);if(void 0!==s&&this._$Em!==s){const t=i.getPropertyOptions(s),n="function"==typeof t.converter?{fromAttribute:t.converter}:void 0!==t.converter?.fromAttribute?t.converter:v;this._$Em=s;const o=n.fromAttribute(e,t.type);this[s]=o??this._$Ej?.get(s)??o,this._$Em=null}}requestUpdate(t,e,i,s=!1,n){if(void 0!==t){const o=this.constructor;if(!1===s&&(n=this[t]),i??=o.getPropertyOptions(t),!((i.hasChanged??y)(n,e)||i.useDefault&&i.reflect&&n===this._$Ej?.get(t)&&!this.hasAttribute(o._$Eu(t,i))))return;this.C(t,e,i)}!1===this.isUpdatePending&&(this._$ES=this._$EP())}C(t,e,{useDefault:i,reflect:s,wrapped:n},o){i&&!(this._$Ej??=new Map).has(t)&&(this._$Ej.set(t,o??e??this[t]),!0!==n||void 0!==o)||(this._$AL.has(t)||(this.hasUpdated||i||(e=void 0),this._$AL.set(t,e)),!0===s&&this._$Em!==t&&(this._$Eq??=new Set).add(t))}async _$EP(){this.isUpdatePending=!0;try{await this._$ES}catch(t){Promise.reject(t)}const t=this.scheduleUpdate();return null!=t&&await t,!this.isUpdatePending}scheduleUpdate(){return this.performUpdate()}performUpdate(){if(!this.isUpdatePending)return;if(!this.hasUpdated){if(this.renderRoot??=this.createRenderRoot(),this._$Ep){for(const[t,e]of this._$Ep)this[t]=e;this._$Ep=void 0}const t=this.constructor.elementProperties;if(t.size>0)for(const[e,i]of t){const{wrapped:t}=i,s=this[e];!0!==t||this._$AL.has(e)||void 0===s||this.C(e,void 0,i,s)}}let t=!1;const e=this._$AL;try{t=this.shouldUpdate(e),t?(this.willUpdate(e),this._$EO?.forEach(t=>t.hostUpdate?.()),this.update(e)):this._$EM()}catch(e){throw t=!1,this._$EM(),e}t&&this._$AE(e)}willUpdate(t){}_$AE(t){this._$EO?.forEach(t=>t.hostUpdated?.()),this.hasUpdated||(this.hasUpdated=!0,this.firstUpdated(t)),this.updated(t)}_$EM(){this._$AL=new Map,this.isUpdatePending=!1}get updateComplete(){return this.getUpdateComplete()}getUpdateComplete(){return this._$ES}shouldUpdate(t){return!0}update(t){this._$Eq&&=this._$Eq.forEach(t=>this._$ET(t,this[t])),this._$EM()}updated(t){}firstUpdated(t){}};w.elementStyles=[],w.shadowRootOptions={mode:"open"},w[f("elementProperties")]=new Map,w[f("finalized")]=new Map,m?.({ReactiveElement:w}),(u.reactiveElementVersions??=[]).push("2.1.2");const k=globalThis,x=t=>t,$=k.trustedTypes,S=$?$.createPolicy("lit-html",{createHTML:t=>t}):void 0,M="$lit$",C=`lit$${Math.random().toFixed(9).slice(2)}$`,D="?"+C,T=`<${D}>`,P=document,R=()=>P.createComment(""),I=t=>null===t||"object"!=typeof t&&"function"!=typeof t,A=Array.isArray,F="[ \t\n\f\r]",E=/<(?:(!--|\/[^a-zA-Z])|(\/?[a-zA-Z][^>\s]*)|(\/?$))/g,z=/-->/g,O=/>/g,N=RegExp(`>|${F}(?:([^\\s"'>=/]+)(${F}*=${F}*(?:[^ \t\n\f\r"'\`<>=]|("|')|))|$)`,"g"),H=/'/g,L=/"/g,B=/^(?:script|style|textarea|title)$/i,q=t=>(e,...i)=>({_$litType$:t,strings:e,values:i}),W=q(1),j=q(2),U=Symbol.for("lit-noChange"),G=Symbol.for("lit-nothing"),V=new WeakMap,K=P.createTreeWalker(P,129);function Y(t,e){if(!A(t)||!t.hasOwnProperty("raw"))throw Error("invalid template strings array");return void 0!==S?S.createHTML(e):e}const X=(t,e)=>{const i=t.length-1,s=[];let n,o=2===e?"":3===e?"":"",a=E;for(let e=0;e"===l[0]?(a=n??E,c=-1):void 0===l[1]?c=-2:(c=a.lastIndex-l[2].length,r=l[1],a=void 0===l[3]?N:'"'===l[3]?L:H):a===L||a===H?a=N:a===z||a===O?a=E:(a=N,n=void 0);const d=a===N&&t[e+1].startsWith("/>")?" ":"";o+=a===E?i+T:c>=0?(s.push(r),i.slice(0,c)+M+i.slice(c)+C+d):i+C+(-2===c?e:d)}return[Y(t,o+(t[i]||">")+(2===e?" ":3===e?"":"")),s]};class J{constructor({strings:t,_$litType$:e},i){let s;this.parts=[];let n=0,o=0;const a=t.length-1,r=this.parts,[l,c]=X(t,e);if(this.el=J.createElement(l,i),K.currentNode=this.el.content,2===e||3===e){const t=this.el.content.firstChild;t.replaceWith(...t.childNodes)}for(;null!==(s=K.nextNode())&&r.length0){s.textContent=$?$.emptyScript:"";for(let i=0;iA(t)||"function"==typeof t?.[Symbol.iterator])(t)?this.k(t):this._(t)}O(t){return this._$AA.parentNode.insertBefore(t,this._$AB)}T(t){this._$AH!==t&&(this._$AR(),this._$AH=this.O(t))}_(t){this._$AH!==G&&I(this._$AH)?this._$AA.nextSibling.data=t:this.T(P.createTextNode(t)),this._$AH=t}$(t){const{values:e,_$litType$:i}=t,s="number"==typeof i?this._$AC(t):(void 0===i.el&&(i.el=J.createElement(Y(i.h,i.h[0]),this.options)),i);if(this._$AH?._$AD===s)this._$AH.p(e);else{const t=new Q(s,this),i=t.u(this.options);t.p(e),this.T(i),this._$AH=t}}_$AC(t){let e=V.get(t.strings);return void 0===e&&V.set(t.strings,e=new J(t)),e}k(t){A(this._$AH)||(this._$AH=[],this._$AR());const e=this._$AH;let i,s=0;for(const n of t)s===e.length?e.push(i=new tt(this.O(R()),this.O(R()),this,this.options)):i=e[s],i._$AI(n),s++;s2||""!==i[0]||""!==i[1]?(this._$AH=Array(i.length-1).fill(new String),this.strings=i):this._$AH=G}_$AI(t,e=this,i,s){const n=this.strings;let o=!1;if(void 0===n)t=Z(this,t,e,0),o=!I(t)||t!==this._$AH&&t!==U,o&&(this._$AH=t);else{const s=t;let a,r;for(t=n[0],a=0;a{const s=i?.renderBefore??e;let n=s._$litPart$;if(void 0===n){const t=i?.renderBefore??null;s._$litPart$=n=new tt(e.insertBefore(R(),t),t,void 0,i??{})}return n._$AI(t),n},ct=globalThis;let ht=class extends w{constructor(){super(...arguments),this.renderOptions={host:this},this._$Do=void 0}createRenderRoot(){const t=super.createRenderRoot();return this.renderOptions.renderBefore??=t.firstChild,t}update(t){const e=this.render();this.hasUpdated||(this.renderOptions.isConnected=this.isConnected),super.update(t),this._$Do=lt(e,this.renderRoot,this.renderOptions)}connectedCallback(){super.connectedCallback(),this._$Do?.setConnected(!0)}disconnectedCallback(){super.disconnectedCallback(),this._$Do?.setConnected(!1)}render(){return U}};ht._$litElement$=!0,ht.finalized=!0,ct.litElementHydrateSupport?.({LitElement:ht});const dt=ct.litElementPolyfillSupport;dt?.({LitElement:ht}),(ct.litElementVersions??=[]).push("4.2.2");const pt=2,ut=t=>(...e)=>({_$litDirective$:t,values:e});let _t=class{constructor(t){}get _$AU(){return this._$AM._$AU}_$AT(t,e,i){this._$Ct=t,this._$AM=e,this._$Ci=i}_$AS(t,e){return this.update(t,e)}update(t,e){return this.render(...e)}};const gt={},mt=ut(class extends _t{constructor(){super(...arguments),this.ot=gt}render(t,e){return e()}update(t,[e,i]){if(Array.isArray(e)){if(Array.isArray(this.ot)&&this.ot.length===e.length&&e.every((t,e)=>t===this.ot[e]))return U}else if(this.ot===e)return U;return this.ot=Array.isArray(e)?Array.from(e):e,this.render(e,i)}}),{I:ft}=at,vt=t=>t,yt=()=>document.createComment(""),bt=(t,e,i)=>{const s=t._$AA.parentNode,n=void 0===e?t._$AB:e._$AA;if(void 0===i){const e=s.insertBefore(yt(),n),o=s.insertBefore(yt(),n);i=new ft(e,o,t,t.options)}else{const e=i._$AB.nextSibling,o=i._$AM,a=o!==t;if(a){let e;i._$AQ?.(t),i._$AM=t,void 0!==i._$AP&&(e=t._$AU)!==o._$AU&&i._$AP(e)}if(e!==n||a){let t=i._$AA;for(;t!==e;){const e=vt(t).nextSibling;vt(s).insertBefore(t,n),t=e}}}return i},wt=(t,e,i=t)=>(t._$AI(e,i),t),kt={},xt=(t,e=kt)=>t._$AH=e,$t=t=>{t._$AR(),t._$AA.remove()},St=(t,e,i)=>{const s=new Map;for(let n=e;n<=i;n++)s.set(t[n],n);return s},Mt=ut(class extends _t{constructor(t){if(super(t),t.type!==pt)throw Error("repeat() can only be used in text expressions")}dt(t,e,i){let s;void 0===i?i=e:void 0!==e&&(s=e);const n=[],o=[];let a=0;for(const e of t)n[a]=s?s(e,a):a,o[a]=i(e,a),a++;return{values:o,keys:n}}render(t,e,i){return this.dt(t,e,i).values}update(t,[e,i,s]){const n=(t=>t._$AH)(t),{values:o,keys:a}=this.dt(e,i,s);if(!Array.isArray(n))return this.ut=a,o;const r=this.ut??=[],l=[];let c,h,d=0,p=n.length-1,u=0,_=o.length-1;for(;d<=p&&u<=_;)if(null===n[d])d++;else if(null===n[p])p--;else if(r[d]===a[u])l[u]=wt(n[d],o[u]),d++,u++;else if(r[p]===a[_])l[_]=wt(n[p],o[_]),p--,_--;else if(r[d]===a[_])l[_]=wt(n[d],o[_]),bt(t,l[_+1],n[d]),d++,_--;else if(r[p]===a[u])l[u]=wt(n[p],o[u]),bt(t,n[d],n[p]),p--,u++;else if(void 0===c&&(c=St(a,u,_),h=St(r,d,p)),c.has(r[d]))if(c.has(r[p])){const e=h.get(a[u]),i=void 0!==e?n[e]:null;if(null===i){const e=bt(t,n[d]);wt(e,o[u]),l[u]=e}else l[u]=wt(i,o[u]),bt(t,n[d],i),n[e]=null;u++}else $t(n[p]),p--;else $t(n[d]),d++;for(;u<=_;){const e=bt(t,l[_+1]);wt(e,o[u]),l[u++]=e}for(;d<=p;){const t=n[d++];null!==t&&$t(t)}return this.ut=a,xt(t,l),U}}),Ct=new WeakMap;let Dt=0;class Tt extends ht{constructor(){super(...arguments),this.title="",this.icon="",this.wide=!1,this.dismissOnScrim=!1,this.hass=null,this._opener=null,this._focusRoot=null,this._useHaDialog=!1,this._closing=!1,this._overlays=[],this._titleId="hp-dialog-title-"+ ++Dt,this._focusInitial=()=>{const t=this._focusableElements(),e=t.find(t=>t.hasAttribute("autofocus"))||t[0]||(this._useHaDialog?null:this.renderRoot.querySelector(".close"))||this.renderRoot.querySelector(".surface")||this.renderRoot.querySelector("ha-dialog");e?.focus({preventScroll:!0})},this._requestClose=()=>{this._closing||(this._closing=!0,this.dispatchEvent(new CustomEvent("hp-close",{bubbles:!0,composed:!0})))},this._onKeyDown=t=>{if("Escape"===t.key){t.preventDefault(),t.stopImmediatePropagation(),this._pruneOverlays();const e=this._overlays[this._overlays.length-1];return e?void this._closeOverlay(e,"escape"):void this._requestClose()}if("Tab"!==t.key||this._useHaDialog)return;const e=this.renderRoot.querySelector(".close"),i=e?[e,...this._focusableElements()]:this._focusableElements();if(!i.length)return t.preventDefault(),void this.renderRoot.querySelector(".surface")?.focus({preventScroll:!0});const s=this._deepActiveElement(),n=i[0],o=i[i.length-1];!t.shiftKey||s!==n&&i.includes(s)?t.shiftKey||s!==o||(t.preventDefault(),n.focus()):(t.preventDefault(),o.focus())},this._onFallbackCancel=t=>{t.preventDefault(),this._requestClose()},this._onFallbackClick=t=>{this.dismissOnScrim&&t.target===t.currentTarget&&this._requestClose()}}connectedCallback(){super.connectedCallback(),this._opener=this._deepActiveElement();const t=this.getRootNode();this._focusRoot=t;const e=Ct.get(t)||{dialogs:new Set,opener:this._opener};e.dialogs.add(this),Ct.set(t,e),this._useHaDialog=!!customElements.get("ha-dialog"),this.addEventListener("keydown",this._onKeyDown,!0)}disconnectedCallback(){this.removeEventListener("keydown",this._onKeyDown,!0);const t=[...this._overlays];this._overlays=[];for(const e of t.reverse())e.close("disconnect");const e=this._focusRoot,i=this._opener;this._opener=null,this._focusRoot=null;const s=e?Ct.get(e):void 0;s?.dialogs.delete(this),super.disconnectedCallback(),e&&s&&requestAnimationFrame(()=>{const t=Ct.get(e);if(!t)return;if(!t.dialogs.size)return t.opener?.isConnected&&t.opener.focus({preventScroll:!0}),void Ct.delete(e);const s=i?.closest("hp-dialog");i?.isConnected&&s&&t.dialogs.has(s)&&i.focus({preventScroll:!0})})}firstUpdated(t){if(super.firstUpdated(t),!this._useHaDialog){const t=this.renderRoot.querySelector("dialog");t&&!t.open&&t.showModal()}queueMicrotask(()=>this._focusInitial())}_deepActiveElement(){let t=document.activeElement;for(;t?.shadowRoot?.activeElement;)t=t.shadowRoot.activeElement;return t&&t!==document.body?t:null}_focusableElements(){const t=["[autofocus]","a[href]","button:not([disabled])",'input:not([disabled]):not([type="hidden"])',"select:not([disabled])","textarea:not([disabled])",'[contenteditable="true"]','[tabindex]:not([tabindex="-1"])'].join(","),e=[],i=new Set,s=n=>{if(!i.has(n)){if(i.add(n),n instanceof HTMLElement){if(n.matches(t)&&e.push(n),n instanceof HTMLSlotElement){for(const t of n.assignedNodes({flatten:!0}))s(t);return}if(n.shadowRoot){for(const t of n.shadowRoot.childNodes)s(t);return}}for(const t of n.childNodes)s(t)}};for(const t of this.childNodes)s(t);const n=this.overlayPortal();return n&&s(n),e.filter(t=>{let e=t;for(;e;){const t=getComputedStyle(e);if(e.hidden||e.inert||"true"===e.getAttribute("aria-hidden")||"none"===t.display||"hidden"===t.visibility)return!1;if(e=e.assignedSlot||e.parentElement||(e.getRootNode()instanceof ShadowRoot?e.getRootNode().host:null),e===this)break}return!0})}_pruneOverlays(){this._overlays=this._overlays.filter(t=>t.owner.isConnected)}_closeOverlay(t,e){const i=this._overlays.findIndex(e=>e.token===t.token);i>=0&&this._overlays.splice(i,1),t.close(e)}registerOverlay(t){this._pruneOverlays();const e=this._overlays.find(e=>e.owner===t.owner);e&&this._overlays.splice(this._overlays.indexOf(e),1);const i=t.group||"transient";for(const t of[...this._overlays].reverse())t.group===i&&this._closeOverlay(t,"exclusive");const s={...t,group:i,token:Symbol("hp-overlay")};this._overlays.push(s);let n=!1;return()=>{if(n)return;n=!0;const t=this._overlays.findIndex(t=>t.token===s.token);t>=0&&this._overlays.splice(t,1)}}closeTransientOverlays(t="outside"){this._pruneOverlays();const e=[...this._overlays].filter(t=>"transient"===(t.group||"transient"));for(const i of e.reverse())this._closeOverlay(i,t);return e.length>0}overlayPortal(){return this.renderRoot.querySelector(".overlay-portal")}render(){const t=W`
${this.icon?W` `:G}
${this.title}
`;return this._useHaDialog?W` sha256Bytes(readFileSync(name));
const committedFile = (sha, name) => runBytes('git', ['show', `${sha}:${name}`]);
const assertBundleSnapshots = (sha) => {
+ // Копия стенда (`demo/srv/assets`) больше не коммитится (#255): её собирает
+ // `npm run bundle:sync` перед браузерными прогонами. В релиз входят ровно
+ // две копии — артефакт сборки и та, что ставит HACS.
const names = [
'dist/houseplan-card.js',
'custom_components/houseplan/frontend/houseplan-card.js',
- 'demo/srv/assets/houseplan-card.js',
];
// Hash Git blobs, not checkout bytes. On Windows, Git can expose CRLF in
// the worktree while the exact tagged blobs and Linux release checkout use
diff --git a/test/repo-hygiene.test.mjs b/test/repo-hygiene.test.mjs
index e5dbc415..ad0b711c 100644
--- a/test/repo-hygiene.test.mjs
+++ b/test/repo-hygiene.test.mjs
@@ -19,3 +19,19 @@ test('the tree carries exactly one *manifest.json: HACS rejects a repository wit
const found = tracked.filter((path) => path.split('/').pop().endsWith('manifest.json'));
assert.deepEqual(found, ['custom_components/houseplan/manifest.json']);
});
+
+// #255. Копия бандла для стенда весит 1.16 МБ и переписывается почти каждым
+// продуктовым коммитом: 364 версии за семь недель — примерно четверть всего
+// репозитория. Она нужна только браузерным прогонам, которые собирают её сами
+// (`npm run bundle:sync`), поэтому в дереве её быть не должно. Проверка стоит
+// здесь, а не в глазах ревьюера: вернуть файл обратно проще всего случайно,
+// одним `git add -A` после локальной сборки.
+test('копия бандла для стенда не коммитится (#255)', () => {
+ const tracked = execFileSync('git', ['ls-files', '-z', 'demo/srv/assets'], { cwd: ROOT })
+ .toString('utf8').split('\0').filter(Boolean);
+ assert.ok(!tracked.includes('demo/srv/assets/houseplan-card.js'),
+ 'demo/srv/assets/houseplan-card.js снова в индексе: соберите его `npm run bundle:sync`, '
+ + 'а из коммита уберите');
+ // Остальное содержимое стенда (иконки, страницы) коммитится и должно остаться.
+ assert.ok(tracked.length > 0, 'каталог стенда пуст: проверьте, что убрали только бандл');
+});