diff --git a/custom_components/houseplan/frontend/houseplan-assets.json b/custom_components/houseplan/frontend/houseplan-assets.json index c80b15a8..3141e104 100644 --- a/custom_components/houseplan/frontend/houseplan-assets.json +++ b/custom_components/houseplan/frontend/houseplan-assets.json @@ -1,125 +1,125 @@ { "schema": 1, - "fingerprint": "b36c2306f25315638c0178090efd6865650040c5565d6ad92430103558fe37db", + "fingerprint": "2195ace683267664d035370d92e860e463a0a745074964ec60eb91b9460fe406", "entry": "houseplan-card.js", "initialViewFiles": [ - "houseplan-assets/houseplan-card-Bi2pkTUe.js", + "houseplan-assets/houseplan-card-DXakp5oa.js", "houseplan-card.js" ], - "initialViewGzipBytes": 287370, + "initialViewGzipBytes": 287369, "lazyFiles": [ - "houseplan-assets/backdrop-pick-BPPgYv_-.js", - "houseplan-assets/de-r_k_qwtG.js", - "houseplan-assets/editor-9X7zagKL.js", - "houseplan-assets/fr-iDaS4KiM.js", - "houseplan-assets/houseplan-editor-runtime-pL7NqSUJ.js", - "houseplan-assets/houseplan-onboarding-runtime-Bzt-dklc.js" + "houseplan-assets/backdrop-pick-YVCyO6A0.js", + "houseplan-assets/de-BEGoVhHu.js", + "houseplan-assets/editor-b0lFtnKI.js", + "houseplan-assets/fr-BDUBoPOz.js", + "houseplan-assets/houseplan-editor-runtime-Bf-E2NBt.js", + "houseplan-assets/houseplan-onboarding-runtime-MR4ITSR4.js" ], - "lazyGzipBytes": 199383, + "lazyGzipBytes": 199380, "lazyEditorFiles": [ - "houseplan-assets/backdrop-pick-BPPgYv_-.js", - "houseplan-assets/editor-9X7zagKL.js", - "houseplan-assets/houseplan-editor-runtime-pL7NqSUJ.js" + "houseplan-assets/backdrop-pick-YVCyO6A0.js", + "houseplan-assets/editor-b0lFtnKI.js", + "houseplan-assets/houseplan-editor-runtime-Bf-E2NBt.js" ], - "lazyEditorGzipBytes": 144689, + "lazyEditorGzipBytes": 144690, "lazyOnboardingFiles": [ - "houseplan-assets/backdrop-pick-BPPgYv_-.js", - "houseplan-assets/houseplan-onboarding-runtime-Bzt-dklc.js" + "houseplan-assets/backdrop-pick-YVCyO6A0.js", + "houseplan-assets/houseplan-onboarding-runtime-MR4ITSR4.js" ], - "lazyOnboardingGzipBytes": 14031, + "lazyOnboardingGzipBytes": 14029, "lazyLocaleFiles": [ - "houseplan-assets/de-r_k_qwtG.js", - "houseplan-assets/fr-iDaS4KiM.js" + "houseplan-assets/de-BEGoVhHu.js", + "houseplan-assets/fr-BDUBoPOz.js" ], - "lazyLocaleGzipBytes": 47735, + "lazyLocaleGzipBytes": 47731, "files": [ { - "path": "houseplan-assets/backdrop-pick-BPPgYv_-.js", - "sha256": "af775ad674123c0fe86c1f367fddab92f6c95cc1a3a455709c46bee48b143872", + "path": "houseplan-assets/backdrop-pick-YVCyO6A0.js", + "sha256": "7eb697cfff4e5c645e5dc870c020d321bdbcc12a7cbb5fb69ff0fd3eaf8a4827", "rawBytes": 20636, - "gzipBytes": 7072, + "gzipBytes": 7070, "isEntry": false, "imports": [ - "houseplan-assets/houseplan-card-Bi2pkTUe.js" + "houseplan-assets/houseplan-card-DXakp5oa.js" ], "dynamicImports": [] }, { - "path": "houseplan-assets/de-r_k_qwtG.js", - "sha256": "3495a17186b5f746f7465999ae6892033644d26b730c076ed83a08b6d118f0e6", + "path": "houseplan-assets/de-BEGoVhHu.js", + "sha256": "1e681536e02fb02a2626b3f3d73903bd2ceacdcb7b4310f1ebdabb67e8ea7857", "rawBytes": 79660, - "gzipBytes": 24118, + "gzipBytes": 24116, "isEntry": false, "imports": [], "dynamicImports": [] }, { - "path": "houseplan-assets/editor-9X7zagKL.js", - "sha256": "795170e9a06f0bf8928a32e04463f4e897a9ac1c39ca73d8203ce182539150b1", + "path": "houseplan-assets/editor-b0lFtnKI.js", + "sha256": "52920f458ae8514f4ab6651a33845aa1b88d3741323f470e0231d2c911ce34dd", "rawBytes": 3826, - "gzipBytes": 1582, + "gzipBytes": 1581, "isEntry": false, "imports": [ - "houseplan-assets/houseplan-card-Bi2pkTUe.js" + "houseplan-assets/houseplan-card-DXakp5oa.js" ], "dynamicImports": [] }, { - "path": "houseplan-assets/fr-iDaS4KiM.js", - "sha256": "2984c303f30680207d7a069105eae0654d618dda3d57149e1d08fa783b0bf811", + "path": "houseplan-assets/fr-BDUBoPOz.js", + "sha256": "59f029c824f5836d699de2034813e9bfd481c837bae50a81de358ff86c042f3b", "rawBytes": 81807, - "gzipBytes": 23617, + "gzipBytes": 23615, "isEntry": false, "imports": [], "dynamicImports": [] }, { - "path": "houseplan-assets/houseplan-card-Bi2pkTUe.js", - "sha256": "4eb22945e063cc1cb1ea3dc7c32fe2c34a8ef66a6896243ffdbe23d06d699115", + "path": "houseplan-assets/houseplan-card-DXakp5oa.js", + "sha256": "f7940dd06a85c23dd2d28fd498a7a6305da32111e871f784351f3e0f5d91794b", "rawBytes": 1017921, "gzipBytes": 286572, "isEntry": false, "imports": [], "dynamicImports": [ - "houseplan-assets/de-r_k_qwtG.js", - "houseplan-assets/editor-9X7zagKL.js", - "houseplan-assets/fr-iDaS4KiM.js", - "houseplan-assets/houseplan-editor-runtime-pL7NqSUJ.js", - "houseplan-assets/houseplan-onboarding-runtime-Bzt-dklc.js" + "houseplan-assets/de-BEGoVhHu.js", + "houseplan-assets/editor-b0lFtnKI.js", + "houseplan-assets/fr-BDUBoPOz.js", + "houseplan-assets/houseplan-editor-runtime-Bf-E2NBt.js", + "houseplan-assets/houseplan-onboarding-runtime-MR4ITSR4.js" ] }, { - "path": "houseplan-assets/houseplan-editor-runtime-pL7NqSUJ.js", - "sha256": "8dc46cb722e0d1703cde49ace8587d2871e8acff44a19108ab5a6e78ef9957ae", - "rawBytes": 527184, - "gzipBytes": 136035, + "path": "houseplan-assets/houseplan-editor-runtime-Bf-E2NBt.js", + "sha256": "378202552bee2c88535b64244cba36ec1f1de7f21676bf6d177b3ab1931d209c", + "rawBytes": 527211, + "gzipBytes": 136039, "isEntry": false, "imports": [ - "houseplan-assets/backdrop-pick-BPPgYv_-.js", - "houseplan-assets/houseplan-card-Bi2pkTUe.js" + "houseplan-assets/backdrop-pick-YVCyO6A0.js", + "houseplan-assets/houseplan-card-DXakp5oa.js" ], "dynamicImports": [] }, { - "path": "houseplan-assets/houseplan-onboarding-runtime-Bzt-dklc.js", - "sha256": "d0ee6193635d42fff228dd4e0bf52ceec5075351032524cb50920887a128128f", + "path": "houseplan-assets/houseplan-onboarding-runtime-MR4ITSR4.js", + "sha256": "b26c1bed651ebef10d36bd435119b3a0e194cc5419999ccfc4ecdff9299c260c", "rawBytes": 28088, "gzipBytes": 6959, "isEntry": false, "imports": [ - "houseplan-assets/backdrop-pick-BPPgYv_-.js", - "houseplan-assets/houseplan-card-Bi2pkTUe.js" + "houseplan-assets/backdrop-pick-YVCyO6A0.js", + "houseplan-assets/houseplan-card-DXakp5oa.js" ], "dynamicImports": [] }, { "path": "houseplan-card.js", - "sha256": "3ce2c954888ca57942b9b3f138da95f1fa5177d5c9965a89d07d179c26ab3300", + "sha256": "9317a9b6fcb643f24931d79e55a7ed692828058ccb9c9b811559c3854962175e", "rawBytes": 1183, - "gzipBytes": 798, + "gzipBytes": 797, "isEntry": true, "imports": [ - "houseplan-assets/houseplan-card-Bi2pkTUe.js" + "houseplan-assets/houseplan-card-DXakp5oa.js" ], "dynamicImports": [] } diff --git a/custom_components/houseplan/frontend/houseplan-assets/backdrop-pick-BPPgYv_-.js b/custom_components/houseplan/frontend/houseplan-assets/backdrop-pick-YVCyO6A0.js similarity index 99% rename from custom_components/houseplan/frontend/houseplan-assets/backdrop-pick-BPPgYv_-.js rename to custom_components/houseplan/frontend/houseplan-assets/backdrop-pick-YVCyO6A0.js index e98cffd8..04039b84 100644 --- a/custom_components/houseplan/frontend/houseplan-assets/backdrop-pick-BPPgYv_-.js +++ b/custom_components/houseplan/frontend/houseplan-assets/backdrop-pick-YVCyO6A0.js @@ -1,4 +1,4 @@ -globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="b36c2306f25315638c0178090efd6865650040c5565d6ad92430103558fe37db";import{d6 as e,c as t,A as i,a as o,b as n,d7 as s}from"./houseplan-card-Bi2pkTUe.js";function r(e){const t=e.visualViewport;return t&&Number.isFinite(t.width)&&Number.isFinite(t.height)?{left:Number(t.offsetLeft)||0,top:Number(t.offsetTop)||0,width:Math.max(0,Number(t.width)||0),height:Math.max(0,Number(t.height)||0)}:{left:0,top:0,width:e.innerWidth,height:e.innerHeight}}function a(e,t,i,o=7,n=8){const s=i.left+n,r=i.top+n,a=Math.max(s,i.left+i.width-n),l=Math.max(r,i.top+i.height-n),h=Math.max(0,a-s),c=Math.max(0,l-r),d=Math.min(Math.max(0,t.width),h),u=Math.min(Math.max(0,t.height),c);let p=e.left;p+d>a&&(p=e.right-d),p=Math.min(Math.max(s,p),Math.max(s,a-d));const _=e.bottom+o,g=e.top-o-u;let m="bottom",f=_;return _+u>l&&g>=r?(m="top",f=Math.min(Math.max(r,g),Math.max(r,l-u))):f=Math.min(Math.max(r,_),Math.max(r,l-u)),{left:Math.round(p),top:Math.round(f),side:m,maxWidth:Math.round(h),maxHeight:Math.round(c)}}class l{constructor(e,t,i){this.owner=e,this.name=t,this.keydown=i,this.host=null,this.root=null}window(){return this.owner.ownerDocument.defaultView}dialog(){return this.owner.closest("hp-dialog")}usesPopover(e=!1){const t=this.window();return!e&&!!t&&function(e){const t=e.HTMLElement?.prototype;return"function"==typeof t?.showPopover&&"function"==typeof t?.hidePopover}(t)}get hasFallback(){return!!this.host}containsPath(e){return e.includes(this.owner)||!!this.host&&e.includes(this.host)}ownsActiveElement(){let e=this.owner.ownerDocument.activeElement;for(;e?.shadowRoot?.activeElement;)e=e.shadowRoot.activeElement;return!(!e||e!==this.owner&&!this.owner.shadowRoot?.contains(e)&&!this.root?.contains(e))}renderFallback(i,o){const n=this.ensureFallback();return n?(e(t`${i}`,n),n):null}surface(e,t){return t?this.owner.shadowRoot?.querySelector(e)||null:this.root?.querySelector(e)||null}destroy(){this.root&&e(i,this.root),this.host?.remove(),this.host=null,this.root=null}ensureFallback(){if(this.root?.isConnected)return this.root;const e=this.dialog()?.overlayPortal()||this.owner.ownerDocument.body;if(!e)return null;const t=this.owner.ownerDocument.createElement("div");return t.dataset.hpOverlay=this.name,t.style.display="contents",this.keydown&&t.addEventListener("keydown",this.keydown,!0),e.append(t),this.host=t,this.root=t.attachShadow({mode:"open"}),this.root}}let h=0;class c extends n{constructor(){super(...arguments),this.text="",this.ariaLabel="",this.pointerHover=!1,this._open=!1,this._openTimer=0,this._closeTimer=0,this._positionRaf=0,this._forceFallback=!1,this._hoverOwned=!1,this._overlayDispose=null,this._scrollDialog=null,this._descriptionId="hp-help-description-"+ ++h,this._surfacePointerEnter=()=>{const e=this._window();this._closeTimer&&e?.clearTimeout(this._closeTimer),this._closeTimer=0},this._surfacePointerLeave=()=>{this._scheduleClose()},this._outsidePointerDown=e=>{if(!this._open)return;const t=e.composedPath();this._floating.containsPath(t)||this._closeHelp(!1,"outside")},this._dialogScroll=e=>{const t=this._floating.containsPath(e.composedPath()),i=e.target,o=this._dialog(),n=i instanceof Node&&(i===o||i instanceof Element&&i.contains(this));var s;this._open&&(s=n,!t&&s)&&this._closeHelp(!1,"scroll")},this._keyDown=e=>{if(!this._open||e.defaultPrevented)return;if("Escape"===e.key)return e.preventDefault(),e.stopImmediatePropagation(),void this._closeHelp(this._floating.ownsActiveElement(),"escape");const t=this.renderRoot.querySelector(".trigger");if(!t||!e.composedPath().includes(t))return;const i=this._surface();if(!i||i.scrollHeight<=i.clientHeight)return;const o=Math.max(40,.8*i.clientHeight),n={ArrowDown:40,ArrowUp:-40,PageDown:o,PageUp:-o};if("Home"===e.key)i.scrollTop=0;else if("End"===e.key)i.scrollTop=i.scrollHeight;else{if(!(e.key in n))return;i.scrollBy({top:n[e.key],behavior:"auto"})}e.preventDefault(),e.stopImmediatePropagation()},this._floating=new l(this,"help",this._keyDown),this._queuePosition=()=>{if(!this._open||this._positionRaf)return;const e=this._window();e&&(this._positionRaf=e.requestAnimationFrame(()=>{this._positionRaf=0,this._position()||this._closeHelp()}))}}connectedCallback(){super.connectedCallback(),this.addEventListener("keydown",this._keyDown,!0)}willUpdate(){this.toggleAttribute("data-has-content",this._hasContent())}disconnectedCallback(){const e=this.ownerDocument.defaultView;this._unsubscribeOpenListeners(),this.removeEventListener("keydown",this._keyDown,!0),this._clearTimers(),this._positionRaf&&e?.cancelAnimationFrame(this._positionRaf),this._positionRaf=0,this._closeHelp(!1,"disconnect"),super.disconnectedCallback()}updated(e){if(e.has("pointerHover")&&!this.pointerHover){const e=this._window();this._openTimer&&e?.clearTimeout(this._openTimer),this._openTimer=0,this._hoverOwned&&this._closeHelp(!1,"outside")}this._hasContent()||!this._open?this._open&&e.has("text")&&(this._usesPopover()||this._renderFallback(),this._queuePosition()):this._closeHelp()}_window(){return this._floating.window()}_dialog(){return this._floating.dialog()}_usesPopover(){return this._floating.usesPopover(this._forceFallback)}_hasContent(){return e=this.text,t=this.ariaLabel,"string"==typeof e&&e.trim().length>0&&"string"==typeof t&&t.trim().length>0;var e,t}_clearTimers(){const e=this._window();this._openTimer&&e?.clearTimeout(this._openTimer),this._closeTimer&&e?.clearTimeout(this._closeTimer),this._openTimer=0,this._closeTimer=0}_scheduleOpen(){const e=this._window();this.pointerHover&&e&&!this._open&&!this._openTimer&&(this._closeTimer&&e.clearTimeout(this._closeTimer),this._closeTimer=0,this._openTimer=e.setTimeout(()=>{this._openTimer=0,this.isConnected&&(this._hoverOwned=!0,this._openHelp())},300))}_scheduleClose(){const e=this._window(),t=this.renderRoot.querySelector(".trigger");e&&!t?.matches(":focus-visible")&&(this._openTimer&&e.clearTimeout(this._openTimer),this._closeTimer&&e.clearTimeout(this._closeTimer),this._openTimer=0,this._closeTimer=e.setTimeout(()=>{this._closeTimer=0,this.isConnected&&this._closeHelp()},150))}_triggerPointerEnter(e){this.pointerHover&&"mouse"===e.pointerType&&this._scheduleOpen()}_triggerPointerLeave(e){"mouse"===e.pointerType&&this._scheduleClose()}_triggerFocus(){queueMicrotask(()=>{const e=this.renderRoot.querySelector(".trigger");e?.matches(":focus-visible")&&(this._hoverOwned=!1,this._openHelp())})}_triggerBlur(){this._scheduleClose()}_triggerClick(){this._open?this._closeHelp():(this._hoverOwned=!1,this._openHelp())}_subscribeOpenListeners(){this.ownerDocument.addEventListener("pointerdown",this._outsidePointerDown,!0),this.ownerDocument.addEventListener("keydown",this._keyDown,!0);const e=this._window();e?.addEventListener("resize",this._queuePosition),e?.addEventListener("orientationchange",this._queuePosition),e?.visualViewport?.addEventListener("resize",this._queuePosition),e?.visualViewport?.addEventListener("scroll",this._queuePosition),this._scrollDialog=this._dialog(),this._scrollDialog?.addEventListener("scroll",this._dialogScroll,!0)}_unsubscribeOpenListeners(){this.ownerDocument.removeEventListener("pointerdown",this._outsidePointerDown,!0),this.ownerDocument.removeEventListener("keydown",this._keyDown,!0);const e=this._window();e?.removeEventListener("resize",this._queuePosition),e?.removeEventListener("orientationchange",this._queuePosition),e?.visualViewport?.removeEventListener("resize",this._queuePosition),e?.visualViewport?.removeEventListener("scroll",this._queuePosition),this._scrollDialog?.removeEventListener("scroll",this._dialogScroll,!0),this._scrollDialog=null}async _openHelp(){!this._open&&this._hasContent()&&(this._clearTimers(),this._forceFallback=!1,this._open=!0,this._subscribeOpenListeners(),await this.updateComplete,this._open&&(this._usesPopover()||this._renderFallback(),this._position()?this._overlayDispose=this._dialog()?.registerOverlay({owner:this,group:"transient",close:e=>this._closeHelp("escape"===e&&this._floating.ownsActiveElement(),e)})||null:this._closeHelp()))}_closeHelp(e=!1,t="exclusive"){if(!this._open&&!this._floating.hasFallback)return;this._clearTimers();const i=this._overlayDispose;this._overlayDispose=null,i?.();const o=this.renderRoot.querySelector(".tooltip");if(o?.hidePopover)try{o.matches(":popover-open")&&o.hidePopover()}catch{}this._open=!1,this._hoverOwned=!1,this._unsubscribeOpenListeners(),this._floating.destroy(),e&&this.updateComplete.then(()=>this.renderRoot.querySelector(".trigger")?.focus())}_tooltipTemplate(e){return t`
a&&(p=e.right-d),p=Math.min(Math.max(s,p),Math.max(s,a-d));const _=e.bottom+o,g=e.top-o-u;let m="bottom",f=_;return _+u>l&&g>=r?(m="top",f=Math.min(Math.max(r,g),Math.max(r,l-u))):f=Math.min(Math.max(r,_),Math.max(r,l-u)),{left:Math.round(p),top:Math.round(f),side:m,maxWidth:Math.round(h),maxHeight:Math.round(c)}}class l{constructor(e,t,i){this.owner=e,this.name=t,this.keydown=i,this.host=null,this.root=null}window(){return this.owner.ownerDocument.defaultView}dialog(){return this.owner.closest("hp-dialog")}usesPopover(e=!1){const t=this.window();return!e&&!!t&&function(e){const t=e.HTMLElement?.prototype;return"function"==typeof t?.showPopover&&"function"==typeof t?.hidePopover}(t)}get hasFallback(){return!!this.host}containsPath(e){return e.includes(this.owner)||!!this.host&&e.includes(this.host)}ownsActiveElement(){let e=this.owner.ownerDocument.activeElement;for(;e?.shadowRoot?.activeElement;)e=e.shadowRoot.activeElement;return!(!e||e!==this.owner&&!this.owner.shadowRoot?.contains(e)&&!this.root?.contains(e))}renderFallback(i,o){const n=this.ensureFallback();return n?(e(t`${i}`,n),n):null}surface(e,t){return t?this.owner.shadowRoot?.querySelector(e)||null:this.root?.querySelector(e)||null}destroy(){this.root&&e(i,this.root),this.host?.remove(),this.host=null,this.root=null}ensureFallback(){if(this.root?.isConnected)return this.root;const e=this.dialog()?.overlayPortal()||this.owner.ownerDocument.body;if(!e)return null;const t=this.owner.ownerDocument.createElement("div");return t.dataset.hpOverlay=this.name,t.style.display="contents",this.keydown&&t.addEventListener("keydown",this.keydown,!0),e.append(t),this.host=t,this.root=t.attachShadow({mode:"open"}),this.root}}let h=0;class c extends n{constructor(){super(...arguments),this.text="",this.ariaLabel="",this.pointerHover=!1,this._open=!1,this._openTimer=0,this._closeTimer=0,this._positionRaf=0,this._forceFallback=!1,this._hoverOwned=!1,this._overlayDispose=null,this._scrollDialog=null,this._descriptionId="hp-help-description-"+ ++h,this._surfacePointerEnter=()=>{const e=this._window();this._closeTimer&&e?.clearTimeout(this._closeTimer),this._closeTimer=0},this._surfacePointerLeave=()=>{this._scheduleClose()},this._outsidePointerDown=e=>{if(!this._open)return;const t=e.composedPath();this._floating.containsPath(t)||this._closeHelp(!1,"outside")},this._dialogScroll=e=>{const t=this._floating.containsPath(e.composedPath()),i=e.target,o=this._dialog(),n=i instanceof Node&&(i===o||i instanceof Element&&i.contains(this));var s;this._open&&(s=n,!t&&s)&&this._closeHelp(!1,"scroll")},this._keyDown=e=>{if(!this._open||e.defaultPrevented)return;if("Escape"===e.key)return e.preventDefault(),e.stopImmediatePropagation(),void this._closeHelp(this._floating.ownsActiveElement(),"escape");const t=this.renderRoot.querySelector(".trigger");if(!t||!e.composedPath().includes(t))return;const i=this._surface();if(!i||i.scrollHeight<=i.clientHeight)return;const o=Math.max(40,.8*i.clientHeight),n={ArrowDown:40,ArrowUp:-40,PageDown:o,PageUp:-o};if("Home"===e.key)i.scrollTop=0;else if("End"===e.key)i.scrollTop=i.scrollHeight;else{if(!(e.key in n))return;i.scrollBy({top:n[e.key],behavior:"auto"})}e.preventDefault(),e.stopImmediatePropagation()},this._floating=new l(this,"help",this._keyDown),this._queuePosition=()=>{if(!this._open||this._positionRaf)return;const e=this._window();e&&(this._positionRaf=e.requestAnimationFrame(()=>{this._positionRaf=0,this._position()||this._closeHelp()}))}}connectedCallback(){super.connectedCallback(),this.addEventListener("keydown",this._keyDown,!0)}willUpdate(){this.toggleAttribute("data-has-content",this._hasContent())}disconnectedCallback(){const e=this.ownerDocument.defaultView;this._unsubscribeOpenListeners(),this.removeEventListener("keydown",this._keyDown,!0),this._clearTimers(),this._positionRaf&&e?.cancelAnimationFrame(this._positionRaf),this._positionRaf=0,this._closeHelp(!1,"disconnect"),super.disconnectedCallback()}updated(e){if(e.has("pointerHover")&&!this.pointerHover){const e=this._window();this._openTimer&&e?.clearTimeout(this._openTimer),this._openTimer=0,this._hoverOwned&&this._closeHelp(!1,"outside")}this._hasContent()||!this._open?this._open&&e.has("text")&&(this._usesPopover()||this._renderFallback(),this._queuePosition()):this._closeHelp()}_window(){return this._floating.window()}_dialog(){return this._floating.dialog()}_usesPopover(){return this._floating.usesPopover(this._forceFallback)}_hasContent(){return e=this.text,t=this.ariaLabel,"string"==typeof e&&e.trim().length>0&&"string"==typeof t&&t.trim().length>0;var e,t}_clearTimers(){const e=this._window();this._openTimer&&e?.clearTimeout(this._openTimer),this._closeTimer&&e?.clearTimeout(this._closeTimer),this._openTimer=0,this._closeTimer=0}_scheduleOpen(){const e=this._window();this.pointerHover&&e&&!this._open&&!this._openTimer&&(this._closeTimer&&e.clearTimeout(this._closeTimer),this._closeTimer=0,this._openTimer=e.setTimeout(()=>{this._openTimer=0,this.isConnected&&(this._hoverOwned=!0,this._openHelp())},300))}_scheduleClose(){const e=this._window(),t=this.renderRoot.querySelector(".trigger");e&&!t?.matches(":focus-visible")&&(this._openTimer&&e.clearTimeout(this._openTimer),this._closeTimer&&e.clearTimeout(this._closeTimer),this._openTimer=0,this._closeTimer=e.setTimeout(()=>{this._closeTimer=0,this.isConnected&&this._closeHelp()},150))}_triggerPointerEnter(e){this.pointerHover&&"mouse"===e.pointerType&&this._scheduleOpen()}_triggerPointerLeave(e){"mouse"===e.pointerType&&this._scheduleClose()}_triggerFocus(){queueMicrotask(()=>{const e=this.renderRoot.querySelector(".trigger");e?.matches(":focus-visible")&&(this._hoverOwned=!1,this._openHelp())})}_triggerBlur(){this._scheduleClose()}_triggerClick(){this._open?this._closeHelp():(this._hoverOwned=!1,this._openHelp())}_subscribeOpenListeners(){this.ownerDocument.addEventListener("pointerdown",this._outsidePointerDown,!0),this.ownerDocument.addEventListener("keydown",this._keyDown,!0);const e=this._window();e?.addEventListener("resize",this._queuePosition),e?.addEventListener("orientationchange",this._queuePosition),e?.visualViewport?.addEventListener("resize",this._queuePosition),e?.visualViewport?.addEventListener("scroll",this._queuePosition),this._scrollDialog=this._dialog(),this._scrollDialog?.addEventListener("scroll",this._dialogScroll,!0)}_unsubscribeOpenListeners(){this.ownerDocument.removeEventListener("pointerdown",this._outsidePointerDown,!0),this.ownerDocument.removeEventListener("keydown",this._keyDown,!0);const e=this._window();e?.removeEventListener("resize",this._queuePosition),e?.removeEventListener("orientationchange",this._queuePosition),e?.visualViewport?.removeEventListener("resize",this._queuePosition),e?.visualViewport?.removeEventListener("scroll",this._queuePosition),this._scrollDialog?.removeEventListener("scroll",this._dialogScroll,!0),this._scrollDialog=null}async _openHelp(){!this._open&&this._hasContent()&&(this._clearTimers(),this._forceFallback=!1,this._open=!0,this._subscribeOpenListeners(),await this.updateComplete,this._open&&(this._usesPopover()||this._renderFallback(),this._position()?this._overlayDispose=this._dialog()?.registerOverlay({owner:this,group:"transient",close:e=>this._closeHelp("escape"===e&&this._floating.ownsActiveElement(),e)})||null:this._closeHelp()))}_closeHelp(e=!1,t="exclusive"){if(!this._open&&!this._floating.hasFallback)return;this._clearTimers();const i=this._overlayDispose;this._overlayDispose=null,i?.();const o=this.renderRoot.querySelector(".tooltip");if(o?.hidePopover)try{o.matches(":popover-open")&&o.hidePopover()}catch{}this._open=!1,this._hoverOwned=!1,this._unsubscribeOpenListeners(),this._floating.destroy(),e&&this.updateComplete.then(()=>this.renderRoot.querySelector(".trigger")?.focus())}_tooltipTemplate(e){return t``}_renderFallback(){const e=c.styles.cssText;this._floating.renderFallback(this._tooltipTemplate(!1),e)}_surface(){return this._floating.surface(".tooltip",this._usesPopover())}_position(){if(!this._open)return!1;const e=this._window(),t=this.renderRoot.querySelector(".trigger");let i=this._surface();if(!e||!t?.isConnected||!i?.isConnected)return!1;const o=r(e);if(i.style.maxWidth=`${Math.max(0,Math.min(320,o.width-16))}px`,i.style.maxHeight=`${Math.max(0,o.height-16)}px`,i.style.visibility="hidden",this._usesPopover()&&i.showPopover)try{i.matches(":popover-open")||i.showPopover()}catch{if(this._forceFallback=!0,this._renderFallback(),i=this._surface(),!i?.isConnected)return!1;i.style.visibility="hidden"}const n=t.getBoundingClientRect(),s=i.getBoundingClientRect();if(!(n.width&&n.height&&s.width&&s.height))return!1;const l=a(n,s,o);return i.style.left=`${l.left}px`,i.style.top=`${l.top}px`,i.dataset.side=l.side,i.style.visibility="",!0}render(){if(!this._hasContent())return i;const e=this.ariaLabel.trim();return t` ({value:e.id,label:e.title||e.id})),this._spacesAuthoritative=!0}catch{this._spaces=[],this._spacesAuthoritative=!1}finally{this._spacesLoading=!1}}}get _lang(){return o(this.hass,this._config?.language)}get _floorToken(){const e=this._config?.floor;return"number"==typeof e?`__houseplan_yaml_floor_index__:${String(e)}`:null}get _formData(){const e={...this._config},o=this._floorToken;return o?e.floor=o:Object.prototype.hasOwnProperty.call(e,"floor")||(e.floor=""),e}get _schema(){const e=this._spaces||[],o=this._lang,a=[{value:"",label:t(o,"editor.floor_none")}],i=this._floorToken;i&&a.push({value:i,label:t(o,"editor.floor_index",{index:String(this._config?.floor)})});const l="string"==typeof this._config?.floor?this._config.floor:"";l&&!e.some(e=>e.value===l)&&a.push({value:l,label:l}),a.push(...e);const n="string"==typeof this._config?.default_floor?this._config.default_floor:"",r=[...e];return n&&!e.some(e=>e.value===n)&&r.unshift({value:n,label:n}),[{name:"title",selector:{text:{}}},{name:"floor",selector:{select:{mode:"dropdown",options:a}}},e.length?{name:"default_floor",selector:{select:{mode:"dropdown",options:r}}}:{name:"default_floor",selector:{text:{}}},{name:"language",selector:{select:{mode:"dropdown",options:s(t(o,"editor.lang_auto"),this._config?.language)}}},{name:"icon_size",selector:{number:{min:1,max:6,step:.1,mode:"box"}}},{name:"show_temperature",selector:{boolean:{}}},{name:"live_states",selector:{boolean:{}}},{name:"show_signal",selector:{boolean:{}}},{name:"kiosk",selector:{boolean:{}}},{name:"cycle",selector:{number:{min:0,max:3600,step:5,mode:"box"}}}]}render(){if(!this.hass||!this._config)return a;const e=i(this,l,o(this.hass,this._config.language));if("cold"===e)return n();if("warm"===e)return r;this._loadSpaces();const s=this._lang,h={title:t(s,"editor.title"),floor:t(s,"editor.floor"),default_floor:t(s,"editor.default_floor"),language:t(s,"editor.language"),icon_size:t(s,"editor.icon_size"),show_temperature:t(s,"editor.show_temperature"),live_states:t(s,"editor.live_states"),show_signal:t(s,"editor.show_signal"),kiosk:t(s,"editor.kiosk"),cycle:t(s,"editor.cycle")},f=this._schema,_=function(e,o,t){if(!t||null===o)return null;const s="string"==typeof e?.default_floor?e.default_floor:"";return!s||o.some(e=>e.value===s)?null:s}(this._config,this._spaces,this._spacesAuthoritative),d=e=>c`({value:e.id,label:e.title||e.id})),this._spacesAuthoritative=!0}catch{this._spaces=[],this._spacesAuthoritative=!1}finally{this._spacesLoading=!1}}}get _lang(){return o(this.hass,this._config?.language)}get _floorToken(){const e=this._config?.floor;return"number"==typeof e?`__houseplan_yaml_floor_index__:${String(e)}`:null}get _formData(){const e={...this._config},o=this._floorToken;return o?e.floor=o:Object.prototype.hasOwnProperty.call(e,"floor")||(e.floor=""),e}get _schema(){const e=this._spaces||[],o=this._lang,a=[{value:"",label:t(o,"editor.floor_none")}],i=this._floorToken;i&&a.push({value:i,label:t(o,"editor.floor_index",{index:String(this._config?.floor)})});const l="string"==typeof this._config?.floor?this._config.floor:"";l&&!e.some(e=>e.value===l)&&a.push({value:l,label:l}),a.push(...e);const n="string"==typeof this._config?.default_floor?this._config.default_floor:"",r=[...e];return n&&!e.some(e=>e.value===n)&&r.unshift({value:n,label:n}),[{name:"title",selector:{text:{}}},{name:"floor",selector:{select:{mode:"dropdown",options:a}}},e.length?{name:"default_floor",selector:{select:{mode:"dropdown",options:r}}}:{name:"default_floor",selector:{text:{}}},{name:"language",selector:{select:{mode:"dropdown",options:s(t(o,"editor.lang_auto"),this._config?.language)}}},{name:"icon_size",selector:{number:{min:1,max:6,step:.1,mode:"box"}}},{name:"show_temperature",selector:{boolean:{}}},{name:"live_states",selector:{boolean:{}}},{name:"show_signal",selector:{boolean:{}}},{name:"kiosk",selector:{boolean:{}}},{name:"cycle",selector:{number:{min:0,max:3600,step:5,mode:"box"}}}]}render(){if(!this.hass||!this._config)return a;const e=i(this,l,o(this.hass,this._config.language));if("cold"===e)return n();if("warm"===e)return r;this._loadSpaces();const s=this._lang,h={title:t(s,"editor.title"),floor:t(s,"editor.floor"),default_floor:t(s,"editor.default_floor"),language:t(s,"editor.language"),icon_size:t(s,"editor.icon_size"),show_temperature:t(s,"editor.show_temperature"),live_states:t(s,"editor.live_states"),show_signal:t(s,"editor.show_signal"),kiosk:t(s,"editor.kiosk"),cycle:t(s,"editor.cycle")},_=this._schema,f=function(e,o,t){if(!t||null===o)return null;const s="string"==typeof e?.default_floor?e.default_floor:"";return!s||o.some(e=>e.value===s)?null:s}(this._config,this._spaces,this._spacesAuthoritative),d=e=>c`h[e.name]||e.name} @value-changed=${this._valueChanged} >`;return c` - ${d(f.slice(0,3))} - ${_?c``:a} - ${d(f.slice(3))} + ${d(_.slice(3))} `}_valueChanged(e){const o={...this._config,...e.detail.value};""===o.floor?delete o.floor:o.floor===this._floorToken&&(o.floor=this._config?.floor);const t=new Event("config-changed",{bubbles:!0,composed:!0});t.detail={config:o},this.dispatchEvent(t)}}h.properties={hass:{attribute:!1},_config:{state:!0},_spaces:{state:!0}},customElements.get("houseplan-card-editor")||customElements.define("houseplan-card-editor",h); diff --git a/dist/houseplan-assets/fr-iDaS4KiM.js b/custom_components/houseplan/frontend/houseplan-assets/fr-BDUBoPOz.js similarity index 99% rename from dist/houseplan-assets/fr-iDaS4KiM.js rename to custom_components/houseplan/frontend/houseplan-assets/fr-BDUBoPOz.js index 206b2281..d323d765 100644 --- a/dist/houseplan-assets/fr-iDaS4KiM.js +++ b/custom_components/houseplan/frontend/houseplan-assets/fr-BDUBoPOz.js @@ -1 +1 @@ -globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="b36c2306f25315638c0178090efd6865650040c5565d6ad92430103558fe37db";var e={"editor.context_actions":"Actions : {object}","editor.tool_options":"Options de l’outil : {tool}","editor.palette":"Palette : {tool}","editor.open_group":"Groupe d’outils : {group}","editor.group_active":"{group} — actif : {item}","editor.disabled_action":"{action} est indisponible : {reason}","editor.loading":"Chargement de l'éditeur…","editor.loading_aria":"L'éditeur de plan est en cours de chargement","editor.load_failed":"Impossible de charger l'éditeur.","editor.refresh_advice":"Actualisez la page et réessayez.","editor.retry_advice":"Vérifiez votre connexion et appuyez à nouveau.","color_picker.title":"Sélecteur de couleur","color_picker.hue":"Teinte","color_picker.saturation":"Saturation","color_picker.value":"Luminosité","color_picker.hex":"Couleur hexadécimale","color_picker.invalid_hex":"Saisissez une couleur hexadécimale à 3 ou 6 chiffres","btn.properties":"Propriétés","btn.keep_as_walls":"Conserver comme murs","btn.delete_room_keep_walls":"Supprimer la pièce, conserver les murs","btn.delete_room_with_walls":"Supprimer la pièce et les murs","title.markup_select":"Sélectionner et modifier les murs, colonnes et contours enregistrés","title.markup_column":"Colonne : cliquez sur un point de la grille pour placer une colonne carrée","markup.partition":"Cloison","markup.column":"Colonne","markup.hint_column":"cliquez sur un point de la grille pour placer une colonne carrée","history.draft_segment":"Ajouter un segment de brouillon de pièce","history.draft_merge":"Relier des contours de pièce inachevés","history.draft_segment_delete":"Supprimer un segment de brouillon de pièce","history.column_add":"Ajouter une colonne","history.physical_edit":"Modifier l’objet physique","history.physical_delete":"Supprimer l’objet physique","history.physical_move":"Déplacer l’objet physique","history.contour_to_partitions":"Convertir le contour en murs fermés","history.wall_chain_finish":"Terminer la chaîne de murs","history.wall_face_batch":"Créer des pièces à partir des murs","toast.column_duplicate":"Une colonne avec le même centre et la même dimension extérieure existe déjà","confirm.delete_draft_title":"Supprimer le contour inachevé ?","confirm.delete_draft_body":"Tout le contour de pièce inachevé sera supprimé. L’annulation ne modifie rien.","confirm.delete_draft_segment_title":"Supprimer le segment de contour ?","confirm.delete_draft_segment_body":"Ce segment de brouillon sera supprimé. Le contour restant peut se scinder en deux.","physical.partition_properties":"Propriétés de la cloison","physical.column_properties":"Propriétés de la colonne","physical.draft_properties":"Propriétés du segment de brouillon","physical.shape":"Forme","physical.square":"Carré","physical.circle":"Cercle","physical.diameter":"Diamètre","physical.side":"Côté","physical.rotation":"Angle de rotation","physical.length":"Longueur","physical.allowed_range":"Autorisé : {min}–{max} {unit}","physical.delete_segment":"Supprimer le segment","physical.delete_draft":"Supprimer tout le contour","physical.column_size_title":"Côté extérieur de la colonne carrée placée par le clic (1–150 cm).","card.title":"Plan de la maison","count.devices":"{n} app.","empty.no_spaces":"Aucun espace pour le moment.","empty.add_first":"Ajoutez le premier espace et importez un plan.","empty.install":"Installez l’intégration House Plan et ajoutez-la dans « Appareils et services ».","btn.add_space":"Ajouter un espace","btn.cancel":"Annuler","btn.save":"Enregistrer","btn.close":"Fermer","btn.delete":"Supprimer","btn.edit":"Modifier","btn.open_in_ha":"Ouvrir dans HA","btn.reset":"Réinitialiser","btn.attach":"Joindre…","btn.upload":"Importer…","btn.replace":"Remplacer…","title.zoom_in":"Zoomer","title.zoom_out":"Dézoomer","title.zoom_fit":"Tout ajuster","title.configure_space":"Configurer l’espace","title.add_space":"Ajouter un espace","title.markup_add":"Murs : tracez une chaîne continue ; Maj verrouille à 45°. Changer d’outil ou quitter l’éditeur termine la chaîne en murs indépendants","title.markup_merge":"Fusionner : cliquez sur une pièce, puis sur la pièce voisine avec laquelle elle partage un mur","title.markup_split":"Diviser une pièce : cliquez sur la pièce, puis sur deux points de ses murs","title.markup_delroom":"Supprimer une pièce : cliquez à l’intérieur de la pièce puis confirmez","title.need_plan":"Importer une image de plan","markup.add":"Murs","markup.merge":"Fusionner","markup.split":"Diviser","markup.resize":"Redimensionner","title.markup_resize":"Redimensionner les pièces : faites glisser une poignée disponible sur un mur horizontal ou vertical","markup.hint_resize":"faites glisser une poignée de mur disponible · le mur s’arrête à la première position non sûre · Échap annule · Ctrl+Z — annuler","resize.disabled.diagonal":"Ce mur est incliné ; le redimensionnement ne prend en charge que les murs horizontaux et verticaux","resize.disabled.side-angle":"Un mur adjacent est incliné ; le redimensionnement exige que les deux murs adjacents rencontrent ce mur à angle droit","resize.disabled.duplicate-physical-wall":"Une cloison distincte, un contour inachevé ou une colonne chevauche ce mur ; supprimez-la ou déplacez-la avant de redimensionner","resize.disabled.partial-shared":"Une pièce voisine n’utilise qu’une partie de ce mur ; il ne peut donc pas être déplacé en toute sécurité comme un mur partagé unique","resize.disabled.unequal-shared":"La pièce voisine utilise des extrémités ou une longueur de mur différentes ; les murs ne peuvent donc pas être déplacés ensemble en toute sécurité","resize.disabled.multiple-rooms":"Déplacer ce mur affecterait plus de deux pièces","resize.disabled.thickness-conflict":"L’épaisseur du mur ne peut pas être conservée en toute sécurité","resize.disabled.opening-conflict":"Une ouverture sur ce mur ne peut pas être déplacée en toute sécurité","resize.disabled.invalid-geometry":"Ce mur ne peut pas être redimensionné sans modifier la structure du plan","resize.limit_stopped":"Mur arrêté : l'étape suivante enfreindrait une limite de jonction","resize.commit_failed":"Le redimensionnement a été annulé car le plan final n’a pas passé le contrôle de géométrie","resize.preview_failed":"Le redimensionnement s’est arrêté à la dernière position sûre car la géométrie du plan ne pouvait pas être préservée","markup.opening":"Ouverture","markup.delete_room":"Supprimer la pièce","history.undo":"Annuler","history.redo":"Rétablir","history.undo_named":"Annuler : {name} (Ctrl+Z)","history.redo_named":"Rétablir : {name} (Ctrl+Maj+Z / Ctrl+Y)","history.undo_empty":"Rien à annuler","history.redo_empty":"Rien à rétablir","history.undone":"Annulé : {name}","history.redone":"Rétabli : {name}","history.add_room":"Créer une pièce","history.split_room":"Diviser la pièce","history.merge_rooms":"Fusionner les pièces","history.resize_room":"Redimensionner la pièce","history.wall_thickness":"Modifier l’épaisseur du mur","history.add_opening":"Ajouter une ouverture de porte ou de fenêtre","history.edit_opening":"Modifier l’ouverture","history.move_opening":"Déplacer l’ouverture","history.delete_opening":"Supprimer l’ouverture","history.delete_room_keep_walls":"Supprimer la pièce, conserver les murs","history.delete_room_with_walls":"Supprimer la pièce et les murs","history.decor_add":"Ajouter un objet décoratif","history.decor_edit":"Modifier l’objet décoratif","history.decor_move":"Déplacer l’objet décoratif","history.decor_transform":"Transformer l’objet décoratif","history.decor_delete":"Supprimer l’objet décoratif","history.backdrop_transform":"Transformer l’arrière-plan du plan","history.device_move":"Déplacer {name}","history.device_stale":"L’historique des positions n’est plus applicable et a été effacé","opening.new":"Nouvelle ouverture","opening.edit":"Ouverture","opening.door":"Porte","opening.window":"Fenêtre","opening.gate":"Portail","opening.passage":"Passage ouvert","opening.passage_binding_warning":"L’enregistrement supprimera le capteur d’ouverture/fermeture et la serrure.","opening.invalid_passage_fields":"Le passage ouvert du plan « {room} » possède des paramètres non pris en charge : {fields}.","opening.type_label":"Type","opening.length_label":"Longueur, cm","opening.contact_label":"Capteur d’ouverture/fermeture","opening.lock_label":"Serrure","opening.none":"— aucun —","opening.search_ph":"Rechercher : nom ou ID d’entité…","opening.invert":"Inverser ouvert/fermé","opening.flip_h":"Charnière sur l’autre montant","opening.flip_v":"Ouverture de l’autre côté","opening.open":"Ouvert","opening.closed":"Fermé","opening.locked":"Verrouillé","opening.unlocked":"Déverrouillé","opening.state_unknown":"indisponible","opening.no_entities":"Aucun capteur associé — symbole statique sur le plan.","toast.opening_no_wall":"Cliquez près d’un mur de pièce ou d’un mur indépendant","opening.host_partition":"Mur indépendant","opening.partition_orphan":"Le mur indépendant de cette ouverture n’existe plus","opening.partition_jamb_margin":"Laissez au moins {distance} entre l’ouverture et l’extrémité du mur","opening.rebind_partition":"Associer à un autre mur indépendant","confirm.delete_partition_openings_title":"Supprimer le mur et les ouvertures ?","confirm.delete_partition_openings_body":"Ce mur contient {count} ouverture(s). Elles seront supprimées avec lui.","confirm.delete_partition_openings_item":"• {type}, {length}","markup.hint_points":"points : {n} · Maj — pas de 45° · Échap — terminer la chaîne · Ctrl+Z — annuler un point · fermer une zone propose de créer une pièce","markup.hint_start":"cliquez sur un point de la grille pour commencer une chaîne de murs","tip.lqi":"signal Zigbee moyen :","tip.area":"surface : {value}","info.device_header":"Appareil sur le plan","info.model":"Modèle","info.state":"État","info.link":"Lien","info.manuals":"Manuels","info.none":"Aucune information supplémentaire","marker.new_device":"Nouvel appareil","marker.name_label":"Nom (affiché sur le plan)","marker.name_ph":"Nom","marker.binding_label":"Associer à un appareil HA","marker.binding_disabled":"désactivé dans Home Assistant","marker.virtual_option":"Appareil virtuel (sans association)","marker.search_ph":"Rechercher un appareil / groupe…","marker.nothing_found":"aucun résultat","marker.room_label":"Pièce","marker.room_override":" (placement forcé)","marker.room_choose":"— sélectionner une pièce —","marker.room_auto":"— selon la zone de l’appareil (auto) —","marker.icon_label":"Icône","marker.icon_ph":"mdi:… (vide = auto)","marker.display_label":"Affichage","display.badge":"Icône + état","display.icon_ripple":"Icône + état et activité","display.static_icon":"Icône toujours statique","marker.display_hint_badge":"L’icône et le fond dynamique affichent l’état de l’appareil sans la pulsation d’activité habituelle. Les alarmes rouges restent visibles.","marker.display_hint_icon_ripple":"L’icône, le fond dynamique et la pulsation affichent une brève animation pour les événements et une animation continue pour le fonctionnement, le mouvement ou la présence. Les alarmes rouges restent prioritaires.","marker.display_hint_value":"Une valeur Home Assistant sélectionnée ou résolue automatiquement remplace l’icône tandis que le fond continue d’indiquer l’état. Les alarmes rouges restent visibles.","marker.display_hint_static_icon":"Le contour adapté au thème et l’icône restent toujours identiques. L’état, l’activité, l’indisponibilité et les alarmes ne modifient pas l’apparence.","marker.static_alarm_warning":"Cet appareil peut signaler des alarmes. L’affichage statique masque l’indication visuelle d’alarme du marqueur.","marker.preview.title":"Aperçu de l’affichage","marker.preview.actual":"Actuel","marker.preview.example":"Exemple","marker.preview.integration":"Fourni par","marker.preview.source":"Source d’affichage","marker.preview.current_state":"État actuel","marker.preview.result":"Sur le plan","marker.preview.details":"Détails de la source","marker.preview.select_source":"Choisissez un appareil ou une entité Home Assistant pour voir son affichage réel.","marker.preview.unknown_provider":"Intégration inconnue","marker.preview.virtual_provider":"House Plan · appareil virtuel","marker.preview.no_source":"Aucune source active","marker.preview.no_state":"Aucun état actuel","marker.preview.mixed_states":"Plusieurs états différents","marker.preview.multiple_sources":"{n} sources","marker.preview.more_sources":"+{n} de plus","marker.preview.scaled":"L’aperçu est redimensionné à {n}% pour tenir dans la zone. La taille enregistrée reste inchangée.","marker.preview.demo_short":"Afficher une activité brève","marker.preview.demo_continuous":"Afficher une activité continue","marker.preview.stop_continuous":"Arrêter l’activité continue","marker.preview.demo_short_notice":"Exemple d’activité brève ; l’état réel de l’appareil reste inchangé.","marker.preview.demo_continuous_notice":"Exemple d’activité continue ; l’état réel de l’appareil reste inchangé.","marker.preview.demo_already_visible":"L’état actuel affiche déjà un véritable effet d’activité ou d’alarme.","marker.preview.reduced_motion":"La réduction des animations est activée sur le système ; l’activité normale est donc affichée sous forme de point.","marker.preview.reason.neutral":"Fond sombre neutre","marker.preview.reason.working":"Fond jaune : l’appareil fonctionne actuellement","marker.preview.reason.working_activity":"Fond jaune et effet d’activité : l’appareil fonctionne actuellement","marker.preview.reason.open":"Fond orange : physiquement ouvert ou déverrouillé","marker.preview.reason.cover_icon_state":"Fond neutre ; l’entité de volet contrôle l’état et l’icône affichés","marker.preview.reason.presence":"Effet d’activité tant qu’une présence est détectée","marker.preview.reason.event":"Effet d’activité bref après un événement détecté","marker.preview.reason.transition":"Effet d’activité pendant que l’appareil se déplace ou change d’état","marker.preview.reason.media_neutral":"Les appareils multimédias restent sur un fond sombre neutre tant qu’ils sont disponibles","marker.preview.reason.unavailable":"Fond neutre atténué : indisponible ou éteint","marker.preview.reason.alarm":"Fond d’alarme rouge ; l’indication d’alarme est toujours affichée","marker.preview.reason.live_states_disabled":"Le style selon les états en direct est désactivé pour cette carte","marker.preview.reason.value_no_state":"Aucune valeur d’état exploitable ; l’icône est affichée à la place","marker.preview.reason.value_ambiguous_sources":"Plusieurs sources de valeur possibles ; l’icône est affichée à la place","marker.preview.reason.value_non_scalar":"La source n’a pas renvoyé de valeur simple ; l’icône est affichée à la place","marker.preview.reason.value_virtual":"Un appareil virtuel n’a aucune valeur Home Assistant ; l’icône est affichée à la place","marker.preview.reason.vacuum_live_plan_only":"La position et la trajectoire en direct de l’aspirateur ne sont disponibles que sur le plan complet","marker.preview.reason.hidden_design_preview":"L’appareil est masqué sur le plan ; cet aperçu de conception reste visible","marker.preview.reason.composite_power_source":"L’état provient de l’entité d’alimentation de l’appareil ; les interrupteurs auxiliaires sont ignorés","marker.preview.reason.activity_display_disabled":"Le mode d’affichage sélectionné n’affiche pas les effets d’activité habituels","marker.preview.reason.ha_disabled":"L’association Home Assistant est désactivée et sera masquée sur le plan","marker.preview.reason.orphaned":"L’association Home Assistant enregistrée est introuvable","marker.preview.reason.static_icon":"Mode statique : l’état de l’appareil ne modifie pas l’icône","marker.activity_color":"Couleur de la pulsation d’activité","marker.ripple_size":"Taille de la pulsation d’activité","marker.activity_alarm_note":"La couleur et la taille n’affectent que l’activité normale et ne modifient pas les alarmes rouges.","marker.pulse_a11y_alarm":"Alarme","marker.pulse_a11y_event":"Événement récent","marker.pulse_a11y_presence":"Présence détectée","marker.pulse_a11y_transition":"Changement d’état","marker.pulse_a11y_running":"En fonctionnement","marker.state_a11y_neutral":"État par défaut","marker.state_a11y_working":"En fonctionnement","marker.state_a11y_open":"Ouvert","marker.state_a11y_locked":"Verrouillé","marker.state_a11y_unlocked":"Déverrouillé","marker.state_a11y_alarm":"Alarme","marker.state_a11y_unavailable":"Indisponible","marker.lqi_a11y_low":"LQI {value}, signal faible","marker.lqi_a11y_mid":"LQI {value}, signal moyen","marker.lqi_a11y_high":"LQI {value}, signal fort","marker.size_label":"Taille / rotation de l’icône","marker.angle_label":"Rotation","marker.model_label":"Modèle","marker.model_ph":"ex. Aqara T&H","marker.link_label":"Lien","marker.desc_label":"Description","marker.desc_ph":"Notes, caractéristiques…","marker.manuals_label":"Manuels (PDF, etc.)","marker.sub_device":"appareil","marker.sub_z2m_group":" · groupe Z2M","marker.sub_group":"groupe","marker.sub_helper":"assistant","space.new":"Nouvel espace","space.header":"Espace","space.title_label":"Titre","space.title_ph":"ex. Garage","space.plan_label":"Plan (arrière-plan)","space.no_plan":"aucune image de plan","space.plan_alt":"plan","room.new":"Nouvelle pièce","room.name_label":"Nom affiché","room.name_ph":"ex. Terrasse","room.area_label":"Zone Home Assistant (non attribuée)","room.no_area_option":"— aucune zone —","room.default_name":"Pièce","device.unnamed":"sans nom","device.light_group":"groupe de lumières","device.fallback":"appareil","device.virtual":"appareil virtuel","confirm.delete_room_title":"Supprimer la pièce « {name} » ?","confirm.delete_room_body":"Choisissez si les murs physiques propres à la pièce doivent être conservés. Les murs partagés avec une autre pièce sont toujours conservés.","confirm.remove_marker_title":"Supprimer l’appareil du plan ?","confirm.remove_marker_body":"L’appareil disparaîtra complètement et ne contribuera plus aux données du plan. Vous pourrez l’ajouter de nouveau plus tard.","confirm.erase_decor":"Effacer l’objet {kind} ? Vous pouvez annuler cette action depuis l’historique de l’éditeur.","confirm.delete_space_title":"Supprimer l’espace ?","confirm.delete_space_body":"L’espace, toutes ses pièces et tout le tracé du plan seront supprimés.","space.delete_blocked":"Cet espace est encore utilisé par {n} appareil(s). Déplacez-les vers un autre espace ou supprimez-les d’abord.","toast.pos_save_failed":"Échec de l’enregistrement de la position : {err}","toast.no_entity":"L’appareil n’a aucune entité adaptée","toast.ha_disabled_action":"Un objet Home Assistant désactivé ne peut pas être utilisé sur le plan.","toast.ha_disabled_show_device":"Un appareil désactivé dans Home Assistant ne peut pas être affiché sur le plan. Activez-le d’abord dans Home Assistant.","toast.ha_disabled_show_entity":"Une entité désactivée dans Home Assistant ne peut pas être affichée sur le plan. Activez-la d’abord dans Home Assistant.","toast.ha_disabled_add":"Un objet Home Assistant désactivé ne peut pas être ajouté au plan. Activez-le d’abord dans Home Assistant.","toast.ha_binding_unverified":"L’état de l’objet n’a pas pu être vérifié via le registre Home Assistant. L’affichage et les actions sont temporairement indisponibles.","toast.markup_needs_server":"Le tracé est disponible une fois la configuration déplacée sur le serveur","toast.space_order_changed":"L’ordre a changé. Si une carte fixe son étage par numéro, vérifiez ces tableaux de bord.","toast.conflict":"La configuration a été modifiée dans une autre fenêtre — données actualisées, répétez votre dernière action","toast.cfg_save_failed":"Échec de l’enregistrement de la configuration : {err}","toast.room_overlap":"Le contour chevauche la pièce « {name} » — les pièces ne doivent pas se chevaucher","toast.contour_cannot_close":"Le contour ne peut pas être fermé car il est dégénéré ou s’auto-intersecte","toast.merge_not_adjacent":"Seules les pièces partageant un mur peuvent être fusionnées","toast.rooms_merged":"Pièces fusionnées dans « {name} »","toast.split_pick_wall":"Commencez la découpe sur le mur de la pièce","toast.split_bad_cut":"La découpe doit aller d’un mur à l’autre à l’intérieur de la pièce, sans croiser de mur ni se croiser elle-même","merge.header":"Fusionner les pièces","merge.hint":"La pièce fusionnée conserve un nom et une zone. L’autre zone est libérée — ses appareils quittent le plan jusqu’à ce qu’une autre pièce la récupère.","merge.keep":"Conserver","merge.no_area":"aucune zone","toast.room_saved":"Pièce enregistrée ({n}). Appareils ajoutés : {added}. Tracez la suivante ou quittez le mode tracé.","toast.room_saved_no_area":"Pièce enregistrée ({n}, sans zone). Tracez la suivante ou quittez le mode tracé.","toast.marker_needs_server":"La modification des appareils est disponible une fois la configuration déplacée sur le serveur","toast.virtual_name_required":"Saisissez un nom pour l’appareil virtuel","toast.marker_saved":"Appareil enregistré","toast.marker_removed":"Appareil supprimé du plan","toast.integration_missing":"L’intégration House Plan n’est pas installée — gestion indisponible","toast.plan_formats":"Formats pris en charge : SVG, PNG, JPG, WebP","toast.plan_required":"Importez un plan — il est obligatoire","toast.space_added_onboard":"Espace ajouté. Tracez les pièces : cliquez sur les points de la grille et fermez le contour.","toast.space_added":"Espace ajouté","toast.space_saved":"Espace enregistré","toast.space_deleted":"Espace supprimé","toast.delete_failed":"Échec de la suppression : {err}","toast.error":"Erreur : {err}","toast.toggle_target_unavailable":"La cible « {name} » est indisponible — aucune action n’a été effectuée","toast.toggle_targets_unavailable":"Cibles indisponibles : {names}. Aucune action n’a été effectuée","toast.file_failed":"Le fichier « {name} » n’a pas été importé : {err}","toast.files_attached":"Fichiers joints : {n}","err.unknown":"erreur inconnue","err.code":"code {code}","err.too_large":"fichier supérieur à {mb} Mo","err.bad_ext":"type non pris en charge (PDF/image attendu)","err.unauthorized":"droits administrateur requis","editor.title":"Titre","editor.default_floor":"Espace initial","editor.default_floor_missing":"L’espace initial « {id} » n’existe plus. Choisissez un autre espace.","editor.floor":"Espace fixe","editor.floor_none":"— non fixé —","editor.floor_index":"Index YAML {index} (conservé)","fixed_floor.loading":"Chargement de l’espace fixe…","fixed_floor.invalid_title":"L’espace fixe est indisponible","fixed_floor.invalid_body":"Vérifiez floor dans la configuration de la carte. Valeur configurée : {value}","editor.icon_size":"Taille des icônes, % de la largeur du plan","editor.show_temperature":"Afficher la température","editor.live_states":"États en direct (on/off, ouvert…)","editor.light_pools":"Halos lumineux et ombres des murs","editor.show_signal":"Afficher le signal Zigbee (LQI)","editor.language":"Langue de l’interface","editor.lang_auto":"Auto (profil HA)","title.icon_rules":"Règles d’icônes : quelle icône MDI attribuer aux appareils selon leur nom","rules.title":"Règles d’icônes","rules.hint":"Les règles sont testées de haut en bas sur « nom de l’appareil + modèle » (expression régulière insensible à la casse) ; la première correspondance gagne. Si rien ne correspond, la classe d’appareil de l’entité est utilisée, puis l’icône générique.","rules.pattern_ph":"regex, ex. plug|socket","rules.icon_ph":"mdi:power-socket-de","rules.add":"Ajouter une règle","rules.reset":"Réinitialiser par défaut","rules.test_ph":"Tester un nom d’appareil…","rules.invalid":"expression régulière invalide","rules.saved":"Règles d’icônes enregistrées","btn.up":"Monter","btn.down":"Descendre","tap.info":"Fiche de l’appareil","tap.more_info":"Boîte de dialogue Plus d’infos de HA","tap.toggle":"Basculer l’état","marker.tap_label":"Action au toucher pour cet appareil","tap.toggle_note":"L’état déterminé est affiché ci-dessous. Les appareils sécurisés ne sont jamais basculés depuis le plan.","import.title":"Créer des espaces à partir des étages HA","import.hint":"Votre Home Assistant connaît déjà ces étages. Sélectionnez ceux à transformer en espaces du plan — vous importerez ensuite une image de plan pour chacun. Les pièces sont ensuite tracées manuellement sur le plan.","import.start":"Créer {n} espace(s)","import.manual":"Commencer de zéro","import.progress":"Étage {i} sur {n}","import.done":"Espaces créés. Tracez les pièces : cliquez sur les points de la grille et fermez le contour.","btn.skip":"Passer","space.scale_label":"Échelle (taille d’une cellule de grille)","space.cell_cm.help":"Relie la grille aux dimensions réelles : les longueurs, les surfaces, l’épaisseur des murs, la taille des ouvertures et le rayon du halo en dépendent. Une modification ultérieure change les dimensions calculées de tout l’espace sans déplacer ses points sur le plan.","space.cell_cm.help.aria":"Aide : échelle de l’espace","space.scale_unit":"cm par cellule","space.scale_unit_imperial":"po par cellule","space.display_section":"Affichage","space.show_borders":"Toujours afficher les contours des pièces","space.zero_wall_style":"Murs d’épaisseur nulle","space.zero_wall_style.help":"Les murs d’épaisseur nulle en pointillés laissent passer le halo et les rayons du soleil, tandis que les murs pleins les bloquent comme une barrière sans surface. Ce choix s’applique à tous ces murs de l’espace, même si leur ligne est masquée en mode Vue.","space.zero_wall_style.help.aria":"Aide : style des murs d’épaisseur nulle","space.zero_wall_dashed":"Pointillés","space.zero_wall_solid":"Plein","space.show_names":"Afficher les noms des pièces (faire glisser pour déplacer)","space.room_color":"Couleur du contour et du nom","space.opacity":"Opacité","space.fill_label":"Remplissage de la pièce","space.fill_mode.help":"« Couleur personnalisée » définit le style, tandis que « Lumière », « Température » et « LQI » utilisent les données actuelles de Home Assistant. Le halo s’active séparément.","space.fill_mode.help.aria":"Aide : mode de remplissage des pièces","fill.none":"Aucun","fill.lqi":"Signal Zigbee","fill.light":"Lumières","fill.custom":"Couleur personnalisée","space.custom_fill":"Couleur de remplissage","space.source_file":"J’ai une image de plan","space.source_draw":"Aucune image — je tracerai les pièces à la main","fill.temp":"Température","tip.temp_avg":"température moyenne :","tip.hum_avg":"humidité moyenne :","space_card.button":"Ouvrir le plan de l’espace","space_card.not_found":"Espace « {id} » introuvable","space_card.loading":"Chargement…","continuity.restore_plan":"Restauration du plan…","continuity.restore_connection":"Restauration de la connexion aux appareils…","continuity.retry":"Réessayer","editor.space":"Espace","editor.framing":"Cadrage","editor.fit_content":"Tout le contenu visible","editor.fit_house":"Ajusté à la géométrie de la maison","editor.show_button":"Afficher le bouton","editor.button_label":"Libellé du bouton","editor.button_target":"Chemin du tableau de bord cible","marker.sub_entity":"entité","title.general_settings":"Paramètres généraux","gs.title":"Paramètres généraux","gs.hint":"Les couleurs de remplissage s’appliquent à tous les espaces ; chaque couleur possède sa propre opacité. Le mode de remplissage utilisé par un espace se règle dans la boîte de dialogue de cet espace.","gs.light_group":"Remplissage : lumières","gs.light_on":"Lumières allumées","gs.light_off":"Toutes les lumières éteintes","gs.temp_group":"Remplissage : température","gs.temp_cold":"Froid","gs.temp_ok":"Confortable","gs.temp_hot":"Chaud","gs.lqi_group":"Remplissage : signal Zigbee","gs.lqi_low":"Signal faible","gs.lqi_high":"Signal fort","gs.reset":"Réinitialiser par défaut","gs.saved":"Paramètres généraux enregistrés","space.show_lqi":"Afficher le signal Zigbee (LQI) à côté des appareils","space.hide_decor":"Masquer la couche décorative","space.hide_decor_tip":"Les lignes, formes, étiquettes et meubles restent à leur place — visibles dans l’éditeur d’arrière-plan, mais pas sur le plan.","space.hide_openings":"Masquer les ouvertures","space.hide_openings_tip":"Les symboles de portes, fenêtres et portails ne sont pas dessinés, mais les ouvertures continuent de fonctionner : la lumière les traverse, le soleil entre par les fenêtres et les capteurs de contact continuent de les ouvrir. L’éditeur de plan les affiche toujours.","gs.light_none":"Aucune source lumineuse","mode.plan":"Éditeur de plan","mode.devices":"Éditeur d’appareils","display.value":"Valeur + état","marker.subarea":"aucune zone, manuel","device.new":"Nouvel appareil — ouvrez son éditeur pour fermer","opening.unlock_action":"Déverrouiller","opening.lock_action":"Verrouiller","opening.lock_pending":"En cours…","title.close_editor":"Fermer l’éditeur (retour à la vue)","title.add_device":"Ajouter un appareil au plan","devbar.add":"Ajouter","devbar.rules":"Règles d’icônes","device_inbox.button":"Appareils","device_inbox.title":"Appareils sur le plan","device_inbox.search":"Rechercher appareils, entités et intégrations…","device_inbox.add_virtual":"Ajouter un appareil virtuel","device_inbox.tab_on_plan":"Sur le plan","device_inbox.tab_available":"Disponibles","device_inbox.tab_hidden":"Masqués","device_inbox.tab_readd":"De nouveau disponibles","device_inbox.only_new":"Nouveaux uniquement","device_inbox.show_entities":"Afficher les entités","device_inbox.show_hidden":"Afficher les masqués sur le plan","device_inbox.show_hidden.help":"Affiche temporairement les marqueurs masqués et désactivés sous forme de fantômes réservés à l’éditeur. La visibilité enregistrée des appareils ne change pas.","device_inbox.show_hidden.help.aria":"Aide : afficher les appareils masqués sur le plan","device_inbox.new":"Nouveau","device_inbox.find":"Trouver sur le plan","device_inbox.edit":"Modifier","device_inbox.hide":"Masquer","device_inbox.show":"Afficher","device_inbox.add":"Ajouter","device_inbox.readd":"Ajouter à nouveau","device_inbox.hide_available":"Masquer de la liste","device_inbox.show_more":"Afficher plus","device_inbox.more_actions":"Plus d'actions","device_inbox.find_hidden_hint":"Activez d'abord « Afficher les masqués sur le plan »","device_inbox.show_disabled":"Activez cette liaison dans Home Assistant avant de l'afficher","device_inbox.empty_on_plan":"Aucun appareil correspondant n'est encore sur le plan.","device_inbox.empty_available":"Aucun appareil disponible à ajouter.","device_inbox.empty_hidden":"Il n'y a aucun appareil masqué.","device_inbox.empty_readd":"Aucun appareil supprimé n'est disponible pour un nouvel ajout.","device_inbox.reason_visible_auto":"Découvert automatiquement","device_inbox.reason_visible_explicit":"Ajouté explicitement","device_inbox.reason_manual_hidden":"Masqué par l'utilisateur","device_inbox.reason_automatic_hidden":"Masqué automatiquement","device_inbox.reason_service_entry":"Entrée de registre de service uniquement","device_inbox.reason_excluded_integration":"Intégration « {integration} » exclue par les filtres de découverte","device_inbox.reason_excluded_domain":"Type d'entité non spatial","device_inbox.reason_grouped_light":"Représenté par un groupe de lumières de la pièce","device_inbox.reason_represented_by_parent":"Représenté par son appareil parent","device_inbox.reason_removed":"Précédemment retiré du plan","device_inbox.reason_available":"Disponible pour ajout au plan","device_inbox.reason_no_bound_room":"La zone HA n'est liée à aucune pièce du plan","device_inbox.status_ha_disabled":"Désactivé dans Home Assistant","device_inbox.status_orphaned":"La liaison n'existe plus dans Home Assistant","device_inbox.status_unverified":"Le registre Home Assistant est temporairement indisponible","device_inbox.saved":"Liste des appareils mise à jour","device_inbox.filters_excluded":"Intégrations exclues","device_inbox.filters_group_lights":"Regrouper les lumières de la pièce en un marqueur","device_inbox.filters_preview_appear":"apparaîtra : {count}","device_inbox.filters_preview_hide":"disparaîtra : {count}","device_inbox.filters_preview_lights":"lumières concernées : {count}","device_inbox.filters_reset":"Rétablir les recommandées","device_inbox.filters_save":"Enregistrer les filtres","device_inbox.filters_search_ph":"Ajouter une intégration…","device_inbox.filters_title":"Filtres de découverte","space.roomcard_section":"La carte de pièce affiche :","space.label_temp":"Température","space.label_hum":"Humidité","space.label_lqi":"Signal Zigbee moyen","space.label_light":"Lumières allumées/éteintes","roomcard.light_on":"Allumé","roomcard.light_off":"Éteint","roomcard.light_partial":"{on} sur {total}","toast.split_pick_inside":"Les points intermédiaires de découpe doivent se trouver à l’intérieur de la pièce","mode.decor":"Éditeur d’arrière-plan","decor.select":"Sélectionner","decor.line":"Ligne","decor.rect":"Rectangle","decor.ellipse":"Ovale","decor.text":"Texte","decor.erase":"Effacer","decor.erase_confirm_title":"Effacer l’objet ?","decor.color":"Couleur","decor.width":"Épaisseur de ligne","decor.line_style":"Style de ligne","decor.line_style_solid":"Plein","decor.line_style_dashed":"Pointillés","decor.fill":"Remplissage","decor.fill_color":"Couleur de remplissage","decor.length":"Longueur","decor.size":"Taille","decor.flip_h":"Retourner horizontalement","decor.flip_v":"Retourner verticalement","decor.angle":"Angle de rotation, °","decor.text_size":"Taille du texte","decor.backdrop_properties":"Propriétés de l’arrière-plan du plan","decor.text_title":"Étiquette de texte","decor.object_title":"Modifier {kind}","decor.text_label":"Texte","decor.live_group":"Insérer une variable HA","decor.live_entity":"Entité","decor.live_entity_ph":"choisir une entité","decor.live_attr":"Valeur","decor.live_attr_ph":"choisir l’état ou un attribut","decor.live_state":"État","decor.backdrop":"Image d’arrière-plan","decor.backdrop_hint":"Faites glisser pour déplacer ; tirez un coin pour redimensionner ; utilisez la poignée supérieure pour faire pivoter. Maj modifie les proportions ou libère l’angle.","decor.backdrop_reset":"Réinitialiser l’image","decor.backdrop_reset_done":"L’image a retrouvé sa position et sa taille d’origine","marker.icon_auto":"Auto : {icon} (selon les règles d’icônes ; choisissez-en une pour remplacer)","marker.icon_pin_auto":"Épingle","mode.plan_tip":"Éditeur de plan — la géométrie du logement : dessiner et diviser/fusionner les pièces, les associer aux zones HA, placer portes, fenêtres et portails, déplacer les cartes de pièces, régler l’échelle","mode.devices_tip":"Éditeur d’appareils — tout ce qui concerne les icônes : faire glisser pour positionner, cliquer pour modifier l’association/l’icône/l’affichage, ajouter des appareils virtuels, règles d’icônes","mode.decor_tip":"Éditeur d’arrière-plan — décoration purement visuelle sous le plan : lignes, rectangles, ovales et étiquettes de texte qui ne réagissent jamais aux clics","space.glow_enabled":"Halo des sources lumineuses","gs.glow_group":"Halo des sources lumineuses","gs.glow_base":"Obscurité de la maison","gs.glow_light":"Couleur / intensité de lumière par défaut","gs.wall_group":"Murs","gs.wall_fill":"Remplissage des murs","gs.glow_radius":"Rayon du halo","gs.glow_radius.help":"Définit le rayon général du halo en mètres ou en pieds ; le rayon propre à un appareil remplace cette valeur.","gs.glow_radius.help.aria":"Aide : rayon général du halo","gs.unit_m":"m","gs.unit_ft":"pi","marker.controls_label":"Contrôle d’autres sources lumineuses","marker.controls.help":"Avec l’action « Basculer l’état », les sources répertoriées basculent avec ce marqueur. Leur halo reste sur leurs propres marqueurs et ce lien ne transforme pas à lui seul le marqueur de contrôle en source lumineuse.","marker.controls.help.aria":"Aide : contrôler d’autres sources lumineuses","marker.controls_filter":"Rechercher des lumières et interrupteurs…","info.controls":"Contrôle","marker.glow_radius_label":"Rayon du halo","marker.glow_radius.help":"Définit le rayon du halo en mètres ou en pieds ; une valeur vide utilise le rayon des paramètres généraux.","marker.glow_radius.help.aria":"Aide : rayon du halo","markup.wallthick":"Épaisseur","markup.select":"Sélectionner","title.markup_wallthick":"Épaisseur — cliquez sur un mur pour définir son épaisseur de 0 à 100 cm.","markup.hint_wallthick":"cliquez sur un mur · Échap ferme sans appliquer","wallthick.field":"Épaisseur","wallthick.unit_cm":"cm","wallthick.unit_in":"po","wallthick.apply_room":"Appliquer à tous les murs de cette pièce","markup.draw_wall_title":"Épaisseur de chaque nouveau segment de mur (0–100 cm). Les murs partagés conservent la valeur existante.","room.queue_progress":"Pièce {current} sur {total}","toast.wall_rooms_saved":"Pièces créées : {n}","toast.wall_chain_saved":"Chaîne de murs enregistrée","toast.wallthick_pick":"Cliquez sur un mur","toast.wallthick_set":"Épaisseur du mur définie","toast.wallthick_cleared":"Épaisseur du mur supprimée","toast.physical_range":"Saisissez une valeur comprise entre {min} et {max} {unit}","toast.zero_wall_opening_conflict":"Supprimez d’abord l’ouverture sur ce segment de mur.","toast.zero_wall_ambiguous":"Le segment de mur est ambigu. Simplifiez ou ajustez la jonction.","toast.zero_wall_migration_blocked":"L’espace n’a pas été converti : {reason}. Aucune donnée n’a été modifiée.","toast.physical_angle":"Saisissez un angle de rotation compris entre 0° inclus et 90° exclu","toast.physical_limit":"L’espace a atteint la limite pour ce type de géométrie","toast.geometry_unsafe":"Modification annulée : la géométrie des murs n’a pas pu être construite en toute sécurité.","junction.limit_angle":"L'angle entre les murs est trop aigu : {actual}°, minimum {limit}°.","junction.limit_valence":"Trop de murs se rejoignent en un nœud : {actual}, maximum {limit}.","junction.limit_length":"Le segment de mur est trop court : {actual} cm, minimum {limit} cm.","junction.limit_distance":"Les murs et les nœuds sont trop proches : {actual} cm, minimum {limit} cm.","junction.limit_clearance":"Il ne reste plus d'intérieur de pièce : {actual} cm², minimum {limit} cm².","junction.limit_check_failed":"La vérification des jonctions n'a pas pu s'exécuter — la modification n'a pas été enregistrée","toast.wall_model_migration_blocked":"Le modèle de murs n’a pas pu être mis à jour : {reason}. Le plan n’a pas été modifié. Lancez « Optimiser les plans » ; si l’erreur se reproduit, corrigez la géométrie de mur conflictuelle.","toast.wall_model_client_outdated":"Mettez à jour la carte et rechargez la page avant de modifier le plan.","wall_model.reason.invalid-room":"contour de pièce invalide","wall_model.reason.zero-length":"segment de mur de longueur nulle","wall_model.reason.third-owner":"mur partagé par plus de deux pièces","wall_model.reason.duplicate-id":"identifiants de mur en conflit","wall_model.reason.thickness-conflict":"valeurs d’épaisseur de mur en conflit","wall_model.reason.opening-host":"l’ouverture ne peut pas être attribuée à un seul mur","toast.delete_room_pick":"Cliquez à l’intérieur de la pièce que vous souhaitez supprimer","toast.plan_snap_ambiguous":"Zoomez pour choisir le nœud du mur","toast.wall_repair_ambiguous":"Le contour de la pièce possède plusieurs connexions possibles. Zoomez et reliez-le explicitement.","toast.wall_repair_too_large":"L’écart dépasse 2 cm. Reliez les murs avant de créer la pièce.","toast.wall_repair_changed":"La géométrie des murs a changé. Essayez de créer de nouveau la pièce.","toast.opening_on_zero_wall":"Les ouvertures ne peuvent pas être placées sur un mur d’épaisseur nulle","marker.from_ha_option":"Choisir dans la liste HA","marker.show_entities":"Afficher les entités","marker.show_entities_tip":"Ajoute à la liste non seulement les appareils, mais aussi toutes leurs entités","marker.pick_ph":"Choisir un appareil…","room.open_area":"Ouvrir la zone HA","view.volumetric":"Vue volumétrique","view.flat":"Vue plane","kiosk.title":"Tailles pour cet écran","kiosk.hint":"Enregistrées uniquement sur cet appareil — chaque tablette murale ou TV peut avoir ses propres tailles confortables.","kiosk.icon_scale":"Taille des icônes d’appareils","kiosk.font_scale":"Taille du texte des cartes de pièces","editor.kiosk":"Mode appareil mural (kiosque)","editor.cycle":"Changer automatiquement d’espace toutes les N secondes (kiosque, 0 = désactivé)","room.settings_title":"Paramètres de la pièce","room.settings_section":"Paramètres de la pièce (remplacent ceux de l’espace)","room.fill_label":"Remplissage de CETTE pièce","fill.inherit":"Comme l’espace","room.custom_fill_space":"Couleur de l’espace","room.custom_fill_own":"Couleur de la pièce","room.temp_src_label":"Source de température","room.hum_src_label":"Source d’humidité","room.src_average":"Moyenne des capteurs de la pièce (par défaut)","room.src_pick":"Un appareil ou une entité HA spécifique","room.src_ph":"Choisir une source…","toast.room_updated":"Pièce mise à jour","space.card_font":"Taille de police des cartes de pièces (tout l’espace)","room.sizes_section":"Tailles de police","room.name_scale":"Taille du nom de la pièce","room.label_scale":"Taille des mesures","preview.room_name":"Salon","toast.cfg_reload_failed":"Impossible de recharger le plan depuis le serveur : {err}","toast.locale_load_failed":"Impossible de charger le pack de langue. L'anglais est utilisé jusqu'au rechargement de la page.","room.settings_short":"Paramètres de la pièce","room.unnamed":"Pièce sans nom","marker.use_climate_temp":"Inclure la température de l’appareil dans la pièce","marker.use_climate_temp_tip":"Ajoute la valeur current_temperature d’un climatiseur ou thermostat à la moyenne de la pièce. Configurez séparément le badge de valeur externe ci-dessous.","marker.value_badge_title":"Badge de valeur","marker.value_badge.help":"Affiche une valeur sélectionnée à côté de l’icône. Cela n’affecte pas les mesures de la pièce, la lumière, le halo ni l’action au toucher.","marker.value_badge.help.aria":"Aide : badge de valeur de l’appareil","marker.value_badge_enabled":"Afficher un badge de valeur","marker.value_badge_source":"Valeur","marker.value_badge_source.help":"Choisissez un état précis, un attribut pris en charge ou une valeur dérivée de cet appareil.","marker.value_badge_source.help.aria":"Aide : source du badge de valeur","marker.value_badge_position":"Position","marker.value_badge_position.help":"Le côté choisi reste fixe et ne bascule pas automatiquement au bord du plan.","marker.value_badge_position.help.aria":"Aide : position du badge de valeur","marker.value_badge_right":"À droite","marker.value_badge_bottom":"En dessous","marker.value_badge_left":"À gauche","marker.value_badge_top":"Au-dessus","marker.value_badge_empty":"Cet appareil n’a aucune valeur disponible","marker.value_badge_static":"Une icône statique n’affiche pas de valeurs en direct. Le paramètre est conservé.","marker.value_badge_missing":"Source indisponible","marker.value_badge_missing_hint":"La source enregistrée est actuellement indisponible. Conservez-la, désactivez le badge ou choisissez une autre valeur.","marker.value_badge_duplicate":"La même valeur est déjà affichée dans l’icône.","marker.value_badge_state":"État · {name}","marker.value_badge_marker_state":"État de la source lumineuse · {name}","marker.value_badge_lqi":"Qualité moyenne du signal Zigbee","marker.value_badge_attr_current_temperature":"Température actuelle · {name}","marker.value_badge_attr_temperature":"Température cible · {name}","marker.value_badge_attr_current_humidity":"Humidité actuelle · {name}","marker.value_badge_attr_humidity":"Humidité · {name}","marker.value_badge_attr_current_position":"Position · {name}","marker.value_badge_attr_percentage":"Vitesse · {name}","marker.value_badge_attr_brightness":"Luminosité · {name}","marker.value_badge_attr_volume_level":"Volume · {name}","marker.value_badge_attr_battery_level":"Batterie · {name}","marker.value_badge_attr_fan_speed":"Vitesse du ventilateur · {name}","marker.value_source":"Source de la valeur","marker.value_source.help":"Choisissez la valeur qui remplace l’icône. L’action au toucher ne change pas.","marker.value_source.help.aria":"Aide : source de la valeur dans le marqueur","marker.value_source_auto":"Automatique (comme avant)","marker.value_source_missing_hint":"La source enregistrée est indisponible. Le marqueur affiche — jusqu’à son retour ou jusqu’au choix d’une autre valeur.","marker.light_role_label":"Cet appareil est-il une source lumineuse ?","marker.light_role.help":"« Auto » utilise le rôle déterminé de l’appareil lié, « Toujours » force sa propre source et « Jamais » l’exclut ; les lumières liées ci-dessus restent indépendantes.","marker.light_role.help.aria":"Aide : cet appareil est-il une source lumineuse","marker.light_role_auto_yes":"Auto (source lumineuse)","marker.light_role_auto_no":"Auto (pas une source lumineuse)","marker.light_role_always":"Toujours une source lumineuse","marker.light_role_never":"Jamais une source lumineuse","marker.light_entity_label":"Entité lumineuse principale","marker.light_entity.help":"Pour un appareil composite, choisissez l’entité dont l’état, la couleur et la luminosité représentent cette source sur le plan. Le choix automatique reste compatible avec les anciens plans.","marker.light_entity.help.aria":"Aide : entité lumineuse principale","marker.light_entity_auto":"Automatique ({entity})","marker.light_entity_none":"aucune entité contrôlable","marker.light_entity_missing":"L’entité enregistrée {entity} est indisponible. House Plan utilise temporairement {fallback} ; le choix enregistré sera restauré si elle revient.","marker.toggle_entity_label":"Entité à basculer","marker.toggle_entity.help":"Pour un appareil composite, choisissez précisément la lumière ou l’interrupteur propre à actionner par un toucher. Automatique conserve les règles de cible précédentes et reste indépendant de l’entité lumineuse principale.","marker.toggle_entity.help.aria":"Aide : entité à basculer","marker.toggle_entity_auto":"Automatique ({entity})","marker.toggle_entity_none":"aucune entité propre contrôlable","marker.toggle_entity_missing":"L’entité enregistrée {entity} ne fait plus partie des canaux sélectionnables de ce marqueur. House Plan utilise temporairement {fallback} ; le choix enregistré sera restauré si elle revient.","marker.glow_color_label":"Couleur et luminosité du halo","marker.glow_mode.help":"Utilisez les valeurs en direct de la source, remplacez uniquement sa couleur ou fixez à la fois la couleur et la luminosité. Le minimum est 1 % ; pour désactiver la source, choisissez « Jamais ».","marker.glow_mode.help.aria":"Aide : couleur et luminosité du halo","marker.glow_mode_auto":"Depuis la source","marker.glow_mode_color":"Définir la couleur","marker.glow_mode_fixed":"Définir la couleur et la luminosité","marker.glow_color":"Couleur du halo","marker.glow_brightness":"Luminosité","marker.glow_disabled_never":"Les paramètres du halo sont indisponibles car ce marqueur est explicitement défini comme n’étant pas une source lumineuse.","marker.glow_disabled_auto":"Le mode Auto n’a trouvé aucune source lumineuse spatiale pour ce marqueur.","marker.glow_disabled_no_entity":"Aucune entité Home Assistant contrôlable et active n’est disponible pour cette source spatiale.","marker.glow_passive_hint":"Cette source ne possède aucune donnée Home Assistant propre. Définissez manuellement sa couleur et sa luminosité ; son rayon reste disponible.","marker.control_broken":"La source enregistrée est absente ou n’est plus marquée comme lumière","marker.control_missing_label":"Lumière du plan manquante","marker.control_passive":"source passive","toast.marker_control_cycle":"Ce lien créerait une chaîne circulaire de contrôles de lumière.","toast.marker_binding_required":"Choisissez un appareil Home Assistant avant de lier une autre source lumineuse.","confirm.unlock_title":"Déverrouiller ?","confirm.unlock_body":"House Plan enverra une commande de déverrouillage à cette serrure.","toast.files_migrate_failed":"Les pièces jointes n’ont pas pu être déplacées vers la nouvelle association ; les liens continuent de pointer vers les anciens fichiers : {err}","space.pick_saved":"Déjà importé","space.pick_saved_hint":"Plans stockés sur le serveur, y compris ceux que vous avez précédemment dissociés","space.no_saved":"Aucun plan n’est encore stocké sur le serveur.","space.loading":"Chargement…","space.used_by":"utilisé par : {list}","space.in_use":"Un espace utilise encore ce plan — dissociez-le d’abord","btn.use":"Utiliser","confirm.delete_plan_title":"Supprimer le fichier du plan ?","confirm.delete_plan_body":"Le fichier sera supprimé du serveur. Cette action est irréversible.","toast.plans_list_failed":"Impossible de lister les plans stockés : {err}","toast.plan_delete_failed":"Impossible de supprimer le plan : {err}","marker.hide":"Masquer","marker.hide_tip":"L’appareil disparaîtra du plan après l’enregistrement mais continuera de compter dans le signal de la pièce. Restaurez-le via « Masqués et désactivés » dans l’éditeur d’appareils.","marker.show":"Afficher","marker.show_tip":"L’appareil apparaîtra de nouveau sur le plan après l’enregistrement.","marker.hidden_ghost":"Appareil masqué par l’utilisateur","marker.ha_disabled_device":"L’appareil est désactivé dans Home Assistant et masqué du plan.","marker.ha_disabled_entity":"L’entité est désactivée dans Home Assistant et masquée du plan.","marker.ha_disabled_all_entities":"L’appareil n’a aucune entité Home Assistant active ; il est donc masqué du plan.","marker.ha_registry_limited":"Le registre Home Assistant complet n’est pas accessible à cet utilisateur. L’objet non vérifié ne peut pas être affiché ni utilisé pour le moment.","marker.delete_tip":"Supprimer complètement l’appareil du plan et de tous les agrégats. Vous pourrez l’ajouter de nouveau plus tard.","tap.run":"Exécuter une automatisation/un script/une scène","tap.none":"Ne rien faire","marker.run_target_label":"Élément à exécuter","marker.run_search_ph":"Rechercher : automatisation, script ou scène…","marker.run_target_gone":"Cible {id} introuvable — choisissez-en une autre","marker.tap_confirm":"Demander une confirmation","marker.tap_confirm_tip":"Afficher une boîte de dialogue de confirmation avant l’action — protection contre les appuis accidentels.","marker.toggle_hint_single":"Cible : {name} ({id}).","marker.virtual_light_target":"Lumière virtuelle : {name}.","marker.virtual_light_current":"État manuel : {state} → {effect}.","marker.virtual_light_state_on":"allumé","marker.virtual_light_state_off":"éteint","marker.toggle_hint_group":"Basculera {count} source(s) : {names}.","marker.toggle_hint_current":"Actuellement : {state} → {effect}.","marker.toggle_hint_group_current":"Actuellement allumées : {on} sur {count} → {effect}.","marker.toggle_hint_skipped":"Seront ignorées ({count}) : {targets}.","marker.toggle_effect_turn_on":"sera allumé","marker.toggle_effect_turn_off":"sera éteint","marker.toggle_effect_open":"sera ouvert","marker.toggle_effect_close":"sera fermé","marker.toggle_effect_stop":"sera arrêté","marker.toggle_effect_toggle":"l’état sera basculé","marker.toggle_skip_missing":"introuvable","marker.toggle_skip_ha_disabled":"désactivé dans HA","marker.toggle_skip_unavailable":"indisponible","marker.toggle_skip_unsupported":"basculement non pris en charge","marker.toggle_skip_secure":"bloqué pour des raisons de sécurité","marker.toggle_none_no_binding":"Cet appareil n’a aucune association ; il n’y a donc aucun état à basculer. Un toucher ne fera rien.","marker.toggle_none_no_actionable_entity":"Cet appareil n’a aucun état pouvant être basculé. Un toucher ne fera rien.","marker.toggle_none_configured_targets_missing":"Les cibles configurées sont indisponibles. L’entité propre de l’appareil ne leur sera pas substituée.","marker.toggle_none_ha_disabled":"La cible est désactivée dans Home Assistant et ne peut pas être utilisée sur le plan.","marker.toggle_none_unavailable":"La cible est actuellement indisponible. Un toucher ne fera rien.","marker.toggle_none_unsupported":"Home Assistant n’expose aucune opération de basculement sûre pour cette entité. Un toucher ne fera rien.","marker.toggle_none_secure":"Le basculement des serrures, alarmes et portails sécurisés depuis le plan est bloqué pour des raisons de sécurité.","run.automation":"automatisation","run.script":"script","run.scene":"scène","confirm.tap_run":"Exécuter « {name} » ?","confirm.tap_toggle":"Basculer « {name} » ?","confirm.current_state":"État actuel : {state}","confirm.expected_state":"Après basculement : {state}","confirm.group_current":"{on} allumé(s) sur {total}","confirm.group_all_on":"tout est allumé","confirm.group_all_off":"tout est éteint","confirm.unavailable_targets":"Indisponibles : {count}","confirm.expected_by_ha":"Home Assistant déterminera l’état","confirm.state_on":"Allumé","confirm.state_off":"Éteint","confirm.state_open":"Ouvert","confirm.state_closed":"Fermé","confirm.state_opening":"Ouverture en cours","confirm.state_closing":"Fermeture en cours","confirm.state_stopped":"Arrêté","confirm.state_unknown":"Inconnu","toast.run_started":"Démarré : {name}","toast.run_target_missing":"Cible d’exécution introuvable — vérifiez les paramètres de l’appareil","toast.run_target_required":"Choisissez une automatisation, un script ou une scène","toast.tap_target_changed":"La cible de l’action a changé. Réessayez.","toast.virtual_light_toggle_failed":"Impossible de basculer la lumière virtuelle : {err}","toast.value_badge_source_required":"Choisissez une valeur pour le badge","btn.run":"Exécuter","vac.section":"Robot aspirateur : position en direct","vac.autocal":"Configurer automatiquement","vac.live":"Position en direct sur le plan","vac.trail":"Afficher le trajet du robot","vac.cal_maps":"Cartes calibrées : {maps}","vac.autocal_no_rooms":"L’intégration ne fournit aucune liste de pièces — ouvrez « Ajuster manuellement »","vac.autocal_no_match":"Les noms de pièces ne correspondent pas (il en faut ≥3 en commun) — ouvrez « Ajuster manuellement »","vac.autocal_done":"Terminé : association via {rooms} pièces. Lancez un nettoyage et vérifiez","vac.cal_need_pos":"Le robot ne transmet pas de coordonnées — lancez un nettoyage puis mettez-le en pause","vac.cal_done":"Calibration enregistrée. Lancez un nettoyage et vérifiez","vac.cal_cancelled":"Calibration annulée","vac.fit":"Ajuster manuellement","vac.fit_hint":"Faites glisser la carte du robot pour la positionner, étirez-la par les coins","vac.fit_rotate":"Rotation de 90°","vac.fit_mirror":"Miroir","vac.trail_never":"Jamais","vac.trail_cleaning":"Pendant le nettoyage","vac.trail_always":"Toujours","gs.bg_group":"Arrière-plan de la scène","gs.bg_color":"Arrière-plan autour du plan","gs.bg_default":"Valeur par défaut du thème","gs.bg_theme":"valeur par défaut du thème","gs.bg_mode":"Arrière-plan du plan","gs.bg_mode.help":"« Suit le soleil » utilise sun.sun ou, à défaut, l’heure locale du navigateur ; « Couleur statique » affiche toujours la couleur choisie.","gs.bg_mode.help.aria":"Aide : arrière-plan général du plan","gs.bg_static":"Couleur statique","gs.bg_daynight":"Suit le soleil","gs.sun_group":"Soleil","gs.sun_missing":"L’entité sun.sun est introuvable — l’arrière-plan suit votre heure locale ; les rayons de soleil par les fenêtres sont indisponibles.","gs.north":"Nord sur le plan","gs.north.help":"L’angle se mesure dans le sens horaire depuis la verticale supérieure du plan ; le nord sert aux rayons des fenêtres, pas à l’arrière-plan « Suit le soleil ».","gs.north.help.aria":"Aide : direction générale du nord","gs.north_ph":"non défini","gs.north_clear":"Effacer","gs.north_letter":"N","gs.sun_rays":"Lumière du soleil à travers les fenêtres","gs.about_group":"À propos","gs.about_version":"Houseplan Card v{v}","gs.about_github":"GitHub · documentation et problèmes","gs.about_telegram":"Discussion Telegram","space.bg_color":"Arrière-plan autour du plan","space.bg_inherit":"Hériter des paramètres généraux","space.bg_inherited":"hérite des paramètres généraux","space.bg_mode":"Arrière-plan du plan","space.bg_mode.help":"Héritez de l’arrière-plan général ou remplacez-le pour cet espace par une couleur statique ou le mode « Suit le soleil ».","space.bg_mode.help.aria":"Aide : arrière-plan de l’espace","space.north":"Nord sur le plan (remplacement)","space.north.help":"Remplace le nord général pour cet espace ; l’angle se mesure dans le sens horaire depuis la verticale supérieure du plan et sert aux rayons des fenêtres.","space.north.help.aria":"Aide : nord de cet espace","space.north_inherited":"hérité : {v}","space.sun_rays":"Lumière du soleil à travers les fenêtres","space.sun_inherit":"Hériter des paramètres généraux","space.sun_on":"Activé","space.sun_off":"Désactivé","canvas.far_objects":"{n} objet(s) éloigné(s) du plan","canvas.show_far":"Afficher","canvas.home_tip":"Le plan est là-bas — cliquez pour l’ajuster à l’écran","gs.grid_group":"Maintenance du plan","gs.grid_hint":"Met à jour les modèles de données, aligne les éléments du plan sur la grille et fusionne les fragments de murs redondants. Un rapport précis est affiché avant tout enregistrement.","gs.align_all":"Optimiser les plans","gs.align_title":"Optimiser les plans","gs.align_none":"Tous les plans utilisent déjà le modèle de données optimisé actuel.","gs.optimize_no_automatic_changes":"Aucune modification automatique n’est à appliquer. Vérifiez les éléments ci-dessous.","gs.align_count":"{n} élément(s) sur {total} seront déplacés, de {cm} cm au maximum.","gs.align_where":"Le plus grand déplacement se trouve dans « {s} ».","gs.align_turned":"Ouvertures dont l’angle est corrigé : {n}.","gs.align_removed_drafts":"Contours invalides réduits par la grille et supprimés : {n}.","gs.optimize_redundant_drafts":"Chaînes de murs enregistrées masquées par des murs de pièces pleins et supprimées : {n}.","gs.align_preflight_failed":"Impossible de vérifier en toute sécurité la géométrie des espaces suivants : {spaces}{more}.","gs.align_preflight_hint":"Les plans n’ont pas été modifiés. Copiez les diagnostics avec le bouton ci-dessous et joignez-les au rapport de bug avec un export de l’espace.","gs.preflight_reason_prepare-exception":"Impossible de préparer la géométrie de l’espace (exception lors de la construction du modèle)","gs.preflight_reason_wall-null":"Le corps du mur n’a pas pu être construit (l’union a renvoyé un résultat vide)","gs.preflight_reason_wall-degraded-extra":"Le corps du mur s’est dégradé avec une géométrie supplémentaire","gs.preflight_reason_wall-failed-core":"Le noyau du corps du mur n’a pas pu être assemblé","gs.preflight_reason_wall-exception":"La construction du mur a déclenché une exception","gs.preflight_reason_floor-null":"Le contour du sol n’a pas pu être construit","gs.preflight_reason_floor-exception":"La construction du sol a déclenché une exception","gs.preflight_copy":"Copier les diagnostics","gs.preflight_copied":"Diagnostics copiés","gs.preflight_update_hint":"Les versions de la carte et de l’intégration diffèrent — mettez House Plan à jour puis réessayez.","gs.align_preflight_space":"Espace {n}","gs.align_preflight_more":", et {n} de plus","gs.optimize_changes":"Migrations de modèle : {m} ; espaces mis à jour : {c} ; valeurs de coordonnées parasites supprimées : {p} ; fragments de murs réels fusionnés : {w} ; fragments de murs d’épaisseur nulle fusionnés : {s} ; murs indépendants : {i}.","gs.zero_walls_migrated":"Portions de murs virtuels converties : {n}.","gs.wall_segments_migrated":"Segments de murs stabilisés : {n}.","gs.optimize_lattice_summary":"Valeurs de coordonnées parasites normalisées : {n} ; déplacement maximal : {cm} cm.","gs.optimize_lattice_space":"{space} : valeurs de coordonnées normalisées : {n} ; valeurs hors grille laissées inchangées : {far}.","gs.optimize_coincident_partitions":"Sections de murs indépendants masquées absorbées dans les murs des pièces : {n}.","gs.optimize_openings_rehosted":"Ouvertures rattachées aux murs des pièces : {n}.","gs.optimize_walls_straightened":"Murs redressés : {n} ; déplacement maximal : {cm} cm.","gs.optimize_walls_straightened_where":"Plus grande correction de mur : {s}.","gs.optimize_walls_straighten_skipped":"Murs proches d’un axe laissés inchangés car ils ne pouvaient pas être réparés en toute sécurité : {n}.","gs.optimize_glow_migration":"Ancien mode Glow : {spaces} espaces → aucun remplissage de données + Glow indépendant ; {rooms} pièces → remplissage de données hérité + Glow indépendant.","gs.optimize_references":"Références réparées : espaces — {spaces} ; pièces — {rooms} ; positions — {positions} ; appareils dissociés des espaces manquants — {detached}.","gs.optimize_reference_more":", et {n} de plus","gs.optimize_orphans_removed":"Enregistrements oubliés supprimés : {total} — étiquettes de pièces : {rooms} ; appareils : {devices} ; marqueurs de groupe : {groups}. Ils appartenaient à des espaces supprimés précédemment.","gs.optimize_live_positions":"Anciennes positions dans des espaces supprimés appartenant à des objets existants : {n}{names}. Elles seront conservées.","gs.optimize_live_positions_remove":"Anciennes positions dans des espaces supprimés appartenant à des objets existants : {n}{names}. Elles sont sélectionnées pour suppression.","gs.optimize_live_names":" : {names}{more}","gs.optimize_live_remove":"Supprimer les anciennes positions","gs.optimize_live_keep":"Conserver les anciennes positions","gs.optimize_live_selected":"Les anciennes positions seront supprimées après l’application de l’optimisation.","gs.optimize_unverified":"Impossible de vérifier en toute sécurité les positions : {n}. Elles ont été laissées inchangées.","gs.optimize_registry_limited":"Un accès administrateur complet aux registres Home Assistant est requis pour une vérification sûre.","gs.optimize_vacuum_warning":"Associations de pièces d’aspirateur nécessitant encore une vérification : {n}.","gs.optimize_details":"Détails","gs.optimize_details_more":"Et {n} enregistrement(s) de plus.","gs.optimize_detail_removed":"sera supprimé","gs.optimize_detail_live":"sera conservé","gs.optimize_detail_unverified":"non vérifié","gs.optimize_detail_room_label":"étiquette de pièce","gs.optimize_detail_device":"appareil","gs.optimize_detail_group":"marqueur de groupe","gs.optimize_detail_unknown":"propriétaire inconnu","gs.optimize_detail_item":"{status} : {kind} {id} ; ancien espace {space}","gs.align_warn":"Les éléments volontairement placés entre les nœuds de la grille seront déplacés. Une seule annulation est disponible après l’opération, uniquement jusqu’à la prochaine modification du plan.","gs.align_run":"Optimiser","gs.align_done":"Plans optimisés : {n} élément(s) déplacé(s), {m} enregistrement(s) maintenu(s), {r} référence(s) réparée(s)","gs.optimize_undo":"Annuler la dernière optimisation","gs.optimize_undone":"La dernière optimisation a été annulée","decor.furniture":"Mobilier","furn.title":"Bibliothèque de mobilier","furn.symbol":"Symbole","furn.group_furniture":"Mobilier","furn.group_appliance":"Électroménager","furn.group_sanitary":"Sanitaires","furn.group_other":"Autre","furn.width":"Largeur","furn.depth":"Profondeur","furn.back_to_categories":"Toutes les catégories","furn.pick_hint":"Choisissez un symbole, puis cliquez sur le plan.","furn.place_hint":"Cliquez sur le plan — le meuble se place contre le mur le plus proche. Maj permet un placement libre.","furn.cat_air_conditioner":"Climatiseurs","furn.cat_armchair":"Fauteuils","furn.cat_bathtub":"Baignoires","furn.cat_bed":"Lits","furn.cat_bidet":"Bidets","furn.cat_boiler":"Chauffe-eau","furn.cat_chair":"Chaises","furn.cat_coffee_table":"Tables basses","furn.cat_cooktop":"Plaques de cuisson","furn.cat_dining_table":"Tables à manger","furn.cat_dishwasher":"Lave-vaisselle","furn.cat_dryer":"Sèche-linge","furn.cat_fireplace":"Cheminées","furn.cat_fridge":"Réfrigérateurs","furn.cat_kitchen_cabinet":"Meubles de cuisine","furn.cat_kitchen_sink":"Éviers de cuisine","furn.cat_nightstand":"Meubles","furn.cat_plant":"Plantes","furn.cat_rug":"Tapis","furn.cat_shelving":"Étagères","furn.cat_shower":"Douches","furn.cat_sink":"Lavabos","furn.cat_sofa":"Canapés","furn.cat_stairs":"Escaliers","furn.cat_toilet":"Toilettes","furn.cat_tv":"Téléviseurs","furn.cat_wardrobe":"Armoires","furn.cat_washer":"Lave-linge","furn.cat_work_table":"Bureaux","furn.sym_sofa":"Canapé","furn.sym_sofa_three_seat":"Canapé trois places","furn.sym_sofa_corner_right":"Canapé d'angle droit","furn.sym_armchair":"Fauteuil","furn.sym_armchair_office":"Chaise de bureau","furn.sym_coffee_table":"Table basse","furn.sym_coffee_table_round":"Table basse ronde","furn.sym_coffee_table_oval":"Table basse ovale","furn.sym_coffee_table_rounded":"Table basse arrondie","furn.sym_table_dining":"Table à manger","furn.sym_table_round":"Table ronde","furn.sym_table_dining_oval":"Table à manger ovale","furn.sym_table_dining_rounded":"Table à manger arrondie","furn.sym_chair":"Chaise","furn.sym_chair_bar":"Tabouret de bar","furn.sym_desk":"Bureau","furn.sym_desk_corner":"Bureau d'angle","furn.sym_bed_double":"Lit double","furn.sym_bed_single":"Lit simple","furn.sym_nightstand":"Table de chevet","furn.sym_cabinet_tv":"Meuble TV","furn.sym_cabinet_shoe":"Meuble à chaussures","furn.sym_cabinet_sink":"Meuble sous lavabo","furn.sym_wardrobe":"Armoire","furn.sym_bookshelf":"Bibliothèque","furn.sym_wall_unit":"Élément mural","furn.sym_kitchen_floor":"Module de cuisine bas","furn.sym_kitchen_floor_corner":"Module de cuisine bas d'angle","furn.sym_kitchen_wall":"Module de cuisine haut","furn.sym_kitchen_wall_corner":"Module de cuisine haut d'angle","furn.sym_shelf_floor":"Étagère au sol","furn.sym_shelf_wall":"Étagère murale","furn.sym_fridge":"Réfrigérateur","furn.sym_stove":"Cuisinière","furn.sym_cooktop_two":"Plaque à deux feux","furn.sym_dishwasher":"Lave-vaisselle","furn.sym_washer":"Lave-linge","furn.sym_dryer":"Sèche-linge","furn.sym_tv":"Téléviseur","furn.sym_tv_wall":"Téléviseur mural","furn.sym_ac":"Climatiseur","furn.sym_water_heater":"Chauffe-eau","furn.sym_toilet":"Toilettes","furn.sym_toilet_built_in":"Toilettes suspendues","furn.sym_bathtub":"Baignoire","furn.sym_bathtub_corner":"Baignoire d'angle","furn.sym_shower":"Douche","furn.sym_sink":"Lavabo","furn.sym_kitchen_sink":"Évier de cuisine","furn.sym_kitchen_sink_double":"Évier de cuisine double","furn.sym_bidet":"Bidet","furn.sym_bidet_built_in":"Bidet suspendu","furn.sym_stairs":"Escalier","furn.sym_fireplace":"Cheminée","furn.sym_plant":"Plante","furn.sym_rug":"Tapis","common.yes":"Oui","common.no":"Non","vac.diag_source":"Source","vac.diag_platform":"Intégration","vac.diag_status":"État","vac.diag_position":"Position","vac.diag_rooms":"Pièces","vac.diag_rooms_value":"{total} · {matched} noms correspondent · {readiness}","vac.autocal_ready":"calibration automatique disponible","vac.autocal_not_ready":"3 noms correspondants requis","vac.diag_path":"Chemin de l’intégration","vac.diag_map":"ID de carte","vac.source_none":"non sélectionné","vac.source_status_ok":"Prêt","vac.source_status_missing":"Manquant","vac.source_status_disabled":"Désactivé dans Home Assistant","vac.source_status_unavailable":"Indisponible","vac.source_status_unverified":"Impossible à vérifier avec les autorisations actuelles","vac.source_status_unsupported":"Aucune donnée de position","vac.source_status_none":"Aucune source","vac.source_banner_missing":"La source enregistrée n’existe plus. Elle n’a pas été remplacée automatiquement ; choisissez une autre source ou restaurez-la dans Home Assistant.","vac.source_banner_disabled":"La source enregistrée est désactivée dans Home Assistant. Activez-la ou choisissez une autre source.","vac.source_banner_unverified":"Les autorisations Home Assistant actuelles ne permettent pas de vérifier cette source enregistrée. Elle reste épinglée et ne sera pas remplacée automatiquement.","vac.choose_source":"Choisir la source","vac.source_auto":"Automatique","vac.source_auto_hint":"Utiliser une entité compatible de cet appareil","vac.all_cameras":"Toutes les caméras","vac.all_cameras_warn":"Une caméra peut ne pas fournir de données du robot. Choisissez-en une uniquement s’il s’agit de la carte de votre aspirateur.","vac.all_cameras_empty":"Aucune autre entité caméra trouvée.","vac.platform_unknown":"intégration inconnue","vac.cap_position":"position","vac.cap_rooms_short":"pièces","vac.cap_path":"trajet","vac.cap_map":"ID de carte","vac.cap_none":"aucune donnée de robot détectée","vac.xcme_hint":"Activez ces attributs Xiaomi Cloud Map Extractor :","vac.documentation":"Documentation","vac.residual_title":"Vérifier la calibration automatique","vac.residual_message":"Les pièces correspondantes présentent un écart maximal de {error}. Appliquez cette calibration approximative, affinez-la manuellement ou annulez sans modifier la configuration enregistrée.","vac.apply_proposal":"Appliquer","gs.backup_group":"Sauvegarde et transfert","gs.backup_hint":"Téléchargez une sauvegarde JSON portable ou prévisualisez et importez une sauvegarde créée par House Plan.","backup.export_open":"Exporter","backup.import_open":"Importer","backup.export_title":"Exporter House Plan","backup.import_title":"Importer House Plan","backup.export_hint":"Choisissez si la sauvegarde doit contenir toute la configuration House Plan ou uniquement l’espace actuel.","backup.full":"Sauvegarde complète","backup.current_space":"Espace actuel","backup.current_space_title":"Espace actuel : {title}","backup.no_current_space":"Aucun espace actuel","backup.plan_only":"Plan uniquement","backup.plan_only_hint":"Conserver les pièces, murs, ouvertures, décorations et positions des étiquettes de pièces sans les appareils ni les associations Home Assistant.","backup.plan_only_preview":"Ce fichier contient uniquement le plan","backup.privacy_warning":"L’archive conserve les noms, identifiants Home Assistant et coordonnées exactes. Les plans internes et pièces jointes sont référencés, pas intégrés ; les états d’exécution et trajets d’aspirateur ne sont pas inclus.","backup.download":"Télécharger le JSON","backup.export_done":"Sauvegarde téléchargée","backup.reading":"Vérification de la sauvegarde…","backup.revalidated":"Le plan a changé depuis cet aperçu. Le résumé a été actualisé ; vérifiez-le et confirmez de nouveau.","backup.error.unauthorized":"Vous n’avez pas l’autorisation d’exporter ou d’importer ce plan.","backup.error.not_ready":"House Plan n’est pas encore prêt. Réessayez dans un instant.","backup.error.too_large":"La sauvegarde dépasse la limite de 8 Mio.","backup.error.invalid_json":"Le fichier sélectionné n’est pas un JSON valide.","backup.error.invalid_format":"Le fichier sélectionné n’est pas une sauvegarde House Plan.","backup.error.unsupported_export_version":"Ce format de sauvegarde n’est pas pris en charge par la version installée.","backup.error.future_model":"La sauvegarde a été créée avec un modèle de données House Plan plus récent.","backup.error.invalid_config":"La sauvegarde contient une configuration House Plan invalide.","backup.error.wall_model_migration_blocked":"Le modèle de murs de la sauvegarde n’a pas pu être mis à niveau en toute sécurité. Optimisez d’abord le plan source, puis exportez-le de nouveau.","backup.error.invalid_layout":"La sauvegarde contient des positions d’objets invalides.","backup.error.invalid_content":"La sauvegarde contient des références de contenu invalides ou incohérentes.","backup.error.space_not_found":"L’espace sélectionné n’existe plus.","backup.error.capacity_exceeded":"L’ajout de cette sauvegarde dépasserait les limites du plan.","backup.error.preview_expired":"L’aperçu a expiré. Sélectionnez de nouveau le fichier de sauvegarde.","backup.error.preview_owner_mismatch":"Cet aperçu appartient à un autre utilisateur Home Assistant.","backup.error.conflict":"Le plan a changé depuis l’aperçu. Vérifiez le résumé actualisé.","backup.error.content_confirmation_required":"Confirmez que le contenu local indisponible peut être dissocié.","backup.error.commit_failed":"La sauvegarde n’a pas pu être appliquée en toute sécurité. Le plan précédent a été restauré ou est en attente de récupération.","backup.error.missing_plan":"Un fichier de plan référencé a disparu depuis l’aperçu. Vérifiez de nouveau la sauvegarde.","backup.error.missing_content":"Une pièce jointe locale référencée a disparu depuis l’aperçu. Vérifiez de nouveau la sauvegarde.","backup.error.marker_control_missing":"Une lumière liée au plan est absente de la sauvegarde.","backup.error.marker_control_not_light":"Une cible liée au plan n’est plus marquée comme source lumineuse.","backup.error.marker_control_self":"Une source lumineuse ne peut pas se contrôler elle-même.","backup.error.marker_control_cycle":"La sauvegarde contient une chaîne circulaire de contrôles de lumière.","backup.error.duplicate_marker_control":"La sauvegarde contient un lien de lumière du plan en doublon.","backup.error.no_backup":"Aucun instantané d’importation ou d’optimisation n’est disponible à restaurer.","backup.error.in_use":"L'élément est encore utilisé","backup.error.invalid_data":"La requête contient des données invalides","backup.error.invalid_light_entity":"La lumière principale doit être une entité light.* ou switch.*","backup.error.invalid_marker_control":"Référence de contrôle de marqueur invalide","backup.error.invalid_name":"Le nom est invalide","backup.error.invalid_partition_opening_host":"L'ouverture doit conserver sa cloison porteuse","backup.error.invalid_partition_opening_jamb_margin":"L'ouverture ne laisse aucun jambage physique au bout du mur","backup.error.invalid_passage_fields":"Un passage ouvert ne peut pas porter de réglages de porte","backup.error.invalid_space_id":"Espace inconnu","backup.error.invalid_toggle_entity":"L'entité de bascule doit être light.* ou switch.*","backup.error.invalid_value_badge":"Réglages de badge de valeur invalides","backup.error.invalid_value_badge_attribute":"Attribut de badge de valeur invalide","backup.error.invalid_value_badge_position":"Position de badge de valeur invalide","backup.error.invalid_value_badge_source":"Source de badge de valeur invalide","backup.error.invalid_value_source":"Source de valeur invalide","backup.error.invalid_value_source_attribute":"Attribut de source de valeur invalide","backup.error.io_error":"Une opération de fichier a échoué sur le serveur","backup.error.not_toggleable":"Cet appareil ne peut pas être basculé","backup.error.nothing_to_repair":"Rien à réparer","backup.error.space_in_use":"L'espace est encore référencé","backup.error.value_badge_source_required":"Le badge de valeur nécessite une source","backup.error.wall_model_client_outdated":"Le plan a été mis à jour ailleurs — rechargez la page","backup.same_source":"Créée sur cette instance Home Assistant","backup.foreign_source":"Créée sur une autre instance Home Assistant","backup.created":"Créée : {value}","backup.versions":"Carte {card} ; intégration {integration} ; modèle de données {model}","backup.count_spaces":"Espaces : {n}","backup.count_rooms":"Pièces : {n}","backup.count_walls":"Murs : {n}","backup.count_openings":"Ouvertures : {n}","backup.count_decor":"Objets décoratifs : {n}","backup.count_markers":"Appareils : {n}","backup.count_layout":"Positions : {n}","backup.bindings":"Associations — appareils : {device}, entités : {entity}, virtuels : {virtual} ; positions sans espace : {legacy}","backup.binding_status":"État des cibles — actives : {active}, désactivées : {disabled}, manquantes : {missing}","backup.missing_areas":"Zones absentes sur la cible : {areas}","backup.dropped_marker_links":"Liens de lumières du plan hors de cet espace transféré omis : {n}.","backup.repaired_target_refs":"Références existantes restaurées par cet import d’espace : {n}.","backup.preserved_unresolved_refs":"Références qui n’ont pas pu être restaurées sans ambiguïté conservées : {n}.","backup.preserved_unresolved_hint":"Aucune donnée n’a été devinée ni supprimée. Après l’importation, lancez « Optimiser les plans » pour examiner les références restantes.","backup.import_details":"Détails des références d’importation","backup.import_detail.incoming_remapped":"Références mises à jour dans la copie importée : {n}","backup.import_detail.target_repaired":"Références existantes restaurées : {n}","backup.import_detail.preserved_unresolved":"Références non résolues conservées : {n}","backup.import_detail.collisions":"Conflits de destination conservés en toute sécurité : {n}","backup.import_detail.dropped_links":"Liens entrants omis selon les règles de transfert : {n}","backup.import_detail.bounded_lineages":"Identifiants trop imbriqués maintenus dans les limites : {n}","backup.replace_warning":"Cela remplace la configuration et la disposition actuelles. Les fichiers importés ne sont jamais supprimés. Une seule annulation reste disponible jusqu’à la prochaine modification du plan.","backup.foreign_bookkeeping":"Les données de suivi des appareils connus/nouveaux propres à l’instance ne seront pas importées.","backup.final_name":"Nom du nouvel espace","backup.target_settings":"Les paramètres généraux de l’instance cible restent inchangés.","backup.duplicates":"Associations déjà présentes : {n}","backup.skip":"Ignorer les appareils en doublon","backup.virtual_copy":"Ajouter des copies virtuelles statiques sûres","backup.content":"Contenu référencé","backup.content_available":"disponible localement","backup.content_external":"lien externe","backup.content_detach_required":"sera dissocié","backup.confirm_detach":"Je comprends que les plans internes et pièces jointes indisponibles seront dissociés de la configuration importée.","backup.replace":"Remplacer","backup.add":"Ajouter un espace","backup.space_done":"Espace importé : {rooms} pièces, {markers} appareils, {refs} références existantes restaurées","backup.full_done":"Sauvegarde restaurée : {spaces} espaces, {rooms} pièces, {markers} appareils","backup.undo_import":"Annuler la dernière importation complète","backup.import_undone":"Importation complète annulée","backdrop.large_title":"Grande image","backdrop.large_body":"Cette image fait {w}×{h} (fichier de {fileMb} Mo) et nécessite environ {decodedMb} Mo de mémoire pour s'afficher. Sur tablette, cela peut faire planter la page.","backdrop.unknown_body":"Les dimensions de l'image n'ont pas pu être lues — le fichier est peut-être endommagé. Continuer peut faire planter la page sur tablette.","backdrop.use_downscaled":"Téléverser une copie réduite","backdrop.reducing":"Réduction…","backdrop.keep_original":"Conserver l'original","backdrop.too_large_title":"Image trop grande","backdrop.too_large_body":"Cette image dépasse ce que les navigateurs peuvent afficher ({w}×{h}, limite {limit} px par côté). Réduisez-la dans un éditeur de bureau puis téléversez-la à nouveau.","backdrop.downscale_failed":"Impossible de créer la copie réduite. Le plan actuel n'a pas été modifié."};const r="b36c2306f25315638c0178090efd6865650040c5565d6ad92430103558fe37db";export{e as dictionary,r as fingerprint}; +globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="2195ace683267664d035370d92e860e463a0a745074964ec60eb91b9460fe406";var e={"editor.context_actions":"Actions : {object}","editor.tool_options":"Options de l’outil : {tool}","editor.palette":"Palette : {tool}","editor.open_group":"Groupe d’outils : {group}","editor.group_active":"{group} — actif : {item}","editor.disabled_action":"{action} est indisponible : {reason}","editor.loading":"Chargement de l'éditeur…","editor.loading_aria":"L'éditeur de plan est en cours de chargement","editor.load_failed":"Impossible de charger l'éditeur.","editor.refresh_advice":"Actualisez la page et réessayez.","editor.retry_advice":"Vérifiez votre connexion et appuyez à nouveau.","color_picker.title":"Sélecteur de couleur","color_picker.hue":"Teinte","color_picker.saturation":"Saturation","color_picker.value":"Luminosité","color_picker.hex":"Couleur hexadécimale","color_picker.invalid_hex":"Saisissez une couleur hexadécimale à 3 ou 6 chiffres","btn.properties":"Propriétés","btn.keep_as_walls":"Conserver comme murs","btn.delete_room_keep_walls":"Supprimer la pièce, conserver les murs","btn.delete_room_with_walls":"Supprimer la pièce et les murs","title.markup_select":"Sélectionner et modifier les murs, colonnes et contours enregistrés","title.markup_column":"Colonne : cliquez sur un point de la grille pour placer une colonne carrée","markup.partition":"Cloison","markup.column":"Colonne","markup.hint_column":"cliquez sur un point de la grille pour placer une colonne carrée","history.draft_segment":"Ajouter un segment de brouillon de pièce","history.draft_merge":"Relier des contours de pièce inachevés","history.draft_segment_delete":"Supprimer un segment de brouillon de pièce","history.column_add":"Ajouter une colonne","history.physical_edit":"Modifier l’objet physique","history.physical_delete":"Supprimer l’objet physique","history.physical_move":"Déplacer l’objet physique","history.contour_to_partitions":"Convertir le contour en murs fermés","history.wall_chain_finish":"Terminer la chaîne de murs","history.wall_face_batch":"Créer des pièces à partir des murs","toast.column_duplicate":"Une colonne avec le même centre et la même dimension extérieure existe déjà","confirm.delete_draft_title":"Supprimer le contour inachevé ?","confirm.delete_draft_body":"Tout le contour de pièce inachevé sera supprimé. L’annulation ne modifie rien.","confirm.delete_draft_segment_title":"Supprimer le segment de contour ?","confirm.delete_draft_segment_body":"Ce segment de brouillon sera supprimé. Le contour restant peut se scinder en deux.","physical.partition_properties":"Propriétés de la cloison","physical.column_properties":"Propriétés de la colonne","physical.draft_properties":"Propriétés du segment de brouillon","physical.shape":"Forme","physical.square":"Carré","physical.circle":"Cercle","physical.diameter":"Diamètre","physical.side":"Côté","physical.rotation":"Angle de rotation","physical.length":"Longueur","physical.allowed_range":"Autorisé : {min}–{max} {unit}","physical.delete_segment":"Supprimer le segment","physical.delete_draft":"Supprimer tout le contour","physical.column_size_title":"Côté extérieur de la colonne carrée placée par le clic (1–150 cm).","card.title":"Plan de la maison","count.devices":"{n} app.","empty.no_spaces":"Aucun espace pour le moment.","empty.add_first":"Ajoutez le premier espace et importez un plan.","empty.install":"Installez l’intégration House Plan et ajoutez-la dans « Appareils et services ».","btn.add_space":"Ajouter un espace","btn.cancel":"Annuler","btn.save":"Enregistrer","btn.close":"Fermer","btn.delete":"Supprimer","btn.edit":"Modifier","btn.open_in_ha":"Ouvrir dans HA","btn.reset":"Réinitialiser","btn.attach":"Joindre…","btn.upload":"Importer…","btn.replace":"Remplacer…","title.zoom_in":"Zoomer","title.zoom_out":"Dézoomer","title.zoom_fit":"Tout ajuster","title.configure_space":"Configurer l’espace","title.add_space":"Ajouter un espace","title.markup_add":"Murs : tracez une chaîne continue ; Maj verrouille à 45°. Changer d’outil ou quitter l’éditeur termine la chaîne en murs indépendants","title.markup_merge":"Fusionner : cliquez sur une pièce, puis sur la pièce voisine avec laquelle elle partage un mur","title.markup_split":"Diviser une pièce : cliquez sur la pièce, puis sur deux points de ses murs","title.markup_delroom":"Supprimer une pièce : cliquez à l’intérieur de la pièce puis confirmez","title.need_plan":"Importer une image de plan","markup.add":"Murs","markup.merge":"Fusionner","markup.split":"Diviser","markup.resize":"Redimensionner","title.markup_resize":"Redimensionner les pièces : faites glisser une poignée disponible sur un mur horizontal ou vertical","markup.hint_resize":"faites glisser une poignée de mur disponible · le mur s’arrête à la première position non sûre · Échap annule · Ctrl+Z — annuler","resize.disabled.diagonal":"Ce mur est incliné ; le redimensionnement ne prend en charge que les murs horizontaux et verticaux","resize.disabled.side-angle":"Un mur adjacent est incliné ; le redimensionnement exige que les deux murs adjacents rencontrent ce mur à angle droit","resize.disabled.duplicate-physical-wall":"Une cloison distincte, un contour inachevé ou une colonne chevauche ce mur ; supprimez-la ou déplacez-la avant de redimensionner","resize.disabled.partial-shared":"Une pièce voisine n’utilise qu’une partie de ce mur ; il ne peut donc pas être déplacé en toute sécurité comme un mur partagé unique","resize.disabled.unequal-shared":"La pièce voisine utilise des extrémités ou une longueur de mur différentes ; les murs ne peuvent donc pas être déplacés ensemble en toute sécurité","resize.disabled.multiple-rooms":"Déplacer ce mur affecterait plus de deux pièces","resize.disabled.thickness-conflict":"L’épaisseur du mur ne peut pas être conservée en toute sécurité","resize.disabled.opening-conflict":"Une ouverture sur ce mur ne peut pas être déplacée en toute sécurité","resize.disabled.invalid-geometry":"Ce mur ne peut pas être redimensionné sans modifier la structure du plan","resize.limit_stopped":"Mur arrêté : l'étape suivante enfreindrait une limite de jonction","resize.commit_failed":"Le redimensionnement a été annulé car le plan final n’a pas passé le contrôle de géométrie","resize.preview_failed":"Le redimensionnement s’est arrêté à la dernière position sûre car la géométrie du plan ne pouvait pas être préservée","markup.opening":"Ouverture","markup.delete_room":"Supprimer la pièce","history.undo":"Annuler","history.redo":"Rétablir","history.undo_named":"Annuler : {name} (Ctrl+Z)","history.redo_named":"Rétablir : {name} (Ctrl+Maj+Z / Ctrl+Y)","history.undo_empty":"Rien à annuler","history.redo_empty":"Rien à rétablir","history.undone":"Annulé : {name}","history.redone":"Rétabli : {name}","history.add_room":"Créer une pièce","history.split_room":"Diviser la pièce","history.merge_rooms":"Fusionner les pièces","history.resize_room":"Redimensionner la pièce","history.wall_thickness":"Modifier l’épaisseur du mur","history.add_opening":"Ajouter une ouverture de porte ou de fenêtre","history.edit_opening":"Modifier l’ouverture","history.move_opening":"Déplacer l’ouverture","history.delete_opening":"Supprimer l’ouverture","history.delete_room_keep_walls":"Supprimer la pièce, conserver les murs","history.delete_room_with_walls":"Supprimer la pièce et les murs","history.decor_add":"Ajouter un objet décoratif","history.decor_edit":"Modifier l’objet décoratif","history.decor_move":"Déplacer l’objet décoratif","history.decor_transform":"Transformer l’objet décoratif","history.decor_delete":"Supprimer l’objet décoratif","history.backdrop_transform":"Transformer l’arrière-plan du plan","history.device_move":"Déplacer {name}","history.device_stale":"L’historique des positions n’est plus applicable et a été effacé","opening.new":"Nouvelle ouverture","opening.edit":"Ouverture","opening.door":"Porte","opening.window":"Fenêtre","opening.gate":"Portail","opening.passage":"Passage ouvert","opening.passage_binding_warning":"L’enregistrement supprimera le capteur d’ouverture/fermeture et la serrure.","opening.invalid_passage_fields":"Le passage ouvert du plan « {room} » possède des paramètres non pris en charge : {fields}.","opening.type_label":"Type","opening.length_label":"Longueur, cm","opening.contact_label":"Capteur d’ouverture/fermeture","opening.lock_label":"Serrure","opening.none":"— aucun —","opening.search_ph":"Rechercher : nom ou ID d’entité…","opening.invert":"Inverser ouvert/fermé","opening.flip_h":"Charnière sur l’autre montant","opening.flip_v":"Ouverture de l’autre côté","opening.open":"Ouvert","opening.closed":"Fermé","opening.locked":"Verrouillé","opening.unlocked":"Déverrouillé","opening.state_unknown":"indisponible","opening.no_entities":"Aucun capteur associé — symbole statique sur le plan.","toast.opening_no_wall":"Cliquez près d’un mur de pièce ou d’un mur indépendant","opening.host_partition":"Mur indépendant","opening.partition_orphan":"Le mur indépendant de cette ouverture n’existe plus","opening.partition_jamb_margin":"Laissez au moins {distance} entre l’ouverture et l’extrémité du mur","opening.rebind_partition":"Associer à un autre mur indépendant","confirm.delete_partition_openings_title":"Supprimer le mur et les ouvertures ?","confirm.delete_partition_openings_body":"Ce mur contient {count} ouverture(s). Elles seront supprimées avec lui.","confirm.delete_partition_openings_item":"• {type}, {length}","markup.hint_points":"points : {n} · Maj — pas de 45° · Échap — terminer la chaîne · Ctrl+Z — annuler un point · fermer une zone propose de créer une pièce","markup.hint_start":"cliquez sur un point de la grille pour commencer une chaîne de murs","tip.lqi":"signal Zigbee moyen :","tip.area":"surface : {value}","info.device_header":"Appareil sur le plan","info.model":"Modèle","info.state":"État","info.link":"Lien","info.manuals":"Manuels","info.none":"Aucune information supplémentaire","marker.new_device":"Nouvel appareil","marker.name_label":"Nom (affiché sur le plan)","marker.name_ph":"Nom","marker.binding_label":"Associer à un appareil HA","marker.binding_disabled":"désactivé dans Home Assistant","marker.virtual_option":"Appareil virtuel (sans association)","marker.search_ph":"Rechercher un appareil / groupe…","marker.nothing_found":"aucun résultat","marker.room_label":"Pièce","marker.room_override":" (placement forcé)","marker.room_choose":"— sélectionner une pièce —","marker.room_auto":"— selon la zone de l’appareil (auto) —","marker.icon_label":"Icône","marker.icon_ph":"mdi:… (vide = auto)","marker.display_label":"Affichage","display.badge":"Icône + état","display.icon_ripple":"Icône + état et activité","display.static_icon":"Icône toujours statique","marker.display_hint_badge":"L’icône et le fond dynamique affichent l’état de l’appareil sans la pulsation d’activité habituelle. Les alarmes rouges restent visibles.","marker.display_hint_icon_ripple":"L’icône, le fond dynamique et la pulsation affichent une brève animation pour les événements et une animation continue pour le fonctionnement, le mouvement ou la présence. Les alarmes rouges restent prioritaires.","marker.display_hint_value":"Une valeur Home Assistant sélectionnée ou résolue automatiquement remplace l’icône tandis que le fond continue d’indiquer l’état. Les alarmes rouges restent visibles.","marker.display_hint_static_icon":"Le contour adapté au thème et l’icône restent toujours identiques. L’état, l’activité, l’indisponibilité et les alarmes ne modifient pas l’apparence.","marker.static_alarm_warning":"Cet appareil peut signaler des alarmes. L’affichage statique masque l’indication visuelle d’alarme du marqueur.","marker.preview.title":"Aperçu de l’affichage","marker.preview.actual":"Actuel","marker.preview.example":"Exemple","marker.preview.integration":"Fourni par","marker.preview.source":"Source d’affichage","marker.preview.current_state":"État actuel","marker.preview.result":"Sur le plan","marker.preview.details":"Détails de la source","marker.preview.select_source":"Choisissez un appareil ou une entité Home Assistant pour voir son affichage réel.","marker.preview.unknown_provider":"Intégration inconnue","marker.preview.virtual_provider":"House Plan · appareil virtuel","marker.preview.no_source":"Aucune source active","marker.preview.no_state":"Aucun état actuel","marker.preview.mixed_states":"Plusieurs états différents","marker.preview.multiple_sources":"{n} sources","marker.preview.more_sources":"+{n} de plus","marker.preview.scaled":"L’aperçu est redimensionné à {n}% pour tenir dans la zone. La taille enregistrée reste inchangée.","marker.preview.demo_short":"Afficher une activité brève","marker.preview.demo_continuous":"Afficher une activité continue","marker.preview.stop_continuous":"Arrêter l’activité continue","marker.preview.demo_short_notice":"Exemple d’activité brève ; l’état réel de l’appareil reste inchangé.","marker.preview.demo_continuous_notice":"Exemple d’activité continue ; l’état réel de l’appareil reste inchangé.","marker.preview.demo_already_visible":"L’état actuel affiche déjà un véritable effet d’activité ou d’alarme.","marker.preview.reduced_motion":"La réduction des animations est activée sur le système ; l’activité normale est donc affichée sous forme de point.","marker.preview.reason.neutral":"Fond sombre neutre","marker.preview.reason.working":"Fond jaune : l’appareil fonctionne actuellement","marker.preview.reason.working_activity":"Fond jaune et effet d’activité : l’appareil fonctionne actuellement","marker.preview.reason.open":"Fond orange : physiquement ouvert ou déverrouillé","marker.preview.reason.cover_icon_state":"Fond neutre ; l’entité de volet contrôle l’état et l’icône affichés","marker.preview.reason.presence":"Effet d’activité tant qu’une présence est détectée","marker.preview.reason.event":"Effet d’activité bref après un événement détecté","marker.preview.reason.transition":"Effet d’activité pendant que l’appareil se déplace ou change d’état","marker.preview.reason.media_neutral":"Les appareils multimédias restent sur un fond sombre neutre tant qu’ils sont disponibles","marker.preview.reason.unavailable":"Fond neutre atténué : indisponible ou éteint","marker.preview.reason.alarm":"Fond d’alarme rouge ; l’indication d’alarme est toujours affichée","marker.preview.reason.live_states_disabled":"Le style selon les états en direct est désactivé pour cette carte","marker.preview.reason.value_no_state":"Aucune valeur d’état exploitable ; l’icône est affichée à la place","marker.preview.reason.value_ambiguous_sources":"Plusieurs sources de valeur possibles ; l’icône est affichée à la place","marker.preview.reason.value_non_scalar":"La source n’a pas renvoyé de valeur simple ; l’icône est affichée à la place","marker.preview.reason.value_virtual":"Un appareil virtuel n’a aucune valeur Home Assistant ; l’icône est affichée à la place","marker.preview.reason.vacuum_live_plan_only":"La position et la trajectoire en direct de l’aspirateur ne sont disponibles que sur le plan complet","marker.preview.reason.hidden_design_preview":"L’appareil est masqué sur le plan ; cet aperçu de conception reste visible","marker.preview.reason.composite_power_source":"L’état provient de l’entité d’alimentation de l’appareil ; les interrupteurs auxiliaires sont ignorés","marker.preview.reason.activity_display_disabled":"Le mode d’affichage sélectionné n’affiche pas les effets d’activité habituels","marker.preview.reason.ha_disabled":"L’association Home Assistant est désactivée et sera masquée sur le plan","marker.preview.reason.orphaned":"L’association Home Assistant enregistrée est introuvable","marker.preview.reason.static_icon":"Mode statique : l’état de l’appareil ne modifie pas l’icône","marker.activity_color":"Couleur de la pulsation d’activité","marker.ripple_size":"Taille de la pulsation d’activité","marker.activity_alarm_note":"La couleur et la taille n’affectent que l’activité normale et ne modifient pas les alarmes rouges.","marker.pulse_a11y_alarm":"Alarme","marker.pulse_a11y_event":"Événement récent","marker.pulse_a11y_presence":"Présence détectée","marker.pulse_a11y_transition":"Changement d’état","marker.pulse_a11y_running":"En fonctionnement","marker.state_a11y_neutral":"État par défaut","marker.state_a11y_working":"En fonctionnement","marker.state_a11y_open":"Ouvert","marker.state_a11y_locked":"Verrouillé","marker.state_a11y_unlocked":"Déverrouillé","marker.state_a11y_alarm":"Alarme","marker.state_a11y_unavailable":"Indisponible","marker.lqi_a11y_low":"LQI {value}, signal faible","marker.lqi_a11y_mid":"LQI {value}, signal moyen","marker.lqi_a11y_high":"LQI {value}, signal fort","marker.size_label":"Taille / rotation de l’icône","marker.angle_label":"Rotation","marker.model_label":"Modèle","marker.model_ph":"ex. Aqara T&H","marker.link_label":"Lien","marker.desc_label":"Description","marker.desc_ph":"Notes, caractéristiques…","marker.manuals_label":"Manuels (PDF, etc.)","marker.sub_device":"appareil","marker.sub_z2m_group":" · groupe Z2M","marker.sub_group":"groupe","marker.sub_helper":"assistant","space.new":"Nouvel espace","space.header":"Espace","space.title_label":"Titre","space.title_ph":"ex. Garage","space.plan_label":"Plan (arrière-plan)","space.no_plan":"aucune image de plan","space.plan_alt":"plan","room.new":"Nouvelle pièce","room.name_label":"Nom affiché","room.name_ph":"ex. Terrasse","room.area_label":"Zone Home Assistant (non attribuée)","room.no_area_option":"— aucune zone —","room.default_name":"Pièce","device.unnamed":"sans nom","device.light_group":"groupe de lumières","device.fallback":"appareil","device.virtual":"appareil virtuel","confirm.delete_room_title":"Supprimer la pièce « {name} » ?","confirm.delete_room_body":"Choisissez si les murs physiques propres à la pièce doivent être conservés. Les murs partagés avec une autre pièce sont toujours conservés.","confirm.remove_marker_title":"Supprimer l’appareil du plan ?","confirm.remove_marker_body":"L’appareil disparaîtra complètement et ne contribuera plus aux données du plan. Vous pourrez l’ajouter de nouveau plus tard.","confirm.erase_decor":"Effacer l’objet {kind} ? Vous pouvez annuler cette action depuis l’historique de l’éditeur.","confirm.delete_space_title":"Supprimer l’espace ?","confirm.delete_space_body":"L’espace, toutes ses pièces et tout le tracé du plan seront supprimés.","space.delete_blocked":"Cet espace est encore utilisé par {n} appareil(s). Déplacez-les vers un autre espace ou supprimez-les d’abord.","toast.pos_save_failed":"Échec de l’enregistrement de la position : {err}","toast.no_entity":"L’appareil n’a aucune entité adaptée","toast.ha_disabled_action":"Un objet Home Assistant désactivé ne peut pas être utilisé sur le plan.","toast.ha_disabled_show_device":"Un appareil désactivé dans Home Assistant ne peut pas être affiché sur le plan. Activez-le d’abord dans Home Assistant.","toast.ha_disabled_show_entity":"Une entité désactivée dans Home Assistant ne peut pas être affichée sur le plan. Activez-la d’abord dans Home Assistant.","toast.ha_disabled_add":"Un objet Home Assistant désactivé ne peut pas être ajouté au plan. Activez-le d’abord dans Home Assistant.","toast.ha_binding_unverified":"L’état de l’objet n’a pas pu être vérifié via le registre Home Assistant. L’affichage et les actions sont temporairement indisponibles.","toast.markup_needs_server":"Le tracé est disponible une fois la configuration déplacée sur le serveur","toast.space_order_changed":"L’ordre a changé. Si une carte fixe son étage par numéro, vérifiez ces tableaux de bord.","toast.conflict":"La configuration a été modifiée dans une autre fenêtre — données actualisées, répétez votre dernière action","toast.cfg_save_failed":"Échec de l’enregistrement de la configuration : {err}","toast.room_overlap":"Le contour chevauche la pièce « {name} » — les pièces ne doivent pas se chevaucher","toast.contour_cannot_close":"Le contour ne peut pas être fermé car il est dégénéré ou s’auto-intersecte","toast.merge_not_adjacent":"Seules les pièces partageant un mur peuvent être fusionnées","toast.rooms_merged":"Pièces fusionnées dans « {name} »","toast.split_pick_wall":"Commencez la découpe sur le mur de la pièce","toast.split_bad_cut":"La découpe doit aller d’un mur à l’autre à l’intérieur de la pièce, sans croiser de mur ni se croiser elle-même","merge.header":"Fusionner les pièces","merge.hint":"La pièce fusionnée conserve un nom et une zone. L’autre zone est libérée — ses appareils quittent le plan jusqu’à ce qu’une autre pièce la récupère.","merge.keep":"Conserver","merge.no_area":"aucune zone","toast.room_saved":"Pièce enregistrée ({n}). Appareils ajoutés : {added}. Tracez la suivante ou quittez le mode tracé.","toast.room_saved_no_area":"Pièce enregistrée ({n}, sans zone). Tracez la suivante ou quittez le mode tracé.","toast.marker_needs_server":"La modification des appareils est disponible une fois la configuration déplacée sur le serveur","toast.virtual_name_required":"Saisissez un nom pour l’appareil virtuel","toast.marker_saved":"Appareil enregistré","toast.marker_removed":"Appareil supprimé du plan","toast.integration_missing":"L’intégration House Plan n’est pas installée — gestion indisponible","toast.plan_formats":"Formats pris en charge : SVG, PNG, JPG, WebP","toast.plan_required":"Importez un plan — il est obligatoire","toast.space_added_onboard":"Espace ajouté. Tracez les pièces : cliquez sur les points de la grille et fermez le contour.","toast.space_added":"Espace ajouté","toast.space_saved":"Espace enregistré","toast.space_deleted":"Espace supprimé","toast.delete_failed":"Échec de la suppression : {err}","toast.error":"Erreur : {err}","toast.toggle_target_unavailable":"La cible « {name} » est indisponible — aucune action n’a été effectuée","toast.toggle_targets_unavailable":"Cibles indisponibles : {names}. Aucune action n’a été effectuée","toast.file_failed":"Le fichier « {name} » n’a pas été importé : {err}","toast.files_attached":"Fichiers joints : {n}","err.unknown":"erreur inconnue","err.code":"code {code}","err.too_large":"fichier supérieur à {mb} Mo","err.bad_ext":"type non pris en charge (PDF/image attendu)","err.unauthorized":"droits administrateur requis","editor.title":"Titre","editor.default_floor":"Espace initial","editor.default_floor_missing":"L’espace initial « {id} » n’existe plus. Choisissez un autre espace.","editor.floor":"Espace fixe","editor.floor_none":"— non fixé —","editor.floor_index":"Index YAML {index} (conservé)","fixed_floor.loading":"Chargement de l’espace fixe…","fixed_floor.invalid_title":"L’espace fixe est indisponible","fixed_floor.invalid_body":"Vérifiez floor dans la configuration de la carte. Valeur configurée : {value}","editor.icon_size":"Taille des icônes, % de la largeur du plan","editor.show_temperature":"Afficher la température","editor.live_states":"États en direct (on/off, ouvert…)","editor.light_pools":"Halos lumineux et ombres des murs","editor.show_signal":"Afficher le signal Zigbee (LQI)","editor.language":"Langue de l’interface","editor.lang_auto":"Auto (profil HA)","title.icon_rules":"Règles d’icônes : quelle icône MDI attribuer aux appareils selon leur nom","rules.title":"Règles d’icônes","rules.hint":"Les règles sont testées de haut en bas sur « nom de l’appareil + modèle » (expression régulière insensible à la casse) ; la première correspondance gagne. Si rien ne correspond, la classe d’appareil de l’entité est utilisée, puis l’icône générique.","rules.pattern_ph":"regex, ex. plug|socket","rules.icon_ph":"mdi:power-socket-de","rules.add":"Ajouter une règle","rules.reset":"Réinitialiser par défaut","rules.test_ph":"Tester un nom d’appareil…","rules.invalid":"expression régulière invalide","rules.saved":"Règles d’icônes enregistrées","btn.up":"Monter","btn.down":"Descendre","tap.info":"Fiche de l’appareil","tap.more_info":"Boîte de dialogue Plus d’infos de HA","tap.toggle":"Basculer l’état","marker.tap_label":"Action au toucher pour cet appareil","tap.toggle_note":"L’état déterminé est affiché ci-dessous. Les appareils sécurisés ne sont jamais basculés depuis le plan.","import.title":"Créer des espaces à partir des étages HA","import.hint":"Votre Home Assistant connaît déjà ces étages. Sélectionnez ceux à transformer en espaces du plan — vous importerez ensuite une image de plan pour chacun. Les pièces sont ensuite tracées manuellement sur le plan.","import.start":"Créer {n} espace(s)","import.manual":"Commencer de zéro","import.progress":"Étage {i} sur {n}","import.done":"Espaces créés. Tracez les pièces : cliquez sur les points de la grille et fermez le contour.","btn.skip":"Passer","space.scale_label":"Échelle (taille d’une cellule de grille)","space.cell_cm.help":"Relie la grille aux dimensions réelles : les longueurs, les surfaces, l’épaisseur des murs, la taille des ouvertures et le rayon du halo en dépendent. Une modification ultérieure change les dimensions calculées de tout l’espace sans déplacer ses points sur le plan.","space.cell_cm.help.aria":"Aide : échelle de l’espace","space.scale_unit":"cm par cellule","space.scale_unit_imperial":"po par cellule","space.display_section":"Affichage","space.show_borders":"Toujours afficher les contours des pièces","space.zero_wall_style":"Murs d’épaisseur nulle","space.zero_wall_style.help":"Les murs d’épaisseur nulle en pointillés laissent passer le halo et les rayons du soleil, tandis que les murs pleins les bloquent comme une barrière sans surface. Ce choix s’applique à tous ces murs de l’espace, même si leur ligne est masquée en mode Vue.","space.zero_wall_style.help.aria":"Aide : style des murs d’épaisseur nulle","space.zero_wall_dashed":"Pointillés","space.zero_wall_solid":"Plein","space.show_names":"Afficher les noms des pièces (faire glisser pour déplacer)","space.room_color":"Couleur du contour et du nom","space.opacity":"Opacité","space.fill_label":"Remplissage de la pièce","space.fill_mode.help":"« Couleur personnalisée » définit le style, tandis que « Lumière », « Température » et « LQI » utilisent les données actuelles de Home Assistant. Le halo s’active séparément.","space.fill_mode.help.aria":"Aide : mode de remplissage des pièces","fill.none":"Aucun","fill.lqi":"Signal Zigbee","fill.light":"Lumières","fill.custom":"Couleur personnalisée","space.custom_fill":"Couleur de remplissage","space.source_file":"J’ai une image de plan","space.source_draw":"Aucune image — je tracerai les pièces à la main","fill.temp":"Température","tip.temp_avg":"température moyenne :","tip.hum_avg":"humidité moyenne :","space_card.button":"Ouvrir le plan de l’espace","space_card.not_found":"Espace « {id} » introuvable","space_card.loading":"Chargement…","continuity.restore_plan":"Restauration du plan…","continuity.restore_connection":"Restauration de la connexion aux appareils…","continuity.retry":"Réessayer","editor.space":"Espace","editor.framing":"Cadrage","editor.fit_content":"Tout le contenu visible","editor.fit_house":"Ajusté à la géométrie de la maison","editor.show_button":"Afficher le bouton","editor.button_label":"Libellé du bouton","editor.button_target":"Chemin du tableau de bord cible","marker.sub_entity":"entité","title.general_settings":"Paramètres généraux","gs.title":"Paramètres généraux","gs.hint":"Les couleurs de remplissage s’appliquent à tous les espaces ; chaque couleur possède sa propre opacité. Le mode de remplissage utilisé par un espace se règle dans la boîte de dialogue de cet espace.","gs.light_group":"Remplissage : lumières","gs.light_on":"Lumières allumées","gs.light_off":"Toutes les lumières éteintes","gs.temp_group":"Remplissage : température","gs.temp_cold":"Froid","gs.temp_ok":"Confortable","gs.temp_hot":"Chaud","gs.lqi_group":"Remplissage : signal Zigbee","gs.lqi_low":"Signal faible","gs.lqi_high":"Signal fort","gs.reset":"Réinitialiser par défaut","gs.saved":"Paramètres généraux enregistrés","space.show_lqi":"Afficher le signal Zigbee (LQI) à côté des appareils","space.hide_decor":"Masquer la couche décorative","space.hide_decor_tip":"Les lignes, formes, étiquettes et meubles restent à leur place — visibles dans l’éditeur d’arrière-plan, mais pas sur le plan.","space.hide_openings":"Masquer les ouvertures","space.hide_openings_tip":"Les symboles de portes, fenêtres et portails ne sont pas dessinés, mais les ouvertures continuent de fonctionner : la lumière les traverse, le soleil entre par les fenêtres et les capteurs de contact continuent de les ouvrir. L’éditeur de plan les affiche toujours.","gs.light_none":"Aucune source lumineuse","mode.plan":"Éditeur de plan","mode.devices":"Éditeur d’appareils","display.value":"Valeur + état","marker.subarea":"aucune zone, manuel","device.new":"Nouvel appareil — ouvrez son éditeur pour fermer","opening.unlock_action":"Déverrouiller","opening.lock_action":"Verrouiller","opening.lock_pending":"En cours…","title.close_editor":"Fermer l’éditeur (retour à la vue)","title.add_device":"Ajouter un appareil au plan","devbar.add":"Ajouter","devbar.rules":"Règles d’icônes","device_inbox.button":"Appareils","device_inbox.title":"Appareils sur le plan","device_inbox.search":"Rechercher appareils, entités et intégrations…","device_inbox.add_virtual":"Ajouter un appareil virtuel","device_inbox.tab_on_plan":"Sur le plan","device_inbox.tab_available":"Disponibles","device_inbox.tab_hidden":"Masqués","device_inbox.tab_readd":"De nouveau disponibles","device_inbox.only_new":"Nouveaux uniquement","device_inbox.show_entities":"Afficher les entités","device_inbox.show_hidden":"Afficher les masqués sur le plan","device_inbox.show_hidden.help":"Affiche temporairement les marqueurs masqués et désactivés sous forme de fantômes réservés à l’éditeur. La visibilité enregistrée des appareils ne change pas.","device_inbox.show_hidden.help.aria":"Aide : afficher les appareils masqués sur le plan","device_inbox.new":"Nouveau","device_inbox.find":"Trouver sur le plan","device_inbox.edit":"Modifier","device_inbox.hide":"Masquer","device_inbox.show":"Afficher","device_inbox.add":"Ajouter","device_inbox.readd":"Ajouter à nouveau","device_inbox.hide_available":"Masquer de la liste","device_inbox.show_more":"Afficher plus","device_inbox.more_actions":"Plus d'actions","device_inbox.find_hidden_hint":"Activez d'abord « Afficher les masqués sur le plan »","device_inbox.show_disabled":"Activez cette liaison dans Home Assistant avant de l'afficher","device_inbox.empty_on_plan":"Aucun appareil correspondant n'est encore sur le plan.","device_inbox.empty_available":"Aucun appareil disponible à ajouter.","device_inbox.empty_hidden":"Il n'y a aucun appareil masqué.","device_inbox.empty_readd":"Aucun appareil supprimé n'est disponible pour un nouvel ajout.","device_inbox.reason_visible_auto":"Découvert automatiquement","device_inbox.reason_visible_explicit":"Ajouté explicitement","device_inbox.reason_manual_hidden":"Masqué par l'utilisateur","device_inbox.reason_automatic_hidden":"Masqué automatiquement","device_inbox.reason_service_entry":"Entrée de registre de service uniquement","device_inbox.reason_excluded_integration":"Intégration « {integration} » exclue par les filtres de découverte","device_inbox.reason_excluded_domain":"Type d'entité non spatial","device_inbox.reason_grouped_light":"Représenté par un groupe de lumières de la pièce","device_inbox.reason_represented_by_parent":"Représenté par son appareil parent","device_inbox.reason_removed":"Précédemment retiré du plan","device_inbox.reason_available":"Disponible pour ajout au plan","device_inbox.reason_no_bound_room":"La zone HA n'est liée à aucune pièce du plan","device_inbox.status_ha_disabled":"Désactivé dans Home Assistant","device_inbox.status_orphaned":"La liaison n'existe plus dans Home Assistant","device_inbox.status_unverified":"Le registre Home Assistant est temporairement indisponible","device_inbox.saved":"Liste des appareils mise à jour","device_inbox.filters_excluded":"Intégrations exclues","device_inbox.filters_group_lights":"Regrouper les lumières de la pièce en un marqueur","device_inbox.filters_preview_appear":"apparaîtra : {count}","device_inbox.filters_preview_hide":"disparaîtra : {count}","device_inbox.filters_preview_lights":"lumières concernées : {count}","device_inbox.filters_reset":"Rétablir les recommandées","device_inbox.filters_save":"Enregistrer les filtres","device_inbox.filters_search_ph":"Ajouter une intégration…","device_inbox.filters_title":"Filtres de découverte","space.roomcard_section":"La carte de pièce affiche :","space.label_temp":"Température","space.label_hum":"Humidité","space.label_lqi":"Signal Zigbee moyen","space.label_light":"Lumières allumées/éteintes","roomcard.light_on":"Allumé","roomcard.light_off":"Éteint","roomcard.light_partial":"{on} sur {total}","toast.split_pick_inside":"Les points intermédiaires de découpe doivent se trouver à l’intérieur de la pièce","mode.decor":"Éditeur d’arrière-plan","decor.select":"Sélectionner","decor.line":"Ligne","decor.rect":"Rectangle","decor.ellipse":"Ovale","decor.text":"Texte","decor.erase":"Effacer","decor.erase_confirm_title":"Effacer l’objet ?","decor.color":"Couleur","decor.width":"Épaisseur de ligne","decor.line_style":"Style de ligne","decor.line_style_solid":"Plein","decor.line_style_dashed":"Pointillés","decor.fill":"Remplissage","decor.fill_color":"Couleur de remplissage","decor.length":"Longueur","decor.size":"Taille","decor.flip_h":"Retourner horizontalement","decor.flip_v":"Retourner verticalement","decor.angle":"Angle de rotation, °","decor.text_size":"Taille du texte","decor.backdrop_properties":"Propriétés de l’arrière-plan du plan","decor.text_title":"Étiquette de texte","decor.object_title":"Modifier {kind}","decor.text_label":"Texte","decor.live_group":"Insérer une variable HA","decor.live_entity":"Entité","decor.live_entity_ph":"choisir une entité","decor.live_attr":"Valeur","decor.live_attr_ph":"choisir l’état ou un attribut","decor.live_state":"État","decor.backdrop":"Image d’arrière-plan","decor.backdrop_hint":"Faites glisser pour déplacer ; tirez un coin pour redimensionner ; utilisez la poignée supérieure pour faire pivoter. Maj modifie les proportions ou libère l’angle.","decor.backdrop_reset":"Réinitialiser l’image","decor.backdrop_reset_done":"L’image a retrouvé sa position et sa taille d’origine","marker.icon_auto":"Auto : {icon} (selon les règles d’icônes ; choisissez-en une pour remplacer)","marker.icon_pin_auto":"Épingle","mode.plan_tip":"Éditeur de plan — la géométrie du logement : dessiner et diviser/fusionner les pièces, les associer aux zones HA, placer portes, fenêtres et portails, déplacer les cartes de pièces, régler l’échelle","mode.devices_tip":"Éditeur d’appareils — tout ce qui concerne les icônes : faire glisser pour positionner, cliquer pour modifier l’association/l’icône/l’affichage, ajouter des appareils virtuels, règles d’icônes","mode.decor_tip":"Éditeur d’arrière-plan — décoration purement visuelle sous le plan : lignes, rectangles, ovales et étiquettes de texte qui ne réagissent jamais aux clics","space.glow_enabled":"Halo des sources lumineuses","gs.glow_group":"Halo des sources lumineuses","gs.glow_base":"Obscurité de la maison","gs.glow_light":"Couleur / intensité de lumière par défaut","gs.wall_group":"Murs","gs.wall_fill":"Remplissage des murs","gs.glow_radius":"Rayon du halo","gs.glow_radius.help":"Définit le rayon général du halo en mètres ou en pieds ; le rayon propre à un appareil remplace cette valeur.","gs.glow_radius.help.aria":"Aide : rayon général du halo","gs.unit_m":"m","gs.unit_ft":"pi","marker.controls_label":"Contrôle d’autres sources lumineuses","marker.controls.help":"Avec l’action « Basculer l’état », les sources répertoriées basculent avec ce marqueur. Leur halo reste sur leurs propres marqueurs et ce lien ne transforme pas à lui seul le marqueur de contrôle en source lumineuse.","marker.controls.help.aria":"Aide : contrôler d’autres sources lumineuses","marker.controls_filter":"Rechercher des lumières et interrupteurs…","info.controls":"Contrôle","marker.glow_radius_label":"Rayon du halo","marker.glow_radius.help":"Définit le rayon du halo en mètres ou en pieds ; une valeur vide utilise le rayon des paramètres généraux.","marker.glow_radius.help.aria":"Aide : rayon du halo","markup.wallthick":"Épaisseur","markup.select":"Sélectionner","title.markup_wallthick":"Épaisseur — cliquez sur un mur pour définir son épaisseur de 0 à 100 cm.","markup.hint_wallthick":"cliquez sur un mur · Échap ferme sans appliquer","wallthick.field":"Épaisseur","wallthick.unit_cm":"cm","wallthick.unit_in":"po","wallthick.apply_room":"Appliquer à tous les murs de cette pièce","markup.draw_wall_title":"Épaisseur de chaque nouveau segment de mur (0–100 cm). Les murs partagés conservent la valeur existante.","room.queue_progress":"Pièce {current} sur {total}","toast.wall_rooms_saved":"Pièces créées : {n}","toast.wall_chain_saved":"Chaîne de murs enregistrée","toast.wallthick_pick":"Cliquez sur un mur","toast.wallthick_set":"Épaisseur du mur définie","toast.wallthick_cleared":"Épaisseur du mur supprimée","toast.physical_range":"Saisissez une valeur comprise entre {min} et {max} {unit}","toast.zero_wall_opening_conflict":"Supprimez d’abord l’ouverture sur ce segment de mur.","toast.zero_wall_ambiguous":"Le segment de mur est ambigu. Simplifiez ou ajustez la jonction.","toast.zero_wall_migration_blocked":"L’espace n’a pas été converti : {reason}. Aucune donnée n’a été modifiée.","toast.physical_angle":"Saisissez un angle de rotation compris entre 0° inclus et 90° exclu","toast.physical_limit":"L’espace a atteint la limite pour ce type de géométrie","toast.geometry_unsafe":"Modification annulée : la géométrie des murs n’a pas pu être construite en toute sécurité.","junction.limit_angle":"L'angle entre les murs est trop aigu : {actual}°, minimum {limit}°.","junction.limit_valence":"Trop de murs se rejoignent en un nœud : {actual}, maximum {limit}.","junction.limit_length":"Le segment de mur est trop court : {actual} cm, minimum {limit} cm.","junction.limit_distance":"Les murs et les nœuds sont trop proches : {actual} cm, minimum {limit} cm.","junction.limit_clearance":"Il ne reste plus d'intérieur de pièce : {actual} cm², minimum {limit} cm².","junction.limit_check_failed":"La vérification des jonctions n'a pas pu s'exécuter — la modification n'a pas été enregistrée","toast.wall_model_migration_blocked":"Le modèle de murs n’a pas pu être mis à jour : {reason}. Le plan n’a pas été modifié. Lancez « Optimiser les plans » ; si l’erreur se reproduit, corrigez la géométrie de mur conflictuelle.","toast.wall_model_client_outdated":"Mettez à jour la carte et rechargez la page avant de modifier le plan.","wall_model.reason.invalid-room":"contour de pièce invalide","wall_model.reason.zero-length":"segment de mur de longueur nulle","wall_model.reason.third-owner":"mur partagé par plus de deux pièces","wall_model.reason.duplicate-id":"identifiants de mur en conflit","wall_model.reason.thickness-conflict":"valeurs d’épaisseur de mur en conflit","wall_model.reason.opening-host":"l’ouverture ne peut pas être attribuée à un seul mur","toast.delete_room_pick":"Cliquez à l’intérieur de la pièce que vous souhaitez supprimer","toast.plan_snap_ambiguous":"Zoomez pour choisir le nœud du mur","toast.wall_repair_ambiguous":"Le contour de la pièce possède plusieurs connexions possibles. Zoomez et reliez-le explicitement.","toast.wall_repair_too_large":"L’écart dépasse 2 cm. Reliez les murs avant de créer la pièce.","toast.wall_repair_changed":"La géométrie des murs a changé. Essayez de créer de nouveau la pièce.","toast.opening_on_zero_wall":"Les ouvertures ne peuvent pas être placées sur un mur d’épaisseur nulle","marker.from_ha_option":"Choisir dans la liste HA","marker.show_entities":"Afficher les entités","marker.show_entities_tip":"Ajoute à la liste non seulement les appareils, mais aussi toutes leurs entités","marker.pick_ph":"Choisir un appareil…","room.open_area":"Ouvrir la zone HA","view.volumetric":"Vue volumétrique","view.flat":"Vue plane","kiosk.title":"Tailles pour cet écran","kiosk.hint":"Enregistrées uniquement sur cet appareil — chaque tablette murale ou TV peut avoir ses propres tailles confortables.","kiosk.icon_scale":"Taille des icônes d’appareils","kiosk.font_scale":"Taille du texte des cartes de pièces","editor.kiosk":"Mode appareil mural (kiosque)","editor.cycle":"Changer automatiquement d’espace toutes les N secondes (kiosque, 0 = désactivé)","room.settings_title":"Paramètres de la pièce","room.settings_section":"Paramètres de la pièce (remplacent ceux de l’espace)","room.fill_label":"Remplissage de CETTE pièce","fill.inherit":"Comme l’espace","room.custom_fill_space":"Couleur de l’espace","room.custom_fill_own":"Couleur de la pièce","room.temp_src_label":"Source de température","room.hum_src_label":"Source d’humidité","room.src_average":"Moyenne des capteurs de la pièce (par défaut)","room.src_pick":"Un appareil ou une entité HA spécifique","room.src_ph":"Choisir une source…","toast.room_updated":"Pièce mise à jour","space.card_font":"Taille de police des cartes de pièces (tout l’espace)","room.sizes_section":"Tailles de police","room.name_scale":"Taille du nom de la pièce","room.label_scale":"Taille des mesures","preview.room_name":"Salon","toast.cfg_reload_failed":"Impossible de recharger le plan depuis le serveur : {err}","toast.locale_load_failed":"Impossible de charger le pack de langue. L'anglais est utilisé jusqu'au rechargement de la page.","room.settings_short":"Paramètres de la pièce","room.unnamed":"Pièce sans nom","marker.use_climate_temp":"Inclure la température de l’appareil dans la pièce","marker.use_climate_temp_tip":"Ajoute la valeur current_temperature d’un climatiseur ou thermostat à la moyenne de la pièce. Configurez séparément le badge de valeur externe ci-dessous.","marker.value_badge_title":"Badge de valeur","marker.value_badge.help":"Affiche une valeur sélectionnée à côté de l’icône. Cela n’affecte pas les mesures de la pièce, la lumière, le halo ni l’action au toucher.","marker.value_badge.help.aria":"Aide : badge de valeur de l’appareil","marker.value_badge_enabled":"Afficher un badge de valeur","marker.value_badge_source":"Valeur","marker.value_badge_source.help":"Choisissez un état précis, un attribut pris en charge ou une valeur dérivée de cet appareil.","marker.value_badge_source.help.aria":"Aide : source du badge de valeur","marker.value_badge_position":"Position","marker.value_badge_position.help":"Le côté choisi reste fixe et ne bascule pas automatiquement au bord du plan.","marker.value_badge_position.help.aria":"Aide : position du badge de valeur","marker.value_badge_right":"À droite","marker.value_badge_bottom":"En dessous","marker.value_badge_left":"À gauche","marker.value_badge_top":"Au-dessus","marker.value_badge_empty":"Cet appareil n’a aucune valeur disponible","marker.value_badge_static":"Une icône statique n’affiche pas de valeurs en direct. Le paramètre est conservé.","marker.value_badge_missing":"Source indisponible","marker.value_badge_missing_hint":"La source enregistrée est actuellement indisponible. Conservez-la, désactivez le badge ou choisissez une autre valeur.","marker.value_badge_duplicate":"La même valeur est déjà affichée dans l’icône.","marker.value_badge_state":"État · {name}","marker.value_badge_marker_state":"État de la source lumineuse · {name}","marker.value_badge_lqi":"Qualité moyenne du signal Zigbee","marker.value_badge_attr_current_temperature":"Température actuelle · {name}","marker.value_badge_attr_temperature":"Température cible · {name}","marker.value_badge_attr_current_humidity":"Humidité actuelle · {name}","marker.value_badge_attr_humidity":"Humidité · {name}","marker.value_badge_attr_current_position":"Position · {name}","marker.value_badge_attr_percentage":"Vitesse · {name}","marker.value_badge_attr_brightness":"Luminosité · {name}","marker.value_badge_attr_volume_level":"Volume · {name}","marker.value_badge_attr_battery_level":"Batterie · {name}","marker.value_badge_attr_fan_speed":"Vitesse du ventilateur · {name}","marker.value_source":"Source de la valeur","marker.value_source.help":"Choisissez la valeur qui remplace l’icône. L’action au toucher ne change pas.","marker.value_source.help.aria":"Aide : source de la valeur dans le marqueur","marker.value_source_auto":"Automatique (comme avant)","marker.value_source_missing_hint":"La source enregistrée est indisponible. Le marqueur affiche — jusqu’à son retour ou jusqu’au choix d’une autre valeur.","marker.light_role_label":"Cet appareil est-il une source lumineuse ?","marker.light_role.help":"« Auto » utilise le rôle déterminé de l’appareil lié, « Toujours » force sa propre source et « Jamais » l’exclut ; les lumières liées ci-dessus restent indépendantes.","marker.light_role.help.aria":"Aide : cet appareil est-il une source lumineuse","marker.light_role_auto_yes":"Auto (source lumineuse)","marker.light_role_auto_no":"Auto (pas une source lumineuse)","marker.light_role_always":"Toujours une source lumineuse","marker.light_role_never":"Jamais une source lumineuse","marker.light_entity_label":"Entité lumineuse principale","marker.light_entity.help":"Pour un appareil composite, choisissez l’entité dont l’état, la couleur et la luminosité représentent cette source sur le plan. Le choix automatique reste compatible avec les anciens plans.","marker.light_entity.help.aria":"Aide : entité lumineuse principale","marker.light_entity_auto":"Automatique ({entity})","marker.light_entity_none":"aucune entité contrôlable","marker.light_entity_missing":"L’entité enregistrée {entity} est indisponible. House Plan utilise temporairement {fallback} ; le choix enregistré sera restauré si elle revient.","marker.toggle_entity_label":"Entité à basculer","marker.toggle_entity.help":"Pour un appareil composite, choisissez précisément la lumière ou l’interrupteur propre à actionner par un toucher. Automatique conserve les règles de cible précédentes et reste indépendant de l’entité lumineuse principale.","marker.toggle_entity.help.aria":"Aide : entité à basculer","marker.toggle_entity_auto":"Automatique ({entity})","marker.toggle_entity_none":"aucune entité propre contrôlable","marker.toggle_entity_missing":"L’entité enregistrée {entity} ne fait plus partie des canaux sélectionnables de ce marqueur. House Plan utilise temporairement {fallback} ; le choix enregistré sera restauré si elle revient.","marker.glow_color_label":"Couleur et luminosité du halo","marker.glow_mode.help":"Utilisez les valeurs en direct de la source, remplacez uniquement sa couleur ou fixez à la fois la couleur et la luminosité. Le minimum est 1 % ; pour désactiver la source, choisissez « Jamais ».","marker.glow_mode.help.aria":"Aide : couleur et luminosité du halo","marker.glow_mode_auto":"Depuis la source","marker.glow_mode_color":"Définir la couleur","marker.glow_mode_fixed":"Définir la couleur et la luminosité","marker.glow_color":"Couleur du halo","marker.glow_brightness":"Luminosité","marker.glow_disabled_never":"Les paramètres du halo sont indisponibles car ce marqueur est explicitement défini comme n’étant pas une source lumineuse.","marker.glow_disabled_auto":"Le mode Auto n’a trouvé aucune source lumineuse spatiale pour ce marqueur.","marker.glow_disabled_no_entity":"Aucune entité Home Assistant contrôlable et active n’est disponible pour cette source spatiale.","marker.glow_passive_hint":"Cette source ne possède aucune donnée Home Assistant propre. Définissez manuellement sa couleur et sa luminosité ; son rayon reste disponible.","marker.control_broken":"La source enregistrée est absente ou n’est plus marquée comme lumière","marker.control_missing_label":"Lumière du plan manquante","marker.control_passive":"source passive","toast.marker_control_cycle":"Ce lien créerait une chaîne circulaire de contrôles de lumière.","toast.marker_binding_required":"Choisissez un appareil Home Assistant avant de lier une autre source lumineuse.","confirm.unlock_title":"Déverrouiller ?","confirm.unlock_body":"House Plan enverra une commande de déverrouillage à cette serrure.","toast.files_migrate_failed":"Les pièces jointes n’ont pas pu être déplacées vers la nouvelle association ; les liens continuent de pointer vers les anciens fichiers : {err}","space.pick_saved":"Déjà importé","space.pick_saved_hint":"Plans stockés sur le serveur, y compris ceux que vous avez précédemment dissociés","space.no_saved":"Aucun plan n’est encore stocké sur le serveur.","space.loading":"Chargement…","space.used_by":"utilisé par : {list}","space.in_use":"Un espace utilise encore ce plan — dissociez-le d’abord","btn.use":"Utiliser","confirm.delete_plan_title":"Supprimer le fichier du plan ?","confirm.delete_plan_body":"Le fichier sera supprimé du serveur. Cette action est irréversible.","toast.plans_list_failed":"Impossible de lister les plans stockés : {err}","toast.plan_delete_failed":"Impossible de supprimer le plan : {err}","marker.hide":"Masquer","marker.hide_tip":"L’appareil disparaîtra du plan après l’enregistrement mais continuera de compter dans le signal de la pièce. Restaurez-le via « Masqués et désactivés » dans l’éditeur d’appareils.","marker.show":"Afficher","marker.show_tip":"L’appareil apparaîtra de nouveau sur le plan après l’enregistrement.","marker.hidden_ghost":"Appareil masqué par l’utilisateur","marker.ha_disabled_device":"L’appareil est désactivé dans Home Assistant et masqué du plan.","marker.ha_disabled_entity":"L’entité est désactivée dans Home Assistant et masquée du plan.","marker.ha_disabled_all_entities":"L’appareil n’a aucune entité Home Assistant active ; il est donc masqué du plan.","marker.ha_registry_limited":"Le registre Home Assistant complet n’est pas accessible à cet utilisateur. L’objet non vérifié ne peut pas être affiché ni utilisé pour le moment.","marker.delete_tip":"Supprimer complètement l’appareil du plan et de tous les agrégats. Vous pourrez l’ajouter de nouveau plus tard.","tap.run":"Exécuter une automatisation/un script/une scène","tap.none":"Ne rien faire","marker.run_target_label":"Élément à exécuter","marker.run_search_ph":"Rechercher : automatisation, script ou scène…","marker.run_target_gone":"Cible {id} introuvable — choisissez-en une autre","marker.tap_confirm":"Demander une confirmation","marker.tap_confirm_tip":"Afficher une boîte de dialogue de confirmation avant l’action — protection contre les appuis accidentels.","marker.toggle_hint_single":"Cible : {name} ({id}).","marker.virtual_light_target":"Lumière virtuelle : {name}.","marker.virtual_light_current":"État manuel : {state} → {effect}.","marker.virtual_light_state_on":"allumé","marker.virtual_light_state_off":"éteint","marker.toggle_hint_group":"Basculera {count} source(s) : {names}.","marker.toggle_hint_current":"Actuellement : {state} → {effect}.","marker.toggle_hint_group_current":"Actuellement allumées : {on} sur {count} → {effect}.","marker.toggle_hint_skipped":"Seront ignorées ({count}) : {targets}.","marker.toggle_effect_turn_on":"sera allumé","marker.toggle_effect_turn_off":"sera éteint","marker.toggle_effect_open":"sera ouvert","marker.toggle_effect_close":"sera fermé","marker.toggle_effect_stop":"sera arrêté","marker.toggle_effect_toggle":"l’état sera basculé","marker.toggle_skip_missing":"introuvable","marker.toggle_skip_ha_disabled":"désactivé dans HA","marker.toggle_skip_unavailable":"indisponible","marker.toggle_skip_unsupported":"basculement non pris en charge","marker.toggle_skip_secure":"bloqué pour des raisons de sécurité","marker.toggle_none_no_binding":"Cet appareil n’a aucune association ; il n’y a donc aucun état à basculer. Un toucher ne fera rien.","marker.toggle_none_no_actionable_entity":"Cet appareil n’a aucun état pouvant être basculé. Un toucher ne fera rien.","marker.toggle_none_configured_targets_missing":"Les cibles configurées sont indisponibles. L’entité propre de l’appareil ne leur sera pas substituée.","marker.toggle_none_ha_disabled":"La cible est désactivée dans Home Assistant et ne peut pas être utilisée sur le plan.","marker.toggle_none_unavailable":"La cible est actuellement indisponible. Un toucher ne fera rien.","marker.toggle_none_unsupported":"Home Assistant n’expose aucune opération de basculement sûre pour cette entité. Un toucher ne fera rien.","marker.toggle_none_secure":"Le basculement des serrures, alarmes et portails sécurisés depuis le plan est bloqué pour des raisons de sécurité.","run.automation":"automatisation","run.script":"script","run.scene":"scène","confirm.tap_run":"Exécuter « {name} » ?","confirm.tap_toggle":"Basculer « {name} » ?","confirm.current_state":"État actuel : {state}","confirm.expected_state":"Après basculement : {state}","confirm.group_current":"{on} allumé(s) sur {total}","confirm.group_all_on":"tout est allumé","confirm.group_all_off":"tout est éteint","confirm.unavailable_targets":"Indisponibles : {count}","confirm.expected_by_ha":"Home Assistant déterminera l’état","confirm.state_on":"Allumé","confirm.state_off":"Éteint","confirm.state_open":"Ouvert","confirm.state_closed":"Fermé","confirm.state_opening":"Ouverture en cours","confirm.state_closing":"Fermeture en cours","confirm.state_stopped":"Arrêté","confirm.state_unknown":"Inconnu","toast.run_started":"Démarré : {name}","toast.run_target_missing":"Cible d’exécution introuvable — vérifiez les paramètres de l’appareil","toast.run_target_required":"Choisissez une automatisation, un script ou une scène","toast.tap_target_changed":"La cible de l’action a changé. Réessayez.","toast.virtual_light_toggle_failed":"Impossible de basculer la lumière virtuelle : {err}","toast.value_badge_source_required":"Choisissez une valeur pour le badge","btn.run":"Exécuter","vac.section":"Robot aspirateur : position en direct","vac.autocal":"Configurer automatiquement","vac.live":"Position en direct sur le plan","vac.trail":"Afficher le trajet du robot","vac.cal_maps":"Cartes calibrées : {maps}","vac.autocal_no_rooms":"L’intégration ne fournit aucune liste de pièces — ouvrez « Ajuster manuellement »","vac.autocal_no_match":"Les noms de pièces ne correspondent pas (il en faut ≥3 en commun) — ouvrez « Ajuster manuellement »","vac.autocal_done":"Terminé : association via {rooms} pièces. Lancez un nettoyage et vérifiez","vac.cal_need_pos":"Le robot ne transmet pas de coordonnées — lancez un nettoyage puis mettez-le en pause","vac.cal_done":"Calibration enregistrée. Lancez un nettoyage et vérifiez","vac.cal_cancelled":"Calibration annulée","vac.fit":"Ajuster manuellement","vac.fit_hint":"Faites glisser la carte du robot pour la positionner, étirez-la par les coins","vac.fit_rotate":"Rotation de 90°","vac.fit_mirror":"Miroir","vac.trail_never":"Jamais","vac.trail_cleaning":"Pendant le nettoyage","vac.trail_always":"Toujours","gs.bg_group":"Arrière-plan de la scène","gs.bg_color":"Arrière-plan autour du plan","gs.bg_default":"Valeur par défaut du thème","gs.bg_theme":"valeur par défaut du thème","gs.bg_mode":"Arrière-plan du plan","gs.bg_mode.help":"« Suit le soleil » utilise sun.sun ou, à défaut, l’heure locale du navigateur ; « Couleur statique » affiche toujours la couleur choisie.","gs.bg_mode.help.aria":"Aide : arrière-plan général du plan","gs.bg_static":"Couleur statique","gs.bg_daynight":"Suit le soleil","gs.sun_group":"Soleil","gs.sun_missing":"L’entité sun.sun est introuvable — l’arrière-plan suit votre heure locale ; les rayons de soleil par les fenêtres sont indisponibles.","gs.north":"Nord sur le plan","gs.north.help":"L’angle se mesure dans le sens horaire depuis la verticale supérieure du plan ; le nord sert aux rayons des fenêtres, pas à l’arrière-plan « Suit le soleil ».","gs.north.help.aria":"Aide : direction générale du nord","gs.north_ph":"non défini","gs.north_clear":"Effacer","gs.north_letter":"N","gs.sun_rays":"Lumière du soleil à travers les fenêtres","gs.about_group":"À propos","gs.about_version":"Houseplan Card v{v}","gs.about_github":"GitHub · documentation et problèmes","gs.about_telegram":"Discussion Telegram","space.bg_color":"Arrière-plan autour du plan","space.bg_inherit":"Hériter des paramètres généraux","space.bg_inherited":"hérite des paramètres généraux","space.bg_mode":"Arrière-plan du plan","space.bg_mode.help":"Héritez de l’arrière-plan général ou remplacez-le pour cet espace par une couleur statique ou le mode « Suit le soleil ».","space.bg_mode.help.aria":"Aide : arrière-plan de l’espace","space.north":"Nord sur le plan (remplacement)","space.north.help":"Remplace le nord général pour cet espace ; l’angle se mesure dans le sens horaire depuis la verticale supérieure du plan et sert aux rayons des fenêtres.","space.north.help.aria":"Aide : nord de cet espace","space.north_inherited":"hérité : {v}","space.sun_rays":"Lumière du soleil à travers les fenêtres","space.sun_inherit":"Hériter des paramètres généraux","space.sun_on":"Activé","space.sun_off":"Désactivé","canvas.far_objects":"{n} objet(s) éloigné(s) du plan","canvas.show_far":"Afficher","canvas.home_tip":"Le plan est là-bas — cliquez pour l’ajuster à l’écran","gs.grid_group":"Maintenance du plan","gs.grid_hint":"Met à jour les modèles de données, aligne les éléments du plan sur la grille et fusionne les fragments de murs redondants. Un rapport précis est affiché avant tout enregistrement.","gs.align_all":"Optimiser les plans","gs.align_title":"Optimiser les plans","gs.align_none":"Tous les plans utilisent déjà le modèle de données optimisé actuel.","gs.optimize_no_automatic_changes":"Aucune modification automatique n’est à appliquer. Vérifiez les éléments ci-dessous.","gs.align_count":"{n} élément(s) sur {total} seront déplacés, de {cm} cm au maximum.","gs.align_where":"Le plus grand déplacement se trouve dans « {s} ».","gs.align_turned":"Ouvertures dont l’angle est corrigé : {n}.","gs.align_removed_drafts":"Contours invalides réduits par la grille et supprimés : {n}.","gs.optimize_redundant_drafts":"Chaînes de murs enregistrées masquées par des murs de pièces pleins et supprimées : {n}.","gs.align_preflight_failed":"Impossible de vérifier en toute sécurité la géométrie des espaces suivants : {spaces}{more}.","gs.align_preflight_hint":"Les plans n’ont pas été modifiés. Copiez les diagnostics avec le bouton ci-dessous et joignez-les au rapport de bug avec un export de l’espace.","gs.preflight_reason_prepare-exception":"Impossible de préparer la géométrie de l’espace (exception lors de la construction du modèle)","gs.preflight_reason_wall-null":"Le corps du mur n’a pas pu être construit (l’union a renvoyé un résultat vide)","gs.preflight_reason_wall-degraded-extra":"Le corps du mur s’est dégradé avec une géométrie supplémentaire","gs.preflight_reason_wall-failed-core":"Le noyau du corps du mur n’a pas pu être assemblé","gs.preflight_reason_wall-exception":"La construction du mur a déclenché une exception","gs.preflight_reason_floor-null":"Le contour du sol n’a pas pu être construit","gs.preflight_reason_floor-exception":"La construction du sol a déclenché une exception","gs.preflight_copy":"Copier les diagnostics","gs.preflight_copied":"Diagnostics copiés","gs.preflight_update_hint":"Les versions de la carte et de l’intégration diffèrent — mettez House Plan à jour puis réessayez.","gs.align_preflight_space":"Espace {n}","gs.align_preflight_more":", et {n} de plus","gs.optimize_changes":"Migrations de modèle : {m} ; espaces mis à jour : {c} ; valeurs de coordonnées parasites supprimées : {p} ; fragments de murs réels fusionnés : {w} ; fragments de murs d’épaisseur nulle fusionnés : {s} ; murs indépendants : {i}.","gs.zero_walls_migrated":"Portions de murs virtuels converties : {n}.","gs.wall_segments_migrated":"Segments de murs stabilisés : {n}.","gs.optimize_lattice_summary":"Valeurs de coordonnées parasites normalisées : {n} ; déplacement maximal : {cm} cm.","gs.optimize_lattice_space":"{space} : valeurs de coordonnées normalisées : {n} ; valeurs hors grille laissées inchangées : {far}.","gs.optimize_coincident_partitions":"Sections de murs indépendants masquées absorbées dans les murs des pièces : {n}.","gs.optimize_openings_rehosted":"Ouvertures rattachées aux murs des pièces : {n}.","gs.optimize_walls_straightened":"Murs redressés : {n} ; déplacement maximal : {cm} cm.","gs.optimize_walls_straightened_where":"Plus grande correction de mur : {s}.","gs.optimize_walls_straighten_skipped":"Murs proches d’un axe laissés inchangés car ils ne pouvaient pas être réparés en toute sécurité : {n}.","gs.optimize_glow_migration":"Ancien mode Glow : {spaces} espaces → aucun remplissage de données + Glow indépendant ; {rooms} pièces → remplissage de données hérité + Glow indépendant.","gs.optimize_references":"Références réparées : espaces — {spaces} ; pièces — {rooms} ; positions — {positions} ; appareils dissociés des espaces manquants — {detached}.","gs.optimize_reference_more":", et {n} de plus","gs.optimize_orphans_removed":"Enregistrements oubliés supprimés : {total} — étiquettes de pièces : {rooms} ; appareils : {devices} ; marqueurs de groupe : {groups}. Ils appartenaient à des espaces supprimés précédemment.","gs.optimize_live_positions":"Anciennes positions dans des espaces supprimés appartenant à des objets existants : {n}{names}. Elles seront conservées.","gs.optimize_live_positions_remove":"Anciennes positions dans des espaces supprimés appartenant à des objets existants : {n}{names}. Elles sont sélectionnées pour suppression.","gs.optimize_live_names":" : {names}{more}","gs.optimize_live_remove":"Supprimer les anciennes positions","gs.optimize_live_keep":"Conserver les anciennes positions","gs.optimize_live_selected":"Les anciennes positions seront supprimées après l’application de l’optimisation.","gs.optimize_unverified":"Impossible de vérifier en toute sécurité les positions : {n}. Elles ont été laissées inchangées.","gs.optimize_registry_limited":"Un accès administrateur complet aux registres Home Assistant est requis pour une vérification sûre.","gs.optimize_vacuum_warning":"Associations de pièces d’aspirateur nécessitant encore une vérification : {n}.","gs.optimize_details":"Détails","gs.optimize_details_more":"Et {n} enregistrement(s) de plus.","gs.optimize_detail_removed":"sera supprimé","gs.optimize_detail_live":"sera conservé","gs.optimize_detail_unverified":"non vérifié","gs.optimize_detail_room_label":"étiquette de pièce","gs.optimize_detail_device":"appareil","gs.optimize_detail_group":"marqueur de groupe","gs.optimize_detail_unknown":"propriétaire inconnu","gs.optimize_detail_item":"{status} : {kind} {id} ; ancien espace {space}","gs.align_warn":"Les éléments volontairement placés entre les nœuds de la grille seront déplacés. Une seule annulation est disponible après l’opération, uniquement jusqu’à la prochaine modification du plan.","gs.align_run":"Optimiser","gs.align_done":"Plans optimisés : {n} élément(s) déplacé(s), {m} enregistrement(s) maintenu(s), {r} référence(s) réparée(s)","gs.optimize_undo":"Annuler la dernière optimisation","gs.optimize_undone":"La dernière optimisation a été annulée","decor.furniture":"Mobilier","furn.title":"Bibliothèque de mobilier","furn.symbol":"Symbole","furn.group_furniture":"Mobilier","furn.group_appliance":"Électroménager","furn.group_sanitary":"Sanitaires","furn.group_other":"Autre","furn.width":"Largeur","furn.depth":"Profondeur","furn.back_to_categories":"Toutes les catégories","furn.pick_hint":"Choisissez un symbole, puis cliquez sur le plan.","furn.place_hint":"Cliquez sur le plan — le meuble se place contre le mur le plus proche. Maj permet un placement libre.","furn.cat_air_conditioner":"Climatiseurs","furn.cat_armchair":"Fauteuils","furn.cat_bathtub":"Baignoires","furn.cat_bed":"Lits","furn.cat_bidet":"Bidets","furn.cat_boiler":"Chauffe-eau","furn.cat_chair":"Chaises","furn.cat_coffee_table":"Tables basses","furn.cat_cooktop":"Plaques de cuisson","furn.cat_dining_table":"Tables à manger","furn.cat_dishwasher":"Lave-vaisselle","furn.cat_dryer":"Sèche-linge","furn.cat_fireplace":"Cheminées","furn.cat_fridge":"Réfrigérateurs","furn.cat_kitchen_cabinet":"Meubles de cuisine","furn.cat_kitchen_sink":"Éviers de cuisine","furn.cat_nightstand":"Meubles","furn.cat_plant":"Plantes","furn.cat_rug":"Tapis","furn.cat_shelving":"Étagères","furn.cat_shower":"Douches","furn.cat_sink":"Lavabos","furn.cat_sofa":"Canapés","furn.cat_stairs":"Escaliers","furn.cat_toilet":"Toilettes","furn.cat_tv":"Téléviseurs","furn.cat_wardrobe":"Armoires","furn.cat_washer":"Lave-linge","furn.cat_work_table":"Bureaux","furn.sym_sofa":"Canapé","furn.sym_sofa_three_seat":"Canapé trois places","furn.sym_sofa_corner_right":"Canapé d'angle droit","furn.sym_armchair":"Fauteuil","furn.sym_armchair_office":"Chaise de bureau","furn.sym_coffee_table":"Table basse","furn.sym_coffee_table_round":"Table basse ronde","furn.sym_coffee_table_oval":"Table basse ovale","furn.sym_coffee_table_rounded":"Table basse arrondie","furn.sym_table_dining":"Table à manger","furn.sym_table_round":"Table ronde","furn.sym_table_dining_oval":"Table à manger ovale","furn.sym_table_dining_rounded":"Table à manger arrondie","furn.sym_chair":"Chaise","furn.sym_chair_bar":"Tabouret de bar","furn.sym_desk":"Bureau","furn.sym_desk_corner":"Bureau d'angle","furn.sym_bed_double":"Lit double","furn.sym_bed_single":"Lit simple","furn.sym_nightstand":"Table de chevet","furn.sym_cabinet_tv":"Meuble TV","furn.sym_cabinet_shoe":"Meuble à chaussures","furn.sym_cabinet_sink":"Meuble sous lavabo","furn.sym_wardrobe":"Armoire","furn.sym_bookshelf":"Bibliothèque","furn.sym_wall_unit":"Élément mural","furn.sym_kitchen_floor":"Module de cuisine bas","furn.sym_kitchen_floor_corner":"Module de cuisine bas d'angle","furn.sym_kitchen_wall":"Module de cuisine haut","furn.sym_kitchen_wall_corner":"Module de cuisine haut d'angle","furn.sym_shelf_floor":"Étagère au sol","furn.sym_shelf_wall":"Étagère murale","furn.sym_fridge":"Réfrigérateur","furn.sym_stove":"Cuisinière","furn.sym_cooktop_two":"Plaque à deux feux","furn.sym_dishwasher":"Lave-vaisselle","furn.sym_washer":"Lave-linge","furn.sym_dryer":"Sèche-linge","furn.sym_tv":"Téléviseur","furn.sym_tv_wall":"Téléviseur mural","furn.sym_ac":"Climatiseur","furn.sym_water_heater":"Chauffe-eau","furn.sym_toilet":"Toilettes","furn.sym_toilet_built_in":"Toilettes suspendues","furn.sym_bathtub":"Baignoire","furn.sym_bathtub_corner":"Baignoire d'angle","furn.sym_shower":"Douche","furn.sym_sink":"Lavabo","furn.sym_kitchen_sink":"Évier de cuisine","furn.sym_kitchen_sink_double":"Évier de cuisine double","furn.sym_bidet":"Bidet","furn.sym_bidet_built_in":"Bidet suspendu","furn.sym_stairs":"Escalier","furn.sym_fireplace":"Cheminée","furn.sym_plant":"Plante","furn.sym_rug":"Tapis","common.yes":"Oui","common.no":"Non","vac.diag_source":"Source","vac.diag_platform":"Intégration","vac.diag_status":"État","vac.diag_position":"Position","vac.diag_rooms":"Pièces","vac.diag_rooms_value":"{total} · {matched} noms correspondent · {readiness}","vac.autocal_ready":"calibration automatique disponible","vac.autocal_not_ready":"3 noms correspondants requis","vac.diag_path":"Chemin de l’intégration","vac.diag_map":"ID de carte","vac.source_none":"non sélectionné","vac.source_status_ok":"Prêt","vac.source_status_missing":"Manquant","vac.source_status_disabled":"Désactivé dans Home Assistant","vac.source_status_unavailable":"Indisponible","vac.source_status_unverified":"Impossible à vérifier avec les autorisations actuelles","vac.source_status_unsupported":"Aucune donnée de position","vac.source_status_none":"Aucune source","vac.source_banner_missing":"La source enregistrée n’existe plus. Elle n’a pas été remplacée automatiquement ; choisissez une autre source ou restaurez-la dans Home Assistant.","vac.source_banner_disabled":"La source enregistrée est désactivée dans Home Assistant. Activez-la ou choisissez une autre source.","vac.source_banner_unverified":"Les autorisations Home Assistant actuelles ne permettent pas de vérifier cette source enregistrée. Elle reste épinglée et ne sera pas remplacée automatiquement.","vac.choose_source":"Choisir la source","vac.source_auto":"Automatique","vac.source_auto_hint":"Utiliser une entité compatible de cet appareil","vac.all_cameras":"Toutes les caméras","vac.all_cameras_warn":"Une caméra peut ne pas fournir de données du robot. Choisissez-en une uniquement s’il s’agit de la carte de votre aspirateur.","vac.all_cameras_empty":"Aucune autre entité caméra trouvée.","vac.platform_unknown":"intégration inconnue","vac.cap_position":"position","vac.cap_rooms_short":"pièces","vac.cap_path":"trajet","vac.cap_map":"ID de carte","vac.cap_none":"aucune donnée de robot détectée","vac.xcme_hint":"Activez ces attributs Xiaomi Cloud Map Extractor :","vac.documentation":"Documentation","vac.residual_title":"Vérifier la calibration automatique","vac.residual_message":"Les pièces correspondantes présentent un écart maximal de {error}. Appliquez cette calibration approximative, affinez-la manuellement ou annulez sans modifier la configuration enregistrée.","vac.apply_proposal":"Appliquer","gs.backup_group":"Sauvegarde et transfert","gs.backup_hint":"Téléchargez une sauvegarde JSON portable ou prévisualisez et importez une sauvegarde créée par House Plan.","backup.export_open":"Exporter","backup.import_open":"Importer","backup.export_title":"Exporter House Plan","backup.import_title":"Importer House Plan","backup.export_hint":"Choisissez si la sauvegarde doit contenir toute la configuration House Plan ou uniquement l’espace actuel.","backup.full":"Sauvegarde complète","backup.current_space":"Espace actuel","backup.current_space_title":"Espace actuel : {title}","backup.no_current_space":"Aucun espace actuel","backup.plan_only":"Plan uniquement","backup.plan_only_hint":"Conserver les pièces, murs, ouvertures, décorations et positions des étiquettes de pièces sans les appareils ni les associations Home Assistant.","backup.plan_only_preview":"Ce fichier contient uniquement le plan","backup.privacy_warning":"L’archive conserve les noms, identifiants Home Assistant et coordonnées exactes. Les plans internes et pièces jointes sont référencés, pas intégrés ; les états d’exécution et trajets d’aspirateur ne sont pas inclus.","backup.download":"Télécharger le JSON","backup.export_done":"Sauvegarde téléchargée","backup.reading":"Vérification de la sauvegarde…","backup.revalidated":"Le plan a changé depuis cet aperçu. Le résumé a été actualisé ; vérifiez-le et confirmez de nouveau.","backup.error.unauthorized":"Vous n’avez pas l’autorisation d’exporter ou d’importer ce plan.","backup.error.not_ready":"House Plan n’est pas encore prêt. Réessayez dans un instant.","backup.error.too_large":"La sauvegarde dépasse la limite de 8 Mio.","backup.error.invalid_json":"Le fichier sélectionné n’est pas un JSON valide.","backup.error.invalid_format":"Le fichier sélectionné n’est pas une sauvegarde House Plan.","backup.error.unsupported_export_version":"Ce format de sauvegarde n’est pas pris en charge par la version installée.","backup.error.future_model":"La sauvegarde a été créée avec un modèle de données House Plan plus récent.","backup.error.invalid_config":"La sauvegarde contient une configuration House Plan invalide.","backup.error.wall_model_migration_blocked":"Le modèle de murs de la sauvegarde n’a pas pu être mis à niveau en toute sécurité. Optimisez d’abord le plan source, puis exportez-le de nouveau.","backup.error.invalid_layout":"La sauvegarde contient des positions d’objets invalides.","backup.error.invalid_content":"La sauvegarde contient des références de contenu invalides ou incohérentes.","backup.error.space_not_found":"L’espace sélectionné n’existe plus.","backup.error.capacity_exceeded":"L’ajout de cette sauvegarde dépasserait les limites du plan.","backup.error.preview_expired":"L’aperçu a expiré. Sélectionnez de nouveau le fichier de sauvegarde.","backup.error.preview_owner_mismatch":"Cet aperçu appartient à un autre utilisateur Home Assistant.","backup.error.conflict":"Le plan a changé depuis l’aperçu. Vérifiez le résumé actualisé.","backup.error.content_confirmation_required":"Confirmez que le contenu local indisponible peut être dissocié.","backup.error.commit_failed":"La sauvegarde n’a pas pu être appliquée en toute sécurité. Le plan précédent a été restauré ou est en attente de récupération.","backup.error.missing_plan":"Un fichier de plan référencé a disparu depuis l’aperçu. Vérifiez de nouveau la sauvegarde.","backup.error.missing_content":"Une pièce jointe locale référencée a disparu depuis l’aperçu. Vérifiez de nouveau la sauvegarde.","backup.error.marker_control_missing":"Une lumière liée au plan est absente de la sauvegarde.","backup.error.marker_control_not_light":"Une cible liée au plan n’est plus marquée comme source lumineuse.","backup.error.marker_control_self":"Une source lumineuse ne peut pas se contrôler elle-même.","backup.error.marker_control_cycle":"La sauvegarde contient une chaîne circulaire de contrôles de lumière.","backup.error.duplicate_marker_control":"La sauvegarde contient un lien de lumière du plan en doublon.","backup.error.no_backup":"Aucun instantané d’importation ou d’optimisation n’est disponible à restaurer.","backup.error.in_use":"L'élément est encore utilisé","backup.error.invalid_data":"La requête contient des données invalides","backup.error.invalid_light_entity":"La lumière principale doit être une entité light.* ou switch.*","backup.error.invalid_marker_control":"Référence de contrôle de marqueur invalide","backup.error.invalid_name":"Le nom est invalide","backup.error.invalid_partition_opening_host":"L'ouverture doit conserver sa cloison porteuse","backup.error.invalid_partition_opening_jamb_margin":"L'ouverture ne laisse aucun jambage physique au bout du mur","backup.error.invalid_passage_fields":"Un passage ouvert ne peut pas porter de réglages de porte","backup.error.invalid_space_id":"Espace inconnu","backup.error.invalid_toggle_entity":"L'entité de bascule doit être light.* ou switch.*","backup.error.invalid_value_badge":"Réglages de badge de valeur invalides","backup.error.invalid_value_badge_attribute":"Attribut de badge de valeur invalide","backup.error.invalid_value_badge_position":"Position de badge de valeur invalide","backup.error.invalid_value_badge_source":"Source de badge de valeur invalide","backup.error.invalid_value_source":"Source de valeur invalide","backup.error.invalid_value_source_attribute":"Attribut de source de valeur invalide","backup.error.io_error":"Une opération de fichier a échoué sur le serveur","backup.error.not_toggleable":"Cet appareil ne peut pas être basculé","backup.error.nothing_to_repair":"Rien à réparer","backup.error.space_in_use":"L'espace est encore référencé","backup.error.value_badge_source_required":"Le badge de valeur nécessite une source","backup.error.wall_model_client_outdated":"Le plan a été mis à jour ailleurs — rechargez la page","backup.same_source":"Créée sur cette instance Home Assistant","backup.foreign_source":"Créée sur une autre instance Home Assistant","backup.created":"Créée : {value}","backup.versions":"Carte {card} ; intégration {integration} ; modèle de données {model}","backup.count_spaces":"Espaces : {n}","backup.count_rooms":"Pièces : {n}","backup.count_walls":"Murs : {n}","backup.count_openings":"Ouvertures : {n}","backup.count_decor":"Objets décoratifs : {n}","backup.count_markers":"Appareils : {n}","backup.count_layout":"Positions : {n}","backup.bindings":"Associations — appareils : {device}, entités : {entity}, virtuels : {virtual} ; positions sans espace : {legacy}","backup.binding_status":"État des cibles — actives : {active}, désactivées : {disabled}, manquantes : {missing}","backup.missing_areas":"Zones absentes sur la cible : {areas}","backup.dropped_marker_links":"Liens de lumières du plan hors de cet espace transféré omis : {n}.","backup.repaired_target_refs":"Références existantes restaurées par cet import d’espace : {n}.","backup.preserved_unresolved_refs":"Références qui n’ont pas pu être restaurées sans ambiguïté conservées : {n}.","backup.preserved_unresolved_hint":"Aucune donnée n’a été devinée ni supprimée. Après l’importation, lancez « Optimiser les plans » pour examiner les références restantes.","backup.import_details":"Détails des références d’importation","backup.import_detail.incoming_remapped":"Références mises à jour dans la copie importée : {n}","backup.import_detail.target_repaired":"Références existantes restaurées : {n}","backup.import_detail.preserved_unresolved":"Références non résolues conservées : {n}","backup.import_detail.collisions":"Conflits de destination conservés en toute sécurité : {n}","backup.import_detail.dropped_links":"Liens entrants omis selon les règles de transfert : {n}","backup.import_detail.bounded_lineages":"Identifiants trop imbriqués maintenus dans les limites : {n}","backup.replace_warning":"Cela remplace la configuration et la disposition actuelles. Les fichiers importés ne sont jamais supprimés. Une seule annulation reste disponible jusqu’à la prochaine modification du plan.","backup.foreign_bookkeeping":"Les données de suivi des appareils connus/nouveaux propres à l’instance ne seront pas importées.","backup.final_name":"Nom du nouvel espace","backup.target_settings":"Les paramètres généraux de l’instance cible restent inchangés.","backup.duplicates":"Associations déjà présentes : {n}","backup.skip":"Ignorer les appareils en doublon","backup.virtual_copy":"Ajouter des copies virtuelles statiques sûres","backup.content":"Contenu référencé","backup.content_available":"disponible localement","backup.content_external":"lien externe","backup.content_detach_required":"sera dissocié","backup.confirm_detach":"Je comprends que les plans internes et pièces jointes indisponibles seront dissociés de la configuration importée.","backup.replace":"Remplacer","backup.add":"Ajouter un espace","backup.space_done":"Espace importé : {rooms} pièces, {markers} appareils, {refs} références existantes restaurées","backup.full_done":"Sauvegarde restaurée : {spaces} espaces, {rooms} pièces, {markers} appareils","backup.undo_import":"Annuler la dernière importation complète","backup.import_undone":"Importation complète annulée","backdrop.large_title":"Grande image","backdrop.large_body":"Cette image fait {w}×{h} (fichier de {fileMb} Mo) et nécessite environ {decodedMb} Mo de mémoire pour s'afficher. Sur tablette, cela peut faire planter la page.","backdrop.unknown_body":"Les dimensions de l'image n'ont pas pu être lues — le fichier est peut-être endommagé. Continuer peut faire planter la page sur tablette.","backdrop.use_downscaled":"Téléverser une copie réduite","backdrop.reducing":"Réduction…","backdrop.keep_original":"Conserver l'original","backdrop.too_large_title":"Image trop grande","backdrop.too_large_body":"Cette image dépasse ce que les navigateurs peuvent afficher ({w}×{h}, limite {limit} px par côté). Réduisez-la dans un éditeur de bureau puis téléversez-la à nouveau.","backdrop.downscale_failed":"Impossible de créer la copie réduite. Le plan actuel n'a pas été modifié."};const r="2195ace683267664d035370d92e860e463a0a745074964ec60eb91b9460fe406";export{e as dictionary,r as fingerprint}; diff --git a/custom_components/houseplan/frontend/houseplan-assets/houseplan-card-Bi2pkTUe.js b/custom_components/houseplan/frontend/houseplan-assets/houseplan-card-DXakp5oa.js similarity index 99% rename from custom_components/houseplan/frontend/houseplan-assets/houseplan-card-Bi2pkTUe.js rename to custom_components/houseplan/frontend/houseplan-assets/houseplan-card-DXakp5oa.js index 9e112d42..0fe0a38e 100644 --- a/custom_components/houseplan/frontend/houseplan-assets/houseplan-card-Bi2pkTUe.js +++ b/custom_components/houseplan/frontend/houseplan-assets/houseplan-card-DXakp5oa.js @@ -1,4 +1,4 @@ -globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="b36c2306f25315638c0178090efd6865650040c5565d6ad92430103558fe37db";const e=globalThis,t=e.ShadowRoot&&(void 0===e.ShadyCSS||e.ShadyCSS.nativeShadow)&&"adoptedStyleSheets"in Document.prototype&&"replace"in CSSStyleSheet.prototype,i=Symbol(),n=new WeakMap;let r=class{constructor(e,t,n){if(this._$cssResult$=!0,n!==i)throw Error("CSSResult is not constructable. Use `unsafeCSS` or `css` instead.");this.cssText=e,this.t=t}get styleSheet(){let e=this.o;const i=this.t;if(t&&void 0===e){const t=void 0!==i&&1===i.length;t&&(e=n.get(i)),void 0===e&&((this.o=e=new CSSStyleSheet).replaceSync(this.cssText),t&&n.set(i,e))}return e}toString(){return this.cssText}};const o=(e,...t)=>{const n=1===e.length?e[0]:t.reduce((t,i,n)=>t+(e=>{if(!0===e._$cssResult$)return e.cssText;if("number"==typeof e)return e;throw Error("Value passed to 'css' function must be a 'css' function result: "+e+". Use 'unsafeCSS' to pass non-literal values, but take care to ensure page security.")})(i)+e[n+1],e[0]);return new r(n,e,i)},s=t?e=>e:e=>e instanceof CSSStyleSheet?(e=>{let t="";for(const i of e.cssRules)t+=i.cssText;return(e=>new r("string"==typeof e?e:e+"",void 0,i))(t)})(e):e,{is:a,defineProperty:l,getOwnPropertyDescriptor:c,getOwnPropertyNames:h,getOwnPropertySymbols:d,getPrototypeOf:u}=Object,p=globalThis,_=p.trustedTypes,m=_?_.emptyScript:"",f=p.reactiveElementPolyfillSupport,g=(e,t)=>e,v={toAttribute(e,t){switch(t){case Boolean:e=e?m:null;break;case Object:case Array:e=null==e?e:JSON.stringify(e)}return e},fromAttribute(e,t){let i=e;switch(t){case Boolean:i=null!==e;break;case Number:i=null===e?null:Number(e);break;case Object:case Array:try{i=JSON.parse(e)}catch(e){i=null}}return i}},y=(e,t)=>!a(e,t),b={attribute:!0,type:String,converter:v,reflect:!1,useDefault:!1,hasChanged:y};Symbol.metadata??=Symbol("metadata"),p.litPropertyMetadata??=new WeakMap;let w=class extends HTMLElement{static addInitializer(e){this._$Ei(),(this.l??=[]).push(e)}static get observedAttributes(){return this.finalize(),this._$Eh&&[...this._$Eh.keys()]}static createProperty(e,t=b){if(t.state&&(t.attribute=!1),this._$Ei(),this.prototype.hasOwnProperty(e)&&((t=Object.create(t)).wrapped=!0),this.elementProperties.set(e,t),!t.noAccessor){const i=Symbol(),n=this.getPropertyDescriptor(e,i,t);void 0!==n&&l(this.prototype,e,n)}}static getPropertyDescriptor(e,t,i){const{get:n,set:r}=c(this.prototype,e)??{get(){return this[t]},set(e){this[t]=e}};return{get:n,set(t){const o=n?.call(this);r?.call(this,t),this.requestUpdate(e,o,i)},configurable:!0,enumerable:!0}}static getPropertyOptions(e){return this.elementProperties.get(e)??b}static _$Ei(){if(this.hasOwnProperty(g("elementProperties")))return;const e=u(this);e.finalize(),void 0!==e.l&&(this.l=[...e.l]),this.elementProperties=new Map(e.elementProperties)}static finalize(){if(this.hasOwnProperty(g("finalized")))return;if(this.finalized=!0,this._$Ei(),this.hasOwnProperty(g("properties"))){const e=this.properties,t=[...h(e),...d(e)];for(const i of t)this.createProperty(i,e[i])}const e=this[Symbol.metadata];if(null!==e){const t=litPropertyMetadata.get(e);if(void 0!==t)for(const[e,i]of t)this.elementProperties.set(e,i)}this._$Eh=new Map;for(const[e,t]of this.elementProperties){const i=this._$Eu(e,t);void 0!==i&&this._$Eh.set(i,e)}this.elementStyles=this.finalizeStyles(this.styles)}static finalizeStyles(e){const t=[];if(Array.isArray(e)){const i=new Set(e.flat(1/0).reverse());for(const e of i)t.unshift(s(e))}else void 0!==e&&t.push(s(e));return t}static _$Eu(e,t){const i=t.attribute;return!1===i?void 0:"string"==typeof i?i:"string"==typeof e?e.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(e=>this.enableUpdating=e),this._$AL=new Map,this._$E_(),this.requestUpdate(),this.constructor.l?.forEach(e=>e(this))}addController(e){(this._$EO??=new Set).add(e),void 0!==this.renderRoot&&this.isConnected&&e.hostConnected?.()}removeController(e){this._$EO?.delete(e)}_$E_(){const e=new Map,t=this.constructor.elementProperties;for(const i of t.keys())this.hasOwnProperty(i)&&(e.set(i,this[i]),delete this[i]);e.size>0&&(this._$Ep=e)}createRenderRoot(){const i=this.shadowRoot??this.attachShadow(this.constructor.shadowRootOptions);return((i,n)=>{if(t)i.adoptedStyleSheets=n.map(e=>e instanceof CSSStyleSheet?e:e.styleSheet);else for(const t of n){const n=document.createElement("style"),r=e.litNonce;void 0!==r&&n.setAttribute("nonce",r),n.textContent=t.cssText,i.appendChild(n)}})(i,this.constructor.elementStyles),i}connectedCallback(){this.renderRoot??=this.createRenderRoot(),this.enableUpdating(!0),this._$EO?.forEach(e=>e.hostConnected?.())}enableUpdating(e){}disconnectedCallback(){this._$EO?.forEach(e=>e.hostDisconnected?.())}attributeChangedCallback(e,t,i){this._$AK(e,i)}_$ET(e,t){const i=this.constructor.elementProperties.get(e),n=this.constructor._$Eu(e,i);if(void 0!==n&&!0===i.reflect){const r=(void 0!==i.converter?.toAttribute?i.converter:v).toAttribute(t,i.type);this._$Em=e,null==r?this.removeAttribute(n):this.setAttribute(n,r),this._$Em=null}}_$AK(e,t){const i=this.constructor,n=i._$Eh.get(e);if(void 0!==n&&this._$Em!==n){const e=i.getPropertyOptions(n),r="function"==typeof e.converter?{fromAttribute:e.converter}:void 0!==e.converter?.fromAttribute?e.converter:v;this._$Em=n;const o=r.fromAttribute(t,e.type);this[n]=o??this._$Ej?.get(n)??o,this._$Em=null}}requestUpdate(e,t,i,n=!1,r){if(void 0!==e){const o=this.constructor;if(!1===n&&(r=this[e]),i??=o.getPropertyOptions(e),!((i.hasChanged??y)(r,t)||i.useDefault&&i.reflect&&r===this._$Ej?.get(e)&&!this.hasAttribute(o._$Eu(e,i))))return;this.C(e,t,i)}!1===this.isUpdatePending&&(this._$ES=this._$EP())}C(e,t,{useDefault:i,reflect:n,wrapped:r},o){i&&!(this._$Ej??=new Map).has(e)&&(this._$Ej.set(e,o??t??this[e]),!0!==r||void 0!==o)||(this._$AL.has(e)||(this.hasUpdated||i||(t=void 0),this._$AL.set(e,t)),!0===n&&this._$Em!==e&&(this._$Eq??=new Set).add(e))}async _$EP(){this.isUpdatePending=!0;try{await this._$ES}catch(e){Promise.reject(e)}const e=this.scheduleUpdate();return null!=e&&await e,!this.isUpdatePending}scheduleUpdate(){return this.performUpdate()}performUpdate(){if(!this.isUpdatePending)return;if(!this.hasUpdated){if(this.renderRoot??=this.createRenderRoot(),this._$Ep){for(const[e,t]of this._$Ep)this[e]=t;this._$Ep=void 0}const e=this.constructor.elementProperties;if(e.size>0)for(const[t,i]of e){const{wrapped:e}=i,n=this[t];!0!==e||this._$AL.has(t)||void 0===n||this.C(t,void 0,i,n)}}let e=!1;const t=this._$AL;try{e=this.shouldUpdate(t),e?(this.willUpdate(t),this._$EO?.forEach(e=>e.hostUpdate?.()),this.update(t)):this._$EM()}catch(t){throw e=!1,this._$EM(),t}e&&this._$AE(t)}willUpdate(e){}_$AE(e){this._$EO?.forEach(e=>e.hostUpdated?.()),this.hasUpdated||(this.hasUpdated=!0,this.firstUpdated(e)),this.updated(e)}_$EM(){this._$AL=new Map,this.isUpdatePending=!1}get updateComplete(){return this.getUpdateComplete()}getUpdateComplete(){return this._$ES}shouldUpdate(e){return!0}update(e){this._$Eq&&=this._$Eq.forEach(e=>this._$ET(e,this[e])),this._$EM()}updated(e){}firstUpdated(e){}};w.elementStyles=[],w.shadowRootOptions={mode:"open"},w[g("elementProperties")]=new Map,w[g("finalized")]=new Map,f?.({ReactiveElement:w}),(p.reactiveElementVersions??=[]).push("2.1.2");const k=globalThis,x=e=>e,$=k.trustedTypes,S=$?$.createPolicy("lit-html",{createHTML:e=>e}):void 0,M="$lit$",T=`lit$${Math.random().toFixed(9).slice(2)}$`,C="?"+T,R=`<${C}>`,D=document,z=()=>D.createComment(""),A=e=>null===e||"object"!=typeof e&&"function"!=typeof e,P=Array.isArray,O="[ \t\n\f\r]",F=/<(?:(!--|\/[^a-zA-Z])|(\/?[a-zA-Z][^>\s]*)|(\/?$))/g,I=/-->/g,E=/>/g,H=RegExp(`>|${O}(?:([^\\s"'>=/]+)(${O}*=${O}*(?:[^ \t\n\f\r"'\`<>=]|("|')|))|$)`,"g"),N=/'/g,L=/"/g,B=/^(?:script|style|textarea|title)$/i,q=e=>(t,...i)=>({_$litType$:e,strings:t,values:i}),W=q(1),j=q(2),U=Symbol.for("lit-noChange"),V=Symbol.for("lit-nothing"),G=new WeakMap,K=D.createTreeWalker(D,129);function Y(e,t){if(!P(e)||!e.hasOwnProperty("raw"))throw Error("invalid template strings array");return void 0!==S?S.createHTML(t):t}const X=(e,t)=>{const i=e.length-1,n=[];let r,o=2===t?"":3===t?"":"",s=F;for(let t=0;t"===l[0]?(s=r??F,c=-1):void 0===l[1]?c=-2:(c=s.lastIndex-l[2].length,a=l[1],s=void 0===l[3]?H:'"'===l[3]?L:N):s===L||s===N?s=H:s===I||s===E?s=F:(s=H,r=void 0);const d=s===H&&e[t+1].startsWith("/>")?" ":"";o+=s===F?i+R:c>=0?(n.push(a),i.slice(0,c)+M+i.slice(c)+T+d):i+T+(-2===c?t:d)}return[Y(e,o+(e[i]||"")+(2===t?"":3===t?"":"")),n]};class Z{constructor({strings:e,_$litType$:t},i){let n;this.parts=[];let r=0,o=0;const s=e.length-1,a=this.parts,[l,c]=X(e,t);if(this.el=Z.createElement(l,i),K.currentNode=this.el.content,2===t||3===t){const e=this.el.content.firstChild;e.replaceWith(...e.childNodes)}for(;null!==(n=K.nextNode())&&a.length0){n.textContent=$?$.emptyScript:"";for(let i=0;iP(e)||"function"==typeof e?.[Symbol.iterator])(e)?this.k(e):this._(e)}O(e){return this._$AA.parentNode.insertBefore(e,this._$AB)}T(e){this._$AH!==e&&(this._$AR(),this._$AH=this.O(e))}_(e){this._$AH!==V&&A(this._$AH)?this._$AA.nextSibling.data=e:this.T(D.createTextNode(e)),this._$AH=e}$(e){const{values:t,_$litType$:i}=e,n="number"==typeof i?this._$AC(e):(void 0===i.el&&(i.el=Z.createElement(Y(i.h,i.h[0]),this.options)),i);if(this._$AH?._$AD===n)this._$AH.p(t);else{const e=new Q(n,this),i=e.u(this.options);e.p(t),this.T(i),this._$AH=e}}_$AC(e){let t=G.get(e.strings);return void 0===t&&G.set(e.strings,t=new Z(e)),t}k(e){P(this._$AH)||(this._$AH=[],this._$AR());const t=this._$AH;let i,n=0;for(const r of e)n===t.length?t.push(i=new ee(this.O(z()),this.O(z()),this,this.options)):i=t[n],i._$AI(r),n++;n2||""!==i[0]||""!==i[1]?(this._$AH=Array(i.length-1).fill(new String),this.strings=i):this._$AH=V}_$AI(e,t=this,i,n){const r=this.strings;let o=!1;if(void 0===r)e=J(this,e,t,0),o=!A(e)||e!==this._$AH&&e!==U,o&&(this._$AH=e);else{const n=e;let s,a;for(e=r[0],s=0;s{const n=i?.renderBefore??t;let r=n._$litPart$;if(void 0===r){const e=i?.renderBefore??null;n._$litPart$=r=new ee(t.insertBefore(z(),e),e,void 0,i??{})}return r._$AI(e),r},ce=globalThis;let he=class extends w{constructor(){super(...arguments),this.renderOptions={host:this},this._$Do=void 0}createRenderRoot(){const e=super.createRenderRoot();return this.renderOptions.renderBefore??=e.firstChild,e}update(e){const t=this.render();this.hasUpdated||(this.renderOptions.isConnected=this.isConnected),super.update(e),this._$Do=le(t,this.renderRoot,this.renderOptions)}connectedCallback(){super.connectedCallback(),this._$Do?.setConnected(!0)}disconnectedCallback(){super.disconnectedCallback(),this._$Do?.setConnected(!1)}render(){return U}};he._$litElement$=!0,he.finalized=!0,ce.litElementHydrateSupport?.({LitElement:he});const de=ce.litElementPolyfillSupport;de?.({LitElement:he}),(ce.litElementVersions??=[]).push("4.2.2");const ue=new WeakMap;let pe=0;class _e extends he{constructor(){super(...arguments),this.title="",this.icon="",this.wide=!1,this.alert=!1,this.describedBy="",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-"+ ++pe,this._focusInitial=()=>{const e=this._focusableElements(),t=e.find(e=>e.hasAttribute("autofocus"))||e[0]||(this._usesHaDialog()?null:this.renderRoot.querySelector(".close"))||this.renderRoot.querySelector(".surface")||this.renderRoot.querySelector("ha-dialog");t?.focus({preventScroll:!0})},this._requestClose=()=>{this._closing||(this._closing=!0,this.dispatchEvent(new CustomEvent("hp-close",{bubbles:!0,composed:!0})))},this._onKeyDown=e=>{if("Escape"===e.key){e.preventDefault(),e.stopImmediatePropagation(),this._pruneOverlays();const t=this._overlays[this._overlays.length-1];return t?void this._closeOverlay(t,"escape"):void this._requestClose()}if("Tab"!==e.key||this._usesHaDialog())return;const t=this.renderRoot.querySelector(".close"),i=t?[t,...this._focusableElements()]:this._focusableElements();if(!i.length)return e.preventDefault(),void this.renderRoot.querySelector(".surface")?.focus({preventScroll:!0});const n=this._deepActiveElement(),r=i[0],o=i[i.length-1];!e.shiftKey||n!==r&&i.includes(n)?e.shiftKey||n!==o||(e.preventDefault(),r.focus()):(e.preventDefault(),o.focus())},this._onFallbackCancel=e=>{e.preventDefault(),this._requestClose()},this._onFallbackClick=e=>{this.dismissOnScrim&&e.target===e.currentTarget&&this._requestClose()}}_usesHaDialog(){return this._useHaDialog&&!this.alert}connectedCallback(){super.connectedCallback(),this._opener=this._deepActiveElement();const e=this.getRootNode();this._focusRoot=e;const t=ue.get(e)||{dialogs:new Set,opener:this._opener};t.dialogs.add(this),ue.set(e,t),this._useHaDialog=!!customElements.get("ha-dialog"),this.addEventListener("keydown",this._onKeyDown,!0)}disconnectedCallback(){this.removeEventListener("keydown",this._onKeyDown,!0);const e=[...this._overlays];this._overlays=[];for(const t of e.reverse())t.close("disconnect");const t=this._focusRoot,i=this._opener;this._opener=null,this._focusRoot=null;const n=t?ue.get(t):void 0;n?.dialogs.delete(this),super.disconnectedCallback(),t&&n&&requestAnimationFrame(()=>{const e=ue.get(t);if(!e)return;if(!e.dialogs.size)return e.opener?.isConnected&&e.opener.focus({preventScroll:!0}),void ue.delete(t);const n=i?.closest("hp-dialog");i?.isConnected&&n&&e.dialogs.has(n)&&i.focus({preventScroll:!0})})}firstUpdated(e){if(super.firstUpdated(e),!this._usesHaDialog()){const e=this.renderRoot.querySelector("dialog");e&&!e.open&&e.showModal()}queueMicrotask(()=>this._focusInitial())}_deepActiveElement(){let e=document.activeElement;for(;e?.shadowRoot?.activeElement;)e=e.shadowRoot.activeElement;return e&&e!==document.body?e:null}_focusableElements(){const e=["[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(","),t=[],i=new Set,n=r=>{if(!i.has(r)){if(i.add(r),r instanceof HTMLElement){if(r.matches(e)&&t.push(r),r instanceof HTMLSlotElement){for(const e of r.assignedNodes({flatten:!0}))n(e);return}if(r.shadowRoot){for(const e of r.shadowRoot.childNodes)n(e);return}}for(const e of r.childNodes)n(e)}};for(const e of this.childNodes)n(e);const r=this.overlayPortal();return r&&n(r),t.filter(e=>{let t=e;for(;t;){const e=getComputedStyle(t);if(t.hidden||t.inert||"true"===t.getAttribute("aria-hidden")||"none"===e.display||"hidden"===e.visibility)return!1;if(t=t.assignedSlot||t.parentElement||(t.getRootNode()instanceof ShadowRoot?t.getRootNode().host:null),t===this)break}return!0})}_pruneOverlays(){this._overlays=this._overlays.filter(e=>e.owner.isConnected)}_closeOverlay(e,t){const i=this._overlays.findIndex(t=>t.token===e.token);i>=0&&this._overlays.splice(i,1),e.close(t)}registerOverlay(e){this._pruneOverlays();const t=this._overlays.find(t=>t.owner===e.owner);t&&this._overlays.splice(this._overlays.indexOf(t),1);const i=e.group||"transient";for(const e of[...this._overlays].reverse())e.group===i&&this._closeOverlay(e,"exclusive");const n={...e,group:i,token:Symbol("hp-overlay")};this._overlays.push(n);let r=!1;return()=>{if(r)return;r=!0;const e=this._overlays.findIndex(e=>e.token===n.token);e>=0&&this._overlays.splice(e,1)}}closeTransientOverlays(e="outside"){this._pruneOverlays();const t=[...this._overlays].filter(e=>"transient"===(e.group||"transient"));for(const i of t.reverse())this._closeOverlay(i,e);return t.length>0}overlayPortal(){return this.renderRoot.querySelector(".overlay-portal")}render(){const e=W` +globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="2195ace683267664d035370d92e860e463a0a745074964ec60eb91b9460fe406";const e=globalThis,t=e.ShadowRoot&&(void 0===e.ShadyCSS||e.ShadyCSS.nativeShadow)&&"adoptedStyleSheets"in Document.prototype&&"replace"in CSSStyleSheet.prototype,i=Symbol(),n=new WeakMap;let r=class{constructor(e,t,n){if(this._$cssResult$=!0,n!==i)throw Error("CSSResult is not constructable. Use `unsafeCSS` or `css` instead.");this.cssText=e,this.t=t}get styleSheet(){let e=this.o;const i=this.t;if(t&&void 0===e){const t=void 0!==i&&1===i.length;t&&(e=n.get(i)),void 0===e&&((this.o=e=new CSSStyleSheet).replaceSync(this.cssText),t&&n.set(i,e))}return e}toString(){return this.cssText}};const o=(e,...t)=>{const n=1===e.length?e[0]:t.reduce((t,i,n)=>t+(e=>{if(!0===e._$cssResult$)return e.cssText;if("number"==typeof e)return e;throw Error("Value passed to 'css' function must be a 'css' function result: "+e+". Use 'unsafeCSS' to pass non-literal values, but take care to ensure page security.")})(i)+e[n+1],e[0]);return new r(n,e,i)},s=t?e=>e:e=>e instanceof CSSStyleSheet?(e=>{let t="";for(const i of e.cssRules)t+=i.cssText;return(e=>new r("string"==typeof e?e:e+"",void 0,i))(t)})(e):e,{is:a,defineProperty:l,getOwnPropertyDescriptor:c,getOwnPropertyNames:h,getOwnPropertySymbols:d,getPrototypeOf:u}=Object,p=globalThis,_=p.trustedTypes,m=_?_.emptyScript:"",f=p.reactiveElementPolyfillSupport,g=(e,t)=>e,v={toAttribute(e,t){switch(t){case Boolean:e=e?m:null;break;case Object:case Array:e=null==e?e:JSON.stringify(e)}return e},fromAttribute(e,t){let i=e;switch(t){case Boolean:i=null!==e;break;case Number:i=null===e?null:Number(e);break;case Object:case Array:try{i=JSON.parse(e)}catch(e){i=null}}return i}},y=(e,t)=>!a(e,t),b={attribute:!0,type:String,converter:v,reflect:!1,useDefault:!1,hasChanged:y};Symbol.metadata??=Symbol("metadata"),p.litPropertyMetadata??=new WeakMap;let w=class extends HTMLElement{static addInitializer(e){this._$Ei(),(this.l??=[]).push(e)}static get observedAttributes(){return this.finalize(),this._$Eh&&[...this._$Eh.keys()]}static createProperty(e,t=b){if(t.state&&(t.attribute=!1),this._$Ei(),this.prototype.hasOwnProperty(e)&&((t=Object.create(t)).wrapped=!0),this.elementProperties.set(e,t),!t.noAccessor){const i=Symbol(),n=this.getPropertyDescriptor(e,i,t);void 0!==n&&l(this.prototype,e,n)}}static getPropertyDescriptor(e,t,i){const{get:n,set:r}=c(this.prototype,e)??{get(){return this[t]},set(e){this[t]=e}};return{get:n,set(t){const o=n?.call(this);r?.call(this,t),this.requestUpdate(e,o,i)},configurable:!0,enumerable:!0}}static getPropertyOptions(e){return this.elementProperties.get(e)??b}static _$Ei(){if(this.hasOwnProperty(g("elementProperties")))return;const e=u(this);e.finalize(),void 0!==e.l&&(this.l=[...e.l]),this.elementProperties=new Map(e.elementProperties)}static finalize(){if(this.hasOwnProperty(g("finalized")))return;if(this.finalized=!0,this._$Ei(),this.hasOwnProperty(g("properties"))){const e=this.properties,t=[...h(e),...d(e)];for(const i of t)this.createProperty(i,e[i])}const e=this[Symbol.metadata];if(null!==e){const t=litPropertyMetadata.get(e);if(void 0!==t)for(const[e,i]of t)this.elementProperties.set(e,i)}this._$Eh=new Map;for(const[e,t]of this.elementProperties){const i=this._$Eu(e,t);void 0!==i&&this._$Eh.set(i,e)}this.elementStyles=this.finalizeStyles(this.styles)}static finalizeStyles(e){const t=[];if(Array.isArray(e)){const i=new Set(e.flat(1/0).reverse());for(const e of i)t.unshift(s(e))}else void 0!==e&&t.push(s(e));return t}static _$Eu(e,t){const i=t.attribute;return!1===i?void 0:"string"==typeof i?i:"string"==typeof e?e.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(e=>this.enableUpdating=e),this._$AL=new Map,this._$E_(),this.requestUpdate(),this.constructor.l?.forEach(e=>e(this))}addController(e){(this._$EO??=new Set).add(e),void 0!==this.renderRoot&&this.isConnected&&e.hostConnected?.()}removeController(e){this._$EO?.delete(e)}_$E_(){const e=new Map,t=this.constructor.elementProperties;for(const i of t.keys())this.hasOwnProperty(i)&&(e.set(i,this[i]),delete this[i]);e.size>0&&(this._$Ep=e)}createRenderRoot(){const i=this.shadowRoot??this.attachShadow(this.constructor.shadowRootOptions);return((i,n)=>{if(t)i.adoptedStyleSheets=n.map(e=>e instanceof CSSStyleSheet?e:e.styleSheet);else for(const t of n){const n=document.createElement("style"),r=e.litNonce;void 0!==r&&n.setAttribute("nonce",r),n.textContent=t.cssText,i.appendChild(n)}})(i,this.constructor.elementStyles),i}connectedCallback(){this.renderRoot??=this.createRenderRoot(),this.enableUpdating(!0),this._$EO?.forEach(e=>e.hostConnected?.())}enableUpdating(e){}disconnectedCallback(){this._$EO?.forEach(e=>e.hostDisconnected?.())}attributeChangedCallback(e,t,i){this._$AK(e,i)}_$ET(e,t){const i=this.constructor.elementProperties.get(e),n=this.constructor._$Eu(e,i);if(void 0!==n&&!0===i.reflect){const r=(void 0!==i.converter?.toAttribute?i.converter:v).toAttribute(t,i.type);this._$Em=e,null==r?this.removeAttribute(n):this.setAttribute(n,r),this._$Em=null}}_$AK(e,t){const i=this.constructor,n=i._$Eh.get(e);if(void 0!==n&&this._$Em!==n){const e=i.getPropertyOptions(n),r="function"==typeof e.converter?{fromAttribute:e.converter}:void 0!==e.converter?.fromAttribute?e.converter:v;this._$Em=n;const o=r.fromAttribute(t,e.type);this[n]=o??this._$Ej?.get(n)??o,this._$Em=null}}requestUpdate(e,t,i,n=!1,r){if(void 0!==e){const o=this.constructor;if(!1===n&&(r=this[e]),i??=o.getPropertyOptions(e),!((i.hasChanged??y)(r,t)||i.useDefault&&i.reflect&&r===this._$Ej?.get(e)&&!this.hasAttribute(o._$Eu(e,i))))return;this.C(e,t,i)}!1===this.isUpdatePending&&(this._$ES=this._$EP())}C(e,t,{useDefault:i,reflect:n,wrapped:r},o){i&&!(this._$Ej??=new Map).has(e)&&(this._$Ej.set(e,o??t??this[e]),!0!==r||void 0!==o)||(this._$AL.has(e)||(this.hasUpdated||i||(t=void 0),this._$AL.set(e,t)),!0===n&&this._$Em!==e&&(this._$Eq??=new Set).add(e))}async _$EP(){this.isUpdatePending=!0;try{await this._$ES}catch(e){Promise.reject(e)}const e=this.scheduleUpdate();return null!=e&&await e,!this.isUpdatePending}scheduleUpdate(){return this.performUpdate()}performUpdate(){if(!this.isUpdatePending)return;if(!this.hasUpdated){if(this.renderRoot??=this.createRenderRoot(),this._$Ep){for(const[e,t]of this._$Ep)this[e]=t;this._$Ep=void 0}const e=this.constructor.elementProperties;if(e.size>0)for(const[t,i]of e){const{wrapped:e}=i,n=this[t];!0!==e||this._$AL.has(t)||void 0===n||this.C(t,void 0,i,n)}}let e=!1;const t=this._$AL;try{e=this.shouldUpdate(t),e?(this.willUpdate(t),this._$EO?.forEach(e=>e.hostUpdate?.()),this.update(t)):this._$EM()}catch(t){throw e=!1,this._$EM(),t}e&&this._$AE(t)}willUpdate(e){}_$AE(e){this._$EO?.forEach(e=>e.hostUpdated?.()),this.hasUpdated||(this.hasUpdated=!0,this.firstUpdated(e)),this.updated(e)}_$EM(){this._$AL=new Map,this.isUpdatePending=!1}get updateComplete(){return this.getUpdateComplete()}getUpdateComplete(){return this._$ES}shouldUpdate(e){return!0}update(e){this._$Eq&&=this._$Eq.forEach(e=>this._$ET(e,this[e])),this._$EM()}updated(e){}firstUpdated(e){}};w.elementStyles=[],w.shadowRootOptions={mode:"open"},w[g("elementProperties")]=new Map,w[g("finalized")]=new Map,f?.({ReactiveElement:w}),(p.reactiveElementVersions??=[]).push("2.1.2");const k=globalThis,x=e=>e,$=k.trustedTypes,S=$?$.createPolicy("lit-html",{createHTML:e=>e}):void 0,M="$lit$",T=`lit$${Math.random().toFixed(9).slice(2)}$`,C="?"+T,R=`<${C}>`,D=document,z=()=>D.createComment(""),A=e=>null===e||"object"!=typeof e&&"function"!=typeof e,P=Array.isArray,O="[ \t\n\f\r]",F=/<(?:(!--|\/[^a-zA-Z])|(\/?[a-zA-Z][^>\s]*)|(\/?$))/g,I=/-->/g,E=/>/g,H=RegExp(`>|${O}(?:([^\\s"'>=/]+)(${O}*=${O}*(?:[^ \t\n\f\r"'\`<>=]|("|')|))|$)`,"g"),N=/'/g,L=/"/g,B=/^(?:script|style|textarea|title)$/i,q=e=>(t,...i)=>({_$litType$:e,strings:t,values:i}),W=q(1),j=q(2),U=Symbol.for("lit-noChange"),V=Symbol.for("lit-nothing"),G=new WeakMap,K=D.createTreeWalker(D,129);function Y(e,t){if(!P(e)||!e.hasOwnProperty("raw"))throw Error("invalid template strings array");return void 0!==S?S.createHTML(t):t}const X=(e,t)=>{const i=e.length-1,n=[];let r,o=2===t?"":3===t?"":"",s=F;for(let t=0;t"===l[0]?(s=r??F,c=-1):void 0===l[1]?c=-2:(c=s.lastIndex-l[2].length,a=l[1],s=void 0===l[3]?H:'"'===l[3]?L:N):s===L||s===N?s=H:s===I||s===E?s=F:(s=H,r=void 0);const d=s===H&&e[t+1].startsWith("/>")?" ":"";o+=s===F?i+R:c>=0?(n.push(a),i.slice(0,c)+M+i.slice(c)+T+d):i+T+(-2===c?t:d)}return[Y(e,o+(e[i]||"")+(2===t?"":3===t?"":"")),n]};class Z{constructor({strings:e,_$litType$:t},i){let n;this.parts=[];let r=0,o=0;const s=e.length-1,a=this.parts,[l,c]=X(e,t);if(this.el=Z.createElement(l,i),K.currentNode=this.el.content,2===t||3===t){const e=this.el.content.firstChild;e.replaceWith(...e.childNodes)}for(;null!==(n=K.nextNode())&&a.length0){n.textContent=$?$.emptyScript:"";for(let i=0;iP(e)||"function"==typeof e?.[Symbol.iterator])(e)?this.k(e):this._(e)}O(e){return this._$AA.parentNode.insertBefore(e,this._$AB)}T(e){this._$AH!==e&&(this._$AR(),this._$AH=this.O(e))}_(e){this._$AH!==V&&A(this._$AH)?this._$AA.nextSibling.data=e:this.T(D.createTextNode(e)),this._$AH=e}$(e){const{values:t,_$litType$:i}=e,n="number"==typeof i?this._$AC(e):(void 0===i.el&&(i.el=Z.createElement(Y(i.h,i.h[0]),this.options)),i);if(this._$AH?._$AD===n)this._$AH.p(t);else{const e=new Q(n,this),i=e.u(this.options);e.p(t),this.T(i),this._$AH=e}}_$AC(e){let t=G.get(e.strings);return void 0===t&&G.set(e.strings,t=new Z(e)),t}k(e){P(this._$AH)||(this._$AH=[],this._$AR());const t=this._$AH;let i,n=0;for(const r of e)n===t.length?t.push(i=new ee(this.O(z()),this.O(z()),this,this.options)):i=t[n],i._$AI(r),n++;n2||""!==i[0]||""!==i[1]?(this._$AH=Array(i.length-1).fill(new String),this.strings=i):this._$AH=V}_$AI(e,t=this,i,n){const r=this.strings;let o=!1;if(void 0===r)e=J(this,e,t,0),o=!A(e)||e!==this._$AH&&e!==U,o&&(this._$AH=e);else{const n=e;let s,a;for(e=r[0],s=0;s{const n=i?.renderBefore??t;let r=n._$litPart$;if(void 0===r){const e=i?.renderBefore??null;n._$litPart$=r=new ee(t.insertBefore(z(),e),e,void 0,i??{})}return r._$AI(e),r},ce=globalThis;let he=class extends w{constructor(){super(...arguments),this.renderOptions={host:this},this._$Do=void 0}createRenderRoot(){const e=super.createRenderRoot();return this.renderOptions.renderBefore??=e.firstChild,e}update(e){const t=this.render();this.hasUpdated||(this.renderOptions.isConnected=this.isConnected),super.update(e),this._$Do=le(t,this.renderRoot,this.renderOptions)}connectedCallback(){super.connectedCallback(),this._$Do?.setConnected(!0)}disconnectedCallback(){super.disconnectedCallback(),this._$Do?.setConnected(!1)}render(){return U}};he._$litElement$=!0,he.finalized=!0,ce.litElementHydrateSupport?.({LitElement:he});const de=ce.litElementPolyfillSupport;de?.({LitElement:he}),(ce.litElementVersions??=[]).push("4.2.2");const ue=new WeakMap;let pe=0;class _e extends he{constructor(){super(...arguments),this.title="",this.icon="",this.wide=!1,this.alert=!1,this.describedBy="",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-"+ ++pe,this._focusInitial=()=>{const e=this._focusableElements(),t=e.find(e=>e.hasAttribute("autofocus"))||e[0]||(this._usesHaDialog()?null:this.renderRoot.querySelector(".close"))||this.renderRoot.querySelector(".surface")||this.renderRoot.querySelector("ha-dialog");t?.focus({preventScroll:!0})},this._requestClose=()=>{this._closing||(this._closing=!0,this.dispatchEvent(new CustomEvent("hp-close",{bubbles:!0,composed:!0})))},this._onKeyDown=e=>{if("Escape"===e.key){e.preventDefault(),e.stopImmediatePropagation(),this._pruneOverlays();const t=this._overlays[this._overlays.length-1];return t?void this._closeOverlay(t,"escape"):void this._requestClose()}if("Tab"!==e.key||this._usesHaDialog())return;const t=this.renderRoot.querySelector(".close"),i=t?[t,...this._focusableElements()]:this._focusableElements();if(!i.length)return e.preventDefault(),void this.renderRoot.querySelector(".surface")?.focus({preventScroll:!0});const n=this._deepActiveElement(),r=i[0],o=i[i.length-1];!e.shiftKey||n!==r&&i.includes(n)?e.shiftKey||n!==o||(e.preventDefault(),r.focus()):(e.preventDefault(),o.focus())},this._onFallbackCancel=e=>{e.preventDefault(),this._requestClose()},this._onFallbackClick=e=>{this.dismissOnScrim&&e.target===e.currentTarget&&this._requestClose()}}_usesHaDialog(){return this._useHaDialog&&!this.alert}connectedCallback(){super.connectedCallback(),this._opener=this._deepActiveElement();const e=this.getRootNode();this._focusRoot=e;const t=ue.get(e)||{dialogs:new Set,opener:this._opener};t.dialogs.add(this),ue.set(e,t),this._useHaDialog=!!customElements.get("ha-dialog"),this.addEventListener("keydown",this._onKeyDown,!0)}disconnectedCallback(){this.removeEventListener("keydown",this._onKeyDown,!0);const e=[...this._overlays];this._overlays=[];for(const t of e.reverse())t.close("disconnect");const t=this._focusRoot,i=this._opener;this._opener=null,this._focusRoot=null;const n=t?ue.get(t):void 0;n?.dialogs.delete(this),super.disconnectedCallback(),t&&n&&requestAnimationFrame(()=>{const e=ue.get(t);if(!e)return;if(!e.dialogs.size)return e.opener?.isConnected&&e.opener.focus({preventScroll:!0}),void ue.delete(t);const n=i?.closest("hp-dialog");i?.isConnected&&n&&e.dialogs.has(n)&&i.focus({preventScroll:!0})})}firstUpdated(e){if(super.firstUpdated(e),!this._usesHaDialog()){const e=this.renderRoot.querySelector("dialog");e&&!e.open&&e.showModal()}queueMicrotask(()=>this._focusInitial())}_deepActiveElement(){let e=document.activeElement;for(;e?.shadowRoot?.activeElement;)e=e.shadowRoot.activeElement;return e&&e!==document.body?e:null}_focusableElements(){const e=["[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(","),t=[],i=new Set,n=r=>{if(!i.has(r)){if(i.add(r),r instanceof HTMLElement){if(r.matches(e)&&t.push(r),r instanceof HTMLSlotElement){for(const e of r.assignedNodes({flatten:!0}))n(e);return}if(r.shadowRoot){for(const e of r.shadowRoot.childNodes)n(e);return}}for(const e of r.childNodes)n(e)}};for(const e of this.childNodes)n(e);const r=this.overlayPortal();return r&&n(r),t.filter(e=>{let t=e;for(;t;){const e=getComputedStyle(t);if(t.hidden||t.inert||"true"===t.getAttribute("aria-hidden")||"none"===e.display||"hidden"===e.visibility)return!1;if(t=t.assignedSlot||t.parentElement||(t.getRootNode()instanceof ShadowRoot?t.getRootNode().host:null),t===this)break}return!0})}_pruneOverlays(){this._overlays=this._overlays.filter(e=>e.owner.isConnected)}_closeOverlay(e,t){const i=this._overlays.findIndex(t=>t.token===e.token);i>=0&&this._overlays.splice(i,1),e.close(t)}registerOverlay(e){this._pruneOverlays();const t=this._overlays.find(t=>t.owner===e.owner);t&&this._overlays.splice(this._overlays.indexOf(t),1);const i=e.group||"transient";for(const e of[...this._overlays].reverse())e.group===i&&this._closeOverlay(e,"exclusive");const n={...e,group:i,token:Symbol("hp-overlay")};this._overlays.push(n);let r=!1;return()=>{if(r)return;r=!0;const e=this._overlays.findIndex(e=>e.token===n.token);e>=0&&this._overlays.splice(e,1)}}closeTransientOverlays(e="outside"){this._pruneOverlays();const t=[...this._overlays].filter(e=>"transient"===(e.group||"transient"));for(const i of t.reverse())this._closeOverlay(i,e);return t.length>0}overlayPortal(){return this.renderRoot.querySelector(".overlay-portal")}render(){const e=W` ${this.icon?W``:V} ${this.title} `;return this._usesHaDialog()?this.describedBy?W`