fix(dialog): align HA settings form shell (#609)

Use Home Assistant's public dialog tokens for the reviewed 560 px canvas, height cap, single scroller and mobile fullscreen layout. Keep generic dialogs and the native fallback unchanged, with authentic-HA evidence and mutation witnesses.

Issue: #609
User-Visible: yes
This commit is contained in:
Claude
2026-09-23 03:18:37 +03:00
parent 6569dced23
commit 4c9e013276
61 changed files with 919 additions and 444 deletions
@@ -1,127 +1,127 @@
{ {
"schema": 1, "schema": 1,
"fingerprint": "2c4a9a013205eef84710c72e2eae1f8c307d94c84078490ecded141d206dd07d", "fingerprint": "1ee973d11082b1a8d53ac3d7d98323bdf0e4137264a98f2a988610f6f244cb2c",
"entry": "houseplan-card.js", "entry": "houseplan-card.js",
"panelEntry": "houseplan-panel.js", "panelEntry": "houseplan-panel.js",
"initialViewFiles": [ "initialViewFiles": [
"houseplan-assets/houseplan-card-eH_pY1mf.js", "houseplan-assets/houseplan-card-BObT7Q45.js",
"houseplan-card.js" "houseplan-card.js"
], ],
"initialViewGzipBytes": 290284, "initialViewGzipBytes": 290460,
"initialPanelFiles": [ "initialPanelFiles": [
"houseplan-assets/houseplan-card-eH_pY1mf.js", "houseplan-assets/houseplan-card-BObT7Q45.js",
"houseplan-panel.js" "houseplan-panel.js"
], ],
"initialPanelGzipBytes": 291805, "initialPanelGzipBytes": 291983,
"initialPanelOnlyFiles": [ "initialPanelOnlyFiles": [
"houseplan-panel.js" "houseplan-panel.js"
], ],
"initialPanelOnlyGzipBytes": 2322, "initialPanelOnlyGzipBytes": 2327,
"lazyFiles": [ "lazyFiles": [
"houseplan-assets/backdrop-pick-2vyBBTgG.js", "houseplan-assets/backdrop-pick-BBzikKL2.js",
"houseplan-assets/de-Bc8aNiKQ.js", "houseplan-assets/de-CvJX0Ow9.js",
"houseplan-assets/editor-v1zFPTHb.js", "houseplan-assets/editor-DEOW1N-C.js",
"houseplan-assets/form-kit.styles-XjSspVjk.js", "houseplan-assets/form-kit.styles-J0n2asaU.js",
"houseplan-assets/fr-DClCaTp6.js", "houseplan-assets/fr-DZUVGtpd.js",
"houseplan-assets/furniture-plan-art.generated-BQJxPKO5.js", "houseplan-assets/furniture-plan-art.generated-DUVSzIvq.js",
"houseplan-assets/houseplan-editor-runtime-DazlWcYl.js", "houseplan-assets/houseplan-editor-runtime-tbnt9LnD.js",
"houseplan-assets/houseplan-onboarding-runtime-j98hXPrW.js", "houseplan-assets/houseplan-onboarding-runtime-86SoSEFc.js",
"houseplan-assets/hp-zigbee-topology-overlay-BIunREL3.js", "houseplan-assets/hp-zigbee-topology-overlay-DJtHrXPE.js",
"houseplan-assets/iso-scene-render-Byk9ZXv9.js", "houseplan-assets/iso-scene-render-B6Aks3Kq.js",
"houseplan-assets/live-interaction-runtime-DjzpPNim.js", "houseplan-assets/live-interaction-runtime-D4mOBGpd.js",
"houseplan-assets/pdf-export-DhvYHpHG.js", "houseplan-assets/pdf-export-f90A6VCG.js",
"houseplan-assets/summary-panel-runtime-loaded-C750G8Rx.js", "houseplan-assets/summary-panel-runtime-loaded-CZlfz0Xl.js",
"houseplan-assets/zigbee-topology-B35vLrYp.js", "houseplan-assets/zigbee-topology-BXOYIu-9.js",
"houseplan-assets/zigbee-topology-runtime-hsXdTYOk.js" "houseplan-assets/zigbee-topology-runtime-tN_qTU1Q.js"
], ],
"lazyGzipBytes": 459905, "lazyGzipBytes": 459952,
"lazyEditorFiles": [ "lazyEditorFiles": [
"houseplan-assets/backdrop-pick-2vyBBTgG.js", "houseplan-assets/backdrop-pick-BBzikKL2.js",
"houseplan-assets/editor-v1zFPTHb.js", "houseplan-assets/editor-DEOW1N-C.js",
"houseplan-assets/form-kit.styles-XjSspVjk.js", "houseplan-assets/form-kit.styles-J0n2asaU.js",
"houseplan-assets/furniture-plan-art.generated-BQJxPKO5.js", "houseplan-assets/furniture-plan-art.generated-DUVSzIvq.js",
"houseplan-assets/houseplan-editor-runtime-DazlWcYl.js", "houseplan-assets/houseplan-editor-runtime-tbnt9LnD.js",
"houseplan-assets/zigbee-topology-B35vLrYp.js" "houseplan-assets/zigbee-topology-BXOYIu-9.js"
], ],
"lazyEditorGzipBytes": 243361, "lazyEditorGzipBytes": 243377,
"lazyOnboardingFiles": [ "lazyOnboardingFiles": [
"houseplan-assets/backdrop-pick-2vyBBTgG.js", "houseplan-assets/backdrop-pick-BBzikKL2.js",
"houseplan-assets/form-kit.styles-XjSspVjk.js", "houseplan-assets/form-kit.styles-J0n2asaU.js",
"houseplan-assets/houseplan-onboarding-runtime-j98hXPrW.js" "houseplan-assets/houseplan-onboarding-runtime-86SoSEFc.js"
], ],
"lazyOnboardingGzipBytes": 33813, "lazyOnboardingGzipBytes": 33822,
"lazyLocaleFiles": [ "lazyLocaleFiles": [
"houseplan-assets/de-Bc8aNiKQ.js", "houseplan-assets/de-CvJX0Ow9.js",
"houseplan-assets/fr-DClCaTp6.js" "houseplan-assets/fr-DZUVGtpd.js"
], ],
"lazyLocaleGzipBytes": 55371, "lazyLocaleGzipBytes": 55376,
"lazyIsometricFiles": [ "lazyIsometricFiles": [
"houseplan-assets/iso-scene-render-Byk9ZXv9.js" "houseplan-assets/iso-scene-render-B6Aks3Kq.js"
], ],
"lazyIsometricGzipBytes": 17639, "lazyIsometricGzipBytes": 17643,
"lazyFurnitureArtFiles": [ "lazyFurnitureArtFiles": [
"houseplan-assets/furniture-plan-art.generated-BQJxPKO5.js" "houseplan-assets/furniture-plan-art.generated-DUVSzIvq.js"
], ],
"lazyFurnitureArtGzipBytes": 16939, "lazyFurnitureArtGzipBytes": 16939,
"lazyPdfFiles": [ "lazyPdfFiles": [
"houseplan-assets/furniture-plan-art.generated-BQJxPKO5.js", "houseplan-assets/furniture-plan-art.generated-DUVSzIvq.js",
"houseplan-assets/pdf-export-DhvYHpHG.js" "houseplan-assets/pdf-export-f90A6VCG.js"
], ],
"lazyPdfGzipBytes": 126825, "lazyPdfGzipBytes": 126826,
"files": [ "files": [
{ {
"path": "houseplan-assets/backdrop-pick-2vyBBTgG.js", "path": "houseplan-assets/backdrop-pick-BBzikKL2.js",
"sha256": "5c1f5f3ac1132cc5970ade27d6797a2674d90945b3567b6b204990b55d394103", "sha256": "89ccbfee082a908b4d357c0d1190e2bf341b0358475b773efb330e49b0f1886f",
"rawBytes": 74076, "rawBytes": 74076,
"gzipBytes": 23929, "gzipBytes": 23933,
"isEntry": false, "isEntry": false,
"imports": [ "imports": [
"houseplan-assets/form-kit.styles-XjSspVjk.js", "houseplan-assets/form-kit.styles-J0n2asaU.js",
"houseplan-assets/houseplan-card-eH_pY1mf.js" "houseplan-assets/houseplan-card-BObT7Q45.js"
], ],
"dynamicImports": [] "dynamicImports": []
}, },
{ {
"path": "houseplan-assets/de-Bc8aNiKQ.js", "path": "houseplan-assets/de-CvJX0Ow9.js",
"sha256": "23a420015836d2cb9dba5bb19349bf2b67f2cf5ed08d4ae77ebbde0cd661baa9", "sha256": "62d35a977800def77047c802e5509342fb52aa96bfab819b69ab7c6fcba25732",
"rawBytes": 92496, "rawBytes": 92496,
"gzipBytes": 27928, "gzipBytes": 27932,
"isEntry": false, "isEntry": false,
"imports": [], "imports": [],
"dynamicImports": [] "dynamicImports": []
}, },
{ {
"path": "houseplan-assets/editor-v1zFPTHb.js", "path": "houseplan-assets/editor-DEOW1N-C.js",
"sha256": "73af9764e3cba343dafc00d13696a3154255ef7f4cb0993f2fefc37ee40c01e8", "sha256": "356e862c4531fec75731b6514e3915e0531954d93e9d2a012ebac3f65765c107",
"rawBytes": 3833, "rawBytes": 3833,
"gzipBytes": 1581, "gzipBytes": 1585,
"isEntry": false, "isEntry": false,
"imports": [ "imports": [
"houseplan-assets/houseplan-card-eH_pY1mf.js" "houseplan-assets/houseplan-card-BObT7Q45.js"
], ],
"dynamicImports": [] "dynamicImports": []
}, },
{ {
"path": "houseplan-assets/form-kit.styles-XjSspVjk.js", "path": "houseplan-assets/form-kit.styles-J0n2asaU.js",
"sha256": "c6f912fabc6288e8f84712cd3ebaf3bfd6c9ab821f511e0b977ef28f0f235ed3", "sha256": "f95006c96a719b7ef5cce919d3afb4d851a21f88e7ae05964624d35228076cb9",
"rawBytes": 25600, "rawBytes": 25600,
"gzipBytes": 5055, "gzipBytes": 5057,
"isEntry": false, "isEntry": false,
"imports": [], "imports": [],
"dynamicImports": [] "dynamicImports": []
}, },
{ {
"path": "houseplan-assets/fr-DClCaTp6.js", "path": "houseplan-assets/fr-DZUVGtpd.js",
"sha256": "4c0e753ff9ae5160f0b702eeaa152ffa7462e96e888115e38ae33bac95bd8544", "sha256": "97ec4f07911fd1b3bd87f1e3c7a23695dbdb144ff2ffb871d51120cdf94d801b",
"rawBytes": 94813, "rawBytes": 94813,
"gzipBytes": 27443, "gzipBytes": 27444,
"isEntry": false, "isEntry": false,
"imports": [], "imports": [],
"dynamicImports": [] "dynamicImports": []
}, },
{ {
"path": "houseplan-assets/furniture-plan-art.generated-BQJxPKO5.js", "path": "houseplan-assets/furniture-plan-art.generated-DUVSzIvq.js",
"sha256": "b293b18c355818c7f51e25562428643d9c524d217fd78fca675be1a2a792b0bc", "sha256": "d99385353bbbb5473838377cc98ce0e87b9767588faa09bcc6897c73a2bca826",
"rawBytes": 52035, "rawBytes": 52035,
"gzipBytes": 16939, "gzipBytes": 16939,
"isEntry": false, "isEntry": false,
@@ -129,184 +129,184 @@
"dynamicImports": [] "dynamicImports": []
}, },
{ {
"path": "houseplan-assets/houseplan-card-eH_pY1mf.js", "path": "houseplan-assets/houseplan-card-BObT7Q45.js",
"sha256": "e5b871748b29287d7c0e66fa30e7fc81cbd96715b839aee4e426885bd998c626", "sha256": "26c0b9d45bb404e6cf448cd8c7ac03a4a91371782bb8121460b4a30c04a40049",
"rawBytes": 1029393, "rawBytes": 1030217,
"gzipBytes": 289483, "gzipBytes": 289656,
"isEntry": false, "isEntry": false,
"imports": [], "imports": [],
"dynamicImports": [ "dynamicImports": [
"houseplan-assets/de-Bc8aNiKQ.js", "houseplan-assets/de-CvJX0Ow9.js",
"houseplan-assets/editor-v1zFPTHb.js", "houseplan-assets/editor-DEOW1N-C.js",
"houseplan-assets/fr-DClCaTp6.js", "houseplan-assets/fr-DZUVGtpd.js",
"houseplan-assets/furniture-plan-art.generated-BQJxPKO5.js", "houseplan-assets/furniture-plan-art.generated-DUVSzIvq.js",
"houseplan-assets/houseplan-editor-runtime-DazlWcYl.js", "houseplan-assets/houseplan-editor-runtime-tbnt9LnD.js",
"houseplan-assets/houseplan-onboarding-runtime-j98hXPrW.js", "houseplan-assets/houseplan-onboarding-runtime-86SoSEFc.js",
"houseplan-assets/hp-zigbee-topology-overlay-BIunREL3.js", "houseplan-assets/hp-zigbee-topology-overlay-DJtHrXPE.js",
"houseplan-assets/iso-scene-render-Byk9ZXv9.js", "houseplan-assets/iso-scene-render-B6Aks3Kq.js",
"houseplan-assets/live-interaction-runtime-DjzpPNim.js", "houseplan-assets/live-interaction-runtime-D4mOBGpd.js",
"houseplan-assets/pdf-export-DhvYHpHG.js", "houseplan-assets/pdf-export-f90A6VCG.js",
"houseplan-assets/summary-panel-runtime-loaded-C750G8Rx.js" "houseplan-assets/summary-panel-runtime-loaded-CZlfz0Xl.js"
] ]
}, },
{ {
"path": "houseplan-assets/houseplan-editor-runtime-DazlWcYl.js", "path": "houseplan-assets/houseplan-editor-runtime-tbnt9LnD.js",
"sha256": "6515e98e1c7d594e6c2943871a906b5a1a0762092e5a4cbfec0470e07863d659", "sha256": "1e3621aa6e07d683bd4564e13fd28aafe905c2663fcd4d1387e8d4ed9d172474",
"rawBytes": 677705, "rawBytes": 677705,
"gzipBytes": 188433, "gzipBytes": 188436,
"isEntry": false, "isEntry": false,
"imports": [ "imports": [
"houseplan-assets/backdrop-pick-2vyBBTgG.js", "houseplan-assets/backdrop-pick-BBzikKL2.js",
"houseplan-assets/form-kit.styles-XjSspVjk.js", "houseplan-assets/form-kit.styles-J0n2asaU.js",
"houseplan-assets/furniture-plan-art.generated-BQJxPKO5.js", "houseplan-assets/furniture-plan-art.generated-DUVSzIvq.js",
"houseplan-assets/houseplan-card-eH_pY1mf.js", "houseplan-assets/houseplan-card-BObT7Q45.js",
"houseplan-assets/zigbee-topology-B35vLrYp.js" "houseplan-assets/zigbee-topology-BXOYIu-9.js"
], ],
"dynamicImports": [ "dynamicImports": [
"houseplan-assets/zigbee-topology-runtime-hsXdTYOk.js" "houseplan-assets/zigbee-topology-runtime-tN_qTU1Q.js"
] ]
}, },
{ {
"path": "houseplan-assets/houseplan-onboarding-runtime-j98hXPrW.js", "path": "houseplan-assets/houseplan-onboarding-runtime-86SoSEFc.js",
"sha256": "6a7765d125bedbb22df7276f80f59bb5156cba93e86d4fb75adaac9c7574d4ea", "sha256": "f717ed132f519053820b921188e8c54c0b9489f22d1a71293fb7f4ffb74069dc",
"rawBytes": 15667, "rawBytes": 15667,
"gzipBytes": 4829, "gzipBytes": 4832,
"isEntry": false, "isEntry": false,
"imports": [ "imports": [
"houseplan-assets/backdrop-pick-2vyBBTgG.js", "houseplan-assets/backdrop-pick-BBzikKL2.js",
"houseplan-assets/form-kit.styles-XjSspVjk.js", "houseplan-assets/form-kit.styles-J0n2asaU.js",
"houseplan-assets/houseplan-card-eH_pY1mf.js" "houseplan-assets/houseplan-card-BObT7Q45.js"
], ],
"dynamicImports": [] "dynamicImports": []
}, },
{ {
"path": "houseplan-assets/hp-zigbee-topology-overlay-BIunREL3.js", "path": "houseplan-assets/hp-zigbee-topology-overlay-DJtHrXPE.js",
"sha256": "8342c4c8f8b62e5caf311c5088fc817246a808bee1de871969a5760d9d11070c", "sha256": "643cf04bb44044dab3a4d831e4866a118e76c796bd3913cba34c0a4927233777",
"rawBytes": 10759, "rawBytes": 10759,
"gzipBytes": 3683, "gzipBytes": 3687,
"isEntry": false, "isEntry": false,
"imports": [ "imports": [
"houseplan-assets/houseplan-card-eH_pY1mf.js", "houseplan-assets/houseplan-card-BObT7Q45.js",
"houseplan-assets/zigbee-topology-B35vLrYp.js", "houseplan-assets/zigbee-topology-BXOYIu-9.js",
"houseplan-assets/zigbee-topology-runtime-hsXdTYOk.js" "houseplan-assets/zigbee-topology-runtime-tN_qTU1Q.js"
], ],
"dynamicImports": [] "dynamicImports": []
}, },
{ {
"path": "houseplan-assets/iso-scene-render-Byk9ZXv9.js", "path": "houseplan-assets/iso-scene-render-B6Aks3Kq.js",
"sha256": "2888754263d7837c59f98c267156ac601611915c53f31d6d8ba14e1656417afb", "sha256": "7fb99a44f111f3108873c466ac7a0f82f23126ca0939bb279420cda3f49891a0",
"rawBytes": 51983, "rawBytes": 51983,
"gzipBytes": 17639, "gzipBytes": 17643,
"isEntry": false, "isEntry": false,
"imports": [ "imports": [
"houseplan-assets/houseplan-card-eH_pY1mf.js" "houseplan-assets/houseplan-card-BObT7Q45.js"
], ],
"dynamicImports": [] "dynamicImports": []
}, },
{ {
"path": "houseplan-assets/live-interaction-runtime-DjzpPNim.js", "path": "houseplan-assets/live-interaction-runtime-D4mOBGpd.js",
"sha256": "56c243a0be7558428fcd7351a903aef112e9e3c8054a43daf180b90e225e2826", "sha256": "d72307dc5213fd81105682bd3cb99bdfe5ab667f3cd708981129e1e68412e80e",
"rawBytes": 8216, "rawBytes": 8216,
"gzipBytes": 3204, "gzipBytes": 3210,
"isEntry": false, "isEntry": false,
"imports": [ "imports": [
"houseplan-assets/houseplan-card-eH_pY1mf.js" "houseplan-assets/houseplan-card-BObT7Q45.js"
], ],
"dynamicImports": [] "dynamicImports": []
}, },
{ {
"path": "houseplan-assets/pdf-export-DhvYHpHG.js", "path": "houseplan-assets/pdf-export-f90A6VCG.js",
"sha256": "ae0e8f7a914fc3034f73c5e0128515019849a373f0a184864f6cd91ffdf0211f", "sha256": "6a7f3d4705720cc9a92a1887fae7e88b1de14a809d61a6360db095570869af37",
"rawBytes": 236264, "rawBytes": 236264,
"gzipBytes": 109886, "gzipBytes": 109887,
"isEntry": false, "isEntry": false,
"imports": [ "imports": [
"houseplan-assets/furniture-plan-art.generated-BQJxPKO5.js", "houseplan-assets/furniture-plan-art.generated-DUVSzIvq.js",
"houseplan-assets/houseplan-card-eH_pY1mf.js" "houseplan-assets/houseplan-card-BObT7Q45.js"
], ],
"dynamicImports": [] "dynamicImports": []
}, },
{ {
"path": "houseplan-assets/summary-panel-editor-D6jtLpQ8.js", "path": "houseplan-assets/summary-panel-editor-DGDH1Z-d.js",
"sha256": "141837c9947c69b51b7f870afc1bb050372c7f26fb36d1ea6fe7a9e1073913ab", "sha256": "a3e3731628c6d0edbc5913180c5d143c7d6d3554cf9af074465d81c88f3b787b",
"rawBytes": 14862, "rawBytes": 14862,
"gzipBytes": 3424, "gzipBytes": 3426,
"isEntry": false, "isEntry": false,
"imports": [ "imports": [
"houseplan-assets/form-kit.styles-XjSspVjk.js", "houseplan-assets/form-kit.styles-J0n2asaU.js",
"houseplan-assets/houseplan-card-eH_pY1mf.js", "houseplan-assets/houseplan-card-BObT7Q45.js",
"houseplan-assets/summary-panel-runtime-loaded-C750G8Rx.js" "houseplan-assets/summary-panel-runtime-loaded-CZlfz0Xl.js"
], ],
"dynamicImports": [] "dynamicImports": []
}, },
{ {
"path": "houseplan-assets/summary-panel-metrics-lT9wi_mo.js", "path": "houseplan-assets/summary-panel-metrics-CRnKPnjo.js",
"sha256": "f21e7ab3dec25618eab55cca71fd9635583941673e402af8091b344a18ec0f26", "sha256": "7d9aa0f49312f3602eefaa33b95a6d64da3c982f3485026e6ed2218de0d6aaa6",
"rawBytes": 2611, "rawBytes": 2611,
"gzipBytes": 1305, "gzipBytes": 1310,
"isEntry": false, "isEntry": false,
"imports": [ "imports": [
"houseplan-assets/houseplan-card-eH_pY1mf.js" "houseplan-assets/houseplan-card-BObT7Q45.js"
], ],
"dynamicImports": [] "dynamicImports": []
}, },
{ {
"path": "houseplan-assets/summary-panel-runtime-loaded-C750G8Rx.js", "path": "houseplan-assets/summary-panel-runtime-loaded-CZlfz0Xl.js",
"sha256": "9b3e61e18a989a38950776a248106dde45b711fc4b80f247bc429e8cb372a25a", "sha256": "02f3b9063bf0bc9a91d165033ce98b09b923804965bd91dcf9a467bd07d19f9c",
"rawBytes": 72733, "rawBytes": 72733,
"gzipBytes": 20171, "gzipBytes": 20173,
"isEntry": false, "isEntry": false,
"imports": [ "imports": [
"houseplan-assets/form-kit.styles-XjSspVjk.js", "houseplan-assets/form-kit.styles-J0n2asaU.js",
"houseplan-assets/houseplan-card-eH_pY1mf.js" "houseplan-assets/houseplan-card-BObT7Q45.js"
], ],
"dynamicImports": [ "dynamicImports": [
"houseplan-assets/summary-panel-editor-D6jtLpQ8.js", "houseplan-assets/summary-panel-editor-DGDH1Z-d.js",
"houseplan-assets/summary-panel-metrics-lT9wi_mo.js" "houseplan-assets/summary-panel-metrics-CRnKPnjo.js"
] ]
}, },
{ {
"path": "houseplan-assets/zigbee-topology-B35vLrYp.js", "path": "houseplan-assets/zigbee-topology-BXOYIu-9.js",
"sha256": "aa8bf029c7fed0133c80c2b557f273f7593a6c7059d7f444bb59124484815a21", "sha256": "8fb689936e9da105676dcac047b497bb2ab65dfe80b184b29e68dacaf659bd3e",
"rawBytes": 18962, "rawBytes": 18962,
"gzipBytes": 7424, "gzipBytes": 7427,
"isEntry": false, "isEntry": false,
"imports": [ "imports": [
"houseplan-assets/houseplan-card-eH_pY1mf.js" "houseplan-assets/houseplan-card-BObT7Q45.js"
], ],
"dynamicImports": [] "dynamicImports": []
}, },
{ {
"path": "houseplan-assets/zigbee-topology-runtime-hsXdTYOk.js", "path": "houseplan-assets/zigbee-topology-runtime-tN_qTU1Q.js",
"sha256": "d60b3845428071ed0a8555fc50e5712e4bd029e38d75c6059a0b314af95dacda", "sha256": "2eb80ffae43caa09e4006ff3fa910752069a502d94463ef58defdf7c8c8dea34",
"rawBytes": 3942, "rawBytes": 3942,
"gzipBytes": 1761, "gzipBytes": 1767,
"isEntry": false, "isEntry": false,
"imports": [ "imports": [
"houseplan-assets/houseplan-card-eH_pY1mf.js", "houseplan-assets/houseplan-card-BObT7Q45.js",
"houseplan-assets/zigbee-topology-B35vLrYp.js" "houseplan-assets/zigbee-topology-BXOYIu-9.js"
], ],
"dynamicImports": [] "dynamicImports": []
}, },
{ {
"path": "houseplan-card.js", "path": "houseplan-card.js",
"sha256": "22729f58ff83f845a5b454830449099c16024d8fac36f87ffd1934c7928b0780", "sha256": "327b0ff49a66e55a7b6fa00b2acdf4dda91606c2e3538559c5b2b431d6c7986f",
"rawBytes": 1205, "rawBytes": 1205,
"gzipBytes": 801, "gzipBytes": 804,
"isEntry": true, "isEntry": true,
"imports": [ "imports": [
"houseplan-assets/houseplan-card-eH_pY1mf.js" "houseplan-assets/houseplan-card-BObT7Q45.js"
], ],
"dynamicImports": [] "dynamicImports": []
}, },
{ {
"path": "houseplan-panel.js", "path": "houseplan-panel.js",
"sha256": "2981cd3ed29739c95c0cb9f351f731bbd363e2fee2a4b9cf354d4c24549bf9dd", "sha256": "234102fcde3bcd24c611dbbfc37c49539b2d89ef0b3ac6529c4f3d10ed77a584",
"rawBytes": 6165, "rawBytes": 6165,
"gzipBytes": 2322, "gzipBytes": 2327,
"isEntry": true, "isEntry": true,
"imports": [ "imports": [
"houseplan-assets/houseplan-card-eH_pY1mf.js" "houseplan-assets/houseplan-card-BObT7Q45.js"
], ],
"dynamicImports": [] "dynamicImports": []
} }
File diff suppressed because one or more lines are too long
@@ -1,4 +1,4 @@
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="2c4a9a013205eef84710c72e2eae1f8c307d94c84078490ecded141d206dd07d";import{az as e,l as o,aC as t,e8 as s,A as a,e9 as i,ea as l,eb as n,E as r,c}from"./houseplan-card-eH_pY1mf.js";class h extends e{constructor(){super(...arguments),this._spaces=null,this._spacesLoading=!1,this._spacesAuthoritative=!1}setConfig(e){this._config=e}async _loadSpaces(){if(!this._spaces&&!this._spacesLoading&&this.hass){this._spacesLoading=!0;try{const e=await this.hass.callWS({type:"houseplan/config/get"});this._spaces=(e?.config?.spaces||[]).map(e=>({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`<ha-form globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="1ee973d11082b1a8d53ac3d7d98323bdf0e4137264a98f2a988610f6f244cb2c";import{az as e,l as o,aC as t,e8 as s,A as a,e9 as i,ea as l,eb as n,E as r,c}from"./houseplan-card-BObT7Q45.js";class h extends e{constructor(){super(...arguments),this._spaces=null,this._spacesLoading=!1,this._spacesAuthoritative=!1}setConfig(e){this._config=e}async _loadSpaces(){if(!this._spaces&&!this._spacesLoading&&this.hass){this._spacesLoading=!0;try{const e=await this.hass.callWS({type:"houseplan/config/get"});this._spaces=(e?.config?.spaces||[]).map(e=>({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`<ha-form
.hass=${this.hass} .hass=${this.hass}
.data=${this._formData} .data=${this._formData}
.schema=${e} .schema=${e}
File diff suppressed because one or more lines are too long
@@ -1,4 +1,4 @@
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="2c4a9a013205eef84710c72e2eae1f8c307d94c84078490ecded141d206dd07d";import{c as a,A as e}from"./houseplan-card-eH_pY1mf.js";import{s,n as t,a as l,m as r,b as o,c as i,d as u}from"./summary-panel-runtime-loaded-C750G8Rx.js";import"./form-kit.styles-XjSspVjk.js";const m=m=>{const{host:c,dialog:d,problems:n,t:b}=m,y=n.find(a=>"error"===a.kind),$=d.localShow!==d.baseLocalShow||!d.localOnly&&!s(t(d.draft),d.base),p=$&&!d.busy&&!y,v=a=>n.find(e=>e.path===a),h=a=>a?b(`summary.problem.${a.code}`):"",k=()=>m.close(),g=a`<label class="summary-switch" for="summary-local-show"> globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="1ee973d11082b1a8d53ac3d7d98323bdf0e4137264a98f2a988610f6f244cb2c";import{c as a,A as e}from"./houseplan-card-BObT7Q45.js";import{s,n as t,a as l,m as r,b as o,c as i,d as u}from"./summary-panel-runtime-loaded-CZlfz0Xl.js";import"./form-kit.styles-J0n2asaU.js";const m=m=>{const{host:c,dialog:d,problems:n,t:b}=m,y=n.find(a=>"error"===a.kind),$=d.localShow!==d.baseLocalShow||!d.localOnly&&!s(t(d.draft),d.base),p=$&&!d.busy&&!y,v=a=>n.find(e=>e.path===a),h=a=>a?b(`summary.problem.${a.code}`):"",k=()=>m.close(),g=a`<label class="summary-switch" for="summary-local-show">
<span class="summary-switch-caption"><strong>${b("summary.show_local")}</strong> <span class="summary-switch-caption"><strong>${b("summary.show_local")}</strong>
<small id="summary-local-show-hint">${b("summary.show_local_hint")}</small></span> <small id="summary-local-show-hint">${b("summary.show_local_hint")}</small></span>
<input id="summary-local-show" data-summary-local-show type="checkbox" <input id="summary-local-show" data-summary-local-show type="checkbox"
@@ -0,0 +1 @@
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="1ee973d11082b1a8d53ac3d7d98323bdf0e4137264a98f2a988610f6f244cb2c";import{ee as e,J as t,aX as n,H as i,aa as o,a8 as r,bP as a,bO as s,aW as l,aV as c,aY as d,ef as u,eg as f,bR as m,eh as g}from"./houseplan-card-BObT7Q45.js";function v(e){if(!e.registry.authoritative)return null;const t=new Set,n=d(e.markers);for(const i of Object.values(e.registry.devices||{}))i?.id&&"service"!==i.entry_type&&!n.devices.has(i.id)&&i.area_id&&e.areaToSpace[i.area_id]&&t.add(i.id);for(const i of e.markers||[]){if(i.removed||"virtual"===i.binding)continue;const o=String(i.binding||"").indexOf(":");if(o<1)continue;const r=i.binding.slice(0,o),a=i.binding.slice(o+1),s="device"===r?e.registry.devices?.[a]:null,l="entity"===r?e.registry.entities?.[a]:null,c="device"===r?a:l?.device_id,d="device"===r?s?.area_id:l?.area_id||c&&e.registry.devices?.[c]?.area_id,u="string"==typeof i.room_id&&i.room_id.length>0&&null===i.area?"":i.area||d||"",f=u&&e.areaToSpace[u]||i.space||e.firstSpaceId;c&&e.registry.devices?.[c]&&e.spaceIds.has(f)&&(!n.devices.has(c)||"entity"===r&&n.liveEntities.has(a))&&t.add(c)}return t}function y(e,t){return e?.length?t?.length?g(e,t):e:t}function _(e,t){const n=l(e.rooms,t.walls,t.openCuts,[],i,t.cellCm,o,r);return{roomGeom:"ok"===n.status||"degraded-extra"===n.status?n.roomGeom:void 0,multiWallNodes:c(e.rooms,t.walls,t.openCuts,i,t.cellCm,o,r)}}function*h(l,c,d=_){try{let u=0;for(const f of c){const c=l.spaces.find(e=>String(e?.id)===f.id);if(!c)continue;const m=e(c,f),g=d(f,m);let v=null;for(const e of f.rooms){if(!e.id)continue;const s=t(e);if(!s)continue;const l=n(f.rooms,e.id,m.walls,m.openCuts,i,m.cellCm,o,r,g.roomGeom,g.multiWallNodes)||s;v=y(v,a(l,m.physicalBodies)),yield}const _=m.cellCm/o;u+=s(v)*_*_/1e4}return u}catch{return null}}function p(e,t,n=_){const i=h(e,t,n);let o=i.next();for(;!o.done;)o=i.next();return o.value}function b(e,t,n,i){if("system"!==e.type)return null;if("device_count"===e.key)return null===t.deviceCount?null:String(t.deviceCount);if("total_area"===e.key)return null===t.areaM2?null:m(t.areaM2,"mi"===n?.config?.unit_system?.length);try{return new Intl.DateTimeFormat(i||void 0,{dateStyle:"short",timeStyle:"short",timeZone:n?.config?.time_zone||void 0}).format(t.now)}catch{return t.now.toLocaleString()}}function S(e,t){const n=e?.states?.[t];if(!n)return null;const i=u(e,t);return i?f(i,String(n.attributes?.unit_of_measurement||"")):null}export{h as cleanFloorAreaSteps,v as representedHaDeviceIds,_ as spaceWallGeometry,S as summaryEntityValue,b as summarySystemValue,p as totalCleanFloorAreaM2};
@@ -1 +0,0 @@
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="2c4a9a013205eef84710c72e2eae1f8c307d94c84078490ecded141d206dd07d";import{ee as e,J as t,aX as n,H as i,aa as o,a8 as r,bP as s,bO as a,aW as c,aV as l,aY as d,ef as u,eg as f,bR as m,eh as g}from"./houseplan-card-eH_pY1mf.js";function v(e){if(!e.registry.authoritative)return null;const t=new Set,n=d(e.markers);for(const i of Object.values(e.registry.devices||{}))i?.id&&"service"!==i.entry_type&&!n.devices.has(i.id)&&i.area_id&&e.areaToSpace[i.area_id]&&t.add(i.id);for(const i of e.markers||[]){if(i.removed||"virtual"===i.binding)continue;const o=String(i.binding||"").indexOf(":");if(o<1)continue;const r=i.binding.slice(0,o),s=i.binding.slice(o+1),a="device"===r?e.registry.devices?.[s]:null,c="entity"===r?e.registry.entities?.[s]:null,l="device"===r?s:c?.device_id,d="device"===r?a?.area_id:c?.area_id||l&&e.registry.devices?.[l]?.area_id,u="string"==typeof i.room_id&&i.room_id.length>0&&null===i.area?"":i.area||d||"",f=u&&e.areaToSpace[u]||i.space||e.firstSpaceId;l&&e.registry.devices?.[l]&&e.spaceIds.has(f)&&(!n.devices.has(l)||"entity"===r&&n.liveEntities.has(s))&&t.add(l)}return t}function y(e,t){return e?.length?t?.length?g(e,t):e:t}function _(e,t){const n=c(e.rooms,t.walls,t.openCuts,[],i,t.cellCm,o,r);return{roomGeom:"ok"===n.status||"degraded-extra"===n.status?n.roomGeom:void 0,multiWallNodes:l(e.rooms,t.walls,t.openCuts,i,t.cellCm,o,r)}}function*h(c,l,d=_){try{let u=0;for(const f of l){const l=c.spaces.find(e=>String(e?.id)===f.id);if(!l)continue;const m=e(l,f),g=d(f,m);let v=null;for(const e of f.rooms){if(!e.id)continue;const a=t(e);if(!a)continue;const c=n(f.rooms,e.id,m.walls,m.openCuts,i,m.cellCm,o,r,g.roomGeom,g.multiWallNodes)||a;v=y(v,s(c,m.physicalBodies)),yield}const _=m.cellCm/o;u+=a(v)*_*_/1e4}return u}catch{return null}}function p(e,t,n=_){const i=h(e,t,n);let o=i.next();for(;!o.done;)o=i.next();return o.value}function S(e,t,n,i){if("system"!==e.type)return null;if("device_count"===e.key)return null===t.deviceCount?null:String(t.deviceCount);if("total_area"===e.key)return null===t.areaM2?null:m(t.areaM2,"mi"===n?.config?.unit_system?.length);try{return new Intl.DateTimeFormat(i||void 0,{dateStyle:"short",timeStyle:"short",timeZone:n?.config?.time_zone||void 0}).format(t.now)}catch{return t.now.toLocaleString()}}function b(e,t){const n=e?.states?.[t];if(!n)return null;const i=u(e,t);return i?f(i,String(n.attributes?.unit_of_measurement||"")):null}export{h as cleanFloorAreaSteps,v as representedHaDeviceIds,_ as spaceWallGeometry,b as summaryEntityValue,S as summarySystemValue,p as totalCleanFloorAreaM2};
@@ -1 +1 @@
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="2c4a9a013205eef84710c72e2eae1f8c307d94c84078490ecded141d206dd07d";import{n as t,b as n}from"./zigbee-topology-B35vLrYp.js";import{aI as e}from"./houseplan-card-eH_pY1mf.js";const o=new WeakMap;function i(t){const n=function(t){const n=t?.connection||t;return!n||"object"!=typeof n&&"function"!=typeof n?null:n}(t);if(!n)return null;let e=o.get(n);return e||(e={revision:0,topologies:[],states:{},listeners:new Set,inflight:new Map},o.set(n,e)),e}function r(t,n,e){t.states={...t.states,[n]:e},function(t){t.revision++;for(const n of t.listeners)n()}(t)}function s(t){const n=t?.code;if("permission"===n||"unsupported"===n||"timeout"===n||"invalid_topic"===n||"invalid_payload"===n)return n;const e=String(t?.message||"").toLowerCase();return e.includes("unauthor")||e.includes("permission")?"permission":e.includes("unknown_command")||e.includes("not found")?"unsupported":"provider"}function a(t){return Object.assign(new Error(t),{code:t})}function c(t,n,e){const o=t.inflight.get(n);if(o)return o;r(t,n,{phase:"loading"});const i=e().then(n=>{if(!n.nodes.length&&n.warnings.some(t=>"invalid_payload"===t.code))throw a("invalid_payload");!function(t,n){t.topologies=[...t.topologies.filter(t=>!(t.provider===n.provider&&t.instanceId===n.instanceId)),n],r(t,"zha"===n.provider?"zha":`z2m:${n.instanceId}`,{phase:"ready",obtainedAt:n.obtainedAt,partial:n.warnings.length>0})}(t,n)}).catch(e=>{r(t,n,{phase:"error",error:s(e)})}).finally(()=>t.inflight.delete(n));return t.inflight.set(n,i),i}function l(t){const n=i(t);return n?{revision:n.revision,topologies:n.topologies,states:n.states}:{revision:0,topologies:[],states:{}}}function u(t,n){const e=i(t);return e?(e.listeners.add(n),()=>e.listeners.delete(n)):()=>{}}function p(t){if(!0!==t?.user?.is_admin)throw a("permission")}function f(n){const e=i(n);return e?c(e,"zha",async()=>{if(p(n),"function"!=typeof n?.callWS)throw a("unsupported");return t(await n.callWS({type:"zha/devices"}))}):Promise.resolve()}function d(t){return null!==t&&"object"==typeof t?t:null}function h(t){const n=d(t),e=n?.payload??t;if("string"!=typeof e)return e;try{return JSON.parse(e)}catch{return null}}async function m(t,n){let e;try{return await Promise.race([t,new Promise((t,o)=>{e=globalThis.setTimeout(()=>o(a("timeout")),Math.max(1,n))})])}finally{void 0!==e&&globalThis.clearTimeout(e)}}function g(t,o,r=15e4){const s=i(t);if(!s)return Promise.resolve();const l=e(o);return c(s,`z2m:${l||String(o)}`,async()=>{if(p(t),!l)throw a("invalid_topic");const e=t.connection,o=e?.subscribeMessage;if("function"!=typeof o||"function"!=typeof t?.callService)throw a("unsupported");const i=function(){const t=globalThis.crypto;return"function"==typeof t?.randomUUID?`houseplan-${t.randomUUID()}`:`houseplan-${Date.now().toString(36)}-${Math.random().toString(36).slice(2)}`}(),s=Date.now()+Math.max(1,r);let c=!1,u=null,f=null,g=null;const y=new Promise(t=>{u=t}),w=new Promise((t,n)=>{f=t,g=n}),b=[];try{const r=await o.call(e,t=>{!0===d(t)?.retain&&h(t)&&u?.()},{type:"mqtt/subscribe",topic:`${l}/bridge/info`});"function"==typeof r&&b.push(r);const p=await o.call(e,t=>{if(!0===d(t)?.retain)return;const n=h(t);null!==n?n&&function(t){const n=d(t),e=n?.transaction??d(n?.data)?.transaction;return"string"==typeof e||"number"==typeof e?String(e):null}(n)===i&&f?.(n):c&&g?.(a("invalid_payload"))},{type:"mqtt/subscribe",topic:`${l}/bridge/response/networkmap`});"function"==typeof p&&b.push(p),await m(y,Math.min(4e3,Math.max(1,s-Date.now()))),c=!0,await t.callService("mqtt","publish",{topic:`${l}/bridge/request/networkmap`,payload:JSON.stringify({type:"raw",routes:!1,transaction:i}),qos:0,retain:!1});const v=await m(w,s-Date.now()),_=d(v)?.status;if(_&&"ok"!==_)throw a("provider");return n(v,l)}finally{for(const t of b)try{t()}catch{}}})}export{f as readZhaTopology,g as refreshZ2mTopology,u as subscribeZigbeeTopology,l as zigbeeTopologyRuntimeSnapshot}; globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="1ee973d11082b1a8d53ac3d7d98323bdf0e4137264a98f2a988610f6f244cb2c";import{n as t,b as n}from"./zigbee-topology-BXOYIu-9.js";import{aI as e}from"./houseplan-card-BObT7Q45.js";const o=new WeakMap;function i(t){const n=function(t){const n=t?.connection||t;return!n||"object"!=typeof n&&"function"!=typeof n?null:n}(t);if(!n)return null;let e=o.get(n);return e||(e={revision:0,topologies:[],states:{},listeners:new Set,inflight:new Map},o.set(n,e)),e}function r(t,n,e){t.states={...t.states,[n]:e},function(t){t.revision++;for(const n of t.listeners)n()}(t)}function s(t){const n=t?.code;if("permission"===n||"unsupported"===n||"timeout"===n||"invalid_topic"===n||"invalid_payload"===n)return n;const e=String(t?.message||"").toLowerCase();return e.includes("unauthor")||e.includes("permission")?"permission":e.includes("unknown_command")||e.includes("not found")?"unsupported":"provider"}function a(t){return Object.assign(new Error(t),{code:t})}function c(t,n,e){const o=t.inflight.get(n);if(o)return o;r(t,n,{phase:"loading"});const i=e().then(n=>{if(!n.nodes.length&&n.warnings.some(t=>"invalid_payload"===t.code))throw a("invalid_payload");!function(t,n){t.topologies=[...t.topologies.filter(t=>!(t.provider===n.provider&&t.instanceId===n.instanceId)),n],r(t,"zha"===n.provider?"zha":`z2m:${n.instanceId}`,{phase:"ready",obtainedAt:n.obtainedAt,partial:n.warnings.length>0})}(t,n)}).catch(e=>{r(t,n,{phase:"error",error:s(e)})}).finally(()=>t.inflight.delete(n));return t.inflight.set(n,i),i}function l(t){const n=i(t);return n?{revision:n.revision,topologies:n.topologies,states:n.states}:{revision:0,topologies:[],states:{}}}function u(t,n){const e=i(t);return e?(e.listeners.add(n),()=>e.listeners.delete(n)):()=>{}}function f(t){if(!0!==t?.user?.is_admin)throw a("permission")}function p(n){const e=i(n);return e?c(e,"zha",async()=>{if(f(n),"function"!=typeof n?.callWS)throw a("unsupported");return t(await n.callWS({type:"zha/devices"}))}):Promise.resolve()}function d(t){return null!==t&&"object"==typeof t?t:null}function h(t){const n=d(t),e=n?.payload??t;if("string"!=typeof e)return e;try{return JSON.parse(e)}catch{return null}}async function m(t,n){let e;try{return await Promise.race([t,new Promise((t,o)=>{e=globalThis.setTimeout(()=>o(a("timeout")),Math.max(1,n))})])}finally{void 0!==e&&globalThis.clearTimeout(e)}}function g(t,o,r=15e4){const s=i(t);if(!s)return Promise.resolve();const l=e(o);return c(s,`z2m:${l||String(o)}`,async()=>{if(f(t),!l)throw a("invalid_topic");const e=t.connection,o=e?.subscribeMessage;if("function"!=typeof o||"function"!=typeof t?.callService)throw a("unsupported");const i=function(){const t=globalThis.crypto;return"function"==typeof t?.randomUUID?`houseplan-${t.randomUUID()}`:`houseplan-${Date.now().toString(36)}-${Math.random().toString(36).slice(2)}`}(),s=Date.now()+Math.max(1,r);let c=!1,u=null,p=null,g=null;const y=new Promise(t=>{u=t}),w=new Promise((t,n)=>{p=t,g=n}),b=[];try{const r=await o.call(e,t=>{!0===d(t)?.retain&&h(t)&&u?.()},{type:"mqtt/subscribe",topic:`${l}/bridge/info`});"function"==typeof r&&b.push(r);const f=await o.call(e,t=>{if(!0===d(t)?.retain)return;const n=h(t);null!==n?n&&function(t){const n=d(t),e=n?.transaction??d(n?.data)?.transaction;return"string"==typeof e||"number"==typeof e?String(e):null}(n)===i&&p?.(n):c&&g?.(a("invalid_payload"))},{type:"mqtt/subscribe",topic:`${l}/bridge/response/networkmap`});"function"==typeof f&&b.push(f),await m(y,Math.min(4e3,Math.max(1,s-Date.now()))),c=!0,await t.callService("mqtt","publish",{topic:`${l}/bridge/request/networkmap`,payload:JSON.stringify({type:"raw",routes:!1,transaction:i}),qos:0,retain:!1});const v=await m(w,s-Date.now()),_=d(v)?.status;if(_&&"ok"!==_)throw a("provider");return n(v,l)}finally{for(const t of b)try{t()}catch{}}})}export{p as readZhaTopology,g as refreshZ2mTopology,u as subscribeZigbeeTopology,l as zigbeeTopologyRuntimeSnapshot};
@@ -1 +1 @@
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="2c4a9a013205eef84710c72e2eae1f8c307d94c84078490ecded141d206dd07d";try{await import("./houseplan-assets/houseplan-card-eH_pY1mf.js")}catch(e){if(!customElements.get("houseplan-card")){const l=String(navigator.language||"en").toLowerCase();const m=l.startsWith("ru")?"House Plan обновился — перезагрузите страницу (Ctrl+F5).":l.startsWith("de")?"House Plan wurde aktualisiert — bitte laden Sie die Seite neu (Strg+F5).":l.startsWith("fr")?"House Plan a été mis à jour — veuillez recharger la page (Ctrl+F5).":"House Plan was updated — please reload the page (Ctrl+F5).";customElements.define("houseplan-card",class extends HTMLElement{setConfig(){}getCardSize(){return 1}connectedCallback(){this.style.cssText="display:block;box-sizing:border-box;padding:16px;border:1px solid var(--divider-color,#e0e0e0);border-radius:var(--ha-card-border-radius,12px);background:var(--card-background-color,#fff);color:var(--primary-text-color,#212121);font:14px/1.4 var(--paper-font-body1_-_font-family,sans-serif)";this.textContent=m}})}console.error("[houseplan] stale houseplan-card.js: the implementation chunk is unavailable",e)} globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="1ee973d11082b1a8d53ac3d7d98323bdf0e4137264a98f2a988610f6f244cb2c";try{await import("./houseplan-assets/houseplan-card-BObT7Q45.js")}catch(e){if(!customElements.get("houseplan-card")){const l=String(navigator.language||"en").toLowerCase();const m=l.startsWith("ru")?"House Plan обновился — перезагрузите страницу (Ctrl+F5).":l.startsWith("de")?"House Plan wurde aktualisiert — bitte laden Sie die Seite neu (Strg+F5).":l.startsWith("fr")?"House Plan a été mis à jour — veuillez recharger la page (Ctrl+F5).":"House Plan was updated — please reload the page (Ctrl+F5).";customElements.define("houseplan-card",class extends HTMLElement{setConfig(){}getCardSize(){return 1}connectedCallback(){this.style.cssText="display:block;box-sizing:border-box;padding:16px;border:1px solid var(--divider-color,#e0e0e0);border-radius:var(--ha-card-border-radius,12px);background:var(--card-background-color,#fff);color:var(--primary-text-color,#212121);font:14px/1.4 var(--paper-font-body1_-_font-family,sans-serif)";this.textContent=m}})}console.error("[houseplan] stale houseplan-card.js: the implementation chunk is unavailable",e)}
File diff suppressed because one or more lines are too long
+17
View File
@@ -19,6 +19,23 @@ Discard and a clean close. It also fails on duplicate `hp-close` events,
external requests, WebSockets or browser errors. The ordinary native-fallback external requests, WebSockets or browser errors. The ordinary native-fallback
contract remains in `demo/smoke_dialog_modal_recovery.mjs`. contract remains in `demo/smoke_dialog_modal_recovery.mjs`.
Issue #609 uses that same unmodified pinned `ha-dialog` to verify the shared
settings-form shell rather than the close lifecycle:
```sh
npm run bundle:sync
node demo/verify_ha_form_shell_609.mjs --capture
```
It opens the real Room settings form and checks the settled WebAwesome surface:
560 px desktop width, the 940 px/viewport height cap, zero duplicate HA body
padding, one HA-owned scroller, a distinct form canvas, footer containment and
edge-to-edge layouts at 480×800 and 390×844. It also keeps HA's own fullscreen
behaviour for a 1280×480 viewport. `--capture` writes the two reviewed diagnostic
images under `docs/design/600-settings-dialogs/pairs/`; without it the command
is read-only. The fast Validate witness is
`demo/smoke_ha_form_shell_parity.mjs`; neither diagnostic is a golden producer.
From a checkout with the usual `npm ci` dependencies and Playwright Chromium: From a checkout with the usual `npm ci` dependencies and Playwright Chromium:
```sh ```sh
+137
View File
@@ -0,0 +1,137 @@
// #609: cheap HA-branch contract for the shared settings form shell.
//
// The explicit verify_ha_form_shell_609.mjs diagnostic loads the pinned real
// HA frontend. Validate needs a fast deterministic witness too, so this stub
// consumes only the same public ha-dialog CSS variables and reproduces HA's
// body scroller plus its width/height fullscreen breakpoints.
import { launch, checkAll, finish } from './serve.mjs';
const HA_DIALOG_STUB = String.raw`
class HaDialog609 extends HTMLElement {
constructor() {
super();
this._open = false;
this.attachShadow({ mode: 'open' }).innerHTML = '<style>'
+ ':host{display:contents}'
+ 'dialog{position:fixed;inset:0;margin:auto;box-sizing:border-box;'
+ 'width:var(--ha-dialog-width-full,min(var(--ha-dialog-width-md,580px),calc(100vw - 48px)));max-width:none;'
+ 'min-height:var(--ha-dialog-min-height,0);max-height:var(--ha-dialog-max-height,calc(100dvh - 80px));'
+ 'padding:0;border:0;border-radius:var(--ha-dialog-border-radius,12px);'
+ 'background:var(--dialog-surface-background,#fff);display:flex;flex-direction:column;overflow:hidden}'
+ '.header{flex:none;height:68px;display:flex;align-items:center;padding:0 16px}'
+ '.body{flex:1 1 auto;min-height:0;padding:var(--dialog-content-padding,12px);overflow:auto}'
+ '.footer{flex:none;display:flex;padding:12px 16px 16px}'
+ '@media (max-width:450px),(max-height:500px){dialog{width:100vw;min-height:100dvh;max-height:100dvh}}'
+ '</style><dialog><div class="header"><slot name="headerTitle"></slot></div>'
+ '<div class="body"><slot></slot></div><div class="footer"><slot name="footer"></slot></div></dialog>';
}
get open() { return this._open; }
set open(value) { this._open = Boolean(value); this._sync(); }
connectedCallback() { this._sync(); }
_sync() {
const dialog = this.shadowRoot.querySelector('dialog');
if (!this.isConnected || !dialog) return;
if (this._open && !dialog.open) {
dialog.showModal();
queueMicrotask(() => this.dispatchEvent(new Event('opened')));
} else if (!this._open && dialog.open) {
dialog.close();
queueMicrotask(() => this.dispatchEvent(new Event('closed')));
}
}
}
customElements.define('ha-dialog', HaDialog609);
`;
const { page, browser } = await launch({ width: 1600, height: 1000 });
const setup = await page.evaluate(async (stub) => {
// eslint-disable-next-line no-new-func
new Function(stub)();
const root = window.__card.shadowRoot || window.__card.renderRoot;
const kinds = ['space', 'settings', 'room', 'marker', 'onboarding'];
for (const kind of kinds) {
const shell = document.createElement('hp-dialog');
shell.dataset.kind = kind;
shell.setAttribute('form-shell', '');
shell.wide = true;
shell.title = `${kind} settings`;
shell.innerHTML = `<div class="hpf-form body"><section class="hpf-card" style="height:1200px">${kind}</section></div>`
+ '<div slot="footer"><button>Cancel</button><button>Save</button></div>';
root.append(shell);
await shell.updateComplete;
}
const generic = document.createElement('hp-dialog');
generic.dataset.kind = 'generic-negative-control';
generic.wide = true;
generic.title = 'Generic dialog';
generic.innerHTML = '<div style="height:1200px">Generic</div><button slot="footer">Close</button>';
root.append(generic);
await generic.updateComplete;
await new Promise((resolve) => requestAnimationFrame(() => requestAnimationFrame(resolve)));
return { formCount: kinds.length };
}, HA_DIALOG_STUB);
const inspect = () => page.evaluate(() => {
const root = window.__card.shadowRoot || window.__card.renderRoot;
const read = (shell) => {
const ha = shell.shadowRoot.querySelector('ha-dialog');
const panel = ha.shadowRoot.querySelector('dialog');
const haBody = ha.shadowRoot.querySelector('.body');
const formBody = shell.querySelector('.body');
const footer = shell.querySelector('[slot="footer"]');
const box = panel.getBoundingClientRect();
const footerBox = footer?.getBoundingClientRect();
return {
width: box.width,
height: box.height,
radius: getComputedStyle(panel).borderRadius,
haPadding: getComputedStyle(haBody).padding,
haOverflow: getComputedStyle(haBody).overflowY,
haScrolls: haBody.scrollHeight > haBody.clientHeight,
formOverflow: formBody ? getComputedStyle(formBody).overflowY : null,
formBackground: formBody ? getComputedStyle(formBody).backgroundColor : null,
surfaceBackground: getComputedStyle(panel).backgroundColor,
footerInside: !footerBox || footerBox.bottom <= box.bottom + 1,
noHorizontalOverflow: panel.scrollWidth <= panel.clientWidth + 1,
};
};
const forms = [...root.querySelectorAll('hp-dialog[form-shell]')].map(read);
const generic = root.querySelector('hp-dialog[data-kind="generic-negative-control"]');
const genericPanel = generic.shadowRoot.querySelector('ha-dialog').shadowRoot.querySelector('dialog');
return { forms, genericWidth: genericPanel.getBoundingClientRect().width };
});
const desktop = await inspect();
await page.setViewportSize({ width: 480, height: 800 });
await page.waitForTimeout(40);
const edge480 = await inspect();
await page.setViewportSize({ width: 390, height: 844 });
await page.waitForTimeout(40);
const mobile390 = await inspect();
await page.setViewportSize({ width: 1280, height: 480 });
await page.waitForTimeout(40);
const shortViewport = await inspect();
const every = (items, predicate) => items.length === setup.formCount && items.every(predicate);
checkAll({
fiveSharedConsumersExercised: setup.formCount === 5 && desktop.forms.length === 5,
desktopWidth560: every(desktop.forms, (item) => Math.abs(item.width - 560) <= 1),
desktopHeightCappedAt940: every(desktop.forms, (item) => item.height <= 941),
oneHaScrollerWithoutDoublePadding: every(desktop.forms, (item) => item.haPadding === '0px'
&& item.haOverflow === 'auto' && item.haScrolls && item.formOverflow === 'visible'),
canvasSurroundsDistinctSurface: every(desktop.forms, (item) => item.formBackground !== 'rgba(0, 0, 0, 0)'
&& item.formBackground !== item.surfaceBackground),
desktopFooterInside: every(desktop.forms, (item) => item.footerInside),
genericWideDialogUnchanged: Math.abs(desktop.genericWidth - 580) <= 1,
edge480IsFullscreen: every(edge480.forms, (item) => Math.abs(item.width - 480) <= 1
&& Math.abs(item.height - 800) <= 1 && item.radius === '0px'
&& item.noHorizontalOverflow && item.footerInside),
mobile390IsFullscreen: every(mobile390.forms, (item) => Math.abs(item.width - 390) <= 1
&& Math.abs(item.height - 844) <= 1 && item.radius === '0px'
&& item.noHorizontalOverflow && item.footerInside),
shortHaViewportKeepsFullscreen: every(shortViewport.forms, (item) => Math.abs(item.height - 480) <= 1
&& item.radius === '0px' && item.footerInside),
});
await finish(browser, { desktop, edge480, mobile390, shortViewport });
+183
View File
@@ -0,0 +1,183 @@
// #609: explicit authentic Home Assistant form-shell diagnostic. This is not
// a regular smoke: it loads the pinned official HA frontend, opens the real
// Room settings form, and verifies the public ha-dialog geometry on desktop
// and both sides of HA's built-in 450 px mobile breakpoint.
import assert from 'node:assert/strict';
import { join } from 'node:path';
import { fileURLToPath } from 'node:url';
import { assertFreshDemoBundle } from './bundle-freshness.mjs';
import { launchHaDialogFixture } from './helpers/ha-dialog-fixture.mjs';
const capture = process.argv.includes('--capture');
const pairDir = fileURLToPath(new URL('../docs/design/600-settings-dialogs/pairs/', import.meta.url));
const fixture = await launchHaDialogFixture({
authentic: true,
viewport: { width: 1600, height: 1000 },
});
const { page } = fixture;
const settle = async () => {
await page.evaluate(async () => {
const card = window.__card;
await card.updateComplete;
const shell = card.shadowRoot.querySelector('hp-dialog[data-kind="room"]');
if (shell) await shell.updateComplete;
await new Promise((resolve) => requestAnimationFrame(() => requestAnimationFrame(resolve)));
});
// Authentic WebAwesome applies a 200 ms show transform; geometry captured
// during it is intentionally smaller than the settled dialog surface.
await page.waitForTimeout(250);
};
const inspect = async () => page.evaluate(() => {
const card = window.__card;
const shell = card.shadowRoot.querySelector('hp-dialog[data-kind="room"]');
const ha = shell?.shadowRoot.querySelector('ha-dialog');
const wa = ha?.shadowRoot.querySelector('wa-dialog');
const panel = wa?.shadowRoot.querySelector('dialog');
const haBody = ha?.shadowRoot.querySelector('.body');
const formBody = shell?.querySelector('.body');
const formCard = shell?.querySelector('.hpf-card');
const footer = shell?.querySelector('[slot="footer"]');
if (!panel || !haBody || !formBody || !formCard || !footer) {
return { missing: { shell: !!shell, ha: !!ha, wa: !!wa, panel: !!panel,
haBody: !!haBody, formBody: !!formBody, formCard: !!formCard, footer: !!footer } };
}
const rect = (node) => {
const value = node.getBoundingClientRect();
return { x: value.x, y: value.y, width: value.width, height: value.height,
right: value.right, bottom: value.bottom };
};
const panelStyle = getComputedStyle(panel);
const haStyle = getComputedStyle(ha);
const haBodyStyle = getComputedStyle(haBody);
const formBodyStyle = getComputedStyle(formBody);
const cardStyle = getComputedStyle(formCard);
const panelBox = panel.getBoundingClientRect();
const overflowNodes = [];
const visit = (root) => {
for (const node of root.querySelectorAll('*')) {
const box = node.getBoundingClientRect();
// wa-dialog itself stays in document flow at the demo host's 8 px page
// inset; its rendered native dialog is fixed and is the geometry users see.
if (node.localName !== 'wa-dialog' && box.width > 0
&& (box.left < panelBox.left - 1 || box.right > panelBox.right + 1)) {
overflowNodes.push({ tag: node.localName, id: node.id, className: String(node.className || ''),
left: box.left, right: box.right, width: box.width });
}
if (node.shadowRoot) visit(node.shadowRoot);
}
};
visit(shell);
visit(shell.shadowRoot);
return {
viewport: { width: innerWidth, height: innerHeight },
panel: rect(panel), haBody: rect(haBody), formBody: rect(formBody), footer: rect(footer),
panelBorderRadius: panelStyle.borderRadius,
haBodyPadding: haBodyStyle.padding,
dialogContentPadding: {
shell: getComputedStyle(shell).getPropertyValue('--dialog-content-padding').trim(),
ha: haStyle.getPropertyValue('--dialog-content-padding').trim(),
body: haBodyStyle.getPropertyValue('--dialog-content-padding').trim(),
},
haBodyOverflowY: haBodyStyle.overflowY,
haBodyScroll: [haBody.scrollHeight, haBody.clientHeight],
formBodyOverflowY: formBodyStyle.overflowY,
formBodyBackground: formBodyStyle.backgroundColor,
cardBackground: cardStyle.backgroundColor,
horizontalOverflow: overflowNodes.length > 0,
documentWidth: [document.documentElement.scrollWidth, document.body.scrollWidth],
overflowNodes: overflowNodes.slice(0, 20),
};
});
const clipPanel = async (name, state) => {
if (!capture) return;
const clip = {
x: Math.max(0, state.panel.x),
y: Math.max(0, state.panel.y),
width: Math.min(state.viewport.width, state.panel.width),
height: Math.min(state.viewport.height, state.panel.height),
};
await page.screenshot({ path: join(pairDir, name), clip });
};
try {
await page.goto(`${fixture.url}/product.html`);
await page.waitForFunction(() => window.__card?._model?.length > 0
&& window.__card?._booting === false);
await assertFreshDemoBundle(page);
await page.evaluate(async () => {
const card = window.__card;
if (card._ensureEditorRuntime && !await card._ensureEditorRuntime()) {
throw new Error('Editor runtime failed to load');
}
card._openRoomEdit(card._curSpaceCfg.rooms[0]);
card.requestUpdate();
await card.updateComplete;
});
await page.waitForFunction(() => {
const shell = window.__card.shadowRoot.querySelector('hp-dialog[data-kind="room"]');
const ha = shell?.shadowRoot.querySelector('ha-dialog');
return ha?.open === true
&& ha.shadowRoot.querySelector('wa-dialog')?.shadowRoot.querySelector('dialog')?.matches(':modal');
});
await settle();
const desktop = await inspect();
assert.equal(desktop.missing, undefined, JSON.stringify(desktop.missing));
assert.ok(Math.abs(desktop.panel.width - 560) <= 1, `desktop width ${desktop.panel.width}`);
assert.ok(desktop.panel.height <= 941 && desktop.panel.height <= desktop.viewport.height - 47,
`desktop height ${desktop.panel.height}`);
if (desktop.haBodyPadding !== '0px') console.error(JSON.stringify(desktop, null, 2));
assert.equal(desktop.haBodyPadding, '0px', JSON.stringify(desktop.dialogContentPadding));
assert.equal(desktop.haBodyOverflowY, 'auto');
assert.equal(desktop.formBodyOverflowY, 'visible');
assert.notEqual(desktop.formBodyBackground, desktop.cardBackground);
assert.ok(desktop.haBodyScroll[0] > desktop.haBodyScroll[1], `desktop scroll ${desktop.haBodyScroll}`);
assert.ok(desktop.footer.bottom <= desktop.panel.bottom + 1);
await clipPanel('room-ha-light.png', desktop);
await page.setViewportSize({ width: 480, height: 800 });
await settle();
const edge = await inspect();
assert.ok(Math.abs(edge.panel.width - 480) <= 1, `480px width ${edge.panel.width}`);
assert.ok(Math.abs(edge.panel.height - 800) <= 1, `480px height ${edge.panel.height}`);
assert.equal(edge.panelBorderRadius, '0px');
if (edge.horizontalOverflow) console.error(JSON.stringify(edge, null, 2));
assert.equal(edge.horizontalOverflow, false);
assert.ok(edge.footer.bottom <= edge.panel.bottom + 1);
await page.setViewportSize({ width: 390, height: 844 });
await settle();
const mobile = await inspect();
assert.ok(Math.abs(mobile.panel.width - 390) <= 1, `390px width ${mobile.panel.width}`);
assert.ok(Math.abs(mobile.panel.height - 844) <= 1, `390px height ${mobile.panel.height}`);
assert.equal(mobile.panelBorderRadius, '0px');
assert.equal(mobile.horizontalOverflow, false);
assert.ok(mobile.footer.bottom <= mobile.panel.bottom + 1);
await clipPanel('room-ha-mobile-light.png', mobile);
await page.setViewportSize({ width: 1280, height: 480 });
await settle();
const short = await inspect();
assert.ok(Math.abs(short.panel.height - 480) <= 1, `short HA fullscreen height ${short.panel.height}`);
assert.equal(short.panelBorderRadius, '0px');
await fixture.assertClean();
console.log(JSON.stringify({
issue: 609,
authenticHaFrontend: fixture.provenance,
capture,
desktop,
edge480: edge,
mobile390: mobile,
shortViewport: short,
pageErrors: fixture.errors,
externalRequests: fixture.externalRequests,
websocketAttempts: fixture.websocketAttempts,
}, null, 2));
console.log('OK');
} finally {
await fixture.close();
}
+143 -143
View File
@@ -1,127 +1,127 @@
{ {
"schema": 1, "schema": 1,
"fingerprint": "2c4a9a013205eef84710c72e2eae1f8c307d94c84078490ecded141d206dd07d", "fingerprint": "1ee973d11082b1a8d53ac3d7d98323bdf0e4137264a98f2a988610f6f244cb2c",
"entry": "houseplan-card.js", "entry": "houseplan-card.js",
"panelEntry": "houseplan-panel.js", "panelEntry": "houseplan-panel.js",
"initialViewFiles": [ "initialViewFiles": [
"houseplan-assets/houseplan-card-eH_pY1mf.js", "houseplan-assets/houseplan-card-BObT7Q45.js",
"houseplan-card.js" "houseplan-card.js"
], ],
"initialViewGzipBytes": 290284, "initialViewGzipBytes": 290460,
"initialPanelFiles": [ "initialPanelFiles": [
"houseplan-assets/houseplan-card-eH_pY1mf.js", "houseplan-assets/houseplan-card-BObT7Q45.js",
"houseplan-panel.js" "houseplan-panel.js"
], ],
"initialPanelGzipBytes": 291805, "initialPanelGzipBytes": 291983,
"initialPanelOnlyFiles": [ "initialPanelOnlyFiles": [
"houseplan-panel.js" "houseplan-panel.js"
], ],
"initialPanelOnlyGzipBytes": 2322, "initialPanelOnlyGzipBytes": 2327,
"lazyFiles": [ "lazyFiles": [
"houseplan-assets/backdrop-pick-2vyBBTgG.js", "houseplan-assets/backdrop-pick-BBzikKL2.js",
"houseplan-assets/de-Bc8aNiKQ.js", "houseplan-assets/de-CvJX0Ow9.js",
"houseplan-assets/editor-v1zFPTHb.js", "houseplan-assets/editor-DEOW1N-C.js",
"houseplan-assets/form-kit.styles-XjSspVjk.js", "houseplan-assets/form-kit.styles-J0n2asaU.js",
"houseplan-assets/fr-DClCaTp6.js", "houseplan-assets/fr-DZUVGtpd.js",
"houseplan-assets/furniture-plan-art.generated-BQJxPKO5.js", "houseplan-assets/furniture-plan-art.generated-DUVSzIvq.js",
"houseplan-assets/houseplan-editor-runtime-DazlWcYl.js", "houseplan-assets/houseplan-editor-runtime-tbnt9LnD.js",
"houseplan-assets/houseplan-onboarding-runtime-j98hXPrW.js", "houseplan-assets/houseplan-onboarding-runtime-86SoSEFc.js",
"houseplan-assets/hp-zigbee-topology-overlay-BIunREL3.js", "houseplan-assets/hp-zigbee-topology-overlay-DJtHrXPE.js",
"houseplan-assets/iso-scene-render-Byk9ZXv9.js", "houseplan-assets/iso-scene-render-B6Aks3Kq.js",
"houseplan-assets/live-interaction-runtime-DjzpPNim.js", "houseplan-assets/live-interaction-runtime-D4mOBGpd.js",
"houseplan-assets/pdf-export-DhvYHpHG.js", "houseplan-assets/pdf-export-f90A6VCG.js",
"houseplan-assets/summary-panel-runtime-loaded-C750G8Rx.js", "houseplan-assets/summary-panel-runtime-loaded-CZlfz0Xl.js",
"houseplan-assets/zigbee-topology-B35vLrYp.js", "houseplan-assets/zigbee-topology-BXOYIu-9.js",
"houseplan-assets/zigbee-topology-runtime-hsXdTYOk.js" "houseplan-assets/zigbee-topology-runtime-tN_qTU1Q.js"
], ],
"lazyGzipBytes": 459905, "lazyGzipBytes": 459952,
"lazyEditorFiles": [ "lazyEditorFiles": [
"houseplan-assets/backdrop-pick-2vyBBTgG.js", "houseplan-assets/backdrop-pick-BBzikKL2.js",
"houseplan-assets/editor-v1zFPTHb.js", "houseplan-assets/editor-DEOW1N-C.js",
"houseplan-assets/form-kit.styles-XjSspVjk.js", "houseplan-assets/form-kit.styles-J0n2asaU.js",
"houseplan-assets/furniture-plan-art.generated-BQJxPKO5.js", "houseplan-assets/furniture-plan-art.generated-DUVSzIvq.js",
"houseplan-assets/houseplan-editor-runtime-DazlWcYl.js", "houseplan-assets/houseplan-editor-runtime-tbnt9LnD.js",
"houseplan-assets/zigbee-topology-B35vLrYp.js" "houseplan-assets/zigbee-topology-BXOYIu-9.js"
], ],
"lazyEditorGzipBytes": 243361, "lazyEditorGzipBytes": 243377,
"lazyOnboardingFiles": [ "lazyOnboardingFiles": [
"houseplan-assets/backdrop-pick-2vyBBTgG.js", "houseplan-assets/backdrop-pick-BBzikKL2.js",
"houseplan-assets/form-kit.styles-XjSspVjk.js", "houseplan-assets/form-kit.styles-J0n2asaU.js",
"houseplan-assets/houseplan-onboarding-runtime-j98hXPrW.js" "houseplan-assets/houseplan-onboarding-runtime-86SoSEFc.js"
], ],
"lazyOnboardingGzipBytes": 33813, "lazyOnboardingGzipBytes": 33822,
"lazyLocaleFiles": [ "lazyLocaleFiles": [
"houseplan-assets/de-Bc8aNiKQ.js", "houseplan-assets/de-CvJX0Ow9.js",
"houseplan-assets/fr-DClCaTp6.js" "houseplan-assets/fr-DZUVGtpd.js"
], ],
"lazyLocaleGzipBytes": 55371, "lazyLocaleGzipBytes": 55376,
"lazyIsometricFiles": [ "lazyIsometricFiles": [
"houseplan-assets/iso-scene-render-Byk9ZXv9.js" "houseplan-assets/iso-scene-render-B6Aks3Kq.js"
], ],
"lazyIsometricGzipBytes": 17639, "lazyIsometricGzipBytes": 17643,
"lazyFurnitureArtFiles": [ "lazyFurnitureArtFiles": [
"houseplan-assets/furniture-plan-art.generated-BQJxPKO5.js" "houseplan-assets/furniture-plan-art.generated-DUVSzIvq.js"
], ],
"lazyFurnitureArtGzipBytes": 16939, "lazyFurnitureArtGzipBytes": 16939,
"lazyPdfFiles": [ "lazyPdfFiles": [
"houseplan-assets/furniture-plan-art.generated-BQJxPKO5.js", "houseplan-assets/furniture-plan-art.generated-DUVSzIvq.js",
"houseplan-assets/pdf-export-DhvYHpHG.js" "houseplan-assets/pdf-export-f90A6VCG.js"
], ],
"lazyPdfGzipBytes": 126825, "lazyPdfGzipBytes": 126826,
"files": [ "files": [
{ {
"path": "houseplan-assets/backdrop-pick-2vyBBTgG.js", "path": "houseplan-assets/backdrop-pick-BBzikKL2.js",
"sha256": "5c1f5f3ac1132cc5970ade27d6797a2674d90945b3567b6b204990b55d394103", "sha256": "89ccbfee082a908b4d357c0d1190e2bf341b0358475b773efb330e49b0f1886f",
"rawBytes": 74076, "rawBytes": 74076,
"gzipBytes": 23929, "gzipBytes": 23933,
"isEntry": false, "isEntry": false,
"imports": [ "imports": [
"houseplan-assets/form-kit.styles-XjSspVjk.js", "houseplan-assets/form-kit.styles-J0n2asaU.js",
"houseplan-assets/houseplan-card-eH_pY1mf.js" "houseplan-assets/houseplan-card-BObT7Q45.js"
], ],
"dynamicImports": [] "dynamicImports": []
}, },
{ {
"path": "houseplan-assets/de-Bc8aNiKQ.js", "path": "houseplan-assets/de-CvJX0Ow9.js",
"sha256": "23a420015836d2cb9dba5bb19349bf2b67f2cf5ed08d4ae77ebbde0cd661baa9", "sha256": "62d35a977800def77047c802e5509342fb52aa96bfab819b69ab7c6fcba25732",
"rawBytes": 92496, "rawBytes": 92496,
"gzipBytes": 27928, "gzipBytes": 27932,
"isEntry": false, "isEntry": false,
"imports": [], "imports": [],
"dynamicImports": [] "dynamicImports": []
}, },
{ {
"path": "houseplan-assets/editor-v1zFPTHb.js", "path": "houseplan-assets/editor-DEOW1N-C.js",
"sha256": "73af9764e3cba343dafc00d13696a3154255ef7f4cb0993f2fefc37ee40c01e8", "sha256": "356e862c4531fec75731b6514e3915e0531954d93e9d2a012ebac3f65765c107",
"rawBytes": 3833, "rawBytes": 3833,
"gzipBytes": 1581, "gzipBytes": 1585,
"isEntry": false, "isEntry": false,
"imports": [ "imports": [
"houseplan-assets/houseplan-card-eH_pY1mf.js" "houseplan-assets/houseplan-card-BObT7Q45.js"
], ],
"dynamicImports": [] "dynamicImports": []
}, },
{ {
"path": "houseplan-assets/form-kit.styles-XjSspVjk.js", "path": "houseplan-assets/form-kit.styles-J0n2asaU.js",
"sha256": "c6f912fabc6288e8f84712cd3ebaf3bfd6c9ab821f511e0b977ef28f0f235ed3", "sha256": "f95006c96a719b7ef5cce919d3afb4d851a21f88e7ae05964624d35228076cb9",
"rawBytes": 25600, "rawBytes": 25600,
"gzipBytes": 5055, "gzipBytes": 5057,
"isEntry": false, "isEntry": false,
"imports": [], "imports": [],
"dynamicImports": [] "dynamicImports": []
}, },
{ {
"path": "houseplan-assets/fr-DClCaTp6.js", "path": "houseplan-assets/fr-DZUVGtpd.js",
"sha256": "4c0e753ff9ae5160f0b702eeaa152ffa7462e96e888115e38ae33bac95bd8544", "sha256": "97ec4f07911fd1b3bd87f1e3c7a23695dbdb144ff2ffb871d51120cdf94d801b",
"rawBytes": 94813, "rawBytes": 94813,
"gzipBytes": 27443, "gzipBytes": 27444,
"isEntry": false, "isEntry": false,
"imports": [], "imports": [],
"dynamicImports": [] "dynamicImports": []
}, },
{ {
"path": "houseplan-assets/furniture-plan-art.generated-BQJxPKO5.js", "path": "houseplan-assets/furniture-plan-art.generated-DUVSzIvq.js",
"sha256": "b293b18c355818c7f51e25562428643d9c524d217fd78fca675be1a2a792b0bc", "sha256": "d99385353bbbb5473838377cc98ce0e87b9767588faa09bcc6897c73a2bca826",
"rawBytes": 52035, "rawBytes": 52035,
"gzipBytes": 16939, "gzipBytes": 16939,
"isEntry": false, "isEntry": false,
@@ -129,184 +129,184 @@
"dynamicImports": [] "dynamicImports": []
}, },
{ {
"path": "houseplan-assets/houseplan-card-eH_pY1mf.js", "path": "houseplan-assets/houseplan-card-BObT7Q45.js",
"sha256": "e5b871748b29287d7c0e66fa30e7fc81cbd96715b839aee4e426885bd998c626", "sha256": "26c0b9d45bb404e6cf448cd8c7ac03a4a91371782bb8121460b4a30c04a40049",
"rawBytes": 1029393, "rawBytes": 1030217,
"gzipBytes": 289483, "gzipBytes": 289656,
"isEntry": false, "isEntry": false,
"imports": [], "imports": [],
"dynamicImports": [ "dynamicImports": [
"houseplan-assets/de-Bc8aNiKQ.js", "houseplan-assets/de-CvJX0Ow9.js",
"houseplan-assets/editor-v1zFPTHb.js", "houseplan-assets/editor-DEOW1N-C.js",
"houseplan-assets/fr-DClCaTp6.js", "houseplan-assets/fr-DZUVGtpd.js",
"houseplan-assets/furniture-plan-art.generated-BQJxPKO5.js", "houseplan-assets/furniture-plan-art.generated-DUVSzIvq.js",
"houseplan-assets/houseplan-editor-runtime-DazlWcYl.js", "houseplan-assets/houseplan-editor-runtime-tbnt9LnD.js",
"houseplan-assets/houseplan-onboarding-runtime-j98hXPrW.js", "houseplan-assets/houseplan-onboarding-runtime-86SoSEFc.js",
"houseplan-assets/hp-zigbee-topology-overlay-BIunREL3.js", "houseplan-assets/hp-zigbee-topology-overlay-DJtHrXPE.js",
"houseplan-assets/iso-scene-render-Byk9ZXv9.js", "houseplan-assets/iso-scene-render-B6Aks3Kq.js",
"houseplan-assets/live-interaction-runtime-DjzpPNim.js", "houseplan-assets/live-interaction-runtime-D4mOBGpd.js",
"houseplan-assets/pdf-export-DhvYHpHG.js", "houseplan-assets/pdf-export-f90A6VCG.js",
"houseplan-assets/summary-panel-runtime-loaded-C750G8Rx.js" "houseplan-assets/summary-panel-runtime-loaded-CZlfz0Xl.js"
] ]
}, },
{ {
"path": "houseplan-assets/houseplan-editor-runtime-DazlWcYl.js", "path": "houseplan-assets/houseplan-editor-runtime-tbnt9LnD.js",
"sha256": "6515e98e1c7d594e6c2943871a906b5a1a0762092e5a4cbfec0470e07863d659", "sha256": "1e3621aa6e07d683bd4564e13fd28aafe905c2663fcd4d1387e8d4ed9d172474",
"rawBytes": 677705, "rawBytes": 677705,
"gzipBytes": 188433, "gzipBytes": 188436,
"isEntry": false, "isEntry": false,
"imports": [ "imports": [
"houseplan-assets/backdrop-pick-2vyBBTgG.js", "houseplan-assets/backdrop-pick-BBzikKL2.js",
"houseplan-assets/form-kit.styles-XjSspVjk.js", "houseplan-assets/form-kit.styles-J0n2asaU.js",
"houseplan-assets/furniture-plan-art.generated-BQJxPKO5.js", "houseplan-assets/furniture-plan-art.generated-DUVSzIvq.js",
"houseplan-assets/houseplan-card-eH_pY1mf.js", "houseplan-assets/houseplan-card-BObT7Q45.js",
"houseplan-assets/zigbee-topology-B35vLrYp.js" "houseplan-assets/zigbee-topology-BXOYIu-9.js"
], ],
"dynamicImports": [ "dynamicImports": [
"houseplan-assets/zigbee-topology-runtime-hsXdTYOk.js" "houseplan-assets/zigbee-topology-runtime-tN_qTU1Q.js"
] ]
}, },
{ {
"path": "houseplan-assets/houseplan-onboarding-runtime-j98hXPrW.js", "path": "houseplan-assets/houseplan-onboarding-runtime-86SoSEFc.js",
"sha256": "6a7765d125bedbb22df7276f80f59bb5156cba93e86d4fb75adaac9c7574d4ea", "sha256": "f717ed132f519053820b921188e8c54c0b9489f22d1a71293fb7f4ffb74069dc",
"rawBytes": 15667, "rawBytes": 15667,
"gzipBytes": 4829, "gzipBytes": 4832,
"isEntry": false, "isEntry": false,
"imports": [ "imports": [
"houseplan-assets/backdrop-pick-2vyBBTgG.js", "houseplan-assets/backdrop-pick-BBzikKL2.js",
"houseplan-assets/form-kit.styles-XjSspVjk.js", "houseplan-assets/form-kit.styles-J0n2asaU.js",
"houseplan-assets/houseplan-card-eH_pY1mf.js" "houseplan-assets/houseplan-card-BObT7Q45.js"
], ],
"dynamicImports": [] "dynamicImports": []
}, },
{ {
"path": "houseplan-assets/hp-zigbee-topology-overlay-BIunREL3.js", "path": "houseplan-assets/hp-zigbee-topology-overlay-DJtHrXPE.js",
"sha256": "8342c4c8f8b62e5caf311c5088fc817246a808bee1de871969a5760d9d11070c", "sha256": "643cf04bb44044dab3a4d831e4866a118e76c796bd3913cba34c0a4927233777",
"rawBytes": 10759, "rawBytes": 10759,
"gzipBytes": 3683, "gzipBytes": 3687,
"isEntry": false, "isEntry": false,
"imports": [ "imports": [
"houseplan-assets/houseplan-card-eH_pY1mf.js", "houseplan-assets/houseplan-card-BObT7Q45.js",
"houseplan-assets/zigbee-topology-B35vLrYp.js", "houseplan-assets/zigbee-topology-BXOYIu-9.js",
"houseplan-assets/zigbee-topology-runtime-hsXdTYOk.js" "houseplan-assets/zigbee-topology-runtime-tN_qTU1Q.js"
], ],
"dynamicImports": [] "dynamicImports": []
}, },
{ {
"path": "houseplan-assets/iso-scene-render-Byk9ZXv9.js", "path": "houseplan-assets/iso-scene-render-B6Aks3Kq.js",
"sha256": "2888754263d7837c59f98c267156ac601611915c53f31d6d8ba14e1656417afb", "sha256": "7fb99a44f111f3108873c466ac7a0f82f23126ca0939bb279420cda3f49891a0",
"rawBytes": 51983, "rawBytes": 51983,
"gzipBytes": 17639, "gzipBytes": 17643,
"isEntry": false, "isEntry": false,
"imports": [ "imports": [
"houseplan-assets/houseplan-card-eH_pY1mf.js" "houseplan-assets/houseplan-card-BObT7Q45.js"
], ],
"dynamicImports": [] "dynamicImports": []
}, },
{ {
"path": "houseplan-assets/live-interaction-runtime-DjzpPNim.js", "path": "houseplan-assets/live-interaction-runtime-D4mOBGpd.js",
"sha256": "56c243a0be7558428fcd7351a903aef112e9e3c8054a43daf180b90e225e2826", "sha256": "d72307dc5213fd81105682bd3cb99bdfe5ab667f3cd708981129e1e68412e80e",
"rawBytes": 8216, "rawBytes": 8216,
"gzipBytes": 3204, "gzipBytes": 3210,
"isEntry": false, "isEntry": false,
"imports": [ "imports": [
"houseplan-assets/houseplan-card-eH_pY1mf.js" "houseplan-assets/houseplan-card-BObT7Q45.js"
], ],
"dynamicImports": [] "dynamicImports": []
}, },
{ {
"path": "houseplan-assets/pdf-export-DhvYHpHG.js", "path": "houseplan-assets/pdf-export-f90A6VCG.js",
"sha256": "ae0e8f7a914fc3034f73c5e0128515019849a373f0a184864f6cd91ffdf0211f", "sha256": "6a7f3d4705720cc9a92a1887fae7e88b1de14a809d61a6360db095570869af37",
"rawBytes": 236264, "rawBytes": 236264,
"gzipBytes": 109886, "gzipBytes": 109887,
"isEntry": false, "isEntry": false,
"imports": [ "imports": [
"houseplan-assets/furniture-plan-art.generated-BQJxPKO5.js", "houseplan-assets/furniture-plan-art.generated-DUVSzIvq.js",
"houseplan-assets/houseplan-card-eH_pY1mf.js" "houseplan-assets/houseplan-card-BObT7Q45.js"
], ],
"dynamicImports": [] "dynamicImports": []
}, },
{ {
"path": "houseplan-assets/summary-panel-editor-D6jtLpQ8.js", "path": "houseplan-assets/summary-panel-editor-DGDH1Z-d.js",
"sha256": "141837c9947c69b51b7f870afc1bb050372c7f26fb36d1ea6fe7a9e1073913ab", "sha256": "a3e3731628c6d0edbc5913180c5d143c7d6d3554cf9af074465d81c88f3b787b",
"rawBytes": 14862, "rawBytes": 14862,
"gzipBytes": 3424, "gzipBytes": 3426,
"isEntry": false, "isEntry": false,
"imports": [ "imports": [
"houseplan-assets/form-kit.styles-XjSspVjk.js", "houseplan-assets/form-kit.styles-J0n2asaU.js",
"houseplan-assets/houseplan-card-eH_pY1mf.js", "houseplan-assets/houseplan-card-BObT7Q45.js",
"houseplan-assets/summary-panel-runtime-loaded-C750G8Rx.js" "houseplan-assets/summary-panel-runtime-loaded-CZlfz0Xl.js"
], ],
"dynamicImports": [] "dynamicImports": []
}, },
{ {
"path": "houseplan-assets/summary-panel-metrics-lT9wi_mo.js", "path": "houseplan-assets/summary-panel-metrics-CRnKPnjo.js",
"sha256": "f21e7ab3dec25618eab55cca71fd9635583941673e402af8091b344a18ec0f26", "sha256": "7d9aa0f49312f3602eefaa33b95a6d64da3c982f3485026e6ed2218de0d6aaa6",
"rawBytes": 2611, "rawBytes": 2611,
"gzipBytes": 1305, "gzipBytes": 1310,
"isEntry": false, "isEntry": false,
"imports": [ "imports": [
"houseplan-assets/houseplan-card-eH_pY1mf.js" "houseplan-assets/houseplan-card-BObT7Q45.js"
], ],
"dynamicImports": [] "dynamicImports": []
}, },
{ {
"path": "houseplan-assets/summary-panel-runtime-loaded-C750G8Rx.js", "path": "houseplan-assets/summary-panel-runtime-loaded-CZlfz0Xl.js",
"sha256": "9b3e61e18a989a38950776a248106dde45b711fc4b80f247bc429e8cb372a25a", "sha256": "02f3b9063bf0bc9a91d165033ce98b09b923804965bd91dcf9a467bd07d19f9c",
"rawBytes": 72733, "rawBytes": 72733,
"gzipBytes": 20171, "gzipBytes": 20173,
"isEntry": false, "isEntry": false,
"imports": [ "imports": [
"houseplan-assets/form-kit.styles-XjSspVjk.js", "houseplan-assets/form-kit.styles-J0n2asaU.js",
"houseplan-assets/houseplan-card-eH_pY1mf.js" "houseplan-assets/houseplan-card-BObT7Q45.js"
], ],
"dynamicImports": [ "dynamicImports": [
"houseplan-assets/summary-panel-editor-D6jtLpQ8.js", "houseplan-assets/summary-panel-editor-DGDH1Z-d.js",
"houseplan-assets/summary-panel-metrics-lT9wi_mo.js" "houseplan-assets/summary-panel-metrics-CRnKPnjo.js"
] ]
}, },
{ {
"path": "houseplan-assets/zigbee-topology-B35vLrYp.js", "path": "houseplan-assets/zigbee-topology-BXOYIu-9.js",
"sha256": "aa8bf029c7fed0133c80c2b557f273f7593a6c7059d7f444bb59124484815a21", "sha256": "8fb689936e9da105676dcac047b497bb2ab65dfe80b184b29e68dacaf659bd3e",
"rawBytes": 18962, "rawBytes": 18962,
"gzipBytes": 7424, "gzipBytes": 7427,
"isEntry": false, "isEntry": false,
"imports": [ "imports": [
"houseplan-assets/houseplan-card-eH_pY1mf.js" "houseplan-assets/houseplan-card-BObT7Q45.js"
], ],
"dynamicImports": [] "dynamicImports": []
}, },
{ {
"path": "houseplan-assets/zigbee-topology-runtime-hsXdTYOk.js", "path": "houseplan-assets/zigbee-topology-runtime-tN_qTU1Q.js",
"sha256": "d60b3845428071ed0a8555fc50e5712e4bd029e38d75c6059a0b314af95dacda", "sha256": "2eb80ffae43caa09e4006ff3fa910752069a502d94463ef58defdf7c8c8dea34",
"rawBytes": 3942, "rawBytes": 3942,
"gzipBytes": 1761, "gzipBytes": 1767,
"isEntry": false, "isEntry": false,
"imports": [ "imports": [
"houseplan-assets/houseplan-card-eH_pY1mf.js", "houseplan-assets/houseplan-card-BObT7Q45.js",
"houseplan-assets/zigbee-topology-B35vLrYp.js" "houseplan-assets/zigbee-topology-BXOYIu-9.js"
], ],
"dynamicImports": [] "dynamicImports": []
}, },
{ {
"path": "houseplan-card.js", "path": "houseplan-card.js",
"sha256": "22729f58ff83f845a5b454830449099c16024d8fac36f87ffd1934c7928b0780", "sha256": "327b0ff49a66e55a7b6fa00b2acdf4dda91606c2e3538559c5b2b431d6c7986f",
"rawBytes": 1205, "rawBytes": 1205,
"gzipBytes": 801, "gzipBytes": 804,
"isEntry": true, "isEntry": true,
"imports": [ "imports": [
"houseplan-assets/houseplan-card-eH_pY1mf.js" "houseplan-assets/houseplan-card-BObT7Q45.js"
], ],
"dynamicImports": [] "dynamicImports": []
}, },
{ {
"path": "houseplan-panel.js", "path": "houseplan-panel.js",
"sha256": "2981cd3ed29739c95c0cb9f351f731bbd363e2fee2a4b9cf354d4c24549bf9dd", "sha256": "234102fcde3bcd24c611dbbfc37c49539b2d89ef0b3ac6529c4f3d10ed77a584",
"rawBytes": 6165, "rawBytes": 6165,
"gzipBytes": 2322, "gzipBytes": 2327,
"isEntry": true, "isEntry": true,
"imports": [ "imports": [
"houseplan-assets/houseplan-card-eH_pY1mf.js" "houseplan-assets/houseplan-card-BObT7Q45.js"
], ],
"dynamicImports": [] "dynamicImports": []
} }
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1,4 +1,4 @@
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="2c4a9a013205eef84710c72e2eae1f8c307d94c84078490ecded141d206dd07d";import{az as e,l as o,aC as t,e8 as s,A as a,e9 as i,ea as l,eb as n,E as r,c}from"./houseplan-card-eH_pY1mf.js";class h extends e{constructor(){super(...arguments),this._spaces=null,this._spacesLoading=!1,this._spacesAuthoritative=!1}setConfig(e){this._config=e}async _loadSpaces(){if(!this._spaces&&!this._spacesLoading&&this.hass){this._spacesLoading=!0;try{const e=await this.hass.callWS({type:"houseplan/config/get"});this._spaces=(e?.config?.spaces||[]).map(e=>({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`<ha-form globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="1ee973d11082b1a8d53ac3d7d98323bdf0e4137264a98f2a988610f6f244cb2c";import{az as e,l as o,aC as t,e8 as s,A as a,e9 as i,ea as l,eb as n,E as r,c}from"./houseplan-card-BObT7Q45.js";class h extends e{constructor(){super(...arguments),this._spaces=null,this._spacesLoading=!1,this._spacesAuthoritative=!1}setConfig(e){this._config=e}async _loadSpaces(){if(!this._spaces&&!this._spacesLoading&&this.hass){this._spacesLoading=!0;try{const e=await this.hass.callWS({type:"houseplan/config/get"});this._spaces=(e?.config?.spaces||[]).map(e=>({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`<ha-form
.hass=${this.hass} .hass=${this.hass}
.data=${this._formData} .data=${this._formData}
.schema=${e} .schema=${e}
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1,4 +1,4 @@
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="2c4a9a013205eef84710c72e2eae1f8c307d94c84078490ecded141d206dd07d";import{c as a,A as e}from"./houseplan-card-eH_pY1mf.js";import{s,n as t,a as l,m as r,b as o,c as i,d as u}from"./summary-panel-runtime-loaded-C750G8Rx.js";import"./form-kit.styles-XjSspVjk.js";const m=m=>{const{host:c,dialog:d,problems:n,t:b}=m,y=n.find(a=>"error"===a.kind),$=d.localShow!==d.baseLocalShow||!d.localOnly&&!s(t(d.draft),d.base),p=$&&!d.busy&&!y,v=a=>n.find(e=>e.path===a),h=a=>a?b(`summary.problem.${a.code}`):"",k=()=>m.close(),g=a`<label class="summary-switch" for="summary-local-show"> globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="1ee973d11082b1a8d53ac3d7d98323bdf0e4137264a98f2a988610f6f244cb2c";import{c as a,A as e}from"./houseplan-card-BObT7Q45.js";import{s,n as t,a as l,m as r,b as o,c as i,d as u}from"./summary-panel-runtime-loaded-CZlfz0Xl.js";import"./form-kit.styles-J0n2asaU.js";const m=m=>{const{host:c,dialog:d,problems:n,t:b}=m,y=n.find(a=>"error"===a.kind),$=d.localShow!==d.baseLocalShow||!d.localOnly&&!s(t(d.draft),d.base),p=$&&!d.busy&&!y,v=a=>n.find(e=>e.path===a),h=a=>a?b(`summary.problem.${a.code}`):"",k=()=>m.close(),g=a`<label class="summary-switch" for="summary-local-show">
<span class="summary-switch-caption"><strong>${b("summary.show_local")}</strong> <span class="summary-switch-caption"><strong>${b("summary.show_local")}</strong>
<small id="summary-local-show-hint">${b("summary.show_local_hint")}</small></span> <small id="summary-local-show-hint">${b("summary.show_local_hint")}</small></span>
<input id="summary-local-show" data-summary-local-show type="checkbox" <input id="summary-local-show" data-summary-local-show type="checkbox"
@@ -0,0 +1 @@
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="1ee973d11082b1a8d53ac3d7d98323bdf0e4137264a98f2a988610f6f244cb2c";import{ee as e,J as t,aX as n,H as i,aa as o,a8 as r,bP as a,bO as s,aW as l,aV as c,aY as d,ef as u,eg as f,bR as m,eh as g}from"./houseplan-card-BObT7Q45.js";function v(e){if(!e.registry.authoritative)return null;const t=new Set,n=d(e.markers);for(const i of Object.values(e.registry.devices||{}))i?.id&&"service"!==i.entry_type&&!n.devices.has(i.id)&&i.area_id&&e.areaToSpace[i.area_id]&&t.add(i.id);for(const i of e.markers||[]){if(i.removed||"virtual"===i.binding)continue;const o=String(i.binding||"").indexOf(":");if(o<1)continue;const r=i.binding.slice(0,o),a=i.binding.slice(o+1),s="device"===r?e.registry.devices?.[a]:null,l="entity"===r?e.registry.entities?.[a]:null,c="device"===r?a:l?.device_id,d="device"===r?s?.area_id:l?.area_id||c&&e.registry.devices?.[c]?.area_id,u="string"==typeof i.room_id&&i.room_id.length>0&&null===i.area?"":i.area||d||"",f=u&&e.areaToSpace[u]||i.space||e.firstSpaceId;c&&e.registry.devices?.[c]&&e.spaceIds.has(f)&&(!n.devices.has(c)||"entity"===r&&n.liveEntities.has(a))&&t.add(c)}return t}function y(e,t){return e?.length?t?.length?g(e,t):e:t}function _(e,t){const n=l(e.rooms,t.walls,t.openCuts,[],i,t.cellCm,o,r);return{roomGeom:"ok"===n.status||"degraded-extra"===n.status?n.roomGeom:void 0,multiWallNodes:c(e.rooms,t.walls,t.openCuts,i,t.cellCm,o,r)}}function*h(l,c,d=_){try{let u=0;for(const f of c){const c=l.spaces.find(e=>String(e?.id)===f.id);if(!c)continue;const m=e(c,f),g=d(f,m);let v=null;for(const e of f.rooms){if(!e.id)continue;const s=t(e);if(!s)continue;const l=n(f.rooms,e.id,m.walls,m.openCuts,i,m.cellCm,o,r,g.roomGeom,g.multiWallNodes)||s;v=y(v,a(l,m.physicalBodies)),yield}const _=m.cellCm/o;u+=s(v)*_*_/1e4}return u}catch{return null}}function p(e,t,n=_){const i=h(e,t,n);let o=i.next();for(;!o.done;)o=i.next();return o.value}function b(e,t,n,i){if("system"!==e.type)return null;if("device_count"===e.key)return null===t.deviceCount?null:String(t.deviceCount);if("total_area"===e.key)return null===t.areaM2?null:m(t.areaM2,"mi"===n?.config?.unit_system?.length);try{return new Intl.DateTimeFormat(i||void 0,{dateStyle:"short",timeStyle:"short",timeZone:n?.config?.time_zone||void 0}).format(t.now)}catch{return t.now.toLocaleString()}}function S(e,t){const n=e?.states?.[t];if(!n)return null;const i=u(e,t);return i?f(i,String(n.attributes?.unit_of_measurement||"")):null}export{h as cleanFloorAreaSteps,v as representedHaDeviceIds,_ as spaceWallGeometry,S as summaryEntityValue,b as summarySystemValue,p as totalCleanFloorAreaM2};
@@ -1 +0,0 @@
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="2c4a9a013205eef84710c72e2eae1f8c307d94c84078490ecded141d206dd07d";import{ee as e,J as t,aX as n,H as i,aa as o,a8 as r,bP as s,bO as a,aW as c,aV as l,aY as d,ef as u,eg as f,bR as m,eh as g}from"./houseplan-card-eH_pY1mf.js";function v(e){if(!e.registry.authoritative)return null;const t=new Set,n=d(e.markers);for(const i of Object.values(e.registry.devices||{}))i?.id&&"service"!==i.entry_type&&!n.devices.has(i.id)&&i.area_id&&e.areaToSpace[i.area_id]&&t.add(i.id);for(const i of e.markers||[]){if(i.removed||"virtual"===i.binding)continue;const o=String(i.binding||"").indexOf(":");if(o<1)continue;const r=i.binding.slice(0,o),s=i.binding.slice(o+1),a="device"===r?e.registry.devices?.[s]:null,c="entity"===r?e.registry.entities?.[s]:null,l="device"===r?s:c?.device_id,d="device"===r?a?.area_id:c?.area_id||l&&e.registry.devices?.[l]?.area_id,u="string"==typeof i.room_id&&i.room_id.length>0&&null===i.area?"":i.area||d||"",f=u&&e.areaToSpace[u]||i.space||e.firstSpaceId;l&&e.registry.devices?.[l]&&e.spaceIds.has(f)&&(!n.devices.has(l)||"entity"===r&&n.liveEntities.has(s))&&t.add(l)}return t}function y(e,t){return e?.length?t?.length?g(e,t):e:t}function _(e,t){const n=c(e.rooms,t.walls,t.openCuts,[],i,t.cellCm,o,r);return{roomGeom:"ok"===n.status||"degraded-extra"===n.status?n.roomGeom:void 0,multiWallNodes:l(e.rooms,t.walls,t.openCuts,i,t.cellCm,o,r)}}function*h(c,l,d=_){try{let u=0;for(const f of l){const l=c.spaces.find(e=>String(e?.id)===f.id);if(!l)continue;const m=e(l,f),g=d(f,m);let v=null;for(const e of f.rooms){if(!e.id)continue;const a=t(e);if(!a)continue;const c=n(f.rooms,e.id,m.walls,m.openCuts,i,m.cellCm,o,r,g.roomGeom,g.multiWallNodes)||a;v=y(v,s(c,m.physicalBodies)),yield}const _=m.cellCm/o;u+=a(v)*_*_/1e4}return u}catch{return null}}function p(e,t,n=_){const i=h(e,t,n);let o=i.next();for(;!o.done;)o=i.next();return o.value}function S(e,t,n,i){if("system"!==e.type)return null;if("device_count"===e.key)return null===t.deviceCount?null:String(t.deviceCount);if("total_area"===e.key)return null===t.areaM2?null:m(t.areaM2,"mi"===n?.config?.unit_system?.length);try{return new Intl.DateTimeFormat(i||void 0,{dateStyle:"short",timeStyle:"short",timeZone:n?.config?.time_zone||void 0}).format(t.now)}catch{return t.now.toLocaleString()}}function b(e,t){const n=e?.states?.[t];if(!n)return null;const i=u(e,t);return i?f(i,String(n.attributes?.unit_of_measurement||"")):null}export{h as cleanFloorAreaSteps,v as representedHaDeviceIds,_ as spaceWallGeometry,b as summaryEntityValue,S as summarySystemValue,p as totalCleanFloorAreaM2};
@@ -1 +1 @@
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="2c4a9a013205eef84710c72e2eae1f8c307d94c84078490ecded141d206dd07d";import{n as t,b as n}from"./zigbee-topology-B35vLrYp.js";import{aI as e}from"./houseplan-card-eH_pY1mf.js";const o=new WeakMap;function i(t){const n=function(t){const n=t?.connection||t;return!n||"object"!=typeof n&&"function"!=typeof n?null:n}(t);if(!n)return null;let e=o.get(n);return e||(e={revision:0,topologies:[],states:{},listeners:new Set,inflight:new Map},o.set(n,e)),e}function r(t,n,e){t.states={...t.states,[n]:e},function(t){t.revision++;for(const n of t.listeners)n()}(t)}function s(t){const n=t?.code;if("permission"===n||"unsupported"===n||"timeout"===n||"invalid_topic"===n||"invalid_payload"===n)return n;const e=String(t?.message||"").toLowerCase();return e.includes("unauthor")||e.includes("permission")?"permission":e.includes("unknown_command")||e.includes("not found")?"unsupported":"provider"}function a(t){return Object.assign(new Error(t),{code:t})}function c(t,n,e){const o=t.inflight.get(n);if(o)return o;r(t,n,{phase:"loading"});const i=e().then(n=>{if(!n.nodes.length&&n.warnings.some(t=>"invalid_payload"===t.code))throw a("invalid_payload");!function(t,n){t.topologies=[...t.topologies.filter(t=>!(t.provider===n.provider&&t.instanceId===n.instanceId)),n],r(t,"zha"===n.provider?"zha":`z2m:${n.instanceId}`,{phase:"ready",obtainedAt:n.obtainedAt,partial:n.warnings.length>0})}(t,n)}).catch(e=>{r(t,n,{phase:"error",error:s(e)})}).finally(()=>t.inflight.delete(n));return t.inflight.set(n,i),i}function l(t){const n=i(t);return n?{revision:n.revision,topologies:n.topologies,states:n.states}:{revision:0,topologies:[],states:{}}}function u(t,n){const e=i(t);return e?(e.listeners.add(n),()=>e.listeners.delete(n)):()=>{}}function p(t){if(!0!==t?.user?.is_admin)throw a("permission")}function f(n){const e=i(n);return e?c(e,"zha",async()=>{if(p(n),"function"!=typeof n?.callWS)throw a("unsupported");return t(await n.callWS({type:"zha/devices"}))}):Promise.resolve()}function d(t){return null!==t&&"object"==typeof t?t:null}function h(t){const n=d(t),e=n?.payload??t;if("string"!=typeof e)return e;try{return JSON.parse(e)}catch{return null}}async function m(t,n){let e;try{return await Promise.race([t,new Promise((t,o)=>{e=globalThis.setTimeout(()=>o(a("timeout")),Math.max(1,n))})])}finally{void 0!==e&&globalThis.clearTimeout(e)}}function g(t,o,r=15e4){const s=i(t);if(!s)return Promise.resolve();const l=e(o);return c(s,`z2m:${l||String(o)}`,async()=>{if(p(t),!l)throw a("invalid_topic");const e=t.connection,o=e?.subscribeMessage;if("function"!=typeof o||"function"!=typeof t?.callService)throw a("unsupported");const i=function(){const t=globalThis.crypto;return"function"==typeof t?.randomUUID?`houseplan-${t.randomUUID()}`:`houseplan-${Date.now().toString(36)}-${Math.random().toString(36).slice(2)}`}(),s=Date.now()+Math.max(1,r);let c=!1,u=null,f=null,g=null;const y=new Promise(t=>{u=t}),w=new Promise((t,n)=>{f=t,g=n}),b=[];try{const r=await o.call(e,t=>{!0===d(t)?.retain&&h(t)&&u?.()},{type:"mqtt/subscribe",topic:`${l}/bridge/info`});"function"==typeof r&&b.push(r);const p=await o.call(e,t=>{if(!0===d(t)?.retain)return;const n=h(t);null!==n?n&&function(t){const n=d(t),e=n?.transaction??d(n?.data)?.transaction;return"string"==typeof e||"number"==typeof e?String(e):null}(n)===i&&f?.(n):c&&g?.(a("invalid_payload"))},{type:"mqtt/subscribe",topic:`${l}/bridge/response/networkmap`});"function"==typeof p&&b.push(p),await m(y,Math.min(4e3,Math.max(1,s-Date.now()))),c=!0,await t.callService("mqtt","publish",{topic:`${l}/bridge/request/networkmap`,payload:JSON.stringify({type:"raw",routes:!1,transaction:i}),qos:0,retain:!1});const v=await m(w,s-Date.now()),_=d(v)?.status;if(_&&"ok"!==_)throw a("provider");return n(v,l)}finally{for(const t of b)try{t()}catch{}}})}export{f as readZhaTopology,g as refreshZ2mTopology,u as subscribeZigbeeTopology,l as zigbeeTopologyRuntimeSnapshot}; globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="1ee973d11082b1a8d53ac3d7d98323bdf0e4137264a98f2a988610f6f244cb2c";import{n as t,b as n}from"./zigbee-topology-BXOYIu-9.js";import{aI as e}from"./houseplan-card-BObT7Q45.js";const o=new WeakMap;function i(t){const n=function(t){const n=t?.connection||t;return!n||"object"!=typeof n&&"function"!=typeof n?null:n}(t);if(!n)return null;let e=o.get(n);return e||(e={revision:0,topologies:[],states:{},listeners:new Set,inflight:new Map},o.set(n,e)),e}function r(t,n,e){t.states={...t.states,[n]:e},function(t){t.revision++;for(const n of t.listeners)n()}(t)}function s(t){const n=t?.code;if("permission"===n||"unsupported"===n||"timeout"===n||"invalid_topic"===n||"invalid_payload"===n)return n;const e=String(t?.message||"").toLowerCase();return e.includes("unauthor")||e.includes("permission")?"permission":e.includes("unknown_command")||e.includes("not found")?"unsupported":"provider"}function a(t){return Object.assign(new Error(t),{code:t})}function c(t,n,e){const o=t.inflight.get(n);if(o)return o;r(t,n,{phase:"loading"});const i=e().then(n=>{if(!n.nodes.length&&n.warnings.some(t=>"invalid_payload"===t.code))throw a("invalid_payload");!function(t,n){t.topologies=[...t.topologies.filter(t=>!(t.provider===n.provider&&t.instanceId===n.instanceId)),n],r(t,"zha"===n.provider?"zha":`z2m:${n.instanceId}`,{phase:"ready",obtainedAt:n.obtainedAt,partial:n.warnings.length>0})}(t,n)}).catch(e=>{r(t,n,{phase:"error",error:s(e)})}).finally(()=>t.inflight.delete(n));return t.inflight.set(n,i),i}function l(t){const n=i(t);return n?{revision:n.revision,topologies:n.topologies,states:n.states}:{revision:0,topologies:[],states:{}}}function u(t,n){const e=i(t);return e?(e.listeners.add(n),()=>e.listeners.delete(n)):()=>{}}function f(t){if(!0!==t?.user?.is_admin)throw a("permission")}function p(n){const e=i(n);return e?c(e,"zha",async()=>{if(f(n),"function"!=typeof n?.callWS)throw a("unsupported");return t(await n.callWS({type:"zha/devices"}))}):Promise.resolve()}function d(t){return null!==t&&"object"==typeof t?t:null}function h(t){const n=d(t),e=n?.payload??t;if("string"!=typeof e)return e;try{return JSON.parse(e)}catch{return null}}async function m(t,n){let e;try{return await Promise.race([t,new Promise((t,o)=>{e=globalThis.setTimeout(()=>o(a("timeout")),Math.max(1,n))})])}finally{void 0!==e&&globalThis.clearTimeout(e)}}function g(t,o,r=15e4){const s=i(t);if(!s)return Promise.resolve();const l=e(o);return c(s,`z2m:${l||String(o)}`,async()=>{if(f(t),!l)throw a("invalid_topic");const e=t.connection,o=e?.subscribeMessage;if("function"!=typeof o||"function"!=typeof t?.callService)throw a("unsupported");const i=function(){const t=globalThis.crypto;return"function"==typeof t?.randomUUID?`houseplan-${t.randomUUID()}`:`houseplan-${Date.now().toString(36)}-${Math.random().toString(36).slice(2)}`}(),s=Date.now()+Math.max(1,r);let c=!1,u=null,p=null,g=null;const y=new Promise(t=>{u=t}),w=new Promise((t,n)=>{p=t,g=n}),b=[];try{const r=await o.call(e,t=>{!0===d(t)?.retain&&h(t)&&u?.()},{type:"mqtt/subscribe",topic:`${l}/bridge/info`});"function"==typeof r&&b.push(r);const f=await o.call(e,t=>{if(!0===d(t)?.retain)return;const n=h(t);null!==n?n&&function(t){const n=d(t),e=n?.transaction??d(n?.data)?.transaction;return"string"==typeof e||"number"==typeof e?String(e):null}(n)===i&&p?.(n):c&&g?.(a("invalid_payload"))},{type:"mqtt/subscribe",topic:`${l}/bridge/response/networkmap`});"function"==typeof f&&b.push(f),await m(y,Math.min(4e3,Math.max(1,s-Date.now()))),c=!0,await t.callService("mqtt","publish",{topic:`${l}/bridge/request/networkmap`,payload:JSON.stringify({type:"raw",routes:!1,transaction:i}),qos:0,retain:!1});const v=await m(w,s-Date.now()),_=d(v)?.status;if(_&&"ok"!==_)throw a("provider");return n(v,l)}finally{for(const t of b)try{t()}catch{}}})}export{p as readZhaTopology,g as refreshZ2mTopology,u as subscribeZigbeeTopology,l as zigbeeTopologyRuntimeSnapshot};
+1 -1
View File
@@ -1 +1 @@
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="2c4a9a013205eef84710c72e2eae1f8c307d94c84078490ecded141d206dd07d";try{await import("./houseplan-assets/houseplan-card-eH_pY1mf.js")}catch(e){if(!customElements.get("houseplan-card")){const l=String(navigator.language||"en").toLowerCase();const m=l.startsWith("ru")?"House Plan обновился — перезагрузите страницу (Ctrl+F5).":l.startsWith("de")?"House Plan wurde aktualisiert — bitte laden Sie die Seite neu (Strg+F5).":l.startsWith("fr")?"House Plan a été mis à jour — veuillez recharger la page (Ctrl+F5).":"House Plan was updated — please reload the page (Ctrl+F5).";customElements.define("houseplan-card",class extends HTMLElement{setConfig(){}getCardSize(){return 1}connectedCallback(){this.style.cssText="display:block;box-sizing:border-box;padding:16px;border:1px solid var(--divider-color,#e0e0e0);border-radius:var(--ha-card-border-radius,12px);background:var(--card-background-color,#fff);color:var(--primary-text-color,#212121);font:14px/1.4 var(--paper-font-body1_-_font-family,sans-serif)";this.textContent=m}})}console.error("[houseplan] stale houseplan-card.js: the implementation chunk is unavailable",e)} globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="1ee973d11082b1a8d53ac3d7d98323bdf0e4137264a98f2a988610f6f244cb2c";try{await import("./houseplan-assets/houseplan-card-BObT7Q45.js")}catch(e){if(!customElements.get("houseplan-card")){const l=String(navigator.language||"en").toLowerCase();const m=l.startsWith("ru")?"House Plan обновился — перезагрузите страницу (Ctrl+F5).":l.startsWith("de")?"House Plan wurde aktualisiert — bitte laden Sie die Seite neu (Strg+F5).":l.startsWith("fr")?"House Plan a été mis à jour — veuillez recharger la page (Ctrl+F5).":"House Plan was updated — please reload the page (Ctrl+F5).";customElements.define("houseplan-card",class extends HTMLElement{setConfig(){}getCardSize(){return 1}connectedCallback(){this.style.cssText="display:block;box-sizing:border-box;padding:16px;border:1px solid var(--divider-color,#e0e0e0);border-radius:var(--ha-card-border-radius,12px);background:var(--card-background-color,#fff);color:var(--primary-text-color,#212121);font:14px/1.4 var(--paper-font-body1_-_font-family,sans-serif)";this.textContent=m}})}console.error("[houseplan] stale houseplan-card.js: the implementation chunk is unavailable",e)}
+1 -1
View File
File diff suppressed because one or more lines are too long
+4
View File
@@ -2,6 +2,10 @@
## Unreleased ## Unreleased
- Settings forms now keep the same reviewed shell inside Home Assistant as in
the standalone preview: a 560 px desktop canvas with one scrollbar and a
height cap, plus edge-to-edge fullscreen layout on phones. Other dialogs are
unchanged ([#609](https://github.com/Matysh/houseplan-card/issues/609)).
- Fixed the close button in Home Assistant's real settings dialogs: choosing - Fixed the close button in Home Assistant's real settings dialogs: choosing
**Continue** after the unsaved-changes prompt now restores the same editable **Continue** after the unsaved-changes prompt now restores the same editable
modal instead of leaving an invisible dialog that required a page reload modal instead of leaving an invisible dialog that required a page reload
+4
View File
@@ -8,6 +8,10 @@
## Не выпущено ## Не выпущено
- Формы настроек теперь выглядят внутри Home Assistant так же, как в принятом
макете: канва шириной 560 px на компьютере с одной прокруткой и ограничением
высоты, а на телефоне — полноэкранный диалог без отступов. Остальные диалоги
не изменились ([#609](https://github.com/Matysh/houseplan-card/issues/609)).
- Исправлен крестик реальных диалогов Home Assistant: после выбора - Исправлен крестик реальных диалогов Home Assistant: после выбора
**«Продолжить»** в вопросе о несохранённых изменениях тот же диалог снова **«Продолжить»** в вопросе о несохранённых изменениях тот же диалог снова
виден и доступен для редактирования, а не остаётся невидимым до перезагрузки виден и доступен для редактирования, а не остаётся невидимым до перезагрузки
+5 -1
View File
@@ -135,7 +135,11 @@ metadata). Only an explicit owner-approved emergency hotfix may skip this gate.
right-click → more-info (v1.38.1); Esc closes every dialog (v1.30.4). right-click → more-info (v1.38.1); Esc closes every dialog (v1.30.4).
Since #607, rejecting the real HA close button after an unsaved-changes Since #607, rejecting the real HA close button after an unsaved-changes
prompt explicitly reconciles the nested modal before reopening it; the same prompt explicitly reconciles the nested modal before reopening it; the same
Device, Room, Space or General-settings draft remains interactive. Device, Room, Space or General-settings draft remains interactive. #609 keeps
every shared settings form on the reviewed 560 px canvas and single HA-owned
scroller in the authentic Home Assistant branch; at 480 px and below the
form is edge-to-edge fullscreen, while generic dialogs retain their previous
sizing.
- **Room settings, tier 3** (v1.42.0): per-room fill/temp-source/label sizes; - **Room settings, tier 3** (v1.42.0): per-room fill/temp-source/label sizes;
the settings button sits at the room's VISUAL centre (inscribed circle + the settings button sits at the room's VISUAL centre (inscribed circle +
centroid pull), icon-derived size, zooms with the plan (v1.51.0). centroid pull), icon-derived size, zooms with the plan (v1.51.0).
@@ -32,6 +32,36 @@ AC10 унаследован от #598, где диалог комнаты не
скоупе #600. PNG пережаты в палитру 256 цветов — для сравнения скоупе #600. PNG пережаты в палитру 256 цветов — для сравнения
раскладки этого достаточно, а вес папки остаётся в полумегабайте. раскладки этого достаточно, а вес папки остаётся в полумегабайте.
## #609: оболочка в настоящем Home Assistant
Парные кадры выше были сняты в нативной ветке `hp-dialog`. Для #609 отдельно
проверена ветка настоящего `ha-dialog` из закреплённого
`home-assistant-frontend==20260729.7` (SHA-256
`ba01782297e9506d3185f99a74d829f3811df322623848af21bcc0b8ea834c12`):
```sh
npm run bundle:sync
node demo/verify_ha_form_shell_609.mjs --capture
```
Официальный компонент и его CSS не модифицируются; локальная фикстура не
поднимает HA, не обращается к сети и падает при внешнем запросе, WebSocket или
ошибке страницы. Измерения после завершения 200-миллисекундной анимации показа:
| Режим | Поверхность | Проверенный результат |
|---|---:|---|
| desktop 1600×1000 | 560×940 | канва вокруг карточек, один скроллер `.body` HA, footer внутри |
| граница 480×800 | 480×800 | fullscreen, радиус 0, горизонтального переполнения нет |
| mobile 390×844 | 390×844 | fullscreen, радиус 0, footer внутри |
| низкое окно 1280×480 | 1280×480 | штатный fullscreen HA сохранён |
Снимки приёмки: `pairs/room-ha-light.png` и
`pairs/room-ha-mobile-light.png`. Это диагностические доказательства, а не
golden-базы; 13 нативных golden-сцен остаются неизменными. Быстрый обязательный
свидетель тех же публичных CSS-контрактов —
`demo/smoke_ha_form_shell_parity.mjs`, а перечень пяти потребителей оболочки
закреплён в `test/form-shell-consumers.test.mjs`.
## Статус по диалогам ## Статус по диалогам
| Диалог | Серия | Референс | Продукт (светлая / тёмная) | Расхождения названы | Готово | | Диалог | Серия | Референс | Продукт (светлая / тёмная) | Расхождения названы | Готово |
Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

+12 -12
View File
@@ -3,7 +3,7 @@
"fixture": "synthetic-only", "fixture": "synthetic-only",
"chromium": "151.0.7922.34", "chromium": "151.0.7922.34",
"oxipng": "oxipng 10.2.0", "oxipng": "oxipng 10.2.0",
"sourceFingerprint": "a30183640fa0ddc006999072d32fdb1bdab6338c6220503470967cc4c4f2ae78", "sourceFingerprint": "4d8c44bc47100744092cf0fc56cc05d68dad37d3d9e0b95707198a2a893895f6",
"captureScriptSha256": "e2d14d89de793011615662af7c83c433768d4761f6cec7f0b3860c797494299e", "captureScriptSha256": "e2d14d89de793011615662af7c83c433768d4761f6cec7f0b3860c797494299e",
"command": "npm run build && node demo/docs/capture.mjs", "command": "npm run build && node demo/docs/capture.mjs",
"scenarios": { "scenarios": {
@@ -15,7 +15,7 @@
}, },
"theme": "dark", "theme": "dark",
"language": "en", "language": "en",
"sourceSha256": "a30183640fa0ddc006999072d32fdb1bdab6338c6220503470967cc4c4f2ae78", "sourceSha256": "4d8c44bc47100744092cf0fc56cc05d68dad37d3d9e0b95707198a2a893895f6",
"imageSha256": "5d1e816c2fde72316809991e9651e242d3cbcd897fb9db0554dc3bde943486f5" "imageSha256": "5d1e816c2fde72316809991e9651e242d3cbcd897fb9db0554dc3bde943486f5"
}, },
"view-touch": { "view-touch": {
@@ -26,7 +26,7 @@
}, },
"theme": "dark", "theme": "dark",
"language": "en", "language": "en",
"sourceSha256": "a30183640fa0ddc006999072d32fdb1bdab6338c6220503470967cc4c4f2ae78", "sourceSha256": "4d8c44bc47100744092cf0fc56cc05d68dad37d3d9e0b95707198a2a893895f6",
"imageSha256": "bc2001f9cd51715a38ad8d913b1c5a4f2220b3917c8dc03b2de65cfb3f62f808" "imageSha256": "bc2001f9cd51715a38ad8d913b1c5a4f2220b3917c8dc03b2de65cfb3f62f808"
}, },
"space-create": { "space-create": {
@@ -37,7 +37,7 @@
}, },
"theme": "dark", "theme": "dark",
"language": "en", "language": "en",
"sourceSha256": "a30183640fa0ddc006999072d32fdb1bdab6338c6220503470967cc4c4f2ae78", "sourceSha256": "4d8c44bc47100744092cf0fc56cc05d68dad37d3d9e0b95707198a2a893895f6",
"imageSha256": "a74330dcdd0d590e2e0008c7030a9dc11df9793682b1a050a7aaa734c651cc30" "imageSha256": "a74330dcdd0d590e2e0008c7030a9dc11df9793682b1a050a7aaa734c651cc30"
}, },
"room-contour-close": { "room-contour-close": {
@@ -48,7 +48,7 @@
}, },
"theme": "dark", "theme": "dark",
"language": "en", "language": "en",
"sourceSha256": "a30183640fa0ddc006999072d32fdb1bdab6338c6220503470967cc4c4f2ae78", "sourceSha256": "4d8c44bc47100744092cf0fc56cc05d68dad37d3d9e0b95707198a2a893895f6",
"imageSha256": "0c354a79f9c3660788b6c5e889a27b6bd78b1f209dc0eef6bb43e2c1344028c4" "imageSha256": "0c354a79f9c3660788b6c5e889a27b6bd78b1f209dc0eef6bb43e2c1344028c4"
}, },
"plan-context-tray": { "plan-context-tray": {
@@ -59,7 +59,7 @@
}, },
"theme": "dark", "theme": "dark",
"language": "en", "language": "en",
"sourceSha256": "a30183640fa0ddc006999072d32fdb1bdab6338c6220503470967cc4c4f2ae78", "sourceSha256": "4d8c44bc47100744092cf0fc56cc05d68dad37d3d9e0b95707198a2a893895f6",
"imageSha256": "64169c543291bc4df806dcf8ff484b42c8ea55eb343323d945344e0e28f2ce97" "imageSha256": "64169c543291bc4df806dcf8ff484b42c8ea55eb343323d945344e0e28f2ce97"
}, },
"device-editor": { "device-editor": {
@@ -70,7 +70,7 @@
}, },
"theme": "dark", "theme": "dark",
"language": "en", "language": "en",
"sourceSha256": "a30183640fa0ddc006999072d32fdb1bdab6338c6220503470967cc4c4f2ae78", "sourceSha256": "4d8c44bc47100744092cf0fc56cc05d68dad37d3d9e0b95707198a2a893895f6",
"imageSha256": "a4c1f55438e669fe7533a01185d50f7396e6fab23a3f2b9c8a669c6a28e6b200" "imageSha256": "a4c1f55438e669fe7533a01185d50f7396e6fab23a3f2b9c8a669c6a28e6b200"
}, },
"device-display-preview": { "device-display-preview": {
@@ -81,7 +81,7 @@
}, },
"theme": "dark", "theme": "dark",
"language": "en", "language": "en",
"sourceSha256": "a30183640fa0ddc006999072d32fdb1bdab6338c6220503470967cc4c4f2ae78", "sourceSha256": "4d8c44bc47100744092cf0fc56cc05d68dad37d3d9e0b95707198a2a893895f6",
"imageSha256": "8029b1cd7329e3fc921ae9ca19abe6f7f2c7246eb45c891d088baedf9972fac2" "imageSha256": "8029b1cd7329e3fc921ae9ca19abe6f7f2c7246eb45c891d088baedf9972fac2"
}, },
"background-editor": { "background-editor": {
@@ -92,7 +92,7 @@
}, },
"theme": "dark", "theme": "dark",
"language": "en", "language": "en",
"sourceSha256": "a30183640fa0ddc006999072d32fdb1bdab6338c6220503470967cc4c4f2ae78", "sourceSha256": "4d8c44bc47100744092cf0fc56cc05d68dad37d3d9e0b95707198a2a893895f6",
"imageSha256": "375900a29aa62632883ede6727b7dbb8b48cabe9d7d0e16425f9779c837f3dd9" "imageSha256": "375900a29aa62632883ede6727b7dbb8b48cabe9d7d0e16425f9779c837f3dd9"
}, },
"room-card": { "room-card": {
@@ -103,7 +103,7 @@
}, },
"theme": "dark", "theme": "dark",
"language": "en", "language": "en",
"sourceSha256": "a30183640fa0ddc006999072d32fdb1bdab6338c6220503470967cc4c4f2ae78", "sourceSha256": "4d8c44bc47100744092cf0fc56cc05d68dad37d3d9e0b95707198a2a893895f6",
"imageSha256": "c985783769da1bce50c9abe92ce1c6852d62701ce940f6f0a041d634ac21e888" "imageSha256": "c985783769da1bce50c9abe92ce1c6852d62701ce940f6f0a041d634ac21e888"
}, },
"device-info": { "device-info": {
@@ -114,7 +114,7 @@
}, },
"theme": "dark", "theme": "dark",
"language": "en", "language": "en",
"sourceSha256": "a30183640fa0ddc006999072d32fdb1bdab6338c6220503470967cc4c4f2ae78", "sourceSha256": "4d8c44bc47100744092cf0fc56cc05d68dad37d3d9e0b95707198a2a893895f6",
"imageSha256": "19e247d5bf49375b238292d45ae32e9eb38a83f5d1a53f6ddde860ed4adcef42" "imageSha256": "19e247d5bf49375b238292d45ae32e9eb38a83f5d1a53f6ddde860ed4adcef42"
}, },
"pdf-export": { "pdf-export": {
@@ -125,7 +125,7 @@
}, },
"theme": "light", "theme": "light",
"language": "en", "language": "en",
"sourceSha256": "a30183640fa0ddc006999072d32fdb1bdab6338c6220503470967cc4c4f2ae78", "sourceSha256": "4d8c44bc47100744092cf0fc56cc05d68dad37d3d9e0b95707198a2a893895f6",
"imageSha256": "4537692fd57a3ed95528eddd748eee5cb6e456ffab7cc49169853d62459252cd" "imageSha256": "4537692fd57a3ed95528eddd748eee5cb6e456ffab7cc49169853d62459252cd"
} }
}, },
+8 -1
View File
@@ -315,7 +315,14 @@ export const LOW_HEADROOM_WARNING_BYTES = 15_000;
* `.markerradios`, `.markerlightdisabled`, `.pdftag`, `.descin`, `.togglehint` * `.markerradios`, `.markerlightdisabled`, `.pdftag`, `.descin`, `.togglehint`
* и др.) — их заменил лист набора в ленивом графе. * и др.) — их заменил лист набора в ленивом графе.
*/ */
export const INITIAL_VIEW_GZIP_CEILING = 290_900; /**
* #609: 290 900 → 291 400 (замер 290 445). Публичные CSS-переменные оболочки
* настоящего `ha-dialog` и мобильные media rules входят в eager-граф: форма
* обязана получить правильную геометрию до загрузки ленивого редактора. Новый
* центр оставляет 955 Б сверху и 1 045 Б до нижней границы полосы; общий бюджет
* не меняется.
*/
export const INITIAL_VIEW_GZIP_CEILING = 291_400;
export const INITIAL_VIEW_CEILING_BAND = 2_000; export const INITIAL_VIEW_CEILING_BAND = 2_000;
/** /**
+1
View File
@@ -60,6 +60,7 @@ export const NOT_AN_INPUT = [
['demo/shot_*.mjs', 'ручные съёмки для документации и разбора, не гейты'], ['demo/shot_*.mjs', 'ручные съёмки для документации и разбора, не гейты'],
['demo/capture_*.mjs', 'ручные съёмки эталонов, запускаются человеком'], ['demo/capture_*.mjs', 'ручные съёмки эталонов, запускаются человеком'],
['demo/verify_ha_dialog_discard_recovery.mjs', 'явная тяжёлая диагностика настоящего ha-dialog для #607; запускается человеком'], ['demo/verify_ha_dialog_discard_recovery.mjs', 'явная тяжёлая диагностика настоящего ha-dialog для #607; запускается человеком'],
['demo/verify_ha_form_shell_609.mjs', 'явная тяжёлая диагностика оболочки форм в настоящем ha-dialog для #609; запускается человеком'],
['demo/helpers/ha-dialog-assets.mjs', 'пиновые HA assets только для явной диагностической съёмки #505; не запускают загрузку в Validate'], ['demo/helpers/ha-dialog-assets.mjs', 'пиновые HA assets только для явной диагностической съёмки #505; не запускают загрузку в Validate'],
['demo/helpers/ha-dialog-fixture.mjs', 'изолированный настоящий ha-dialog только для явной визуальной приёмки #505, не обычный smoke'], ['demo/helpers/ha-dialog-fixture.mjs', 'изолированный настоящий ha-dialog только для явной визуальной приёмки #505, не обычный smoke'],
['demo/screencast_visual_continuity.mjs', 'ручной скринкаст'], ['demo/screencast_visual_continuity.mjs', 'ручной скринкаст'],
+33
View File
@@ -72,6 +72,39 @@ function relocateEditorPatch(patch, cardSource, editorSource) {
// `find` обязан встречаться в файле ровно один раз: патч, который ложится «куда // `find` обязан встречаться в файле ровно один раз: патч, который ложится «куда
// попало», проверяет не то, что объявлен проверять. Это контролирует --check. // попало», проверяет не то, что объявлен проверять. Это контролирует --check.
const MUTANT_DEFINITIONS = [ const MUTANT_DEFINITIONS = [
{
id: 'ha-form-shell-width-falls-back-to-generic',
guard: 'node demo/smoke_ha_form_shell_parity.mjs',
because: '#609 AC1/AC8: the authentic HA branch must consume the reviewed 560 px form '
+ 'width; falling back to HA generic medium width recreates the released/native mismatch',
patches: [{
file: 'src/hp-dialog.ts',
find: ' --ha-dialog-width-md: 560px;',
replace: ' --ha-dialog-width-md: 580px;',
}],
},
{
id: 'ha-form-shell-loses-canvas',
guard: 'node demo/smoke_ha_form_shell_parity.mjs',
because: '#609 AC3: forms in HA need the same canvas-and-card hierarchy as the reviewed '
+ 'native shell; painting the body as the dialog surface erases that hierarchy',
patches: [{
file: 'src/styles/dialogs.styles.ts',
find: ' background: var(--hpf-canvas, var(--secondary-background-color, color-mix(in srgb, var(--card-background-color, var(--hp-bg, #202126)) 90%, var(--primary-text-color, #000))));',
replace: ' background: var(--card-background-color, var(--hp-bg, #202126));',
}],
},
{
id: 'ha-form-shell-mobile-keeps-desktop-inset',
guard: 'node demo/smoke_ha_form_shell_parity.mjs',
because: '#609 AC4/AC8: at 480 px and below the form shell is edge-to-edge; retaining the '
+ 'desktop 48 px height inset clips the reviewed mobile surface and footer',
patches: [{
file: 'src/hp-dialog.ts',
find: ' --ha-dialog-max-height: var(--safe-height, 100dvh);',
replace: ' --ha-dialog-max-height: calc(var(--safe-height, 100dvh) - 48px);',
}],
},
{ {
id: 'attribution-judges-the-head-definition-on-the-base', id: 'attribution-judges-the-head-definition-on-the-base',
guard: 'node --test --test-name-pattern="#568" test/mutation-guard-outcome.test.mjs', guard: 'node --test --test-name-pattern="#568" test/mutation-guard-outcome.test.mjs',
+5 -3
View File
@@ -140,11 +140,13 @@ export const SMOKE_LINKS = [
+ 'lifecycle effects are not visible to source or pure color conversion tests', + 'lifecycle effects are not visible to source or pure color conversion tests',
}, },
{ {
symbols: ['HpDialog', '_ensureNativeModal', '_useHaDialog', '_usesHaDialog'], symbols: ['HpDialog', '_ensureNativeModal', '_useHaDialog', '_usesHaDialog', 'dialogsStyles'],
smokes: ['smoke_dialog_modal_recovery.mjs'], smokes: ['smoke_dialog_modal_recovery.mjs', 'smoke_ha_form_shell_parity.mjs'],
because: 'the #463 production-bundle scenario observes native top-layer state, geometric ' because: 'the #463 production-bundle scenario observes native top-layer state, geometric '
+ 'centring, ::backdrop, update/reconnect recovery and late ha-dialog registration; none ' + 'centring, ::backdrop, update/reconnect recovery and late ha-dialog registration; none '
+ 'of those browser lifecycle effects can be proved from the Lit source alone', + 'of those browser lifecycle effects can be proved from the Lit source alone. The #609 '
+ 'scenario separately exercises the public HA sizing tokens, one HA body scroller, form '
+ 'canvas and responsive fullscreen geometry used by all five form-shell consumers',
}, },
{ {
symbols: [ symbols: [
+34 -1
View File
@@ -195,7 +195,18 @@ export class HpDialog extends LitElement {
через переменную, которую уже читает :host([wide]); высота min(940, через переменную, которую уже читает :host([wide]); высота min(940,
окно − 48); единственный скроллер — .content, тело формы высотой не окно − 48); единственный скроллер — .content, тело формы высотой не
владеет (К6). Generic wide и остальные диалоги не трогаются (Q7). */ владеет (К6). Generic wide и остальные диалоги не трогаются (Q7). */
:host([form-shell]) { --hp-dialog-wide-width: 560px; } :host([form-shell]) {
--hp-dialog-wide-width: 560px;
}
:host([form-shell]) ha-dialog {
/* Public HA dialog hooks. Keep the authentic branch on the same outer
geometry as the native form shell without reaching into HA's shadow
tree. The light-DOM form owns its 16 px canvas padding, so HA must not
add a second inset around it. */
--ha-dialog-width-md: 560px;
--ha-dialog-max-height: min(940px, calc(100dvh - 48px));
--dialog-content-padding: 0;
}
:host([form-shell]) .surface { max-height: min(940px, calc(100vh - 48px)); } :host([form-shell]) .surface { max-height: min(940px, calc(100vh - 48px)); }
:host([form-shell]) .content { :host([form-shell]) .content {
flex: 1 1 auto; flex: 1 1 auto;
@@ -207,9 +218,27 @@ export class HpDialog extends LitElement {
:host([form-shell]) .close { width: 44px; height: 44px; } :host([form-shell]) .close { width: 44px; height: 44px; }
:host([form-shell]) .header { min-height: 70px; } :host([form-shell]) .header { min-height: 70px; }
@media (max-width: 480px) { @media (max-width: 480px) {
:host([form-shell]) ha-dialog {
--ha-dialog-width-md: var(--safe-width, 100vw);
--ha-dialog-width-full: var(--safe-width, 100vw);
--ha-dialog-min-height: var(--safe-height, 100dvh);
--ha-dialog-max-height: var(--safe-height, 100dvh);
--ha-dialog-border-radius: 0;
--dialog-surface-margin-top: 0;
}
:host([form-shell]) .surface { width: 100vw; max-height: 100vh; border: 0; border-radius: 0; } :host([form-shell]) .surface { width: 100vw; max-height: 100vh; border: 0; border-radius: 0; }
:host([form-shell]) .badge { max-width: 105px; } :host([form-shell]) .badge { max-width: 105px; }
} }
/* HA itself switches every dialog to fullscreen when viewport height is
500 px or less. Its radius token is inherited from hp-dialog, so mirror
the public responsive token here instead of leaving rounded corners on
an otherwise edge-to-edge authentic HA surface. */
@media (max-height: 500px) {
:host([form-shell]) ha-dialog {
--ha-dialog-border-radius: 0;
--dialog-surface-margin-top: 0;
}
}
.header { .header {
min-height: 56px; min-height: 56px;
@@ -309,6 +338,10 @@ export class HpDialog extends LitElement {
if (this._useHaDialog === null) { if (this._useHaDialog === null) {
this._useHaDialog = !!customElements.get('ha-dialog'); this._useHaDialog = !!customElements.get('ha-dialog');
} }
// The branch is immutable for this connected instance. Reflect it only so
// the card's light-DOM form canvas can fill HA's body without changing the
// already-reviewed native fallback geometry.
this.toggleAttribute('ha-dialog-shell', this._usesHaDialog());
this.addEventListener('keydown', this._onKeyDown, true); this.addEventListener('keydown', this._onKeyDown, true);
queueMicrotask(() => { queueMicrotask(() => {
// Re-entering the top layer lets the UA choose a default focus target. // Re-entering the top layer lets the UA choose a default focus target.
+2
View File
@@ -579,7 +579,9 @@ export const dialogsStyles = css`
overflow: visible; overflow: visible;
padding: 16px; padding: 16px;
box-sizing: border-box; box-sizing: border-box;
background: var(--hpf-canvas, var(--secondary-background-color, color-mix(in srgb, var(--card-background-color, var(--hp-bg, #202126)) 90%, var(--primary-text-color, #000))));
} }
hp-dialog[form-shell][ha-dialog-shell] .body { min-height: 100%; }
@media (max-width: 480px) { @media (max-width: 480px) {
hp-dialog[form-shell] .body { padding: 12px; } hp-dialog[form-shell] .body { padding: 12px; }
} }
+18
View File
@@ -0,0 +1,18 @@
import test from 'node:test';
import assert from 'node:assert/strict';
import { readFileSync } from 'node:fs';
const consumers = [
['space', 'src/editors/space-settings-dialog.ts'],
['settings', 'src/editors/general-settings-dialog.ts'],
['room', 'src/editors/room-settings-dialog.ts'],
['marker', 'src/editors/marker-dialog.ts'],
['onboarding', 'src/houseplan-onboarding-runtime.ts'],
];
test('#609 all five settings consumers opt into the shared form shell', () => {
for (const [kind, file] of consumers) {
const source = readFileSync(new URL(`../${file}`, import.meta.url), 'utf8');
assert.match(source, new RegExp(`data-kind=["']${kind}["'][^>]*form-shell`), file);
}
});