Compare commits

...
21 Commits
Author SHA1 Message Date
Matysh 24e48935c3 Release v1.79.0 candidate: reconcile mirrored main workflow history
Полные бенчмарки производительности / Бенчмарки рендера и геометрии (blend) (push) Canceled after 0s
Полные бенчмарки производительности / Бенчмарки рендера и геометрии (interaction) (push) Canceled after 0s
Полные бенчмарки производительности / Бенчмарки рендера и геометрии (isometric) (push) Canceled after 0s
Полные бенчмарки производительности / Бенчмарки рендера и геометрии (isometric-backdrop) (push) Canceled after 0s
Полные бенчмарки производительности / Бенчмарки рендера и геометрии (isometric-stage3) (push) Canceled after 0s
Полные бенчмарки производительности / Бенчмарки рендера и геометрии (large-house) (push) Canceled after 0s
Полные бенчмарки производительности / Бенчмарки рендера и геометрии (led-strips) (push) Canceled after 0s
Полные бенчмарки производительности / Бенчмарки рендера и геометрии (overlay) (push) Canceled after 0s
Полные бенчмарки производительности / Бенчмарки рендера и геометрии (space-glow) (push) Canceled after 0s
Проверка (CI) / Предполёт: документация, провенанс, процесс (push) Canceled after 0s
Полные бенчмарки производительности / Бенчмарки рендера и геометрии (plan-snap) (push) Canceled after 0s
Полные бенчмарки производительности / Бенчмарки рендера и геометрии (space-default) (push) Canceled after 0s
Проверка (CI) / Классификация изменённых файлов (push) Canceled after 0s
Проверка (CI) / Переиспользование: это дерево уже проверено (push) Canceled after 0s
Проверка (CI) / HACS: валидация репозитория (push) Canceled after 0s
Проверка (CI) / Hassfest: манифест интеграции (push) Canceled after 0s
Проверка (CI) / Мутанты по диффу (1/6): затронутые свидетели краснеют (push) Canceled after 0s
Проверка (CI) / Мутанты по диффу (2/6): затронутые свидетели краснеют (push) Canceled after 0s
Проверка (CI) / Мутанты по диффу (3/6): затронутые свидетели краснеют (push) Canceled after 0s
Проверка (CI) / Мутанты по диффу (4/6): затронутые свидетели краснеют (push) Canceled after 0s
Проверка (CI) / Мутанты по диффу (5/6): затронутые свидетели краснеют (push) Canceled after 0s
Проверка (CI) / Мутанты по диффу (6/6): затронутые свидетели краснеют (push) Canceled after 0s
Проверка (CI) / Фронтенд: типы, юниты, мутанты, синхрон бандла (push) Canceled after 0s
Проверка (CI) / Бандл головы dev для стенда (push) Canceled after 0s
Проверка (CI) / Смоки в браузере (шард 1 из 3) (push) Canceled after 0s
Проверка (CI) / Смоки в браузере (шард 2 из 3) (push) Canceled after 0s
Проверка (CI) / Смоки в браузере (шард 3 из 3) (push) Canceled after 0s
Проверка (CI) / Смоки: все шарды зелёные (push) Canceled after 0s
Проверка (CI) / Golden-кадры против принятых эталонов (push) Canceled after 0s
Проверка (CI) / Перф-смок: бюджет времени кадра (push) Canceled after 0s
Проверка (CI) / Геометрия: TS/Python parity исполнена (push) Canceled after 0s
Проверка (CI) / Бэкенд: pytest в Home Assistant (push) Canceled after 0s
Проверка (CI) / Доказательство выполненных проверок (push) Canceled after 0s
Merge the previously mirrored #716 workflow callers. Both already match dev
byte-for-byte; the candidate Git tree is unchanged. This makes the stable
promotion a fast-forward without rewriting main or dev history.

Release: v1.79.0
Issue: #716
Issue: #780
Issue: #788
User-Visible: no
2026-10-03 22:26:34 +03:00
Matysh 6b0d7d66dd Release v1.79.0 candidate
Promote published v1.79.0-beta.7 without feature-source changes.
Aggregate stable highlights since v1.78.0 and rebuild versioned assets.

Release: v1.79.0
Issue: #780
Issue: #788
User-Visible: yes
2026-10-03 22:24:42 +03:00
Matysh 0588fa8f0a Release v1.79.0-beta.7 candidate
Release: v1.79.0-beta.7
Issue: #788
User-Visible: yes
2026-10-03 20:12:10 +03:00
claude[bot] 019cfa5c5a docs: accept derived artifacts on dev for v1.79.0-beta.7
Производные артефакты беты — одним коммитом на dev (PROCESS.md §8, §11.4, #697).
Прогон: https://github.com/Matysh/houseplan-card/actions/runs/37139464966
Скриншоты документации: отпечаток исходников; изменённые кадры: нет.

Issue: #697
User-Visible: no
2026-10-03 17:11:26 +00:00
Matysh 5fff48f7b1 docs(led): record full regression acceptance and self-review
Issue: #788
User-Visible: no
2026-10-03 19:38:27 +03:00
Matysh a74a50d331 test(led): align mutation witness after occluder filtering
Keep the executable shared-masonry proof without adding new text anchors
against the monolith. Update the unchanged circle-event mutation oracle.

Issue: #788
User-Visible: no
2026-10-03 19:21:46 +03:00
Matysh 416d2fae71 perf(led): avoid redundant tube and barrier calculations
Preserve exact light fields while culling provably distant occluders,
reusing physical tube paths across camera updates and excluding LED emitter
data from aligned architectural fingerprints. Cover output equivalence,
in-place invalidation, resize tags and hyphenated benchmark chunk hashes.

Issue: #788
User-Visible: yes
2026-10-03 19:18:49 +03:00
Matysh 08bc58cc0e chore(golden): accept corrected LED end-cap feather
Reviewed Linux Validate 37134548622 on c142e4f7. The right free cap now
fades through the valid wall-circle crescent instead of cutting it away.
One declared frame changed; 199 baselines retained, 101 exact witnesses.
Private household screenshots were not uploaded or committed.

Issue: #788
User-Visible: no
Release: v1.79.0-beta.7
Baseline-Reviewed: https://github.com/Matysh/houseplan-card/actions/runs/37134548622
2026-10-03 18:58:09 +03:00
Matysh c142e4f7b5 fix(led): preserve strip corners and feather the complete light field
Keep real end and corner emitters, robust decimal joins and wall-circle
sweep events. Render one positive-winding compound visibility clip so
Chromium cannot cancel or cut away overlapping light regions.

Add independent pixel oracles for glow falloff and wall-following tubes.
Replace the lossy fan-count limit with explicit cached-path bounds while
retaining the original timing and warm-cycle heap-growth limits.

Issue: #788
User-Visible: yes
2026-10-03 18:46:35 +03:00
Matysh ad10a5b099 chore(release): prepare v1.79.0-beta.6
Build the beta candidate, date both changelogs, refresh release notes and tighten release ratchets.

Release: v1.79.0-beta.6
Issue: #786
Issue: #787
User-Visible: yes
2026-10-03 17:58:43 +03:00
Matysh 76310fc981 docs(screenshots): обновить fingerprint после #787 2026-10-03 17:39:20 +03:00
Matysh 0f466743c3 chore(golden): эталон прямоугольной LED-ленты (#787)
Issue: #787
User-Visible: no
Release: v1.79.0-beta.6
Baseline-Reviewed-Local: sha256:44eb42f580fc9f973509af68f47565b4cad2a9a6200e445e728f6198e785ef98
2026-10-03 17:26:56 +03:00
Matysh 35ef231191 fix(led): сохранить прямоугольник через проёмы (#787)
Issue: #787
User-Visible: yes
2026-10-03 17:17:50 +03:00
Matysh fab28af26f docs(screenshots): обновить fingerprint после #786 2026-10-03 17:00:16 +03:00
Matysh a54429d4a3 chore(golden): эталон гладких торцов LED-ленты (#786)
Issue: #786
User-Visible: no
Release: v1.79.0-beta.6
Baseline-Reviewed-Local: sha256:1c7933e47079b24064413013a999ed10376a0aad05f8c8f57f1c683bb64c6ae7
2026-10-03 16:51:39 +03:00
Matysh 9598768167 fix(led): сгладить торцы поля свечения (#786)
Issue: #786
User-Visible: yes
2026-10-03 16:41:10 +03:00
Matysh aa1105468b chore(release): prepare v1.79.0-beta.5
Проверка (CI) / Предполёт: документация, провенанс, процесс (push) Canceled after 0s
Проверка (CI) / Классификация изменённых файлов (push) Canceled after 0s
Проверка (CI) / Переиспользование: это дерево уже проверено (push) Canceled after 0s
Проверка (CI) / HACS: валидация репозитория (push) Canceled after 0s
Проверка (CI) / Hassfest: манифест интеграции (push) Canceled after 0s
Проверка (CI) / Мутанты по диффу (1/6): затронутые свидетели краснеют (push) Canceled after 0s
Проверка (CI) / Мутанты по диффу (2/6): затронутые свидетели краснеют (push) Canceled after 0s
Проверка (CI) / Мутанты по диффу (3/6): затронутые свидетели краснеют (push) Canceled after 0s
Проверка (CI) / Мутанты по диффу (4/6): затронутые свидетели краснеют (push) Canceled after 0s
Проверка (CI) / Мутанты по диффу (5/6): затронутые свидетели краснеют (push) Canceled after 0s
Проверка (CI) / Мутанты по диффу (6/6): затронутые свидетели краснеют (push) Canceled after 0s
Проверка (CI) / Фронтенд: типы, юниты, мутанты, синхрон бандла (push) Canceled after 0s
Проверка (CI) / Бандл головы dev для стенда (push) Canceled after 0s
Проверка (CI) / Смоки в браузере (шард 1 из 3) (push) Canceled after 0s
Проверка (CI) / Смоки в браузере (шард 2 из 3) (push) Canceled after 0s
Проверка (CI) / Смоки в браузере (шард 3 из 3) (push) Canceled after 0s
Проверка (CI) / Смоки: все шарды зелёные (push) Canceled after 0s
Проверка (CI) / Golden-кадры против принятых эталонов (push) Canceled after 0s
Проверка (CI) / Перф-смок: бюджет времени кадра (push) Canceled after 0s
Проверка (CI) / Геометрия: TS/Python parity исполнена (push) Canceled after 0s
Проверка (CI) / Бэкенд: pytest в Home Assistant (push) Canceled after 0s
Проверка (CI) / Доказательство выполненных проверок (push) Canceled after 0s
Build the beta candidate, date both changelogs, refresh release notes and tighten release ratchets.

Release: v1.79.0-beta.5
Issue: #785
User-Visible: yes
2026-10-03 14:24:42 +03:00
claude[bot] 42d1a8a9dc docs: accept derived artifacts on dev for v1.79.0-beta.5
Производные артефакты беты — одним коммитом на dev (PROCESS.md §8, §11.4, #697).
Прогон: https://github.com/Matysh/houseplan-card/actions/runs/37119340533
Скриншоты документации: отпечаток исходников; изменённые кадры: нет.

Issue: #697
User-Visible: no
2026-10-03 11:22:39 +00:00
Matysh 8b88a6f606 chore(golden): accept LED strip continuity scenes (#785)
Issue: #785
User-Visible: no
Release: v1.79.0-beta.5
Baseline-Reviewed-Local: sha256:c30cae622673c0e45a45de8a63d12e8c0f7cc5cc1ff5bf147450849a7158e35e
2026-10-03 14:12:46 +03:00
Matysh 4c7e9815f3 fix(led): сохранить непрерывный Glow и толщину ленты (#785)
Issue: #785
User-Visible: yes
2026-10-03 14:00:14 +03:00
Claude 2022e183a5 ci: mirror thin workflow callers in main after #716
Проверка (CI) / Предполёт: документация, провенанс, процесс (push) Canceled after 0s
Проверка (CI) / Классификация изменённых файлов (push) Canceled after 0s
Проверка (CI) / Переиспользование: это дерево уже проверено (push) Canceled after 0s
Проверка (CI) / HACS: валидация репозитория (push) Canceled after 0s
Проверка (CI) / Hassfest: манифест интеграции (push) Canceled after 0s
Проверка (CI) / Мутанты по диффу (1/6): затронутые свидетели краснеют (push) Canceled after 0s
Проверка (CI) / Мутанты по диффу (2/6): затронутые свидетели краснеют (push) Canceled after 0s
Проверка (CI) / Мутанты по диффу (3/6): затронутые свидетели краснеют (push) Canceled after 0s
Проверка (CI) / Мутанты по диффу (4/6): затронутые свидетели краснеют (push) Canceled after 0s
Проверка (CI) / Мутанты по диффу (5/6): затронутые свидетели краснеют (push) Canceled after 0s
Проверка (CI) / Мутанты по диффу (6/6): затронутые свидетели краснеют (push) Canceled after 0s
Проверка (CI) / Фронтенд: типы, юниты, мутанты, синхрон бандла (push) Canceled after 0s
Проверка (CI) / Бандл головы dev для стенда (push) Canceled after 0s
Проверка (CI) / Смоки в браузере (шард 1 из 3) (push) Canceled after 0s
Проверка (CI) / Смоки в браузере (шард 2 из 3) (push) Canceled after 0s
Проверка (CI) / Смоки в браузере (шард 3 из 3) (push) Canceled after 0s
Проверка (CI) / Смоки: все шарды зелёные (push) Canceled after 0s
Проверка (CI) / Golden-кадры против принятых эталонов (push) Canceled after 0s
Проверка (CI) / Перф-смок: бюджет времени кадра (push) Canceled after 0s
Проверка (CI) / Геометрия: TS/Python parity исполнена (push) Canceled after 0s
Проверка (CI) / Бэкенд: pytest в Home Assistant (push) Canceled after 0s
Проверка (CI) / Доказательство выполненных проверок (push) Canceled after 0s
Кнопку и запуск workflow_dispatch GitHub даёт только workflow, чей файл
лежит в ветке по умолчанию: ship-review.yml (#696) и beta-derived.yml (#697)
жили только в dev и не запускались вовсе. Два тонких вызывающих файла —
кнопка, входы, run-name, потолок прав и concurrency; тела `_ship-review.yml`
и `_beta-derived.yml` вызываются `@dev`. Файлы байт-в-байт равны ветке
задачи issue/716-register-dispatch-workflows@5451542e. В dev она сливается
после этого коммита: в обратном порядке preflight workflow_sync на dev
нашёл бы файлы, которых нет в main.

Issue: #716
User-Visible: no
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018qZfe7YS4rqEMKoVeS3GKd
2026-09-30 21:40:31 +03:00
144 changed files with 3185 additions and 1640 deletions
+1 -1
View File
@@ -57,7 +57,7 @@ SCHEDULED_GRACE_S = 30 * 24 * 3600
FILES_DIR = "houseplan/files"
ASSETS_DIR = "houseplan/assets"
CONF_ADMIN_ONLY = "admin_only"
VERSION = "1.79.0-beta.4"
VERSION = "1.79.0"
DECOR_ASSETS_API_VERSION = 1
SUMMARY_PANEL_API_VERSION = 1
@@ -1,598 +1,598 @@
{
"schema": 1,
"fingerprint": "fd4a405e9c5a21035258c45feca26dca03d59d4cfba4280f89ff5f82675515ac",
"fingerprint": "ab07da35681c15ab6136c323500b69766580ea4a788e399ea88f9e7497549172",
"entry": "houseplan-card.js",
"panelEntry": "houseplan-panel.js",
"initialViewFiles": [
"houseplan-assets/houseplan-card-CDzf9V5z.js",
"houseplan-assets/houseplan-card-BOdiRDFR.js",
"houseplan-card.js"
],
"initialViewGzipBytes": 300069,
"initialViewGzipBytes": 300133,
"initialPanelFiles": [
"houseplan-assets/houseplan-card-CDzf9V5z.js",
"houseplan-assets/houseplan-card-BOdiRDFR.js",
"houseplan-panel.js"
],
"initialPanelGzipBytes": 301590,
"initialPanelGzipBytes": 301657,
"initialPanelOnlyFiles": [
"houseplan-panel.js"
],
"initialPanelOnlyGzipBytes": 2324,
"initialPanelOnlyGzipBytes": 2328,
"lazyFiles": [
"houseplan-assets/backdrop-pick-361D_NhT.js",
"houseplan-assets/de-wSrjkMCX.js",
"houseplan-assets/editor-CAHVNjOb.js",
"houseplan-assets/form-kit.styles-Dq1Y4tz1.js",
"houseplan-assets/fr-Cb7RjPXv.js",
"houseplan-assets/furniture-plan-art.generated-DHB0O8RC.js",
"houseplan-assets/houseplan-editor-runtime-D7Nrak81.js",
"houseplan-assets/houseplan-onboarding-runtime-BDfCLIiS.js",
"houseplan-assets/hp-zigbee-topology-overlay-W_gG_T_A.js",
"houseplan-assets/iso-scene-render-CBGc0yON.js",
"houseplan-assets/led-strip-editor-55w_99OW.js",
"houseplan-assets/led-strip-geometry-BcPfXtN-.js",
"houseplan-assets/led-strip-runtime-C0OS8_qS.js",
"houseplan-assets/live-interaction-runtime-CgDUYt60.js",
"houseplan-assets/moon-runtime-DkqNfOp0.js",
"houseplan-assets/namespace-language-BPjMJUHI.js",
"houseplan-assets/pdf-export-UdR2EXb9.js",
"houseplan-assets/space-editor-N5uYQl3H.js",
"houseplan-assets/summary-panel-runtime-loaded-BcDAIp5L.js",
"houseplan-assets/zigbee-topology-Co7YPeRf.js",
"houseplan-assets/zigbee-topology-runtime-ByS3kW9n.js"
"houseplan-assets/backdrop-pick-DHF8oaNH.js",
"houseplan-assets/de-C4xCvmYr.js",
"houseplan-assets/editor-CFo6BxSe.js",
"houseplan-assets/form-kit.styles-B6HsmMPA.js",
"houseplan-assets/fr-BJJefRIG.js",
"houseplan-assets/furniture-plan-art.generated-XIg9ZqQe.js",
"houseplan-assets/houseplan-editor-runtime-CqreRULk.js",
"houseplan-assets/houseplan-onboarding-runtime-DOfjrx0M.js",
"houseplan-assets/hp-zigbee-topology-overlay-BAaZNyAl.js",
"houseplan-assets/iso-scene-render-CR7lxY-w.js",
"houseplan-assets/led-strip-editor-kcNyoue_.js",
"houseplan-assets/led-strip-geometry-DaLifxqY.js",
"houseplan-assets/led-strip-runtime-Bx6qpdWk.js",
"houseplan-assets/live-interaction-runtime-C1983oH8.js",
"houseplan-assets/moon-runtime-Ca1mxhJl.js",
"houseplan-assets/namespace-language-D86tJUeD.js",
"houseplan-assets/pdf-export-C-Y4BSVu.js",
"houseplan-assets/space-editor-EDOQT48H.js",
"houseplan-assets/summary-panel-runtime-loaded-CcLP5B5v.js",
"houseplan-assets/zigbee-topology-BG_a6cIb.js",
"houseplan-assets/zigbee-topology-runtime-CynQ2m3K.js"
],
"lazyGzipBytes": 477990,
"lazyGzipBytes": 478817,
"lazyEditorFiles": [
"houseplan-assets/backdrop-pick-361D_NhT.js",
"houseplan-assets/editor-CAHVNjOb.js",
"houseplan-assets/form-kit.styles-Dq1Y4tz1.js",
"houseplan-assets/furniture-plan-art.generated-DHB0O8RC.js",
"houseplan-assets/houseplan-editor-runtime-D7Nrak81.js",
"houseplan-assets/namespace-language-BPjMJUHI.js",
"houseplan-assets/zigbee-topology-Co7YPeRf.js"
"houseplan-assets/backdrop-pick-DHF8oaNH.js",
"houseplan-assets/editor-CFo6BxSe.js",
"houseplan-assets/form-kit.styles-B6HsmMPA.js",
"houseplan-assets/furniture-plan-art.generated-XIg9ZqQe.js",
"houseplan-assets/houseplan-editor-runtime-CqreRULk.js",
"houseplan-assets/namespace-language-D86tJUeD.js",
"houseplan-assets/zigbee-topology-BG_a6cIb.js"
],
"lazyEditorGzipBytes": 240863,
"lazyEditorGzipBytes": 240843,
"lazyOnboardingFiles": [
"houseplan-assets/backdrop-pick-361D_NhT.js",
"houseplan-assets/form-kit.styles-Dq1Y4tz1.js",
"houseplan-assets/houseplan-onboarding-runtime-BDfCLIiS.js",
"houseplan-assets/namespace-language-BPjMJUHI.js"
"houseplan-assets/backdrop-pick-DHF8oaNH.js",
"houseplan-assets/form-kit.styles-B6HsmMPA.js",
"houseplan-assets/houseplan-onboarding-runtime-DOfjrx0M.js",
"houseplan-assets/namespace-language-D86tJUeD.js"
],
"lazyOnboardingGzipBytes": 28403,
"lazyOnboardingGzipBytes": 28402,
"lazyLocaleFiles": [
"houseplan-assets/de-wSrjkMCX.js",
"houseplan-assets/fr-Cb7RjPXv.js"
"houseplan-assets/de-C4xCvmYr.js",
"houseplan-assets/fr-BJJefRIG.js"
],
"lazyLocaleGzipBytes": 53859,
"lazyLocaleGzipBytes": 53876,
"lazyIsometricFiles": [
"houseplan-assets/iso-scene-render-CBGc0yON.js"
"houseplan-assets/iso-scene-render-CR7lxY-w.js"
],
"lazyIsometricGzipBytes": 12345,
"lazyIsometricGzipBytes": 12348,
"lazyFurnitureArtFiles": [
"houseplan-assets/furniture-plan-art.generated-DHB0O8RC.js"
"houseplan-assets/furniture-plan-art.generated-XIg9ZqQe.js"
],
"lazyFurnitureArtGzipBytes": 16940,
"lazyFurnitureArtGzipBytes": 16936,
"lazyPdfFiles": [
"houseplan-assets/furniture-plan-art.generated-DHB0O8RC.js",
"houseplan-assets/pdf-export-UdR2EXb9.js"
"houseplan-assets/furniture-plan-art.generated-XIg9ZqQe.js",
"houseplan-assets/pdf-export-C-Y4BSVu.js"
],
"lazyPdfGzipBytes": 126938,
"lazyPdfGzipBytes": 126934,
"lazyMoonFiles": [
"houseplan-assets/moon-runtime-DkqNfOp0.js"
"houseplan-assets/moon-runtime-Ca1mxhJl.js"
],
"lazyMoonGzipBytes": 11713,
"lazyLedFiles": [
"houseplan-assets/led-strip-field-DvtQ7tpM.js",
"houseplan-assets/led-strip-geometry-BcPfXtN-.js",
"houseplan-assets/led-strip-runtime-C0OS8_qS.js"
"houseplan-assets/led-strip-field-ObbckCkp.js",
"houseplan-assets/led-strip-geometry-DaLifxqY.js",
"houseplan-assets/led-strip-runtime-Bx6qpdWk.js"
],
"lazyLedGzipBytes": 9544,
"lazyLedGzipBytes": 10613,
"lazyLedEditorFiles": [
"houseplan-assets/led-strip-editor-55w_99OW.js",
"houseplan-assets/led-strip-geometry-BcPfXtN-.js",
"houseplan-assets/namespace-language-BPjMJUHI.js"
"houseplan-assets/led-strip-editor-kcNyoue_.js",
"houseplan-assets/led-strip-geometry-DaLifxqY.js",
"houseplan-assets/namespace-language-D86tJUeD.js"
],
"lazyLedEditorGzipBytes": 10033,
"lazyLedEditorGzipBytes": 10707,
"lazyNamespaceLocaleFiles": [
"houseplan-assets/led-de-D8AOGwO9.js",
"houseplan-assets/led-fr-Dyd_xJWH.js",
"houseplan-assets/led-ru-DxKs7cgH.js",
"houseplan-assets/settings-de-hkfrpcmk.js",
"houseplan-assets/settings-fr-CTDbCfmV.js",
"houseplan-assets/settings-ru-_XLAbOEk.js",
"houseplan-assets/support-de-DF73IEHL.js",
"houseplan-assets/support-fr-BBhMT3I0.js",
"houseplan-assets/support-ru-Bd7vkOXI.js",
"houseplan-assets/tools-de-DwmzTHwi.js",
"houseplan-assets/tools-fr-Dp5JXY-G.js",
"houseplan-assets/tools-ru-CAQB2Qhv.js",
"houseplan-assets/topology-de-DFY0lBO-.js",
"houseplan-assets/topology-fr-DbNDk6Er.js",
"houseplan-assets/topology-ru-BNVYY-_i.js"
"houseplan-assets/led-de-yp1GefDC.js",
"houseplan-assets/led-fr-CHODsRJm.js",
"houseplan-assets/led-ru-D2-9Yy6l.js",
"houseplan-assets/settings-de-ZP6F6dIF.js",
"houseplan-assets/settings-fr-doqd_TsB.js",
"houseplan-assets/settings-ru-CQ1W2gik.js",
"houseplan-assets/support-de-haZQ7q8i.js",
"houseplan-assets/support-fr-DnRyZ_Ga.js",
"houseplan-assets/support-ru-B7zzXsuL.js",
"houseplan-assets/tools-de-CYXPPfUH.js",
"houseplan-assets/tools-fr-DvygRB10.js",
"houseplan-assets/tools-ru-2xmu2w_8.js",
"houseplan-assets/topology-de-COda8n9n.js",
"houseplan-assets/topology-fr-BT9yhzay.js",
"houseplan-assets/topology-ru-C-d06yvD.js"
],
"lazyNamespaceLocaleGzipBytes": 30051,
"lazyNamespaceLocaleGzipBytes": 30082,
"files": [
{
"path": "houseplan-assets/backdrop-pick-361D_NhT.js",
"sha256": "8d80eb83488438a96d33410716b91398f1aa7456884d8e9e9094165a830ec9c0",
"path": "houseplan-assets/backdrop-pick-DHF8oaNH.js",
"sha256": "7262c67e3f88f44ee6c6a0973073d1f7c3c9f177ff8254758a21c4e3867c5b06",
"rawBytes": 55329,
"gzipBytes": 18026,
"gzipBytes": 18027,
"isEntry": false,
"imports": [
"houseplan-assets/form-kit.styles-Dq1Y4tz1.js",
"houseplan-assets/houseplan-card-CDzf9V5z.js",
"houseplan-assets/namespace-language-BPjMJUHI.js"
"houseplan-assets/form-kit.styles-B6HsmMPA.js",
"houseplan-assets/houseplan-card-BOdiRDFR.js",
"houseplan-assets/namespace-language-D86tJUeD.js"
],
"dynamicImports": [
"houseplan-assets/settings-de-hkfrpcmk.js",
"houseplan-assets/settings-fr-CTDbCfmV.js",
"houseplan-assets/settings-ru-_XLAbOEk.js"
"houseplan-assets/settings-de-ZP6F6dIF.js",
"houseplan-assets/settings-fr-doqd_TsB.js",
"houseplan-assets/settings-ru-CQ1W2gik.js"
]
},
{
"path": "houseplan-assets/de-wSrjkMCX.js",
"sha256": "b6873407a3663932da1261fb151e3c81c78e4cfda3ad3d88946e076c524e2e27",
"path": "houseplan-assets/de-C4xCvmYr.js",
"sha256": "e3778d3139c05e075281f96460e15a6aaafe8dd9200306b0a3799a1bc5710828",
"rawBytes": 89873,
"gzipBytes": 27163,
"gzipBytes": 27169,
"isEntry": false,
"imports": [],
"dynamicImports": []
},
{
"path": "houseplan-assets/editor-CAHVNjOb.js",
"sha256": "29b283f4d700ecf0256cb09f858a3944f9722c40711ad3ed9d9fee90d5a2175f",
"path": "houseplan-assets/editor-CFo6BxSe.js",
"sha256": "81d90441a06989a01a09c19e8c73567b80cd4d6ba52e4ea4796e096e1e5b7aa4",
"rawBytes": 3833,
"gzipBytes": 1583,
"gzipBytes": 1584,
"isEntry": false,
"imports": [
"houseplan-assets/houseplan-card-CDzf9V5z.js"
"houseplan-assets/houseplan-card-BOdiRDFR.js"
],
"dynamicImports": []
},
{
"path": "houseplan-assets/form-kit.styles-Dq1Y4tz1.js",
"sha256": "57078cb29919b2d801225f1f15f59fcac028907b7126b5a684a5ab89b50ace38",
"path": "houseplan-assets/form-kit.styles-B6HsmMPA.js",
"sha256": "d18d3eb8bf1dd9dda6d6fdeed84edc16d3945e8a7e23b1d88e5f2edcef0a0af6",
"rawBytes": 25605,
"gzipBytes": 5058,
"gzipBytes": 5059,
"isEntry": false,
"imports": [],
"dynamicImports": []
},
{
"path": "houseplan-assets/fr-Cb7RjPXv.js",
"sha256": "f04f19f0f56a70d201c521b74be3a6f7f3b687a93bd91785d50f0984c68508cb",
"path": "houseplan-assets/fr-BJJefRIG.js",
"sha256": "4932ff13f6fdc339e9d67123105f9bd97f051395a3c3310240fc07b119d87024",
"rawBytes": 92266,
"gzipBytes": 26696,
"gzipBytes": 26707,
"isEntry": false,
"imports": [],
"dynamicImports": []
},
{
"path": "houseplan-assets/furniture-plan-art.generated-DHB0O8RC.js",
"sha256": "1f693cbcb7992e269d7a7602962fcce33f21230e7b0edce7c0359942230da941",
"path": "houseplan-assets/furniture-plan-art.generated-XIg9ZqQe.js",
"sha256": "10a0b09e4b1513bd02ffba047d6931add1d1106c453af03f6b3c778b5bb55e15",
"rawBytes": 52035,
"gzipBytes": 16940,
"gzipBytes": 16936,
"isEntry": false,
"imports": [],
"dynamicImports": []
},
{
"path": "houseplan-assets/houseplan-card-CDzf9V5z.js",
"sha256": "43829456356d3d4d59efa17ccbb75326350ad79fc4413862dfa50ec98c1ca24e",
"rawBytes": 1056226,
"gzipBytes": 299266,
"path": "houseplan-assets/houseplan-card-BOdiRDFR.js",
"sha256": "37c784960d53789a66988a4e4ab8a8afe88aeddb80c5f244f3d453ef86c3ba8c",
"rawBytes": 1056405,
"gzipBytes": 299329,
"isEntry": false,
"imports": [],
"dynamicImports": [
"houseplan-assets/de-wSrjkMCX.js",
"houseplan-assets/editor-CAHVNjOb.js",
"houseplan-assets/fr-Cb7RjPXv.js",
"houseplan-assets/furniture-plan-art.generated-DHB0O8RC.js",
"houseplan-assets/houseplan-editor-runtime-D7Nrak81.js",
"houseplan-assets/houseplan-onboarding-runtime-BDfCLIiS.js",
"houseplan-assets/hp-zigbee-topology-overlay-W_gG_T_A.js",
"houseplan-assets/iso-scene-render-CBGc0yON.js",
"houseplan-assets/led-strip-editor-55w_99OW.js",
"houseplan-assets/led-strip-runtime-C0OS8_qS.js",
"houseplan-assets/live-interaction-runtime-CgDUYt60.js",
"houseplan-assets/moon-runtime-DkqNfOp0.js",
"houseplan-assets/pdf-export-UdR2EXb9.js",
"houseplan-assets/space-editor-N5uYQl3H.js",
"houseplan-assets/summary-panel-runtime-loaded-BcDAIp5L.js"
"houseplan-assets/de-C4xCvmYr.js",
"houseplan-assets/editor-CFo6BxSe.js",
"houseplan-assets/fr-BJJefRIG.js",
"houseplan-assets/furniture-plan-art.generated-XIg9ZqQe.js",
"houseplan-assets/houseplan-editor-runtime-CqreRULk.js",
"houseplan-assets/houseplan-onboarding-runtime-DOfjrx0M.js",
"houseplan-assets/hp-zigbee-topology-overlay-BAaZNyAl.js",
"houseplan-assets/iso-scene-render-CR7lxY-w.js",
"houseplan-assets/led-strip-editor-kcNyoue_.js",
"houseplan-assets/led-strip-runtime-Bx6qpdWk.js",
"houseplan-assets/live-interaction-runtime-C1983oH8.js",
"houseplan-assets/moon-runtime-Ca1mxhJl.js",
"houseplan-assets/pdf-export-C-Y4BSVu.js",
"houseplan-assets/space-editor-EDOQT48H.js",
"houseplan-assets/summary-panel-runtime-loaded-CcLP5B5v.js"
]
},
{
"path": "houseplan-assets/houseplan-editor-runtime-D7Nrak81.js",
"sha256": "ba4c1682823b15bce834bd41d0bc0d7fc4327fc6cc099175eb5651c285f9a938",
"path": "houseplan-assets/houseplan-editor-runtime-CqreRULk.js",
"sha256": "772b538d5b87265a0e88117f01034a3ccadd5f4e928ced77cb99254ab74e299a",
"rawBytes": 695353,
"gzipBytes": 194544,
"gzipBytes": 194530,
"isEntry": false,
"imports": [
"houseplan-assets/backdrop-pick-361D_NhT.js",
"houseplan-assets/form-kit.styles-Dq1Y4tz1.js",
"houseplan-assets/furniture-plan-art.generated-DHB0O8RC.js",
"houseplan-assets/houseplan-card-CDzf9V5z.js",
"houseplan-assets/namespace-language-BPjMJUHI.js",
"houseplan-assets/zigbee-topology-Co7YPeRf.js"
"houseplan-assets/backdrop-pick-DHF8oaNH.js",
"houseplan-assets/form-kit.styles-B6HsmMPA.js",
"houseplan-assets/furniture-plan-art.generated-XIg9ZqQe.js",
"houseplan-assets/houseplan-card-BOdiRDFR.js",
"houseplan-assets/namespace-language-D86tJUeD.js",
"houseplan-assets/zigbee-topology-BG_a6cIb.js"
],
"dynamicImports": [
"houseplan-assets/support-de-DF73IEHL.js",
"houseplan-assets/support-fr-BBhMT3I0.js",
"houseplan-assets/support-ru-Bd7vkOXI.js",
"houseplan-assets/tools-de-DwmzTHwi.js",
"houseplan-assets/tools-fr-Dp5JXY-G.js",
"houseplan-assets/tools-ru-CAQB2Qhv.js",
"houseplan-assets/zigbee-topology-runtime-ByS3kW9n.js"
"houseplan-assets/support-de-haZQ7q8i.js",
"houseplan-assets/support-fr-DnRyZ_Ga.js",
"houseplan-assets/support-ru-B7zzXsuL.js",
"houseplan-assets/tools-de-CYXPPfUH.js",
"houseplan-assets/tools-fr-DvygRB10.js",
"houseplan-assets/tools-ru-2xmu2w_8.js",
"houseplan-assets/zigbee-topology-runtime-CynQ2m3K.js"
]
},
{
"path": "houseplan-assets/houseplan-onboarding-runtime-BDfCLIiS.js",
"sha256": "89044bd3a7f52fc1f1b373b31576dc1d7180a011c1eeef264f79c6f5d00023e0",
"path": "houseplan-assets/houseplan-onboarding-runtime-DOfjrx0M.js",
"sha256": "242ae570916ec2a000a8a0079a948826faeb45c0968cc1006e9670f9d3c4088b",
"rawBytes": 15886,
"gzipBytes": 4910,
"gzipBytes": 4907,
"isEntry": false,
"imports": [
"houseplan-assets/backdrop-pick-361D_NhT.js",
"houseplan-assets/form-kit.styles-Dq1Y4tz1.js",
"houseplan-assets/houseplan-card-CDzf9V5z.js",
"houseplan-assets/namespace-language-BPjMJUHI.js"
"houseplan-assets/backdrop-pick-DHF8oaNH.js",
"houseplan-assets/form-kit.styles-B6HsmMPA.js",
"houseplan-assets/houseplan-card-BOdiRDFR.js",
"houseplan-assets/namespace-language-D86tJUeD.js"
],
"dynamicImports": []
},
{
"path": "houseplan-assets/hp-zigbee-topology-overlay-W_gG_T_A.js",
"sha256": "673cd02181555b4849ebe42fd3053ce67b7f97dcd14fcfc61e81c119be120c5b",
"path": "houseplan-assets/hp-zigbee-topology-overlay-BAaZNyAl.js",
"sha256": "8cb7c3f010cf7ef792a676bfd994c4498f31222dd12ded79e3e2f37dfae4f52e",
"rawBytes": 10958,
"gzipBytes": 3768,
"isEntry": false,
"imports": [
"houseplan-assets/houseplan-card-CDzf9V5z.js",
"houseplan-assets/namespace-language-BPjMJUHI.js",
"houseplan-assets/zigbee-topology-Co7YPeRf.js",
"houseplan-assets/zigbee-topology-runtime-ByS3kW9n.js"
"houseplan-assets/houseplan-card-BOdiRDFR.js",
"houseplan-assets/namespace-language-D86tJUeD.js",
"houseplan-assets/zigbee-topology-BG_a6cIb.js",
"houseplan-assets/zigbee-topology-runtime-CynQ2m3K.js"
],
"dynamicImports": []
},
{
"path": "houseplan-assets/iso-scene-render-CBGc0yON.js",
"sha256": "1f2456f515056c6fba882cbd6b510635bdb1c12d63cb648b741c4e61b13e6197",
"path": "houseplan-assets/iso-scene-render-CR7lxY-w.js",
"sha256": "1986dd43c8b76580f893c1629d494f7747f02aa8d544baff20d56fe10b470bb5",
"rawBytes": 36700,
"gzipBytes": 12345,
"gzipBytes": 12348,
"isEntry": false,
"imports": [
"houseplan-assets/houseplan-card-CDzf9V5z.js"
"houseplan-assets/houseplan-card-BOdiRDFR.js"
],
"dynamicImports": []
},
{
"path": "houseplan-assets/led-de-D8AOGwO9.js",
"sha256": "cc7a9e048e16ad6c7869d7f72a0e4d7bde6451d29eb8fd5ec205a887fec62d97",
"path": "houseplan-assets/led-de-yp1GefDC.js",
"sha256": "eb9ce8bb536ac20e11cf4fe925d68f28b1ba8a5ea02c61abf9c3bb939de0a4c4",
"rawBytes": 1907,
"gzipBytes": 919,
"gzipBytes": 921,
"isEntry": false,
"imports": [],
"dynamicImports": []
},
{
"path": "houseplan-assets/led-fr-Dyd_xJWH.js",
"sha256": "e293c332b3bb877683b7781c16e0fad2cb6a72f271d779c7a398af29b2497027",
"path": "houseplan-assets/led-fr-CHODsRJm.js",
"sha256": "adb428bd63b6157ef0a5d749badf94e95204c9c3b83e5f3022accf65d304435e",
"rawBytes": 1886,
"gzipBytes": 905,
"gzipBytes": 906,
"isEntry": false,
"imports": [],
"dynamicImports": []
},
{
"path": "houseplan-assets/led-ru-DxKs7cgH.js",
"sha256": "06d0b17e3954e65270dcb7356f6672923185e8b5af38632eebbe99b5af1aab50",
"path": "houseplan-assets/led-ru-D2-9Yy6l.js",
"sha256": "bc5575139b30d6e93e07673f47865c332e71011796929a52043645a904d6df31",
"rawBytes": 2525,
"gzipBytes": 1105,
"gzipBytes": 1106,
"isEntry": false,
"imports": [],
"dynamicImports": []
},
{
"path": "houseplan-assets/led-strip-editor-55w_99OW.js",
"sha256": "77ee4a59643984f94f1ff57f96013858e2cdc258b13ae01497b46f4057f62442",
"path": "houseplan-assets/led-strip-editor-kcNyoue_.js",
"sha256": "dac9fdcaae6444caa1773a07384155cc92b916d2ebf3498e1dfc1b3525a84753",
"rawBytes": 21704,
"gzipBytes": 7380,
"gzipBytes": 7381,
"isEntry": false,
"imports": [
"houseplan-assets/houseplan-card-CDzf9V5z.js",
"houseplan-assets/led-strip-geometry-BcPfXtN-.js",
"houseplan-assets/namespace-language-BPjMJUHI.js"
"houseplan-assets/houseplan-card-BOdiRDFR.js",
"houseplan-assets/led-strip-geometry-DaLifxqY.js",
"houseplan-assets/namespace-language-D86tJUeD.js"
],
"dynamicImports": [
"houseplan-assets/led-de-D8AOGwO9.js",
"houseplan-assets/led-fr-Dyd_xJWH.js",
"houseplan-assets/led-ru-DxKs7cgH.js"
"houseplan-assets/led-de-yp1GefDC.js",
"houseplan-assets/led-fr-CHODsRJm.js",
"houseplan-assets/led-ru-D2-9Yy6l.js"
]
},
{
"path": "houseplan-assets/led-strip-field-DvtQ7tpM.js",
"sha256": "6b3bf5cf737a4b3136d65951e57bc93d07664fc34cc2ddc7ba502a1c567496d3",
"rawBytes": 7384,
"gzipBytes": 3073,
"path": "houseplan-assets/led-strip-field-ObbckCkp.js",
"sha256": "b85d8de01906a7e70f28baff534cf1a211216c99b72005b6d77a0d19cbb5ce8f",
"rawBytes": 7920,
"gzipBytes": 3321,
"isEntry": false,
"imports": [
"houseplan-assets/houseplan-card-CDzf9V5z.js",
"houseplan-assets/led-strip-geometry-BcPfXtN-.js"
"houseplan-assets/houseplan-card-BOdiRDFR.js",
"houseplan-assets/led-strip-geometry-DaLifxqY.js"
],
"dynamicImports": []
},
{
"path": "houseplan-assets/led-strip-geometry-BcPfXtN-.js",
"sha256": "96e1f3dce530f9e05d7b55bc32c9b998c8e9d291bef92c7c2b78d57948ece933",
"rawBytes": 5231,
"gzipBytes": 2244,
"path": "houseplan-assets/led-strip-geometry-DaLifxqY.js",
"sha256": "2dfbe1509da809008c9a525a7ed02226c026aaa5c0dafcb9f3dc1c44151ed63e",
"rawBytes": 7055,
"gzipBytes": 2917,
"isEntry": false,
"imports": [],
"dynamicImports": []
},
{
"path": "houseplan-assets/led-strip-runtime-C0OS8_qS.js",
"sha256": "933125d5e1f0504e56291e5289237630a79f5502f9b5701dc3d76f2dc470aed6",
"rawBytes": 10760,
"gzipBytes": 4227,
"path": "houseplan-assets/led-strip-runtime-Bx6qpdWk.js",
"sha256": "6fd2d3578e550dfbe8c38308923e21f9fddeb469f64e8fcf295dc292949ddf32",
"rawBytes": 11179,
"gzipBytes": 4375,
"isEntry": false,
"imports": [
"houseplan-assets/houseplan-card-CDzf9V5z.js",
"houseplan-assets/led-strip-geometry-BcPfXtN-.js"
"houseplan-assets/houseplan-card-BOdiRDFR.js",
"houseplan-assets/led-strip-geometry-DaLifxqY.js"
],
"dynamicImports": [
"houseplan-assets/led-strip-field-DvtQ7tpM.js"
"houseplan-assets/led-strip-field-ObbckCkp.js"
]
},
{
"path": "houseplan-assets/live-interaction-runtime-CgDUYt60.js",
"sha256": "5e3ea0225cba5931aa51cd398062f5cb17d82f0f33bee9101fa61ed455b40fdb",
"path": "houseplan-assets/live-interaction-runtime-C1983oH8.js",
"sha256": "04be552ac07f99c03713f162ce0b6129c8491dfd89da9cd8e07cd71866fe309c",
"rawBytes": 8370,
"gzipBytes": 3280,
"gzipBytes": 3281,
"isEntry": false,
"imports": [
"houseplan-assets/houseplan-card-CDzf9V5z.js"
"houseplan-assets/houseplan-card-BOdiRDFR.js"
],
"dynamicImports": []
},
{
"path": "houseplan-assets/moon-runtime-DkqNfOp0.js",
"sha256": "1d6df38c7320b9f9cff3b9f3afa152f4c295109fe2c0b94924d5d2e606468962",
"path": "houseplan-assets/moon-runtime-Ca1mxhJl.js",
"sha256": "97b9f55cb8e2915acb5eaa260f21e2103bc08f0e654c1c0b03c3000604319730",
"rawBytes": 30292,
"gzipBytes": 11713,
"isEntry": false,
"imports": [
"houseplan-assets/houseplan-card-CDzf9V5z.js"
"houseplan-assets/houseplan-card-BOdiRDFR.js"
],
"dynamicImports": []
},
{
"path": "houseplan-assets/namespace-language-BPjMJUHI.js",
"sha256": "d108e467e8a0e61c1f9cf0ba408f01d9415920c3e843219144f19ab0634cbb1b",
"path": "houseplan-assets/namespace-language-D86tJUeD.js",
"sha256": "012aa30cbf8bbbb2eff6b7ef05970ff90fb2b4b576910578e3527b75e68ffda6",
"rawBytes": 675,
"gzipBytes": 409,
"isEntry": false,
"imports": [
"houseplan-assets/houseplan-card-CDzf9V5z.js"
"houseplan-assets/houseplan-card-BOdiRDFR.js"
],
"dynamicImports": []
},
{
"path": "houseplan-assets/pdf-export-UdR2EXb9.js",
"sha256": "839a0cb681cfcb67b74899d306b3e09e8b7fae59f46283b335c671c845554242",
"path": "houseplan-assets/pdf-export-C-Y4BSVu.js",
"sha256": "fba700bc14c66c695f1b3de3e82abdf5fb6b14b70773c3d0f0e185dcf2989491",
"rawBytes": 236714,
"gzipBytes": 109998,
"isEntry": false,
"imports": [
"houseplan-assets/furniture-plan-art.generated-DHB0O8RC.js",
"houseplan-assets/houseplan-card-CDzf9V5z.js"
"houseplan-assets/furniture-plan-art.generated-XIg9ZqQe.js",
"houseplan-assets/houseplan-card-BOdiRDFR.js"
],
"dynamicImports": []
},
{
"path": "houseplan-assets/settings-de-hkfrpcmk.js",
"sha256": "7430bf272d66366ca4e7f3d6c8178cda97f2bc65112a475aeb98388338726c6d",
"path": "houseplan-assets/settings-de-ZP6F6dIF.js",
"sha256": "12dd3028d2de2e4fc3bfcf2299e45e253075ca23b95235436ef1cf9156738a3e",
"rawBytes": 8886,
"gzipBytes": 3408,
"gzipBytes": 3411,
"isEntry": false,
"imports": [],
"dynamicImports": []
},
{
"path": "houseplan-assets/settings-fr-CTDbCfmV.js",
"sha256": "e00be71088032b53b6d81e3a690c5ff178dfbf21745c21e63fc20c1f7c5a82b7",
"path": "houseplan-assets/settings-fr-doqd_TsB.js",
"sha256": "0c1f01b69c2b1704ddd29e99dd7609ad679655b5241b3e2b8921057198005ff3",
"rawBytes": 9297,
"gzipBytes": 3381,
"gzipBytes": 3385,
"isEntry": false,
"imports": [],
"dynamicImports": []
},
{
"path": "houseplan-assets/settings-ru-_XLAbOEk.js",
"sha256": "410a961660d4ac60f59f9301d651a98e14617de88af04ea728b7cd819b08630b",
"path": "houseplan-assets/settings-ru-CQ1W2gik.js",
"sha256": "bad5c925aac84429d0831a1036ea3162ead8d4431db35ea577b0e806c8fbdbf1",
"rawBytes": 12284,
"gzipBytes": 3898,
"gzipBytes": 3900,
"isEntry": false,
"imports": [],
"dynamicImports": []
},
{
"path": "houseplan-assets/space-editor-N5uYQl3H.js",
"sha256": "6382ce5fca7f70735041e35b3db96e3f1e4feeed35abacc46f1311c3a60465db",
"path": "houseplan-assets/space-editor-EDOQT48H.js",
"sha256": "47339ab7329ffd1a0cbd21980c1cf2a2041d7a514ed5992e73a07abdce6fb764",
"rawBytes": 2619,
"gzipBytes": 1127,
"gzipBytes": 1130,
"isEntry": false,
"imports": [
"houseplan-assets/houseplan-card-CDzf9V5z.js"
"houseplan-assets/houseplan-card-BOdiRDFR.js"
],
"dynamicImports": []
},
{
"path": "houseplan-assets/summary-panel-editor-CgZXeEXz.js",
"sha256": "ca0343b11e17cb8a871630e11e00a9def2ba99290339abbd79e577f2dd3e3bd6",
"rawBytes": 14867,
"gzipBytes": 3429,
"path": "houseplan-assets/summary-panel-editor-BZnGwuVh.js",
"sha256": "516e3462d3896a9ca782ee0f2f3266a4da6e6b6664e92a619a23b8991e600795",
"rawBytes": 14862,
"gzipBytes": 3427,
"isEntry": false,
"imports": [
"houseplan-assets/form-kit.styles-Dq1Y4tz1.js",
"houseplan-assets/houseplan-card-CDzf9V5z.js",
"houseplan-assets/summary-panel-runtime-loaded-BcDAIp5L.js"
"houseplan-assets/form-kit.styles-B6HsmMPA.js",
"houseplan-assets/houseplan-card-BOdiRDFR.js",
"houseplan-assets/summary-panel-runtime-loaded-CcLP5B5v.js"
],
"dynamicImports": []
},
{
"path": "houseplan-assets/summary-panel-metrics-DpgEBDDi.js",
"sha256": "ffe7025d0d913a2c27825836e263fedec5fd4c6671087654a80a826bf8e9ac63",
"path": "houseplan-assets/summary-panel-metrics-D_ZXPJxz.js",
"sha256": "3be26833b041416cef359e4c7086a0b0e6788680dda8f1583ae76d9256f944fa",
"rawBytes": 2701,
"gzipBytes": 1345,
"gzipBytes": 1348,
"isEntry": false,
"imports": [
"houseplan-assets/houseplan-card-CDzf9V5z.js"
"houseplan-assets/houseplan-card-BOdiRDFR.js"
],
"dynamicImports": []
},
{
"path": "houseplan-assets/summary-panel-runtime-loaded-BcDAIp5L.js",
"sha256": "82d20ca0d38461911e5fc0a9aa44da29fdd680fceaa82927f1044df649698fa2",
"path": "houseplan-assets/summary-panel-runtime-loaded-CcLP5B5v.js",
"sha256": "7db94205b54996355041487465d6bade0530e5ac0d13a0eb9b7645086171ce58",
"rawBytes": 73476,
"gzipBytes": 20486,
"gzipBytes": 20491,
"isEntry": false,
"imports": [
"houseplan-assets/form-kit.styles-Dq1Y4tz1.js",
"houseplan-assets/houseplan-card-CDzf9V5z.js"
"houseplan-assets/form-kit.styles-B6HsmMPA.js",
"houseplan-assets/houseplan-card-BOdiRDFR.js"
],
"dynamicImports": [
"houseplan-assets/summary-panel-editor-CgZXeEXz.js",
"houseplan-assets/summary-panel-metrics-DpgEBDDi.js"
"houseplan-assets/summary-panel-editor-BZnGwuVh.js",
"houseplan-assets/summary-panel-metrics-D_ZXPJxz.js"
]
},
{
"path": "houseplan-assets/support-de-DF73IEHL.js",
"sha256": "8407d526294bc1a2f2a83da0b70bf03c2d28d37daac7b0b2b7c561f32e52ed12",
"path": "houseplan-assets/support-de-haZQ7q8i.js",
"sha256": "f377e9d552978c850f069eeb05b20c7572f81c7a8c7b2d60838a7907f1c2b3ef",
"rawBytes": 6167,
"gzipBytes": 2396,
"gzipBytes": 2400,
"isEntry": false,
"imports": [],
"dynamicImports": []
},
{
"path": "houseplan-assets/support-fr-BBhMT3I0.js",
"sha256": "59eb34e74a98bac8905fd10e02eecd955a9cf7727685d3a70d8657f739457af0",
"path": "houseplan-assets/support-fr-DnRyZ_Ga.js",
"sha256": "bb66f839f3b63a74212dc83d273db535dd4597e5f43c5c1b35f0e1fac401e424",
"rawBytes": 6333,
"gzipBytes": 2430,
"gzipBytes": 2433,
"isEntry": false,
"imports": [],
"dynamicImports": []
},
{
"path": "houseplan-assets/support-ru-Bd7vkOXI.js",
"sha256": "0c32195ce4c911d2fb90831144b44ac7d406f6adc80555210d1e1d1ee1d5dd37",
"path": "houseplan-assets/support-ru-B7zzXsuL.js",
"sha256": "63ec59059f3a10c994e4292c4c2b125bb7b2916326dbae27f9975c14be008822",
"rawBytes": 8376,
"gzipBytes": 2876,
"gzipBytes": 2878,
"isEntry": false,
"imports": [],
"dynamicImports": []
},
{
"path": "houseplan-assets/tools-de-DwmzTHwi.js",
"sha256": "3d296ea3821fbe12df454c6042745746b9db49090cbfb10afe9ace758c7ccc06",
"path": "houseplan-assets/tools-de-CYXPPfUH.js",
"sha256": "411c98cf876e42d7255882d0faa486602453f871d443b0c2b59c22e3b2552efb",
"rawBytes": 4130,
"gzipBytes": 1375,
"gzipBytes": 1378,
"isEntry": false,
"imports": [],
"dynamicImports": []
},
{
"path": "houseplan-assets/tools-fr-Dp5JXY-G.js",
"sha256": "31b0111901af3654a491997ff9d993ec907a48a90fa193bcc70026ba063e2cf4",
"path": "houseplan-assets/tools-fr-DvygRB10.js",
"sha256": "f7d35402d5f3504baa8c00dc8bd5170487535c1b87f9a8367a28e332cda92bf2",
"rawBytes": 4136,
"gzipBytes": 1358,
"gzipBytes": 1360,
"isEntry": false,
"imports": [],
"dynamicImports": []
},
{
"path": "houseplan-assets/tools-ru-CAQB2Qhv.js",
"sha256": "c6bf82ded09db3f8238f44d138467839a3483de829d26a7be2e51c42240fcbcb",
"path": "houseplan-assets/tools-ru-2xmu2w_8.js",
"sha256": "14e6c4c22d615293903fc4f25d831f0af042b4e48234d4f2e114ef7d8817d57a",
"rawBytes": 5633,
"gzipBytes": 1695,
"gzipBytes": 1697,
"isEntry": false,
"imports": [],
"dynamicImports": []
},
{
"path": "houseplan-assets/topology-de-DFY0lBO-.js",
"sha256": "562f694c384b9e9df72b61f1b4d2ec05f7bc410576e46ea422f1eeab6c1dbd8e",
"path": "houseplan-assets/topology-de-COda8n9n.js",
"sha256": "88ff4a8cccc94e3eba040af628d9a85db664cbf20586f95704e0823a6215c1f9",
"rawBytes": 2698,
"gzipBytes": 1337,
"gzipBytes": 1336,
"isEntry": false,
"imports": [],
"dynamicImports": []
},
{
"path": "houseplan-assets/topology-fr-DbNDk6Er.js",
"sha256": "282a3d6bbd74abb3aa2a675d2b73793a41de1beef18b1e85298919985b6347d6",
"path": "houseplan-assets/topology-fr-BT9yhzay.js",
"sha256": "60cb68c5c9086ec5f4901627a6baa3e3c8cdfda430b0977622b260984122fcfa",
"rawBytes": 2718,
"gzipBytes": 1354,
"gzipBytes": 1356,
"isEntry": false,
"imports": [],
"dynamicImports": []
},
{
"path": "houseplan-assets/topology-ru-BNVYY-_i.js",
"sha256": "4ce8c7f4383b7724a1b0aff888b57ff1ca8d477df125a3b57f522dea2319ea23",
"path": "houseplan-assets/topology-ru-C-d06yvD.js",
"sha256": "ca9a68f252b8275c954ae7ff7ea56d07a8ea5cf14f18eaac285fd0c63a7bad8f",
"rawBytes": 3669,
"gzipBytes": 1614,
"gzipBytes": 1615,
"isEntry": false,
"imports": [],
"dynamicImports": []
},
{
"path": "houseplan-assets/zigbee-topology-Co7YPeRf.js",
"sha256": "16d9fe1e49fa01d791803f5753c238716e1a3f6da5103c6291c9618f89ac63a0",
"path": "houseplan-assets/zigbee-topology-BG_a6cIb.js",
"sha256": "98d8e54ec59e2d1810b124a0a0c6c2f528c112ab17d12bc3c0a129e13c456c72",
"rawBytes": 10958,
"gzipBytes": 4303,
"gzipBytes": 4298,
"isEntry": false,
"imports": [
"houseplan-assets/houseplan-card-CDzf9V5z.js",
"houseplan-assets/namespace-language-BPjMJUHI.js"
"houseplan-assets/houseplan-card-BOdiRDFR.js",
"houseplan-assets/namespace-language-D86tJUeD.js"
],
"dynamicImports": [
"houseplan-assets/topology-de-DFY0lBO-.js",
"houseplan-assets/topology-fr-DbNDk6Er.js",
"houseplan-assets/topology-ru-BNVYY-_i.js"
"houseplan-assets/topology-de-COda8n9n.js",
"houseplan-assets/topology-fr-BT9yhzay.js",
"houseplan-assets/topology-ru-C-d06yvD.js"
]
},
{
"path": "houseplan-assets/zigbee-topology-runtime-ByS3kW9n.js",
"sha256": "64f6de7adc3876b915c7472f31d0ffad421271c48161a29e8390b10d85519e1e",
"path": "houseplan-assets/zigbee-topology-runtime-CynQ2m3K.js",
"sha256": "966ef9fa87888f0ed561d1061b36f0192c27700f040305ae038fe9509c7a7e33",
"rawBytes": 3983,
"gzipBytes": 1790,
"gzipBytes": 1789,
"isEntry": false,
"imports": [
"houseplan-assets/houseplan-card-CDzf9V5z.js",
"houseplan-assets/namespace-language-BPjMJUHI.js",
"houseplan-assets/zigbee-topology-Co7YPeRf.js"
"houseplan-assets/houseplan-card-BOdiRDFR.js",
"houseplan-assets/namespace-language-D86tJUeD.js",
"houseplan-assets/zigbee-topology-BG_a6cIb.js"
],
"dynamicImports": []
},
{
"path": "houseplan-card.js",
"sha256": "b22eafb488fd6cdc7ff797b48887d9c469f0aed1868da22b21ed992fa2187bdc",
"sha256": "80338f4a64b84431f95438482aeabe1cc6b0f399ccb0c600b318c0f6e6cccc38",
"rawBytes": 1205,
"gzipBytes": 803,
"gzipBytes": 804,
"isEntry": true,
"imports": [
"houseplan-assets/houseplan-card-CDzf9V5z.js"
"houseplan-assets/houseplan-card-BOdiRDFR.js"
],
"dynamicImports": []
},
{
"path": "houseplan-panel.js",
"sha256": "5295cb11c681c7c7f0d97bb4b9d3ab22ee16735463b7af56d6c59a67622a811c",
"sha256": "ce8c313af85073d1c54ccc74e2111c1f14c5d8e3e8539bc59ec436d6d3e0d574",
"rawBytes": 6165,
"gzipBytes": 2324,
"gzipBytes": 2328,
"isEntry": true,
"imports": [
"houseplan-assets/houseplan-card-CDzf9V5z.js"
"houseplan-assets/houseplan-card-BOdiRDFR.js"
],
"dynamicImports": []
}
File diff suppressed because one or more lines are too long
@@ -1,14 +1,14 @@
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="fd4a405e9c5a21035258c45feca26dca03d59d4cfba4280f89ff5f82675515ac";import{aG as e,l as o,aJ as t,eD as s,A as a,eE as i,eF as l,eG as n,E as r,c}from"./houseplan-card-CDzf9V5z.js";class f 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,f={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")},h=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__="ab07da35681c15ab6136c323500b69766580ea4a788e399ea88f9e7497549172";import{aG as e,l as o,aJ as t,eE as s,A as a,eF as i,eG as l,eH as n,E as r,c}from"./houseplan-card-BOdiRDFR.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")},_=this._schema,f=function(e,o,t){if(!t||null===o)return null;const s="string"==typeof e?.default_floor?e.default_floor:"";return!s||o.some(e=>e.value===s)?null:s}(this._config,this._spaces,this._spacesAuthoritative),u=e=>c`<ha-form
.hass=${this.hass}
.data=${this._formData}
.schema=${e}
.computeLabel=${e=>f[e.name]||e.name}
.computeLabel=${e=>h[e.name]||e.name}
@value-changed=${this._valueChanged}
></ha-form>`;return c`
${d(h.slice(0,3))}
${_?c`<div class="default-floor-error" role="alert"
${u(_.slice(0,3))}
${f?c`<div class="default-floor-error" role="alert"
style="color:var(--error-color,#db4437);margin:-4px 0 12px;overflow-wrap:anywhere">
${t(s,"editor.default_floor_missing",{id:_})}
${t(s,"editor.default_floor_missing",{id:f})}
</div>`:a}
${d(h.slice(3))}
`}_valueChanged(e){const o={...this._config,...e.detail.value};""===o.floor?delete o.floor:o.floor===this._floorToken&&(o.floor=this._config?.floor);const t=new Event("config-changed",{bubbles:!0,composed:!0});t.detail={config:o},this.dispatchEvent(t)}}f.properties={hass:{attribute:!1},_config:{state:!0},_spaces:{state:!0}},customElements.get("houseplan-card-editor")||customElements.define("houseplan-card-editor",f);
${u(_.slice(3))}
`}_valueChanged(e){const o={...this._config,...e.detail.value};""===o.floor?delete o.floor:o.floor===this._floorToken&&(o.floor=this._config?.floor);const t=new Event("config-changed",{bubbles:!0,composed:!0});t.detail={config:o},this.dispatchEvent(t)}}h.properties={hass:{attribute:!1},_config:{state:!0},_spaces:{state:!0}},customElements.get("houseplan-card-editor")||customElements.define("houseplan-card-editor",h);
@@ -1 +1 @@
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="fd4a405e9c5a21035258c45feca26dca03d59d4cfba4280f89ff5f82675515ac";var e={"led.tool":"LED-Streifen","led.hint":"Zeichnen Sie den Streifen Punkt für Punkt entlang der Wandflächen oder über den Boden; er rastet am Raster und an Wandflächen ein. Danach wählen Sie das Gerät, das er darstellt.","led.start":"Klicken, um den Streifen zu beginnen","led.start_touch":"Tippen, um den Streifen zu beginnen","led.points":"Punkte: {n} · Umschalt — 45°-Schritte · Esc — fertig · Strg+Z — Punkt entfernen","led.points_touch":"Punkte: {n} · Werkzeug wechseln zum Beenden","led.finish":"Fertig","led.stopped":"Der Streifen stößt an eine Wand","led.unbound":"Streifen ist mit keinem Gerät verbunden","led.bind":"Gerät verbinden","led.change":"Gerät wechseln","led.later":"Später","led.unbind":"Trennen","led.delete":"Streifen löschen","led.settings":"Geräteeinstellungen","led.type_note":"LED-Streifen: Form im Geräte-Editor auf dem Plan bearbeiten","led.show_strip":"Als LED-Streifen zeigen","led.show_icon":"Als Symbol zeigen","led.cancel":"Abbrechen","led.taken":"Bereits mit einem anderen LED-Streifen verbunden","led.space":"Zuerst den LED-Streifen lösen: Er gehört zu seinem Bereich","led.limit_points":"Höchstens 50 Punkte pro Streifen","led.limit_strips":"Höchstens 50 Streifen pro Bereich","led.pick_title":"Gerät für den Streifen wählen","led.pick_new":"Neues Gerät…","led.pick_empty":"Auf diesem Plan gibt es noch keine freien Geräte.","led.saved":"LED-Streifen gespeichert","led.save_failed":"Streifen nicht gespeichert: {err}","led.history_draw":"LED-Streifen","led.history_shape":"Form des LED-Streifens","led.history_view":"Darstellung des Geräts","led.optimize_walls":"Streifen durch Wände: {n} ({spaces})"};const n="fd4a405e9c5a21035258c45feca26dca03d59d4cfba4280f89ff5f82675515ac";export{e as dictionary,n as fingerprint};
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="ab07da35681c15ab6136c323500b69766580ea4a788e399ea88f9e7497549172";var e={"led.tool":"LED-Streifen","led.hint":"Zeichnen Sie den Streifen Punkt für Punkt entlang der Wandflächen oder über den Boden; er rastet am Raster und an Wandflächen ein. Danach wählen Sie das Gerät, das er darstellt.","led.start":"Klicken, um den Streifen zu beginnen","led.start_touch":"Tippen, um den Streifen zu beginnen","led.points":"Punkte: {n} · Umschalt — 45°-Schritte · Esc — fertig · Strg+Z — Punkt entfernen","led.points_touch":"Punkte: {n} · Werkzeug wechseln zum Beenden","led.finish":"Fertig","led.stopped":"Der Streifen stößt an eine Wand","led.unbound":"Streifen ist mit keinem Gerät verbunden","led.bind":"Gerät verbinden","led.change":"Gerät wechseln","led.later":"Später","led.unbind":"Trennen","led.delete":"Streifen löschen","led.settings":"Geräteeinstellungen","led.type_note":"LED-Streifen: Form im Geräte-Editor auf dem Plan bearbeiten","led.show_strip":"Als LED-Streifen zeigen","led.show_icon":"Als Symbol zeigen","led.cancel":"Abbrechen","led.taken":"Bereits mit einem anderen LED-Streifen verbunden","led.space":"Zuerst den LED-Streifen lösen: Er gehört zu seinem Bereich","led.limit_points":"Höchstens 50 Punkte pro Streifen","led.limit_strips":"Höchstens 50 Streifen pro Bereich","led.pick_title":"Gerät für den Streifen wählen","led.pick_new":"Neues Gerät…","led.pick_empty":"Auf diesem Plan gibt es noch keine freien Geräte.","led.saved":"LED-Streifen gespeichert","led.save_failed":"Streifen nicht gespeichert: {err}","led.history_draw":"LED-Streifen","led.history_shape":"Form des LED-Streifens","led.history_view":"Darstellung des Geräts","led.optimize_walls":"Streifen durch Wände: {n} ({spaces})"};const n="ab07da35681c15ab6136c323500b69766580ea4a788e399ea88f9e7497549172";export{e as dictionary,n as fingerprint};
@@ -1 +1 @@
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="fd4a405e9c5a21035258c45feca26dca03d59d4cfba4280f89ff5f82675515ac";var e={"led.tool":"Ruban LED","led.hint":"Tracez le ruban point par point le long des faces des murs ou sur le sol ; il s’aimante à la grille et aux faces des murs. Ensuite, choisissez l’appareil qu’il représente.","led.start":"Cliquez pour commencer le ruban","led.start_touch":"Touchez pour commencer le ruban","led.points":"Points : {n} · Maj — pas de 45° · Échap — terminer · Ctrl+Z — retirer le point","led.points_touch":"Points : {n} · changez d’outil pour terminer","led.finish":"Terminer","led.stopped":"Le ruban bute contre un mur","led.unbound":"Ruban non lié à un appareil","led.bind":"Lier un appareil","led.change":"Changer d’appareil","led.later":"Plus tard","led.unbind":"Délier","led.delete":"Supprimer le ruban","led.settings":"Réglages de l’appareil","led.type_note":"Ruban LED : modifiez sa forme sur le plan dans l’éditeur d’appareils","led.show_strip":"Afficher en ruban LED","led.show_icon":"Afficher en icône","led.cancel":"Annuler","led.taken":"Déjà lié à un autre ruban LED","led.space":"Détachez d’abord le ruban LED : il appartient à son espace","led.limit_points":"50 points au maximum par ruban","led.limit_strips":"50 rubans au maximum par espace","led.pick_title":"Choisissez l’appareil du ruban","led.pick_new":"Nouvel appareil…","led.pick_empty":"Aucun appareil libre sur ce plan pour l’instant.","led.saved":"Ruban LED enregistré","led.save_failed":"Ruban non enregistré : {err}","led.history_draw":"Ruban LED","led.history_shape":"Forme du ruban LED","led.history_view":"Représentation de l’appareil","led.optimize_walls":"Rubans traversant des murs : {n} ({spaces})"};const a="fd4a405e9c5a21035258c45feca26dca03d59d4cfba4280f89ff5f82675515ac";export{e as dictionary,a as fingerprint};
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="ab07da35681c15ab6136c323500b69766580ea4a788e399ea88f9e7497549172";var e={"led.tool":"Ruban LED","led.hint":"Tracez le ruban point par point le long des faces des murs ou sur le sol ; il s’aimante à la grille et aux faces des murs. Ensuite, choisissez l’appareil qu’il représente.","led.start":"Cliquez pour commencer le ruban","led.start_touch":"Touchez pour commencer le ruban","led.points":"Points : {n} · Maj — pas de 45° · Échap — terminer · Ctrl+Z — retirer le point","led.points_touch":"Points : {n} · changez d’outil pour terminer","led.finish":"Terminer","led.stopped":"Le ruban bute contre un mur","led.unbound":"Ruban non lié à un appareil","led.bind":"Lier un appareil","led.change":"Changer d’appareil","led.later":"Plus tard","led.unbind":"Délier","led.delete":"Supprimer le ruban","led.settings":"Réglages de l’appareil","led.type_note":"Ruban LED : modifiez sa forme sur le plan dans l’éditeur d’appareils","led.show_strip":"Afficher en ruban LED","led.show_icon":"Afficher en icône","led.cancel":"Annuler","led.taken":"Déjà lié à un autre ruban LED","led.space":"Détachez d’abord le ruban LED : il appartient à son espace","led.limit_points":"50 points au maximum par ruban","led.limit_strips":"50 rubans au maximum par espace","led.pick_title":"Choisissez l’appareil du ruban","led.pick_new":"Nouvel appareil…","led.pick_empty":"Aucun appareil libre sur ce plan pour l’instant.","led.saved":"Ruban LED enregistré","led.save_failed":"Ruban non enregistré : {err}","led.history_draw":"Ruban LED","led.history_shape":"Forme du ruban LED","led.history_view":"Représentation de l’appareil","led.optimize_walls":"Rubans traversant des murs : {n} ({spaces})"};const a="ab07da35681c15ab6136c323500b69766580ea4a788e399ea88f9e7497549172";export{e as dictionary,a as fingerprint};
@@ -1 +1 @@
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="fd4a405e9c5a21035258c45feca26dca03d59d4cfba4280f89ff5f82675515ac";var e={"led.tool":"LED-лента","led.hint":"Нарисуйте ленту по точкам вдоль граней стен или по полу — она прилипает к сетке и граням. После завершения выберите устройство, которое она показывает.","led.start":"Нажмите, чтобы начать ленту","led.start_touch":"Коснитесь, чтобы начать ленту","led.points":"Точек: {n} · Shift — шаг 45° · Esc — завершить · Ctrl+Z — убрать точку","led.points_touch":"Точек: {n} · смените инструмент, чтобы завершить","led.finish":"Завершить","led.stopped":"Лента упёрлась в стену","led.unbound":"Лента не привязана к устройству","led.bind":"Привязать устройство","led.change":"Сменить устройство","led.later":"Позже","led.unbind":"Отвязать","led.delete":"Удалить ленту","led.settings":"Настройки устройства","led.type_note":"LED-лента: форма редактируется на плане в редакторе устройств","led.show_strip":"Показывать LED-лентой","led.show_icon":"Показывать значком","led.cancel":"Отмена","led.taken":"Уже привязано к другой LED-ленте","led.space":"Сначала отвяжите LED-ленту: она принадлежит своему пространству","led.limit_points":"Не более 50 точек в ленте","led.limit_strips":"Не более 50 лент в пространстве","led.pick_title":"Выберите устройство для ленты","led.pick_new":"Новое устройство…","led.pick_empty":"На этом плане пока нет свободных устройств.","led.saved":"LED-лента сохранена","led.save_failed":"Лента не сохранена: {err}","led.history_draw":"LED-лента","led.history_shape":"Форма LED-ленты","led.history_view":"Вид устройства","led.optimize_walls":"Лент, проходящих сквозь стены: {n} ({spaces})"};const d="fd4a405e9c5a21035258c45feca26dca03d59d4cfba4280f89ff5f82675515ac";export{e as dictionary,d as fingerprint};
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="ab07da35681c15ab6136c323500b69766580ea4a788e399ea88f9e7497549172";var e={"led.tool":"LED-лента","led.hint":"Нарисуйте ленту по точкам вдоль граней стен или по полу — она прилипает к сетке и граням. После завершения выберите устройство, которое она показывает.","led.start":"Нажмите, чтобы начать ленту","led.start_touch":"Коснитесь, чтобы начать ленту","led.points":"Точек: {n} · Shift — шаг 45° · Esc — завершить · Ctrl+Z — убрать точку","led.points_touch":"Точек: {n} · смените инструмент, чтобы завершить","led.finish":"Завершить","led.stopped":"Лента упёрлась в стену","led.unbound":"Лента не привязана к устройству","led.bind":"Привязать устройство","led.change":"Сменить устройство","led.later":"Позже","led.unbind":"Отвязать","led.delete":"Удалить ленту","led.settings":"Настройки устройства","led.type_note":"LED-лента: форма редактируется на плане в редакторе устройств","led.show_strip":"Показывать LED-лентой","led.show_icon":"Показывать значком","led.cancel":"Отмена","led.taken":"Уже привязано к другой LED-ленте","led.space":"Сначала отвяжите LED-ленту: она принадлежит своему пространству","led.limit_points":"Не более 50 точек в ленте","led.limit_strips":"Не более 50 лент в пространстве","led.pick_title":"Выберите устройство для ленты","led.pick_new":"Новое устройство…","led.pick_empty":"На этом плане пока нет свободных устройств.","led.saved":"LED-лента сохранена","led.save_failed":"Лента не сохранена: {err}","led.history_draw":"LED-лента","led.history_shape":"Форма LED-ленты","led.history_view":"Вид устройства","led.optimize_walls":"Лент, проходящих сквозь стены: {n} ({spaces})"};const l="ab07da35681c15ab6136c323500b69766580ea4a788e399ea88f9e7497549172";export{e as dictionary,l as fingerprint};
@@ -1,31 +0,0 @@
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="fd4a405e9c5a21035258c45feca26dca03d59d4cfba4280f89ff5f82675515ac";import{eT as e,eU as t,az as s,eV as n,eW as a,eO as i,A as r,eX as o,eY as c,eZ as l,e as p,i as d,E as h}from"./houseplan-card-CDzf9V5z.js";import{i as u,k as f,m as $}from"./led-strip-geometry-BcPfXtN-.js";const g=p(class extends d{constructor(e){super(e),this.deps=null}render(e,t){return t()}update(e,[t,s]){return this.deps&&this.deps.length===t.length&&t.every((e,t)=>e===this.deps[t])?h:(this.deps=t,s())}}),m="fd4a405e9c5a21035258c45feca26dca03d59d4cfba4280f89ff5f82675515ac",w=48,M=e=>e.map(e=>[e[0],e[1]]);class k{constructor(e=50){this.limit=e,this.entries=new Map,this.space="",this.recomputes=0,this.ids=new Map}get size(){return this.entries.size}id(e){let t=this.ids.get(e);return null==t&&(t=this.ids.size+1,this.ids.set(e,t)),t}forSpace(e){e!==this.space&&(this.entries.clear(),this.ids.clear(),this.space=e)}read(e,t){if(this.entries.has(e)){const t=this.entries.get(e)??null;return this.entries.delete(e),this.entries.set(e,t),t}this.recomputes+=1;const s=t();for(this.entries.set(e,s);this.entries.size>this.limit;){const e=this.entries.keys().next().value;if(void 0===e)break;this.entries.delete(e)}return s}clear(){this.entries.clear(),this.ids.clear(),this.space=""}get sources(){let e=0;for(const t of this.entries.values())for(const s of t?.pieces||[])e+=s.clip?.length??0;return e}}const y=e=>{const t=Math.round(1e4*e)/1e4;return Object.is(t,-0)?"0":String(t)},x=e=>`${e.map((e,t)=>`${t?"L":"M"}${y(e[0])} ${y(e[1])}`).join(" ")} Z`;function v(e,t,s){const n=1.01*t;return s.occluders.some(t=>t?.length>=4&&e.some(e=>((e,t)=>{const s=t[2]-t[0],n=t[3]-t[1],a=s*s+n*n,i=a?Math.max(0,Math.min(1,((e[0]-t[0])*s+(e[1]-t[1])*n)/a)):0;return Math.hypot(e[0]-t[0]-i*s,e[1]-t[1]-i*n)})(e,t)<n))?e.map(e=>o([e[0],e[1]],t,s.occluders,12)).filter(e=>e.length>=3).map(x):null}const b=new WeakMap;function I(e){const t=u(M(e.points));if(t.length<2||!(e.radius>0))return null;const s=e.radius,n=f(t),a=`${(n?t.slice(0,-1):t).map((e,t)=>`${t?"L":"M"}${y(e[0])} ${y(e[1])}`).join(" ")}${n?" Z":""}`,i=[];let r=[t[0]],o=s;for(let e=1;e<t.length;e++){let n=t[e-1];const a=t[e];let c=Math.hypot(a[0]-n[0],a[1]-n[1]);for(;c>o+1e-12;){const e=o/c,t=[n[0]+(a[0]-n[0])*e,n[1]+(a[1]-n[1])*e];r.push(t),i.push(r),r=[t],n=t,c-=o,o=s}r.push(a),o-=c}r.length>1&&i.push(r);const c=[];let l=1/0,p=1/0,d=-1/0,h=-1/0;for(const t of i){const n=[];for(const a of $(t,e.faces,s/4)){const e=n[n.length-1];(!e||Math.hypot(a[0]-e[0],a[1]-e[1])>=s/4)&&n.push(a)}if(!n.length)continue;let a;try{a=v(n,s,e.scene)}catch{continue}if(!a||a.length){c.push({d:t.map((e,t)=>`${t?"L":"M"}${y(e[0])} ${y(e[1])}`).join(" "),clip:a});for(const e of t)l=Math.min(l,e[0]),p=Math.min(p,e[1]),d=Math.max(d,e[0]),h=Math.max(h,e[1])}}return c.length?{d:a,pieces:c,box:{x:l-s,y:p-s,w:d-l+2*s,h:h-p+2*s}}:null}function U(t){const s=100*Math.max(0,Math.min(1,t));for(let t=1;t<e.length;t++){const[n,a]=e[t-1],[i,r]=e[t];if(s<=i)return a+(r-a)*(s-n)/Math.max(1e-9,i-n)}return 0}const j=new WeakMap,z=new WeakMap;function S(e){j.get(e)?.clear(),j.delete(e);const s=z.get(e);s&&t(s.state,s.host),z.delete(e)}function q(e){return!!z.get(e)?.state.renderedSources.size}function C(e){const t=j.get(e);return{visibility:t?.size??0,sources:t?.sources??0,recomputes:t?.recomputes??0}}function P(e){let t=j.get(e);return t||(t=new k,j.set(e,t)),t}function _(e){if(!e.scene)return s``;const t=P(e.owner);t.forSpace(e.spaceId);const o=function(e){let t=z.get(e.owner);if(t)t.callbacks.requestUpdate=e.requestUpdate,t.callbacks.isConnected=e.isConnected,t.callbacks.reducedMotion=e.reducedMotion;else{const s={requestUpdate:e.requestUpdate,isConnected:e.isConnected,reducedMotion:e.reducedMotion},n={window:()=>window,isConnected:()=>s.isConnected(),requestUpdate:()=>s.requestUpdate(),reducedMotion:()=>s.reducedMotion?.()??window.matchMedia?.("(prefers-reduced-motion: reduce)").matches??!1};t={state:c(),host:n,callbacks:s,spaceId:""},z.set(e.owner,t)}return t.spaceId&&t.spaceId!==e.spaceId&&l(t.state,t.host,t.spaceId),t.spaceId=e.spaceId,t}(e),p=e.scene,d=new Set,h=e.views.flatMap(s=>{const a=`${e.spaceId}|${s.strip.id}`;d.add(a);const i=s.glow&&"on"===s.state&&!!s.appearance,r=n(o.state,o.host,a,i);if(!r)return[];i&&s.appearance&&o.state.lastAppearance.set(a,s.appearance);const c=i?s.appearance:o.state.lastAppearance.get(a)??null;if(!c)return[];const l=`${s.strip.id}|${h=s.strip.points,h.map(e=>`${e[0].toFixed(5)},${e[1].toFixed(5)}`).join(";")}|${s.radius.toFixed(5)}|${p.fingerprint}`;var h;const u=t.read(l,()=>I({points:s.strip.points,radius:s.radius,scene:p,polygons:e.polygons,faces:e.faces,spaceId:e.spaceId}));return u?[{view:{...s,appearance:c},geometry:u,transition:r}]:[]});if(a(o.state,o.host,e.spaceId,d),!h.length)return s``;const u=Array.from({length:48},(e,t)=>{const s=1-t/48;return{half:s,value:U((s+(1-(t+1)/48))/2)}});return s`<g class="led-fields" pointer-events="none" aria-hidden="true"
data-led-cache="${t.size}" data-led-recomputes="${t.recomputes}">
<defs><clipPath id="hp-led-floor">${function(e){let t=b.get(e);return t||(t=e.floor.filter(e=>e.length>=3).map(x),b.set(e,t)),t}(p).map(e=>s`<path d="${e}"></path>`)}</clipPath></defs>
<g clip-path="url(#hp-led-floor)">
${i(h,({view:e})=>e.strip.id,({view:e,geometry:n,transition:a})=>{const i=`${t.id(e.strip.id)}`,o=e.radius,c=n.box,l=f(M(e.strip.points)),p=n.pieces.filter(e=>!!e.clip),d=n.pieces.filter(e=>!e.clip),h=p.length>0;return g([n,a.entering,a.leaving,e.appearance.c,e.appearance.alpha,o,i],()=>s`<g
class="glow-spot led-field ${a.entering?"is-entering":""} ${a.leaving?"is-leaving":""}"
data-led-field="${e.strip.id}" data-led-phase="${a.entering?"entering":a.leaving?"leaving":"visible"}"
data-pieces="${n.pieces.length}" data-bands="${48}"
data-closed="${l?"true":"false"}">
<defs>
${h?s`<clipPath id="hp-led-visible-${i}">
${d.map(e=>s`<path d="${e.d}" fill="none" stroke="white"
stroke-width="${2*o}" stroke-linecap="round" stroke-linejoin="round"></path>`)}
${p.map(e=>s`<path d="${e.clip.join(" ")}"></path>`)}
</clipPath>`:r}
<mask id="hp-led-mask-${i}" maskUnits="userSpaceOnUse"
x="${c.x}" y="${c.y}" width="${c.w}" height="${c.h}"
color-interpolation="sRGB" style="mask-type:luminance">
<rect x="${c.x}" y="${c.y}" width="${c.w}" height="${c.h}" fill="black"></rect>
<g clip-path=${h?`url(#hp-led-visible-${i})`:r}>
${u.map(e=>s`<path d="${n.d}" fill="none" stroke="${(e=>{const t=Math.round(255*Math.max(0,Math.min(1,e)));return`rgb(${t},${t},${t})`})(e.value)}"
stroke-width="${2*e.half*o}" stroke-linecap="round" stroke-linejoin="round"></path>`)}
</g>
</mask>
</defs>
<rect class="glow-pool led-pool" x="${c.x}" y="${c.y}" width="${c.w}" height="${c.h}"
fill="${e.appearance?.c??"transparent"}" fill-opacity="${(e.appearance?.alpha??0).toFixed(4)}"
mask="url(#hp-led-mask-${i})"></rect>
</g>`)})}
</g>
</g>`}export{w as LED_FIELD_BANDS,m as LED_FIELD_FINGERPRINT,k as LedFieldCache,I as buildFieldGeometry,U as falloffAt,q as hasLedField,P as ledFieldCache,C as ledFieldStats,S as releaseLedField,_ as renderLedField};
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
@@ -0,0 +1,47 @@
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="ab07da35681c15ab6136c323500b69766580ea4a788e399ea88f9e7497549172";import{eu as e,eC as t,c6 as o,eJ as s,eK as i,ad as n,ee as a,O as r,eL as l,az as d,ef as c,aL as p,eM as u,eN as h,eO as f,A as m,eP as v}from"./houseplan-card-BOdiRDFR.js";import{L as g,v as w,s as $,a as _,b as y,p as k,c as b,d as C,e as P}from"./led-strip-geometry-DaLifxqY.js";const M="ab07da35681c15ab6136c323500b69766580ea4a788e399ea88f9e7497549172";let F,L=null,U=null;function x(e,t){return L||U||F===e||""===F||(U=(void 0===F?import("./led-strip-field-ObbckCkp.js"):import(new URL(`./led-strip-field-ObbckCkp.js?${Date.now()}`,import.meta.url).href)).then(e=>{e.LED_FIELD_FINGERPRINT===s?L=e:F=""},()=>{F=e}).finally(()=>{U=null})),L||U?.then(()=>L&&t()),L}const D=e=>e.some(e=>e.glow&&"on"===e.state),R=e=>e.map(e=>[e[0],e[1]]),E="#383838";function A(s,i){if(!s)return null;const n=Array.isArray(s.masonryGeometry)?s.masonryGeometry:[],a=[...e(s.masonryGeometry),...s.opaqueBodies],r=[];for(const e of a)for(let t=0;t<e.length;t++){const o=e[t],s=e[(t+1)%e.length];o&&s&&r.push({a:[o[0],o[1]],b:[s[0],s[1]]})}const l=25,d=new Map;r.forEach((e,t)=>{const o=Math.floor(Math.min(e.a[0],e.b[0])/l),s=Math.floor(Math.max(e.a[0],e.b[0])/l),i=Math.floor(Math.min(e.a[1],e.b[1])/l),n=Math.floor(Math.max(e.a[1],e.b[1])/l);for(let e=o;e<=s;e++)for(let o=i;o<=n;o++){const s=`${e},${o}`,i=d.get(s);i?i.push(t):d.set(s,[t])}});const c=e=>{let t=1/0,o=1/0,s=-1/0,i=-1/0;for(const n of e)t=Math.min(t,n[0]),o=Math.min(o,n[1]),s=Math.max(s,n[0]),i=Math.max(i,n[1]);return[t,o,s,i]},p=(e,t)=>e[0]>=t[0]&&e[0]<=t[2]&&e[1]>=t[1]&&e[1]<=t[3],u=n.filter(e=>e?.[0]?.length).map(e=>({box:c(e[0]),poly:e})),h=s.opaqueBodies.map(e=>({box:c(e),body:e}));return{faces:r,inside:e=>u.some(({box:o,poly:s})=>p(e,o)&&t([e[0],e[1]],[s]))||h.some(({box:t,body:s})=>p(e,t)&&o([e[0],e[1]],s)),epsilon:i,near:e=>{const t=new Set;for(let o=Math.floor(e[0]/l);o<=Math.floor(e[2]/l);o++)for(let s=Math.floor(e[1]/l);s<=Math.floor(e[3]/l);s++)for(const e of d.get(`${o},${s}`)||[])t.add(e);return[...t].map(e=>r[e])}}}function I(e){const t=e.candidate?.sourceEid||e.device.primary||"",o=t?e.hass?.states?.[t]?.state:void 0,s="unavailable"===o||"unknown"===o||!!t&&!!e.hass&&!e.hass.states?.[t]&&!e.device.virtual,i=Number(e.device.marker?.glow_radius_cm),n=Number.isFinite(i)&&i>0?i/e.cellCm*e.gridPitch:e.defaultRadius,a=s?null:e.candidate?.appearance??null;return{strip:e.strip,device:e.device,state:s?"unavailable":a?"on":"off",glow:e.glow,appearance:a,radius:n}}const T=new WeakMap;function j(e,t,o){const s=P*o;const i=T.get(e);if(i&&i.faces===t&&i.epsilon===t?.epsilon&&i.value.t===s&&i.points.length===e.points.length&&i.points.every((t,o)=>t[0]===e.points[o][0]&&t[1]===e.points[o][1]))return i.value;const n=R(e.points),a=y(n,t,s/2),r={t:s,path:a,d:k(a)};return T.set(e,{faces:t,epsilon:t?.epsilon,points:n,value:r}),r}function G(e){if(!e.views.length)return d``;const t=e.handlers,o=[...e.views].sort((e,t)=>e.strip.id<t.strip.id?1:e.strip.id>t.strip.id?-1:0),s=e.iso;return d`<g class="led-strips" data-hp-led-strips="${o.length}"
data-hp-iso=${s?"raised":m}>
${s?d`<defs><filter id="hp-led-iso-shadow" filterUnits="userSpaceOnUse"
x="-100000" y="-100000" width="200000" height="200000">
<feGaussianBlur stdDeviation="${s.shadow.sigma}"></feGaussianBlur></filter></defs>`:m}
<style>
.led-strip .led-focus { fill: none; stroke: transparent; }
.led-strip:has(.led-hit:focus-visible) .led-focus { stroke: var(--primary-color, #03a9f4); }
.led-strip .led-hit { fill: none; stroke: transparent; cursor: pointer; outline: none; }
</style>
${v(o,e=>e.strip.id,o=>{const{t:i,path:n,d:a}=j(o.strip,e.faces,e.d),r="unavailable"===o.state,l=r?"#9e9e9e":"on"===o.state&&!o.glow&&o.appearance?o.appearance.c:"#FFFFFF",c=2*b(i*e.perUnit)/(e.perUnit||1),p=o.device,u=t=>function(e,t,o){const s=e.currentTarget,i=s?.getScreenCTM?.();if(!i||o.views.length<2)return t;const n=i.inverse(),a=[n.a*e.clientX+n.c*e.clientY+n.e,n.b*e.clientX+n.d*e.clientY+n.f],r=o.views.map(e=>{const{t:t,path:s}=j(e.strip,o.faces,o.d);return{id:e.strip.id,points:s.points.map(e=>[e[0]*o.perUnit,e[1]*o.perUnit]),closed:s.closed,thicknessPx:t*o.perUnit}}),l=C([a[0]*o.perUnit,a[1]*o.perUnit],r);return o.views.find(e=>e.strip.id===l)||t}(t,o,e).device,h=s?`translate(0 ${-s.lift})`:m;return d`<g class="led-strip state-${o.state}" data-led-strip="${o.strip.id}"
data-marker="${p.id}" data-state="${o.state}" data-closed="${n.closed?"true":"false"}">
${s?d`<path class="led-iso-shadow" d="${a}" fill="none" stroke="black"
stroke-opacity="${s.shadow.opacity}" stroke-width="${i}" stroke-linecap="round"
stroke-linejoin="round" filter="url(#hp-led-iso-shadow)" pointer-events="none"
transform="translate(${s.shadow.dx} ${s.shadow.dy-s.lift})"></path>
${[1,.5].map(e=>d`<path class="led-iso-edge" d="${a}" fill="none" stroke="${s.edge}"
stroke-width="${i}" stroke-linecap="round" stroke-linejoin="round" pointer-events="none"
transform="translate(0 ${-s.lift+s.depth*e})"></path>`)}`:m}
<g transform=${h}>
<path class="led-outline" d="${a}" fill="none" stroke="${E}" stroke-width="${i}"
stroke-linecap="round" stroke-linejoin="round"
stroke-dasharray=${r?`${2*i} ${1.5*i}`:m}></path>
<path class="led-core" d="${a}" fill="none" stroke="${l}" stroke-width="${i/2}"
stroke-linecap="round" stroke-linejoin="round"
stroke-dasharray=${r?`${2*i} ${1.5*i}`:m}></path>
<path class="led-focus" d="${a}" stroke-width="${1.6*i}" stroke-linecap="round"
stroke-linejoin="round" aria-hidden="true"></path>
${t?d`<path class="led-hit" d="${a}" stroke-width="${c}"
stroke-linecap="round" stroke-linejoin="round" pointer-events="stroke"
role="button" tabindex="0" aria-label="${t.label(p)}"
data-hp="device" data-id="${p.id}"
@click=${e=>t.click(e,u(e))}
@keydown=${e=>t.keydown(e,p)}
@contextmenu=${e=>t.contextmenu(e,u(e))}
@pointerdown=${e=>t.pointerdown(e,u(e))}
@pointermove=${e=>t.pointermove(e,u(e))}
@pointerup=${e=>t.pointerup(e,u(e))}
@pointercancel=${e=>t.pointercancel(e,p)}
@lostpointercapture=${e=>t.pointercancel(e,p)}
@pointerover=${e=>t.pointerover(e,u(e))}
@pointerleave=${()=>t.pointerleave()}
@focus=${e=>t.focus(e,p)}
@blur=${()=>t.blur(p)}></path>`:m}
</g>
</g>`})}
</g>`}function H(e,t,o,s){return(t?e.find(e=>e.id===t):void 0)??(o?e.find(e=>s(o,e)):void 0)}function N(e){const t=new Map(e.devices.map(e=>[e.id,e])),o=g/e.cellCm*e.gridPitch,s=new Map(i({hass:e.hass,devices:e.devices,virtualLights:e.virtualLights,spaceId:e.space.id,defaultColor:e.defaultColor,paletteAlpha:e.paletteAlpha,defaultRadiusUnits:o,cellCm:e.cellCm,gridPitch:e.gridPitch,position:()=>({x:0,y:0})}).map(e=>[e.key,e])),r=[];for(const i of e.space.led_strips||[]){if(!1===i?.active||!i.marker||!w(i.points))continue;const a={...i,points:i.points.map(e=>[e[0]*n,e[1]*n])},l=t.get(a.marker);if(!l||l.space!==e.space.id)continue;if(l.hidden&&!e.showHidden)continue;const d=H(e.space.rooms,l.marker?.room_id,$(R(a.points)),e.inRoom);r.push(I({strip:a,device:l,candidate:s.get(`${e.space.id}|${l.id}`)??null,hass:e.hass,glow:!!d&&e.glowFor(d),defaultRadius:o,cellCm:e.cellCm,gridPitch:e.gridPitch}))}const l=_/e.cellCm*e.gridPitch;return{views:r,faces:A(e.scene,l),d:e.iconPct/100*a(e.space),scene:e.scene,polygons:e.polygons}}const q=new WeakMap;function B(e){for(const t of q.get(e)?.frame.views??[])T.delete(t.strip);q.delete(e),L?.releaseLedField(e)}function S(e){return{shapes:q.get(e)?.frame.views.length??0,...L?.ledFieldStats(e)??{visibility:0,sources:0,visibilityPaths:0,pathChars:0,recomputes:0}}}function O(e,t,o){const s=t.rooms.flatMap(e=>{const t=r(e);return t?[{room:e,poly:t}]:[]}),i=s.length?e._lightBarriers(t,s.map(({room:e,poly:t})=>({r:e,poly:t}))):null,n=[t,e._renderDevices,e._renderPlanHass,o,i,e._mode,e._showAll],a=q.get(e);if(a&&a.key.every((e,t)=>e===n[t]))return a.frame;for(const e of a?.frame.views??[])T.delete(e.strip);const d=e._config?.icon_size??2.5,c=N({space:t,devices:e._renderDevices,hass:e._renderPlanHass,virtualLights:e._virtualLights,defaultColor:e._fillColors.glow_light.c,paletteAlpha:e._fillColors.glow_light.a,cellCm:e._cellCm,gridPitch:e._gridPitch,iconPct:d>8?2.5:d,scene:i,polygons:s,glowFor:e=>l(o,e),inRoom:(t,o)=>e._pointInRoom(t,o),showHidden:"devices"===e._mode&&e._showAll});return!1!==e.isConnected&&q.set(e,{key:n,frame:c}),c}function W(e,t,o,s){const i=O(e,t,o),n=e._stageEl?.clientWidth,a="iso"===e._renderProjection&&"view"===e._mode,r=a?i.d*c:i.d,l="theme-dark"===p(e._renderPlanHass)?"dark":"light",m=!!e._isoLightFloors?.size,v=u(l,m),g=G({views:i.views,d:r,iso:a?{lift:f.lift*r,depth:f.depth*r,edge:h(E,l,m),shadow:{dx:v.dx*r,dy:v.dy*r,sigma:v.sigma*r,opacity:v.opacityWhite}}:null,faces:i.faces,perUnit:n&&s.w?n/s.w:1,handlers:"view"===e._mode?{click:(t,o)=>e._clickDevice(t,o),keydown:(t,o)=>e._keyDevice(t,o),contextmenu:(t,o)=>e._ctxDevice(t,o),pointerdown:(t,o)=>e._pointerDown(t,o),pointermove:(t,o)=>{const s=e._pointerMove(t,o);s&&e._showDeviceTip(t,s)},pointerup:(t,o)=>e._pointerUp(t,o),pointercancel:(t,o)=>e._pointerCancel(t,o),pointerover:(t,o)=>e._showDeviceTip(t,o),pointerleave:()=>e._clearPointerHover(),focus:(t,o)=>e._showDeviceFocusTip(t,o),blur:t=>e._hideDeviceFocusTip(t.id),label:e=>e.name}:null});return"plan"===e._mode||"decor"===e._mode?d`<g class="led-passive" opacity="0.45" pointer-events="none">${g}</g>`:g}function z(e,t,o){if(!1===e.isConnected)return d``;const s=O(e,t,o),i=s.scene&&(D(s.views)||L?.hasLedField(e))?L||x(t.id,()=>!1!==e.isConnected&&e.requestUpdate()):null;return i?i.renderLedField({views:s.views,scene:s.scene,polygons:s.polygons,faces:s.faces,spaceId:t.id,owner:e,requestUpdate:()=>e.requestUpdate(),isConnected:()=>!1!==e.isConnected}):d``}function Y(e){const t=e.space.rooms.flatMap(e=>{const t=r(e);return t?[{room:e,poly:t}]:[]}),o=N({space:e.space,devices:e.devices,hass:e.hass,virtualLights:e.virtualLights,defaultColor:e.defaultColor,paletteAlpha:e.paletteAlpha,cellCm:e.cellCm,gridPitch:e.gridPitch,iconPct:e.iconPct,scene:e.scene,polygons:t,glowFor:e.glowFor,inRoom:e.inRoom,showHidden:!1}),s=e.live?o.views:o.views.map(e=>({...e,state:"off",appearance:null,glow:!1})),i=A({masonryGeometry:e.bodies.masonryGeometry,opaqueBodies:e.bodies.opaqueBodies},_/e.cellCm*e.gridPitch),n=e.scene&&e.live&&(D(s)||L?.hasLedField(e.owner))?x(e.space.id,e.ready):null;return d`${n?n.renderLedField({views:s,scene:e.scene,polygons:t,faces:i,spaceId:e.space.id,owner:e.owner,requestUpdate:e.ready,isConnected:()=>!0}):m}${G({views:s,d:o.d,faces:i,perUnit:e.perUnit,handlers:null})}`}export{M as LED_RUNTIME_FINGERPRINT,A as faceContext,x as ledField,N as ledFrame,O as ledFrameFor,S as ledStats,I as ledStripView,j as ledStripePath,B as releaseLed,z as renderLedFieldFor,W as renderLedLayerFor,G as renderLedStripes,Y as renderStaticLed,H as stripRoom};
@@ -1,47 +0,0 @@
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="fd4a405e9c5a21035258c45feca26dca03d59d4cfba4280f89ff5f82675515ac";import{et as e,eB as t,c6 as o,eI as s,eJ as i,ad as n,ed as a,O as r,eK as l,az as d,ee as c,aL as p,eL as u,eM as h,eN as f,A as m,eO as v}from"./houseplan-card-CDzf9V5z.js";import{L as g,v as w,s as $,a as _,p as y,b as k,c as b,d as C,e as P,f as M}from"./led-strip-geometry-BcPfXtN-.js";const F="fd4a405e9c5a21035258c45feca26dca03d59d4cfba4280f89ff5f82675515ac";let L,U=null,x=null;function D(e,t){return U||x||L===e||""===L||(x=(void 0===L?import("./led-strip-field-DvtQ7tpM.js"):import(new URL(`./led-strip-field-DvtQ7tpM.js?${Date.now()}`,import.meta.url).href)).then(e=>{e.LED_FIELD_FINGERPRINT===s?U=e:L=""},()=>{L=e}).finally(()=>{x=null})),U||x?.then(()=>U&&t()),U}const R=e=>e.some(e=>e.glow&&"on"===e.state),E=e=>e.map(e=>[e[0],e[1]]),A="#383838";function I(s,i){if(!s)return null;const n=Array.isArray(s.masonryGeometry)?s.masonryGeometry:[],a=[...e(s.masonryGeometry),...s.opaqueBodies],r=[];for(const e of a)for(let t=0;t<e.length;t++){const o=e[t],s=e[(t+1)%e.length];o&&s&&r.push({a:[o[0],o[1]],b:[s[0],s[1]]})}const l=25,d=new Map;r.forEach((e,t)=>{const o=Math.floor(Math.min(e.a[0],e.b[0])/l),s=Math.floor(Math.max(e.a[0],e.b[0])/l),i=Math.floor(Math.min(e.a[1],e.b[1])/l),n=Math.floor(Math.max(e.a[1],e.b[1])/l);for(let e=o;e<=s;e++)for(let o=i;o<=n;o++){const s=`${e},${o}`,i=d.get(s);i?i.push(t):d.set(s,[t])}});const c=e=>{let t=1/0,o=1/0,s=-1/0,i=-1/0;for(const n of e)t=Math.min(t,n[0]),o=Math.min(o,n[1]),s=Math.max(s,n[0]),i=Math.max(i,n[1]);return[t,o,s,i]},p=(e,t)=>e[0]>=t[0]&&e[0]<=t[2]&&e[1]>=t[1]&&e[1]<=t[3],u=n.filter(e=>e?.[0]?.length).map(e=>({box:c(e[0]),poly:e})),h=s.opaqueBodies.map(e=>({box:c(e),body:e}));return{faces:r,inside:e=>u.some(({box:o,poly:s})=>p(e,o)&&t([e[0],e[1]],[s]))||h.some(({box:t,body:s})=>p(e,t)&&o([e[0],e[1]],s)),epsilon:i,near:e=>{const t=new Set;for(let o=Math.floor(e[0]/l);o<=Math.floor(e[2]/l);o++)for(let s=Math.floor(e[1]/l);s<=Math.floor(e[3]/l);s++)for(const e of d.get(`${o},${s}`)||[])t.add(e);return[...t].map(e=>r[e])}}}function T(e){const t=e.candidate?.sourceEid||e.device.primary||"",o=t?e.hass?.states?.[t]?.state:void 0,s="unavailable"===o||"unknown"===o||!!t&&!!e.hass&&!e.hass.states?.[t]&&!e.device.virtual,i=Number(e.device.marker?.glow_radius_cm),n=Number.isFinite(i)&&i>0?i/e.cellCm*e.gridPitch:e.defaultRadius,a=s?null:e.candidate?.appearance??null;return{strip:e.strip,device:e.device,state:s?"unavailable":a?"on":"off",glow:e.glow,appearance:a,radius:n}}function j(e,t){const o=function(e,t){return("on"===e.state?P:M)*t}(e,t.d);return{t:o,path:b(E(e.strip.points),t.faces,o/2)}}function B(e){if(!e.views.length)return d``;const t=e.handlers,o=[...e.views].sort((e,t)=>e.strip.id<t.strip.id?1:e.strip.id>t.strip.id?-1:0),s=e.iso;return d`<g class="led-strips" data-hp-led-strips="${o.length}"
data-hp-iso=${s?"raised":m}>
${s?d`<defs><filter id="hp-led-iso-shadow" filterUnits="userSpaceOnUse"
x="-100000" y="-100000" width="200000" height="200000">
<feGaussianBlur stdDeviation="${s.shadow.sigma}"></feGaussianBlur></filter></defs>`:m}
<style>
.led-strip .led-focus { fill: none; stroke: transparent; }
.led-strip:has(.led-hit:focus-visible) .led-focus { stroke: var(--primary-color, #03a9f4); }
.led-strip .led-hit { fill: none; stroke: transparent; cursor: pointer; outline: none; }
</style>
${v(o,e=>e.strip.id,o=>{const{t:i,path:n}=j(o,e),a=y(n),r="unavailable"===o.state,l=r?"#9e9e9e":"on"===o.state&&!o.glow&&o.appearance?o.appearance.c:"#FFFFFF",c=2*k(i*e.perUnit)/(e.perUnit||1),p=o.device,u=t=>function(e,t,o){const s=e.currentTarget,i=s?.getScreenCTM?.();if(!i||o.views.length<2)return t;const n=i.inverse(),a=[n.a*e.clientX+n.c*e.clientY+n.e,n.b*e.clientX+n.d*e.clientY+n.f],r=o.views.map(e=>{const{t:t,path:s}=j(e,o);return{id:e.strip.id,points:s.points.map(e=>[e[0]*o.perUnit,e[1]*o.perUnit]),closed:s.closed,thicknessPx:t*o.perUnit}}),l=C([a[0]*o.perUnit,a[1]*o.perUnit],r);return o.views.find(e=>e.strip.id===l)||t}(t,o,e).device,h=s?`translate(0 ${-s.lift})`:m;return d`<g class="led-strip state-${o.state}" data-led-strip="${o.strip.id}"
data-marker="${p.id}" data-state="${o.state}" data-closed="${n.closed?"true":"false"}">
${s?d`<path class="led-iso-shadow" d="${a}" fill="none" stroke="black"
stroke-opacity="${s.shadow.opacity}" stroke-width="${i}" stroke-linecap="round"
stroke-linejoin="round" filter="url(#hp-led-iso-shadow)" pointer-events="none"
transform="translate(${s.shadow.dx} ${s.shadow.dy-s.lift})"></path>
${[1,.5].map(e=>d`<path class="led-iso-edge" d="${a}" fill="none" stroke="${s.edge}"
stroke-width="${i}" stroke-linecap="round" stroke-linejoin="round" pointer-events="none"
transform="translate(0 ${-s.lift+s.depth*e})"></path>`)}`:m}
<g transform=${h}>
<path class="led-outline" d="${a}" fill="none" stroke="${A}" stroke-width="${i}"
stroke-linecap="round" stroke-linejoin="round"
stroke-dasharray=${r?`${2*i} ${1.5*i}`:m}></path>
<path class="led-core" d="${a}" fill="none" stroke="${l}" stroke-width="${i/2}"
stroke-linecap="round" stroke-linejoin="round"
stroke-dasharray=${r?`${2*i} ${1.5*i}`:m}></path>
<path class="led-focus" d="${a}" stroke-width="${1.6*i}" stroke-linecap="round"
stroke-linejoin="round" aria-hidden="true"></path>
${t?d`<path class="led-hit" d="${a}" stroke-width="${c}"
stroke-linecap="round" stroke-linejoin="round" pointer-events="stroke"
role="button" tabindex="0" aria-label="${t.label(p)}"
data-hp="device" data-id="${p.id}"
@click=${e=>t.click(e,u(e))}
@keydown=${e=>t.keydown(e,p)}
@contextmenu=${e=>t.contextmenu(e,u(e))}
@pointerdown=${e=>t.pointerdown(e,u(e))}
@pointermove=${e=>t.pointermove(e,u(e))}
@pointerup=${e=>t.pointerup(e,u(e))}
@pointercancel=${e=>t.pointercancel(e,p)}
@lostpointercapture=${e=>t.pointercancel(e,p)}
@pointerover=${e=>t.pointerover(e,u(e))}
@pointerleave=${()=>t.pointerleave()}
@focus=${e=>t.focus(e,p)}
@blur=${()=>t.blur(p)}></path>`:m}
</g>
</g>`})}
</g>`}function G(e,t,o,s){return(t?e.find(e=>e.id===t):void 0)??(o?e.find(e=>s(o,e)):void 0)}function H(e){const t=new Map(e.devices.map(e=>[e.id,e])),o=g/e.cellCm*e.gridPitch,s=new Map(i({hass:e.hass,devices:e.devices,virtualLights:e.virtualLights,spaceId:e.space.id,defaultColor:e.defaultColor,paletteAlpha:e.paletteAlpha,defaultRadiusUnits:o,cellCm:e.cellCm,gridPitch:e.gridPitch,position:()=>({x:0,y:0})}).map(e=>[e.key,e])),r=[];for(const i of e.space.led_strips||[]){if(!1===i?.active||!i.marker||!w(i.points))continue;const a={...i,points:i.points.map(e=>[e[0]*n,e[1]*n])},l=t.get(a.marker);if(!l||l.space!==e.space.id)continue;if(l.hidden&&!e.showHidden)continue;const d=G(e.space.rooms,l.marker?.room_id,$(E(a.points)),e.inRoom);r.push(T({strip:a,device:l,candidate:s.get(`${e.space.id}|${l.id}`)??null,hass:e.hass,glow:!!d&&e.glowFor(d),defaultRadius:o,cellCm:e.cellCm,gridPitch:e.gridPitch}))}const l=_/e.cellCm*e.gridPitch;return{views:r,faces:I(e.scene,l),d:e.iconPct/100*a(e.space),scene:e.scene,polygons:e.polygons}}const N=new WeakMap;function q(e){N.delete(e),U?.releaseLedField(e)}function S(e){return{shapes:N.get(e)?.frame.views.length??0,...U?.ledFieldStats(e)??{visibility:0,sources:0,recomputes:0}}}function O(e,t,o){const s=t.rooms.flatMap(e=>{const t=r(e);return t?[{room:e,poly:t}]:[]}),i=s.length?e._lightBarriers(t,s.map(({room:e,poly:t})=>({r:e,poly:t}))):null,n=[t,e._renderDevices,e._renderPlanHass,o,i,e._mode,e._showAll],a=N.get(e);if(a&&a.key.every((e,t)=>e===n[t]))return a.frame;const d=e._config?.icon_size??2.5,c=H({space:t,devices:e._renderDevices,hass:e._renderPlanHass,virtualLights:e._virtualLights,defaultColor:e._fillColors.glow_light.c,paletteAlpha:e._fillColors.glow_light.a,cellCm:e._cellCm,gridPitch:e._gridPitch,iconPct:d>8?2.5:d,scene:i,polygons:s,glowFor:e=>l(o,e),inRoom:(t,o)=>e._pointInRoom(t,o),showHidden:"devices"===e._mode&&e._showAll});return!1!==e.isConnected&&N.set(e,{key:n,frame:c}),c}function z(e,t,o,s){const i=O(e,t,o),n=e._stageEl?.clientWidth,a="iso"===e._renderProjection&&"view"===e._mode,r=a?i.d*c:i.d,l="theme-dark"===p(e._renderPlanHass)?"dark":"light",m=!!e._isoLightFloors?.size,v=u(l,m),g=B({views:i.views,d:r,iso:a?{lift:f.lift*r,depth:f.depth*r,edge:h(A,l,m),shadow:{dx:v.dx*r,dy:v.dy*r,sigma:v.sigma*r,opacity:v.opacityWhite}}:null,faces:i.faces,perUnit:n&&s.w?n/s.w:1,handlers:"view"===e._mode?{click:(t,o)=>e._clickDevice(t,o),keydown:(t,o)=>e._keyDevice(t,o),contextmenu:(t,o)=>e._ctxDevice(t,o),pointerdown:(t,o)=>e._pointerDown(t,o),pointermove:(t,o)=>{const s=e._pointerMove(t,o);s&&e._showDeviceTip(t,s)},pointerup:(t,o)=>e._pointerUp(t,o),pointercancel:(t,o)=>e._pointerCancel(t,o),pointerover:(t,o)=>e._showDeviceTip(t,o),pointerleave:()=>e._clearPointerHover(),focus:(t,o)=>e._showDeviceFocusTip(t,o),blur:t=>e._hideDeviceFocusTip(t.id),label:e=>e.name}:null});return"plan"===e._mode||"decor"===e._mode?d`<g class="led-passive" opacity="0.45" pointer-events="none">${g}</g>`:g}function W(e,t,o){if(!1===e.isConnected)return d``;const s=O(e,t,o),i=s.scene&&(R(s.views)||U?.hasLedField(e))?U||D(t.id,()=>!1!==e.isConnected&&e.requestUpdate()):null;return i?i.renderLedField({views:s.views,scene:s.scene,polygons:s.polygons,faces:s.faces,spaceId:t.id,owner:e,requestUpdate:()=>e.requestUpdate(),isConnected:()=>!1!==e.isConnected}):d``}function Y(e){const t=e.space.rooms.flatMap(e=>{const t=r(e);return t?[{room:e,poly:t}]:[]}),o=H({space:e.space,devices:e.devices,hass:e.hass,virtualLights:e.virtualLights,defaultColor:e.defaultColor,paletteAlpha:e.paletteAlpha,cellCm:e.cellCm,gridPitch:e.gridPitch,iconPct:e.iconPct,scene:e.scene,polygons:t,glowFor:e.glowFor,inRoom:e.inRoom,showHidden:!1}),s=e.live?o.views:o.views.map(e=>({...e,state:"off",appearance:null,glow:!1})),i=I({masonryGeometry:e.bodies.masonryGeometry,opaqueBodies:e.bodies.opaqueBodies},_/e.cellCm*e.gridPitch),n=e.scene&&e.live&&(R(s)||U?.hasLedField(e.owner))?D(e.space.id,e.ready):null;return d`${n?n.renderLedField({views:s,scene:e.scene,polygons:t,faces:i,spaceId:e.space.id,owner:e.owner,requestUpdate:e.ready,isConnected:()=>!0}):m}${B({views:s,d:o.d,faces:i,perUnit:e.perUnit,handlers:null})}`}export{F as LED_RUNTIME_FINGERPRINT,I as faceContext,D as ledField,H as ledFrame,O as ledFrameFor,S as ledStats,T as ledStripView,q as releaseLed,W as renderLedFieldFor,z as renderLedLayerFor,B as renderLedStripes,Y as renderStaticLed,G as stripRoom};
@@ -1 +0,0 @@
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="fd4a405e9c5a21035258c45feca26dca03d59d4cfba4280f89ff5f82675515ac";import{eQ as a,eR as e,eF as n}from"./houseplan-card-CDzf9V5z.js";function c(n,c){return new a([{code:"en",dictionary:n},{code:"ru",loadDictionary:c.ru},{code:"de",loadDictionary:c.de},{code:"fr",loadDictionary:c.fr}],"fd4a405e9c5a21035258c45feca26dca03d59d4cfba4280f89ff5f82675515ac",console.warn,e)}function o(a){return function(a,e){return{state:n=>{const c=a.state(n);return"pending"!==c&&e.some(a=>"pending"===a.state(n))?"pending":c},dictionary:e=>a.dictionary(e),ensure:n=>Promise.all([a,...e].map(a=>a.ensure(n))).then(()=>{})}}(n,a)}export{c as n,o as s};
@@ -0,0 +1 @@
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="ab07da35681c15ab6136c323500b69766580ea4a788e399ea88f9e7497549172";import{eR as e,eS as a,eG as n}from"./houseplan-card-BOdiRDFR.js";function o(n,o){return new e([{code:"en",dictionary:n},{code:"ru",loadDictionary:o.ru},{code:"de",loadDictionary:o.de},{code:"fr",loadDictionary:o.fr}],"ab07da35681c15ab6136c323500b69766580ea4a788e399ea88f9e7497549172",console.warn,a)}function r(e){return function(e,a){return{state:n=>{const o=e.state(n);return"pending"!==o&&a.some(e=>"pending"===e.state(n))?"pending":o},dictionary:a=>e.dictionary(a),ensure:n=>Promise.all([e,...a].map(e=>e.ensure(n))).then(()=>{})}}(n,e)}export{o as n,r as s};
@@ -1,6 +1,6 @@
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="fd4a405e9c5a21035258c45feca26dca03d59d4cfba4280f89ff5f82675515ac";import{aG as e,l as t,aJ as s,A as a,eE as o,eF as i,eG as n,E as c,eP as l,c as r}from"./houseplan-card-CDzf9V5z.js";class h extends e{constructor(){super(...arguments),this._spaces=null,this._spacesLoading=!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}))}catch{this._spaces=[]}finally{this._spacesLoading=!1}}}get _lang(){return t(this.hass,this._config?.language)}get _schema(){const e=this._spaces||[];return[e.length?{name:"space",selector:{select:{mode:"dropdown",options:e}}}:{name:"space",selector:{text:{}}},{name:"title",selector:{text:{}}},{name:"fit",selector:{select:{mode:"dropdown",options:[{value:"content",label:s(this._lang,"editor.fit_content")},{value:"house",label:s(this._lang,"editor.fit_house")}]}}},{name:"show_button",selector:{boolean:{}}},{name:"button_label",selector:{text:{}}},{name:"button_target",selector:{text:{}}},{name:"icon_size",selector:{number:{min:1,max:6,step:.1,mode:"box"}}},{name:"show_temperature",selector:{boolean:{}}},{name:"live_states",selector:{boolean:{}}},{name:"light_pools",selector:{boolean:{}}},{name:"show_signal",selector:{boolean:{}}}]}render(){if(!this.hass||!this._config)return a;const e=o(this,i,t(this.hass,this._config.language));if("cold"===e)return n();if("warm"===e)return c;this._loadSpaces();const h=this._lang,_={space:s(h,"editor.space"),title:s(h,"editor.title"),fit:s(h,"editor.framing"),show_button:s(h,"editor.show_button"),button_label:s(h,"editor.button_label"),button_target:s(h,"editor.button_target"),icon_size:s(h,"editor.icon_size"),show_temperature:s(h,"editor.show_temperature"),live_states:s(h,"editor.live_states"),light_pools:s(h,"editor.light_pools"),show_signal:s(h,"editor.show_signal")};return r`<ha-form
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="ab07da35681c15ab6136c323500b69766580ea4a788e399ea88f9e7497549172";import{aG as e,l as t,aJ as s,A as a,eF as o,eG as i,eH as n,E as l,eQ as c,c as r}from"./houseplan-card-BOdiRDFR.js";class h extends e{constructor(){super(...arguments),this._spaces=null,this._spacesLoading=!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}))}catch{this._spaces=[]}finally{this._spacesLoading=!1}}}get _lang(){return t(this.hass,this._config?.language)}get _schema(){const e=this._spaces||[];return[e.length?{name:"space",selector:{select:{mode:"dropdown",options:e}}}:{name:"space",selector:{text:{}}},{name:"title",selector:{text:{}}},{name:"fit",selector:{select:{mode:"dropdown",options:[{value:"content",label:s(this._lang,"editor.fit_content")},{value:"house",label:s(this._lang,"editor.fit_house")}]}}},{name:"show_button",selector:{boolean:{}}},{name:"button_label",selector:{text:{}}},{name:"button_target",selector:{text:{}}},{name:"icon_size",selector:{number:{min:1,max:6,step:.1,mode:"box"}}},{name:"show_temperature",selector:{boolean:{}}},{name:"live_states",selector:{boolean:{}}},{name:"light_pools",selector:{boolean:{}}},{name:"show_signal",selector:{boolean:{}}}]}render(){if(!this.hass||!this._config)return a;const e=o(this,i,t(this.hass,this._config.language));if("cold"===e)return n();if("warm"===e)return l;this._loadSpaces();const h=this._lang,_={space:s(h,"editor.space"),title:s(h,"editor.title"),fit:s(h,"editor.framing"),show_button:s(h,"editor.show_button"),button_label:s(h,"editor.button_label"),button_target:s(h,"editor.button_target"),icon_size:s(h,"editor.icon_size"),show_temperature:s(h,"editor.show_temperature"),live_states:s(h,"editor.live_states"),light_pools:s(h,"editor.light_pools"),show_signal:s(h,"editor.show_signal")};return r`<ha-form
.hass=${this.hass}
.data=${{...this._config,fit:l(this._config.fit)}}
.data=${{...this._config,fit:c(this._config.fit)}}
.schema=${this._schema}
.computeLabel=${e=>_[e.name]||e.name}
@value-changed=${this._valueChanged}
@@ -1,4 +1,4 @@
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="fd4a405e9c5a21035258c45feca26dca03d59d4cfba4280f89ff5f82675515ac";import{c as a,A as s}from"./houseplan-card-CDzf9V5z.js";import{s as e,n as t,a as l,m as r,b as o,c as i,d as u}from"./summary-panel-runtime-loaded-BcDAIp5L.js";import"./form-kit.styles-Dq1Y4tz1.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&&!e(t(d.draft),d.base),p=$&&!d.busy&&!y,v=a=>n.find(s=>s.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__="ab07da35681c15ab6136c323500b69766580ea4a788e399ea88f9e7497549172";import{c as a,A as e}from"./houseplan-card-BOdiRDFR.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-CcLP5B5v.js";import"./form-kit.styles-B6HsmMPA.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>
<small id="summary-local-show-hint">${b("summary.show_local_hint")}</small></span>
<input id="summary-local-show" data-summary-local-show type="checkbox"
@@ -10,31 +10,31 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="fd4a405e9c5a21035258c45feca26dca03d5
dismiss-on-scrim aria-busy=${String(d.busy)}
@hp-close=${k}>
<div class="body summary-editor" @click=${()=>m.closeSource()}>
${d.localOnly?a`<p class="summary-local-hint">${b(d.localOnlyHint)}</p>`:s}
${d.localOnly?a`<p class="summary-local-hint">${b(d.localOnlyHint)}</p>`:e}
<section class="summary-general" aria-labelledby="summary-general-title">
<h3 id="summary-general-title">${b("summary.general_settings")}</h3>
<div class="summary-general-grid">
${d.localOnly?s:a`<div class="summary-field">
${d.localOnly?e:a`<div class="summary-field">
<label for="summary-panel-title">${b("summary.panel_title")}</label>
<input id="summary-panel-title" type="text" .value=${d.draft.title}
?disabled=${d.busy}
data-summary-error=${String(d.attempted&&"title"===y?.path)}
aria-invalid=${"error"===v("title")?.kind?"true":"false"}
@input=${a=>m.mutate(s=>{s.title=a.target.value})} />
${v("title")?a`<div class="summary-problem error">${h(v("title"))}</div>`:s}
@input=${a=>m.mutate(e=>{e.title=a.target.value})} />
${v("title")?a`<div class="summary-problem error">${h(v("title"))}</div>`:e}
</div>`}
${g}
${d.localOnly?s:a`<label class="summary-switch" for="summary-mobile-show">
${d.localOnly?e:a`<label class="summary-switch" for="summary-mobile-show">
<span class="summary-switch-caption"><strong>${b("summary.show_mobile")}</strong>
<small id="summary-mobile-show-hint">${b("summary.show_mobile_hint")}</small></span>
<input id="summary-mobile-show" data-summary-mobile-show type="checkbox"
.checked=${d.draft.show_on_mobile} ?disabled=${!d.localShow||d.busy}
aria-label=${b("summary.show_mobile")} aria-describedby="summary-mobile-show-hint"
@change=${a=>m.mutate(s=>{s.show_on_mobile=a.target.checked})} /></label>`}
@change=${a=>m.mutate(e=>{e.show_on_mobile=a.target.checked})} /></label>`}
</div>
${m.storageUnavailable?a`<div class="summary-problem warning">${b("summary.storage_unavailable")}</div>`:s}
${m.storageUnavailable?a`<div class="summary-problem warning">${b("summary.storage_unavailable")}</div>`:e}
</section>
${d.localOnly?s:a`
${d.localOnly?e:a`
<section class="summary-blocks-card" aria-labelledby="summary-blocks-title">
<header class="summary-blocks-heading">
<div><h3 id="summary-blocks-title">${b("summary.blocks")}</h3>
@@ -42,7 +42,7 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="fd4a405e9c5a21035258c45feca26dca03d5
<span class="summary-block-count">${b("summary.block_count").replace("{count}",String(d.draft.blocks.length)).replace("{limit}","10")}</span>
</header>
<div class="summary-editor-blocks">
${d.draft.blocks.map((e,t)=>{const u=`blocks.${t}`,n=v(`${u}.scope`);return a`<article class="summary-editor-block"
${d.draft.blocks.map((s,t)=>{const u=`blocks.${t}`,n=v(`${u}.scope`);return a`<article class="summary-editor-block"
@dragover=${a=>a.preventDefault()}
@drop=${a=>m.drop(a,`block:${t}`)}>
<div class="summary-block-head">
@@ -57,40 +57,40 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="fd4a405e9c5a21035258c45feca26dca03d5
?disabled=${t===d.draft.blocks.length-1||d.busy}
@click=${()=>m.mutate(a=>{a.blocks=r(a.blocks,t,t+1)})}>${l("down")}</button>
</div>
<input class="summary-block-title" type="text" .value=${e.title}
<input class="summary-block-title" type="text" .value=${s.title}
placeholder=${b("summary.block_title")} aria-label=${b("summary.block_title")}
?disabled=${d.busy}
data-summary-error=${String(d.attempted&&y?.path===`${u}.title`)}
aria-invalid=${"error"===v(`${u}.title`)?.kind?"true":"false"}
@input=${a=>m.mutate(s=>{s.blocks[t].title=a.target.value})} />
@input=${a=>m.mutate(e=>{e.blocks[t].title=a.target.value})} />
<button class="summary-icon-button summary-visibility" type="button"
?disabled=${d.busy} aria-pressed=${String(e.visible)}
title=${b(e.visible?"summary.hide_block":"summary.show_block")}
aria-label=${b(e.visible?"summary.hide_block":"summary.show_block")}
@click=${()=>m.mutate(a=>{a.blocks[t].visible=!a.blocks[t].visible})}>${l(e.visible?"eye":"eyeOff")}</button>
${v(`${u}.title`)?a`<div class="summary-problem error summary-block-title-error">${h(v(`${u}.title`))}</div>`:s}
?disabled=${d.busy} aria-pressed=${String(s.visible)}
title=${b(s.visible?"summary.hide_block":"summary.show_block")}
aria-label=${b(s.visible?"summary.hide_block":"summary.show_block")}
@click=${()=>m.mutate(a=>{a.blocks[t].visible=!a.blocks[t].visible})}>${l(s.visible?"eye":"eyeOff")}</button>
${v(`${u}.title`)?a`<div class="summary-problem error summary-block-title-error">${h(v(`${u}.title`))}</div>`:e}
<div class="summary-scope">
<select .value=${e.scope.type} ?disabled=${d.busy}
<select .value=${s.scope.type} ?disabled=${d.busy}
aria-label=${b("summary.scope")}
@change=${a=>m.mutate(s=>{s.blocks[t].scope="space"===a.target.value?{type:"space",space_id:c._space}:{type:"all"}})}>
<option value="all" ?selected=${"all"===e.scope.type}>${b("summary.scope_all")}</option>
<option value="space" ?selected=${"space"===e.scope.type}>${b("summary.scope_space")}</option>
@change=${a=>m.mutate(e=>{e.blocks[t].scope="space"===a.target.value?{type:"space",space_id:c._space}:{type:"all"}})}>
<option value="all" ?selected=${"all"===s.scope.type}>${b("summary.scope_all")}</option>
<option value="space" ?selected=${"space"===s.scope.type}>${b("summary.scope_space")}</option>
</select>
${"space"===e.scope.type?a`<select .value=${e.scope.space_id}
${"space"===s.scope.type?a`<select .value=${s.scope.space_id}
?disabled=${d.busy} aria-label=${b("summary.scope_space")}
data-summary-error=${String(d.attempted&&y?.path===`${u}.scope`)}
aria-invalid=${"error"===n?.kind?"true":"false"}
@change=${a=>m.mutate(s=>{const e=s.blocks[t].scope;"space"===e.type&&(e.space_id=a.target.value)})}>
${c._model.some(a=>a.id===e.scope.space_id)?s:a`<option value=${e.scope.space_id} selected>${e.scope.space_id}</option>`}
${c._model.map(s=>a`<option value=${s.id}
?selected=${s.id===e.scope.space_id}>${s.title}</option>`)}
</select>`:s}
@change=${a=>m.mutate(e=>{const s=e.blocks[t].scope;"space"===s.type&&(s.space_id=a.target.value)})}>
${c._model.some(a=>a.id===s.scope.space_id)?e:a`<option value=${s.scope.space_id} selected>${s.scope.space_id}</option>`}
${c._model.map(e=>a`<option value=${e.id}
?selected=${e.id===s.scope.space_id}>${e.title}</option>`)}
</select>`:e}
</div>
${n?a`<div class="summary-problem summary-scope-problem ${n.kind}">${h(n)}</div>`:s}
${n?a`<div class="summary-problem summary-scope-problem ${n.kind}">${h(n)}</div>`:e}
</div>
<div class="summary-block-body">
<div class="summary-editor-values">
${e.values.map((i,c)=>{const n=`${u}.values.${c}`,$=v(`${n}.source`),p=m.sourceToken(i.source),k=d.activeSource?.blockId===e.id&&d.activeSource.valueId===i.id,g="system"===i.source.type?b(`summary.system.${i.source.key}`):i.source.entity_id?m.entityIndex.labels.get(i.source.entity_id)||i.source.entity_id:b("summary.select_source"),_="system"===i.source.type?b("summary.system_source"):i.source.entity_id,f=k?o(m.entityIndex,d.entityFilter):null,w="entity"===i.source.type&&!!i.source.entity_id&&!m.entityIndex.labels.has(i.source.entity_id),S=`${e.id}\n${i.id}`;return a`<div class="summary-editor-value"
${s.values.map((i,c)=>{const n=`${u}.values.${c}`,$=v(`${n}.source`),p=m.sourceToken(i.source),k=d.activeSource?.blockId===s.id&&d.activeSource.valueId===i.id,g="system"===i.source.type?b(`summary.system.${i.source.key}`):i.source.entity_id?m.entityIndex.labels.get(i.source.entity_id)||i.source.entity_id:b("summary.select_source"),_="system"===i.source.type?b("summary.system_source"):i.source.entity_id,f=k?o(m.entityIndex,d.entityFilter):null,w="entity"===i.source.type&&!!i.source.entity_id&&!m.entityIndex.labels.has(i.source.entity_id),S=`${s.id}\n${i.id}`;return a`<div class="summary-editor-value"
@dragover=${a=>{a.preventDefault(),a.stopPropagation()}}
@drop=${a=>m.drop(a,`value:${t}:${c}`)}>
<span class="summary-drag" draggable=${String(!d.busy)} title=${b("summary.drag")}
@@ -101,7 +101,7 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="fd4a405e9c5a21035258c45feca26dca03d5
@click=${()=>m.mutate(a=>{a.blocks[t].values=r(a.blocks[t].values,c,c-1)})}>${l("up")}</button>
<button class="summary-icon-button" type="button" title=${b("summary.down")}
aria-label=${b("summary.down")}
?disabled=${c===e.values.length-1||d.busy}
?disabled=${c===s.values.length-1||d.busy}
@click=${()=>m.mutate(a=>{a.blocks[t].values=r(a.blocks[t].values,c,c+1)})}>${l("down")}</button>
</div>
<div class="summary-value-label">
@@ -109,8 +109,8 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="fd4a405e9c5a21035258c45feca26dca03d5
placeholder=${b("summary.value_name")} aria-label=${b("summary.value_name")}
data-summary-error=${String(d.attempted&&y?.path===`${n}.label`)}
aria-invalid=${"error"===v(`${n}.label`)?.kind?"true":"false"}
@input=${a=>m.mutate(s=>{s.blocks[t].values[c].label=a.target.value})} />
${v(`${n}.label`)?a`<div class="summary-problem error">${h(v(`${n}.label`))}</div>`:s}
@input=${a=>m.mutate(e=>{e.blocks[t].values[c].label=a.target.value})} />
${v(`${n}.label`)?a`<div class="summary-problem error">${h(v(`${n}.label`))}</div>`:e}
</div>
<div class="summary-source-field">
<button class="summary-source" type="button"
@@ -119,9 +119,9 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="fd4a405e9c5a21035258c45feca26dca03d5
data-summary-error=${String(d.attempted&&y?.path===`${n}.source`)}
aria-invalid=${"error"===$?.kind?"true":"false"}
aria-haspopup="listbox" aria-expanded=${k?"true":"false"}
@click=${a=>{a.stopPropagation(),k?m.closeSource():m.openSource(e.id,i.id)}}>
@click=${a=>{a.stopPropagation(),k?m.closeSource():m.openSource(s.id,i.id)}}>
<span class="summary-source-caption"><strong>${g}</strong>
${_?a`<small>${_}</small>`:s}</span>
${_?a`<small>${_}</small>`:e}</span>
${l("chevron")}
</button>
${k&&f?a`<div class="summary-source-picker"
@@ -135,39 +135,39 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="fd4a405e9c5a21035258c45feca26dca03d5
<div class="summary-source-results" role="listbox"
aria-label=${b("summary.select_source")}>
<div class="summary-source-group">${b("summary.system_group")}</div>
${["device_count","total_area","datetime"].map(s=>a`
${["device_count","total_area","datetime"].map(e=>a`
<button type="button" role="option"
?disabled=${d.busy}
aria-selected=${p===`system:${s}`?"true":"false"}
@click=${()=>m.setSource(e.id,i.id,`system:${s}`)}>
${b(`summary.system.${s}`)}
aria-selected=${p===`system:${e}`?"true":"false"}
@click=${()=>m.setSource(s.id,i.id,`system:${e}`)}>
${b(`summary.system.${e}`)}
</button>`)}
${w?a`<div class="summary-source-group">${b("summary.current_source")}</div>
<button type="button" role="option" class="broken" aria-selected="true"
?disabled=${d.busy}
@click=${()=>m.setSource(e.id,i.id,p)}>
@click=${()=>m.setSource(s.id,i.id,p)}>
${g}
</button>`:s}
</button>`:e}
<div class="summary-source-group">${b("summary.entities_group")}</div>
${f.entries.map(s=>a`<button type="button" role="option"
${f.entries.map(e=>a`<button type="button" role="option"
?disabled=${d.busy}
aria-selected=${p===`entity:${s.id}`?"true":"false"}
@click=${()=>m.setSource(e.id,i.id,`entity:${s.id}`)}>
<span>${s.label}</span><small>${s.id}</small>
aria-selected=${p===`entity:${e.id}`?"true":"false"}
@click=${()=>m.setSource(s.id,i.id,`entity:${e.id}`)}>
<span>${e.label}</span><small>${e.id}</small>
</button>`)}
${f.total?s:a`<div class="summary-empty">${b("summary.no_search_results")}</div>`}
${f.truncated?a`<div class="summary-refine">${b("summary.refine_search")}</div>`:s}
${f.total?e:a`<div class="summary-empty">${b("summary.no_search_results")}</div>`}
${f.truncated?a`<div class="summary-refine">${b("summary.refine_search")}</div>`:e}
</div>
</div>`:s}
${$?a`<div class="summary-problem ${$.kind}">${h($)}</div>`:s}
</div>`:e}
${$?a`<div class="summary-problem ${$.kind}">${h($)}</div>`:e}
</div>
<button class="summary-icon-button summary-value-remove" type="button"
title=${b("btn.delete")} aria-label=${b("btn.delete")} ?disabled=${d.busy}
@click=${()=>m.mutate(a=>{a.blocks[t].values.splice(c,1)})}>${l("close")}</button>
</div>`})}
<button class="summary-add summary-add-value" type="button"
?disabled=${e.values.length>=20||d.busy}
title=${e.values.length>=20?b("summary.limit_values"):""}
?disabled=${s.values.length>=20||d.busy}
title=${s.values.length>=20?b("summary.limit_values"):""}
@click=${()=>m.mutate(a=>{a.blocks[t].values.push(i())})}>
${l("plus")}${b("summary.add_value")}
</button>
@@ -186,11 +186,11 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="fd4a405e9c5a21035258c45feca26dca03d5
${l("plus")}${b("summary.add_block")}
</button>
</section>
${d.error?a`<div class="summary-problem error" role="alert">${d.error}</div>`:s}
${d.error?a`<div class="summary-problem error" role="alert">${d.error}</div>`:e}
${d.conflict?a`<button class="btn ghost summary-reload" type="button"
?disabled=${d.busy} @click=${()=>m.reload()}>
<ha-icon icon="mdi:reload"></ha-icon>${b("summary.reload_current")}
</button>`:s}
</button>`:e}
`}
</div>
<div class="row summary-editor-footer" slot="footer">
@@ -1 +1 @@
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="fd4a405e9c5a21035258c45feca26dca03d59d4cfba4280f89ff5f82675515ac";import{e_ as e,O as t,b5 as n,M as i,af as o,ad as r,ce as s,e$ as a,cd as c,b4 as l,b3 as d,b6 as u,f0 as f,f1 as m,cg as g,f2 as v}from"./houseplan-card-CDzf9V5z.js";function y(e){if(!e.registry.authoritative)return null;const t=new Set,n=u(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 _(e,t){return e?.length?t?.length?v(e,t):e:t}function h(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:d(e.rooms,t.walls,t.openCuts,i,t.cellCm,o,r)}}function*p(l,d,u=h){try{let f=0;for(const m of d){const d=l.spaces.find(e=>String(e?.id)===m.id);if(!d)continue;const g=e(d,m),v=u(m,g);let y=null;for(const e of m.rooms){if(!e.id)continue;const a=t(e);if(!a)continue;const c=n(m.rooms,e.id,g.walls,g.openCuts,i,g.cellCm,o,r,v.roomGeom,v.multiWallNodes)||a;y=_(y,s(c,g.physicalBodies)),yield}const h=a(y||[],m.stairs);let p=h.next();for(;!p.done;)yield,p=h.next();y=p.value;const b=g.cellCm/o;f+=c(y)*b*b/1e4}return f}catch{return null}}function b(e,t,n=h){const i=p(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:g(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 C(e,t){const n=e?.states?.[t];if(!n)return null;const i=f(e,t);return i?m(i,String(n.attributes?.unit_of_measurement||"")):null}export{p as cleanFloorAreaSteps,y as representedHaDeviceIds,h as spaceWallGeometry,C as summaryEntityValue,S as summarySystemValue,b as totalCleanFloorAreaM2};
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="ab07da35681c15ab6136c323500b69766580ea4a788e399ea88f9e7497549172";import{e$ as e,O as t,b5 as n,M as i,af as o,ad as r,cf as s,f0 as a,ce as l,b4 as c,b3 as u,b6 as d,f1 as f,f2 as m,ch as g,f3 as v}from"./houseplan-card-BOdiRDFR.js";function y(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,l="entity"===r?e.registry.entities?.[s]:null,c="device"===r?s:l?.device_id,u="device"===r?a?.area_id:l?.area_id||c&&e.registry.devices?.[c]?.area_id,d="string"==typeof i.room_id&&i.room_id.length>0&&null===i.area?"":i.area||u||"",f=d&&e.areaToSpace[d]||i.space||e.firstSpaceId;c&&e.registry.devices?.[c]&&e.spaceIds.has(f)&&(!n.devices.has(c)||"entity"===r&&n.liveEntities.has(s))&&t.add(c)}return t}function _(e,t){return e?.length?t?.length?v(e,t):e:t}function h(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:u(e.rooms,t.walls,t.openCuts,i,t.cellCm,o,r)}}function*p(c,u,d=h){try{let f=0;for(const m of u){const u=c.spaces.find(e=>String(e?.id)===m.id);if(!u)continue;const g=e(u,m),v=d(m,g);let y=null;for(const e of m.rooms){if(!e.id)continue;const a=t(e);if(!a)continue;const l=n(m.rooms,e.id,g.walls,g.openCuts,i,g.cellCm,o,r,v.roomGeom,v.multiWallNodes)||a;y=_(y,s(l,g.physicalBodies)),yield}const h=a(y||[],m.stairs);let p=h.next();for(;!p.done;)yield,p=h.next();y=p.value;const b=g.cellCm/o;f+=l(y)*b*b/1e4}return f}catch{return null}}function b(e,t,n=h){const i=p(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:g(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 C(e,t){const n=e?.states?.[t];if(!n)return null;const i=f(e,t);return i?m(i,String(n.attributes?.unit_of_measurement||"")):null}export{p as cleanFloorAreaSteps,y as representedHaDeviceIds,h as spaceWallGeometry,C as summaryEntityValue,S as summarySystemValue,b as totalCleanFloorAreaM2};
@@ -1 +1 @@
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="fd4a405e9c5a21035258c45feca26dca03d59d4cfba4280f89ff5f82675515ac";var e={"furn.title":"Möbelbibliothek","furn.symbol":"Symbol","furn.group_furniture":"Möbel","furn.group_appliance":"Geräte","furn.group_sanitary":"Sanitär","furn.group_other":"Sonstiges","furn.width":"Breite","furn.depth":"Tiefe","furn.back_to_categories":"Alle Kategorien","furn.pick_hint":"Wählen Sie eine Kategorie und dann ein Symbol.","furn.place_hint":"Klicken Sie auf den Plan — das Element wird an der nächsten Wand platziert. Mit Shift wird es frei platziert.","furn.cat_air_conditioner":"Klimaanlagen","furn.cat_armchair":"Sessel","furn.cat_bathtub":"Badewannen","furn.cat_bed":"Betten","furn.cat_bidet":"Bidets","furn.cat_boiler":"Warmwasserbereiter","furn.cat_chair":"Stühle","furn.cat_coffee_table":"Couchtische","furn.cat_computer":"Computer","furn.cat_cooktop":"Kochfelder","furn.cat_dining_table":"Esstische","furn.cat_dishwasher":"Geschirrspüler","furn.cat_dryer":"Wäschetrockner","furn.cat_exercise":"Fitnessgerät","furn.cat_fireplace":"Kamine","furn.cat_fridge":"Kühlschränke","furn.cat_hood":"Dunstabzugshaube","furn.cat_kitchen_cabinet":"Küchenschränke","furn.cat_kitchen_sink":"Küchenspülen","furn.cat_nightstand":"Schränke","furn.cat_oven":"Backofen","furn.cat_plant":"Pflanzen","furn.cat_rug":"Teppiche","furn.cat_shelving":"Regale","furn.cat_shower":"Duschen","furn.cat_sink":"Waschbecken","furn.cat_sofa":"Sofas","furn.cat_stairs":"Treppen","furn.cat_toilet":"Toiletten","furn.cat_tv":"Fernseher","furn.cat_wardrobe":"Kleiderschränke","furn.cat_washer":"Waschmaschinen","furn.cat_work_table":"Schreibtische","furn.sym_exercise":"Fitnessgerät","furn.sym_computer":"Computer","furn.sym_hood":"Dunstabzugshaube","furn.sym_oven":"Backofen","furn.sym_sofa":"Zweisitzer-Sofa","furn.sym_sofa_three_seat":"Dreisitzer-Sofa","furn.sym_sofa_corner_right":"Ecksofa rechts","furn.sym_armchair":"Polstersessel","furn.sym_armchair_office":"Bürostuhl","furn.sym_coffee_table":"Rechteckiger Couchtisch","furn.sym_coffee_table_round":"Runder Couchtisch","furn.sym_coffee_table_oval":"Ovaler Couchtisch","furn.sym_coffee_table_rounded":"Abgerundeter Couchtisch","furn.sym_table_dining":"Rechteckiger Esstisch","furn.sym_table_round":"Rundtisch","furn.sym_table_dining_oval":"Ovaler Esstisch","furn.sym_table_dining_rounded":"Abgerundeter Esstisch","furn.sym_chair":"Stuhl","furn.sym_chair_bar":"Barhocker","furn.sym_desk":"Rechteckiger Schreibtisch","furn.sym_desk_corner":"Eckschreibtisch","furn.sym_bed_double":"Doppelbett","furn.sym_bed_single":"Einzelbett","furn.sym_nightstand":"Nachttisch","furn.sym_cabinet_tv":"TV-Schrank","furn.sym_cabinet_shoe":"Schuhschrank","furn.sym_cabinet_sink":"Waschtischunterschrank","furn.sym_wardrobe":"Kleiderschrank","furn.sym_bookshelf":"Bücherschrank","furn.sym_wall_unit":"Schrankwand","furn.sym_kitchen_floor":"Küchen-Unterschrank","furn.sym_kitchen_floor_corner":"Küchen-Eckunterschrank","furn.sym_kitchen_wall":"Küchen-Hängeschrank","furn.sym_kitchen_wall_corner":"Küchen-Eckhängeschrank","furn.sym_shelf_floor":"Standregal","furn.sym_shelf_wall":"Wandregal","furn.sym_fridge":"Kühlschrank","furn.sym_stove":"Vierflammiges Kochfeld","furn.sym_cooktop_two":"Zweiflammiges Kochfeld","furn.sym_dishwasher":"Geschirrspüler","furn.sym_washer":"Waschmaschine","furn.sym_dryer":"Wäschetrockner","furn.sym_tv":"Fernseher mit Standfuß","furn.sym_tv_wall":"Wandfernseher","furn.sym_ac":"Klimaanlage","furn.sym_water_heater":"Wassererhitzer","furn.sym_toilet":"Stand-WC","furn.sym_toilet_built_in":"Wand-WC","furn.sym_bathtub":"Rechteckige Badewanne","furn.sym_bathtub_corner":"Eckbadewanne","furn.sym_shower":"Dusche","furn.sym_sink":"Waschbecken","furn.sym_kitchen_sink":"Einzel-Küchenspüle","furn.sym_kitchen_sink_double":"Doppel-Küchenspüle","furn.sym_bidet":"Stand-Bidet","furn.sym_bidet_built_in":"Wand-Bidet","furn.sym_stairs":"Treppe","furn.sym_fireplace":"Kamin","furn.sym_plant":"Pflanze","furn.sym_rug":"Teppich"};const r="fd4a405e9c5a21035258c45feca26dca03d59d4cfba4280f89ff5f82675515ac";export{e as dictionary,r as fingerprint};
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="ab07da35681c15ab6136c323500b69766580ea4a788e399ea88f9e7497549172";var e={"furn.title":"Möbelbibliothek","furn.symbol":"Symbol","furn.group_furniture":"Möbel","furn.group_appliance":"Geräte","furn.group_sanitary":"Sanitär","furn.group_other":"Sonstiges","furn.width":"Breite","furn.depth":"Tiefe","furn.back_to_categories":"Alle Kategorien","furn.pick_hint":"Wählen Sie eine Kategorie und dann ein Symbol.","furn.place_hint":"Klicken Sie auf den Plan — das Element wird an der nächsten Wand platziert. Mit Shift wird es frei platziert.","furn.cat_air_conditioner":"Klimaanlagen","furn.cat_armchair":"Sessel","furn.cat_bathtub":"Badewannen","furn.cat_bed":"Betten","furn.cat_bidet":"Bidets","furn.cat_boiler":"Warmwasserbereiter","furn.cat_chair":"Stühle","furn.cat_coffee_table":"Couchtische","furn.cat_computer":"Computer","furn.cat_cooktop":"Kochfelder","furn.cat_dining_table":"Esstische","furn.cat_dishwasher":"Geschirrspüler","furn.cat_dryer":"Wäschetrockner","furn.cat_exercise":"Fitnessgerät","furn.cat_fireplace":"Kamine","furn.cat_fridge":"Kühlschränke","furn.cat_hood":"Dunstabzugshaube","furn.cat_kitchen_cabinet":"Küchenschränke","furn.cat_kitchen_sink":"Küchenspülen","furn.cat_nightstand":"Schränke","furn.cat_oven":"Backofen","furn.cat_plant":"Pflanzen","furn.cat_rug":"Teppiche","furn.cat_shelving":"Regale","furn.cat_shower":"Duschen","furn.cat_sink":"Waschbecken","furn.cat_sofa":"Sofas","furn.cat_stairs":"Treppen","furn.cat_toilet":"Toiletten","furn.cat_tv":"Fernseher","furn.cat_wardrobe":"Kleiderschränke","furn.cat_washer":"Waschmaschinen","furn.cat_work_table":"Schreibtische","furn.sym_exercise":"Fitnessgerät","furn.sym_computer":"Computer","furn.sym_hood":"Dunstabzugshaube","furn.sym_oven":"Backofen","furn.sym_sofa":"Zweisitzer-Sofa","furn.sym_sofa_three_seat":"Dreisitzer-Sofa","furn.sym_sofa_corner_right":"Ecksofa rechts","furn.sym_armchair":"Polstersessel","furn.sym_armchair_office":"Bürostuhl","furn.sym_coffee_table":"Rechteckiger Couchtisch","furn.sym_coffee_table_round":"Runder Couchtisch","furn.sym_coffee_table_oval":"Ovaler Couchtisch","furn.sym_coffee_table_rounded":"Abgerundeter Couchtisch","furn.sym_table_dining":"Rechteckiger Esstisch","furn.sym_table_round":"Rundtisch","furn.sym_table_dining_oval":"Ovaler Esstisch","furn.sym_table_dining_rounded":"Abgerundeter Esstisch","furn.sym_chair":"Stuhl","furn.sym_chair_bar":"Barhocker","furn.sym_desk":"Rechteckiger Schreibtisch","furn.sym_desk_corner":"Eckschreibtisch","furn.sym_bed_double":"Doppelbett","furn.sym_bed_single":"Einzelbett","furn.sym_nightstand":"Nachttisch","furn.sym_cabinet_tv":"TV-Schrank","furn.sym_cabinet_shoe":"Schuhschrank","furn.sym_cabinet_sink":"Waschtischunterschrank","furn.sym_wardrobe":"Kleiderschrank","furn.sym_bookshelf":"Bücherschrank","furn.sym_wall_unit":"Schrankwand","furn.sym_kitchen_floor":"Küchen-Unterschrank","furn.sym_kitchen_floor_corner":"Küchen-Eckunterschrank","furn.sym_kitchen_wall":"Küchen-Hängeschrank","furn.sym_kitchen_wall_corner":"Küchen-Eckhängeschrank","furn.sym_shelf_floor":"Standregal","furn.sym_shelf_wall":"Wandregal","furn.sym_fridge":"Kühlschrank","furn.sym_stove":"Vierflammiges Kochfeld","furn.sym_cooktop_two":"Zweiflammiges Kochfeld","furn.sym_dishwasher":"Geschirrspüler","furn.sym_washer":"Waschmaschine","furn.sym_dryer":"Wäschetrockner","furn.sym_tv":"Fernseher mit Standfuß","furn.sym_tv_wall":"Wandfernseher","furn.sym_ac":"Klimaanlage","furn.sym_water_heater":"Wassererhitzer","furn.sym_toilet":"Stand-WC","furn.sym_toilet_built_in":"Wand-WC","furn.sym_bathtub":"Rechteckige Badewanne","furn.sym_bathtub_corner":"Eckbadewanne","furn.sym_shower":"Dusche","furn.sym_sink":"Waschbecken","furn.sym_kitchen_sink":"Einzel-Küchenspüle","furn.sym_kitchen_sink_double":"Doppel-Küchenspüle","furn.sym_bidet":"Stand-Bidet","furn.sym_bidet_built_in":"Wand-Bidet","furn.sym_stairs":"Treppe","furn.sym_fireplace":"Kamin","furn.sym_plant":"Pflanze","furn.sym_rug":"Teppich"};const r="ab07da35681c15ab6136c323500b69766580ea4a788e399ea88f9e7497549172";export{e as dictionary,r as fingerprint};
@@ -1 +1 @@
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="fd4a405e9c5a21035258c45feca26dca03d59d4cfba4280f89ff5f82675515ac";var e={"furn.title":"Bibliothèque de mobilier","furn.symbol":"Symbole","furn.group_furniture":"Mobilier","furn.group_appliance":"Électroménager","furn.group_sanitary":"Sanitaires","furn.group_other":"Autre","furn.width":"Largeur","furn.depth":"Profondeur","furn.back_to_categories":"Toutes les catégories","furn.pick_hint":"Choisissez un symbole, puis cliquez sur le plan.","furn.place_hint":"Cliquez sur le plan — le meuble se place contre le mur le plus proche. Maj permet un placement libre.","furn.cat_air_conditioner":"Climatiseurs","furn.cat_armchair":"Fauteuils","furn.cat_bathtub":"Baignoires","furn.cat_bed":"Lits","furn.cat_bidet":"Bidets","furn.cat_boiler":"Chauffe-eau","furn.cat_chair":"Chaises","furn.cat_coffee_table":"Tables basses","furn.cat_computer":"Ordinateur","furn.cat_cooktop":"Plaques de cuisson","furn.cat_dining_table":"Tables à manger","furn.cat_dishwasher":"Lave-vaisselle","furn.cat_dryer":"Sèche-linge","furn.cat_exercise":"Équipement de sport","furn.cat_fireplace":"Cheminées","furn.cat_fridge":"Réfrigérateurs","furn.cat_hood":"Hotte","furn.cat_kitchen_cabinet":"Meubles de cuisine","furn.cat_kitchen_sink":"Éviers de cuisine","furn.cat_nightstand":"Meubles","furn.cat_oven":"Four","furn.cat_plant":"Plantes","furn.cat_rug":"Tapis","furn.cat_shelving":"Étagères","furn.cat_shower":"Douches","furn.cat_sink":"Lavabos","furn.cat_sofa":"Canapés","furn.cat_stairs":"Escaliers","furn.cat_toilet":"Toilettes","furn.cat_tv":"Téléviseurs","furn.cat_wardrobe":"Armoires","furn.cat_washer":"Lave-linge","furn.cat_work_table":"Bureaux","furn.sym_exercise":"Équipement de sport","furn.sym_computer":"Ordinateur","furn.sym_hood":"Hotte","furn.sym_oven":"Four","furn.sym_sofa":"Canapé","furn.sym_sofa_three_seat":"Canapé trois places","furn.sym_sofa_corner_right":"Canapé d'angle droit","furn.sym_armchair":"Fauteuil","furn.sym_armchair_office":"Chaise de bureau","furn.sym_coffee_table":"Table basse","furn.sym_coffee_table_round":"Table basse ronde","furn.sym_coffee_table_oval":"Table basse ovale","furn.sym_coffee_table_rounded":"Table basse arrondie","furn.sym_table_dining":"Table à manger","furn.sym_table_round":"Table ronde","furn.sym_table_dining_oval":"Table à manger ovale","furn.sym_table_dining_rounded":"Table à manger arrondie","furn.sym_chair":"Chaise","furn.sym_chair_bar":"Tabouret de bar","furn.sym_desk":"Bureau","furn.sym_desk_corner":"Bureau d'angle","furn.sym_bed_double":"Lit double","furn.sym_bed_single":"Lit simple","furn.sym_nightstand":"Table de chevet","furn.sym_cabinet_tv":"Meuble TV","furn.sym_cabinet_shoe":"Meuble à chaussures","furn.sym_cabinet_sink":"Meuble sous lavabo","furn.sym_wardrobe":"Armoire","furn.sym_bookshelf":"Bibliothèque","furn.sym_wall_unit":"Élément mural","furn.sym_kitchen_floor":"Module de cuisine bas","furn.sym_kitchen_floor_corner":"Module de cuisine bas d'angle","furn.sym_kitchen_wall":"Module de cuisine haut","furn.sym_kitchen_wall_corner":"Module de cuisine haut d'angle","furn.sym_shelf_floor":"Étagère au sol","furn.sym_shelf_wall":"Étagère murale","furn.sym_fridge":"Réfrigérateur","furn.sym_stove":"Cuisinière","furn.sym_cooktop_two":"Plaque à deux feux","furn.sym_dishwasher":"Lave-vaisselle","furn.sym_washer":"Lave-linge","furn.sym_dryer":"Sèche-linge","furn.sym_tv":"Téléviseur","furn.sym_tv_wall":"Téléviseur mural","furn.sym_ac":"Climatiseur","furn.sym_water_heater":"Chauffe-eau","furn.sym_toilet":"Toilettes","furn.sym_toilet_built_in":"Toilettes suspendues","furn.sym_bathtub":"Baignoire","furn.sym_bathtub_corner":"Baignoire d'angle","furn.sym_shower":"Douche","furn.sym_sink":"Lavabo","furn.sym_kitchen_sink":"Évier de cuisine","furn.sym_kitchen_sink_double":"Évier de cuisine double","furn.sym_bidet":"Bidet","furn.sym_bidet_built_in":"Bidet suspendu","furn.sym_stairs":"Escalier","furn.sym_fireplace":"Cheminée","furn.sym_plant":"Plante","furn.sym_rug":"Tapis"};const r="fd4a405e9c5a21035258c45feca26dca03d59d4cfba4280f89ff5f82675515ac";export{e as dictionary,r as fingerprint};
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="ab07da35681c15ab6136c323500b69766580ea4a788e399ea88f9e7497549172";var e={"furn.title":"Bibliothèque de mobilier","furn.symbol":"Symbole","furn.group_furniture":"Mobilier","furn.group_appliance":"Électroménager","furn.group_sanitary":"Sanitaires","furn.group_other":"Autre","furn.width":"Largeur","furn.depth":"Profondeur","furn.back_to_categories":"Toutes les catégories","furn.pick_hint":"Choisissez un symbole, puis cliquez sur le plan.","furn.place_hint":"Cliquez sur le plan — le meuble se place contre le mur le plus proche. Maj permet un placement libre.","furn.cat_air_conditioner":"Climatiseurs","furn.cat_armchair":"Fauteuils","furn.cat_bathtub":"Baignoires","furn.cat_bed":"Lits","furn.cat_bidet":"Bidets","furn.cat_boiler":"Chauffe-eau","furn.cat_chair":"Chaises","furn.cat_coffee_table":"Tables basses","furn.cat_computer":"Ordinateur","furn.cat_cooktop":"Plaques de cuisson","furn.cat_dining_table":"Tables à manger","furn.cat_dishwasher":"Lave-vaisselle","furn.cat_dryer":"Sèche-linge","furn.cat_exercise":"Équipement de sport","furn.cat_fireplace":"Cheminées","furn.cat_fridge":"Réfrigérateurs","furn.cat_hood":"Hotte","furn.cat_kitchen_cabinet":"Meubles de cuisine","furn.cat_kitchen_sink":"Éviers de cuisine","furn.cat_nightstand":"Meubles","furn.cat_oven":"Four","furn.cat_plant":"Plantes","furn.cat_rug":"Tapis","furn.cat_shelving":"Étagères","furn.cat_shower":"Douches","furn.cat_sink":"Lavabos","furn.cat_sofa":"Canapés","furn.cat_stairs":"Escaliers","furn.cat_toilet":"Toilettes","furn.cat_tv":"Téléviseurs","furn.cat_wardrobe":"Armoires","furn.cat_washer":"Lave-linge","furn.cat_work_table":"Bureaux","furn.sym_exercise":"Équipement de sport","furn.sym_computer":"Ordinateur","furn.sym_hood":"Hotte","furn.sym_oven":"Four","furn.sym_sofa":"Canapé","furn.sym_sofa_three_seat":"Canapé trois places","furn.sym_sofa_corner_right":"Canapé d'angle droit","furn.sym_armchair":"Fauteuil","furn.sym_armchair_office":"Chaise de bureau","furn.sym_coffee_table":"Table basse","furn.sym_coffee_table_round":"Table basse ronde","furn.sym_coffee_table_oval":"Table basse ovale","furn.sym_coffee_table_rounded":"Table basse arrondie","furn.sym_table_dining":"Table à manger","furn.sym_table_round":"Table ronde","furn.sym_table_dining_oval":"Table à manger ovale","furn.sym_table_dining_rounded":"Table à manger arrondie","furn.sym_chair":"Chaise","furn.sym_chair_bar":"Tabouret de bar","furn.sym_desk":"Bureau","furn.sym_desk_corner":"Bureau d'angle","furn.sym_bed_double":"Lit double","furn.sym_bed_single":"Lit simple","furn.sym_nightstand":"Table de chevet","furn.sym_cabinet_tv":"Meuble TV","furn.sym_cabinet_shoe":"Meuble à chaussures","furn.sym_cabinet_sink":"Meuble sous lavabo","furn.sym_wardrobe":"Armoire","furn.sym_bookshelf":"Bibliothèque","furn.sym_wall_unit":"Élément mural","furn.sym_kitchen_floor":"Module de cuisine bas","furn.sym_kitchen_floor_corner":"Module de cuisine bas d'angle","furn.sym_kitchen_wall":"Module de cuisine haut","furn.sym_kitchen_wall_corner":"Module de cuisine haut d'angle","furn.sym_shelf_floor":"Étagère au sol","furn.sym_shelf_wall":"Étagère murale","furn.sym_fridge":"Réfrigérateur","furn.sym_stove":"Cuisinière","furn.sym_cooktop_two":"Plaque à deux feux","furn.sym_dishwasher":"Lave-vaisselle","furn.sym_washer":"Lave-linge","furn.sym_dryer":"Sèche-linge","furn.sym_tv":"Téléviseur","furn.sym_tv_wall":"Téléviseur mural","furn.sym_ac":"Climatiseur","furn.sym_water_heater":"Chauffe-eau","furn.sym_toilet":"Toilettes","furn.sym_toilet_built_in":"Toilettes suspendues","furn.sym_bathtub":"Baignoire","furn.sym_bathtub_corner":"Baignoire d'angle","furn.sym_shower":"Douche","furn.sym_sink":"Lavabo","furn.sym_kitchen_sink":"Évier de cuisine","furn.sym_kitchen_sink_double":"Évier de cuisine double","furn.sym_bidet":"Bidet","furn.sym_bidet_built_in":"Bidet suspendu","furn.sym_stairs":"Escalier","furn.sym_fireplace":"Cheminée","furn.sym_plant":"Plante","furn.sym_rug":"Tapis"};const r="ab07da35681c15ab6136c323500b69766580ea4a788e399ea88f9e7497549172";export{e as dictionary,r as fingerprint};
@@ -1 +1 @@
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="fd4a405e9c5a21035258c45feca26dca03d59d4cfba4280f89ff5f82675515ac";var e={title:"Zigbee-Verbindungen",toggle:"Zigbee-Verbindungen beim Darüberfahren über ein Gerät anzeigen",hint:"Es werden nur beobachtete direkte Nachbarn angezeigt. Beim Darüberfahren werden keine Daten abgerufen.",help:"Zeigt, mit welchen Zigbee-Geräten jedes Gerät direkt verbunden ist. Die Linienfarbe ist die Verbindungsqualität (LQI) auf derselben Skala wie der LQI-Wert des Geräts: rot bei 40 und darunter, grün bei 180 und darüber. Eine gestrichelte Linie bedeutet, dass die Qualität nicht gemeldet wurde. Ein Pfeil zeigt auf das nächste Gerät auf dem Weg zum Koordinator: ein Pfeil führt hinaus, eingehende Pfeile sind die Geräte, die über dieses Gerät routen. Eine Linie ohne Pfeil ist ein Ersatznachbar. Das ist der Routenbaum, den House Plan bildet, nicht der Weg eines Pakets in diesem Moment: eine Beschriftung am Pfeilende bedeutet, dass das Ziel nicht auf diesem Plan liegt, und ein fehlender Pfeil, dass die Route unbekannt ist. Die Daten stammen aus dem letzten Laden und veralten; Verbindungen sind nur mit der Maus sichtbar.",help_aria:"Hilfe: Zigbee-Verbindungen",admin_only:"Topologiedaten sind nur für Home-Assistant-Administratoren verfügbar.",save_first:"Speichere diese Einstellung, bevor Topologiedaten geladen werden.",zha:"ZHA",zha_read:"ZHA-Daten lesen",zha_hint:"Liest den ZHA-Topologiecache; es wird kein Funkscan gestartet.",z2m:"Zigbee2MQTT",z2m_topics:"Basistopics (eines pro Zeile)",z2m_update:"Karte aktualisieren",z2m_warning:"Ein Netzwerkscan kann 10 Sekunden bis 2 Minuten dauern und Zigbee vorübergehend verlangsamen.",status_idle:"Daten nicht geladen",status_loading:"Wird geladen…",status_ready:"Empfangen: {time}",status_stale:"Empfangen: {time} · veraltet",status_partial:"Empfangen: {time} · einige Knoten fehlen",status_no_links:"Empfangen: {time} · keine beobachteten Verbindungen gefunden",error_permission:"Administratorrechte sind erforderlich.",error_unsupported:"Dieser Anbieter oder die Home-Assistant-API ist nicht verfügbar.",error_timeout:"Der Anbieter hat nicht rechtzeitig geantwortet.",error_invalid_topic:"Prüfe das Zigbee2MQTT-Basistopic.",error_invalid_payload:"Der Anbieter hat nicht unterstützte Topologiedaten geliefert.",error_provider:"Topologiedaten konnten nicht geladen werden.",remote_count:"+{n} in anderen Bereichen",route_device_not_on_plan:"Gerät ist nicht im Plan",route_coordinator_not_on_plan:"Koordinator ist nicht im Plan",route_other_space:"anderer Bereich"};const n="fd4a405e9c5a21035258c45feca26dca03d59d4cfba4280f89ff5f82675515ac";export{e as dictionary,n as fingerprint};
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="ab07da35681c15ab6136c323500b69766580ea4a788e399ea88f9e7497549172";var e={title:"Zigbee-Verbindungen",toggle:"Zigbee-Verbindungen beim Darüberfahren über ein Gerät anzeigen",hint:"Es werden nur beobachtete direkte Nachbarn angezeigt. Beim Darüberfahren werden keine Daten abgerufen.",help:"Zeigt, mit welchen Zigbee-Geräten jedes Gerät direkt verbunden ist. Die Linienfarbe ist die Verbindungsqualität (LQI) auf derselben Skala wie der LQI-Wert des Geräts: rot bei 40 und darunter, grün bei 180 und darüber. Eine gestrichelte Linie bedeutet, dass die Qualität nicht gemeldet wurde. Ein Pfeil zeigt auf das nächste Gerät auf dem Weg zum Koordinator: ein Pfeil führt hinaus, eingehende Pfeile sind die Geräte, die über dieses Gerät routen. Eine Linie ohne Pfeil ist ein Ersatznachbar. Das ist der Routenbaum, den House Plan bildet, nicht der Weg eines Pakets in diesem Moment: eine Beschriftung am Pfeilende bedeutet, dass das Ziel nicht auf diesem Plan liegt, und ein fehlender Pfeil, dass die Route unbekannt ist. Die Daten stammen aus dem letzten Laden und veralten; Verbindungen sind nur mit der Maus sichtbar.",help_aria:"Hilfe: Zigbee-Verbindungen",admin_only:"Topologiedaten sind nur für Home-Assistant-Administratoren verfügbar.",save_first:"Speichere diese Einstellung, bevor Topologiedaten geladen werden.",zha:"ZHA",zha_read:"ZHA-Daten lesen",zha_hint:"Liest den ZHA-Topologiecache; es wird kein Funkscan gestartet.",z2m:"Zigbee2MQTT",z2m_topics:"Basistopics (eines pro Zeile)",z2m_update:"Karte aktualisieren",z2m_warning:"Ein Netzwerkscan kann 10 Sekunden bis 2 Minuten dauern und Zigbee vorübergehend verlangsamen.",status_idle:"Daten nicht geladen",status_loading:"Wird geladen…",status_ready:"Empfangen: {time}",status_stale:"Empfangen: {time} · veraltet",status_partial:"Empfangen: {time} · einige Knoten fehlen",status_no_links:"Empfangen: {time} · keine beobachteten Verbindungen gefunden",error_permission:"Administratorrechte sind erforderlich.",error_unsupported:"Dieser Anbieter oder die Home-Assistant-API ist nicht verfügbar.",error_timeout:"Der Anbieter hat nicht rechtzeitig geantwortet.",error_invalid_topic:"Prüfe das Zigbee2MQTT-Basistopic.",error_invalid_payload:"Der Anbieter hat nicht unterstützte Topologiedaten geliefert.",error_provider:"Topologiedaten konnten nicht geladen werden.",remote_count:"+{n} in anderen Bereichen",route_device_not_on_plan:"Gerät ist nicht im Plan",route_coordinator_not_on_plan:"Koordinator ist nicht im Plan",route_other_space:"anderer Bereich"};const n="ab07da35681c15ab6136c323500b69766580ea4a788e399ea88f9e7497549172";export{e as dictionary,n as fingerprint};
@@ -1 +1 @@
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="fd4a405e9c5a21035258c45feca26dca03d59d4cfba4280f89ff5f82675515ac";var e={title:"Liens Zigbee",toggle:"Afficher les liens Zigbee au survol d’un appareil",hint:"Seuls les voisins directs observés sont affichés. Le survol ne lance aucune requête.",help:"Montre avec quels appareils Zigbee chaque appareil communique directement. La couleur de la ligne est la qualité du lien (LQI) sur la même échelle que l'indicateur LQI de l'appareil : rouge à 40 et en dessous, vert à 180 et au-dessus. Une ligne pointillée signifie que la qualité n'a pas été communiquée. Une flèche pointe vers l'appareil suivant sur le chemin du coordinateur : une flèche part, les flèches entrantes sont les appareils qui passent par celui-ci. Une ligne sans flèche est un voisin de secours. C'est l'arbre de routes que construit House Plan, pas le trajet d'un paquet à cet instant : une étiquette au bout d'une flèche signifie que sa cible n'est pas sur ce plan, et l'absence de flèche que la route est inconnue. Les données proviennent du dernier chargement et vieillissent ; les liens ne sont visibles qu'à la souris.",help_aria:"Aide : liens Zigbee",admin_only:"Les données de topologie sont réservées aux administrateurs Home Assistant.",save_first:"Enregistrez ce réglage avant de charger les données de topologie.",zha:"ZHA",zha_read:"Lire les données ZHA",zha_hint:"Lit la topologie en cache de ZHA sans lancer d’analyse radio.",z2m:"Zigbee2MQTT",z2m_topics:"Topics de base (un par ligne)",z2m_update:"Actualiser la carte",z2m_warning:"L’analyse de la carte réseau peut durer de 10 secondes à 2 minutes et réduire temporairement la réactivité de Zigbee.",status_idle:"Données non chargées",status_loading:"Chargement…",status_ready:"Reçu : {time}",status_stale:"Reçu : {time} · obsolète",status_partial:"Reçu : {time} · certains nœuds sont omis",status_no_links:"Reçu : {time} · aucun lien observé trouvé",error_permission:"Les droits administrateur sont requis.",error_unsupported:"Ce fournisseur ou l’API Home Assistant n’est pas disponible.",error_timeout:"Le fournisseur n’a pas répondu à temps.",error_invalid_topic:"Vérifiez le topic de base Zigbee2MQTT.",error_invalid_payload:"Le fournisseur a renvoyé des données de topologie non prises en charge.",error_provider:"Impossible de charger les données de topologie.",remote_count:"+{n} dans d’autres espaces",route_device_not_on_plan:"appareil absent du plan",route_coordinator_not_on_plan:"coordinateur absent du plan",route_other_space:"autre espace"};const s="fd4a405e9c5a21035258c45feca26dca03d59d4cfba4280f89ff5f82675515ac";export{e as dictionary,s as fingerprint};
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="ab07da35681c15ab6136c323500b69766580ea4a788e399ea88f9e7497549172";var e={title:"Liens Zigbee",toggle:"Afficher les liens Zigbee au survol d’un appareil",hint:"Seuls les voisins directs observés sont affichés. Le survol ne lance aucune requête.",help:"Montre avec quels appareils Zigbee chaque appareil communique directement. La couleur de la ligne est la qualité du lien (LQI) sur la même échelle que l'indicateur LQI de l'appareil : rouge à 40 et en dessous, vert à 180 et au-dessus. Une ligne pointillée signifie que la qualité n'a pas été communiquée. Une flèche pointe vers l'appareil suivant sur le chemin du coordinateur : une flèche part, les flèches entrantes sont les appareils qui passent par celui-ci. Une ligne sans flèche est un voisin de secours. C'est l'arbre de routes que construit House Plan, pas le trajet d'un paquet à cet instant : une étiquette au bout d'une flèche signifie que sa cible n'est pas sur ce plan, et l'absence de flèche que la route est inconnue. Les données proviennent du dernier chargement et vieillissent ; les liens ne sont visibles qu'à la souris.",help_aria:"Aide : liens Zigbee",admin_only:"Les données de topologie sont réservées aux administrateurs Home Assistant.",save_first:"Enregistrez ce réglage avant de charger les données de topologie.",zha:"ZHA",zha_read:"Lire les données ZHA",zha_hint:"Lit la topologie en cache de ZHA sans lancer d’analyse radio.",z2m:"Zigbee2MQTT",z2m_topics:"Topics de base (un par ligne)",z2m_update:"Actualiser la carte",z2m_warning:"L’analyse de la carte réseau peut durer de 10 secondes à 2 minutes et réduire temporairement la réactivité de Zigbee.",status_idle:"Données non chargées",status_loading:"Chargement…",status_ready:"Reçu : {time}",status_stale:"Reçu : {time} · obsolète",status_partial:"Reçu : {time} · certains nœuds sont omis",status_no_links:"Reçu : {time} · aucun lien observé trouvé",error_permission:"Les droits administrateur sont requis.",error_unsupported:"Ce fournisseur ou l’API Home Assistant n’est pas disponible.",error_timeout:"Le fournisseur n’a pas répondu à temps.",error_invalid_topic:"Vérifiez le topic de base Zigbee2MQTT.",error_invalid_payload:"Le fournisseur a renvoyé des données de topologie non prises en charge.",error_provider:"Impossible de charger les données de topologie.",remote_count:"+{n} dans d’autres espaces",route_device_not_on_plan:"appareil absent du plan",route_coordinator_not_on_plan:"coordinateur absent du plan",route_other_space:"autre espace"};const s="ab07da35681c15ab6136c323500b69766580ea4a788e399ea88f9e7497549172";export{e as dictionary,s as fingerprint};
@@ -1 +1 @@
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="fd4a405e9c5a21035258c45feca26dca03d59d4cfba4280f89ff5f82675515ac";var e={title:"Связи Zigbee",toggle:"Показывать связи Zigbee при наведении на устройство",hint:"Показываются только наблюдаемые прямые соседи. Наведение ничего не запрашивает.",help:"Показывает, с какими устройствами Zigbee каждое связано напрямую. Цвет линии — качество связи (LQI) по той же шкале, что у показателя LQI устройства: красный при 40 и ниже, зелёный при 180 и выше. Пунктир — качество не сообщено. Стрелка ведёт к следующему устройству по пути к координатору: исходящая одна, входящие — те, кто ходит через это устройство. Линия без стрелки — запасной сосед. Это дерево маршрутов, которое строит House Plan, а не путь пакета в эту секунду: подпись на конце стрелки значит, что цель не на этом плане, а отсутствие стрелки — что путь неизвестен. Данные из последней загрузки и устаревают, связи видны только при работе мышью.",help_aria:"Справка: связи Zigbee",admin_only:"Данные топологии доступны только администраторам Home Assistant.",save_first:"Сохраните настройку перед загрузкой данных топологии.",zha:"ZHA",zha_read:"Прочитать данные ZHA",zha_hint:"Читает сохранённую топологию ZHA и не запускает радио-сканирование.",z2m:"Zigbee2MQTT",z2m_topics:"Базовые топики (по одному в строке)",z2m_update:"Обновить карту",z2m_warning:"Сканирование карты сети занимает от 10 секунд до 2 минут и временно может снизить отзывчивость Zigbee.",status_idle:"Данные не загружены",status_loading:"Загрузка…",status_ready:"Получено: {time}",status_stale:"Получено: {time} · данные устарели",status_partial:"Получено: {time} · часть узлов не показана",status_no_links:"Получено: {time} · наблюдаемые связи не найдены",error_permission:"Нужны права администратора.",error_unsupported:"Провайдер или API Home Assistant недоступен.",error_timeout:"Провайдер не ответил вовремя.",error_invalid_topic:"Проверьте базовый топик Zigbee2MQTT.",error_invalid_payload:"Провайдер вернул неподдерживаемые данные топологии.",error_provider:"Не удалось загрузить данные топологии.",remote_count:"+{n} в других пространствах",route_device_not_on_plan:"устройства нет на плане",route_coordinator_not_on_plan:"координатора нет на плане",route_other_space:"другое пространство"};const a="fd4a405e9c5a21035258c45feca26dca03d59d4cfba4280f89ff5f82675515ac";export{e as dictionary,a as fingerprint};
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="ab07da35681c15ab6136c323500b69766580ea4a788e399ea88f9e7497549172";var e={title:"Связи Zigbee",toggle:"Показывать связи Zigbee при наведении на устройство",hint:"Показываются только наблюдаемые прямые соседи. Наведение ничего не запрашивает.",help:"Показывает, с какими устройствами Zigbee каждое связано напрямую. Цвет линии — качество связи (LQI) по той же шкале, что у показателя LQI устройства: красный при 40 и ниже, зелёный при 180 и выше. Пунктир — качество не сообщено. Стрелка ведёт к следующему устройству по пути к координатору: исходящая одна, входящие — те, кто ходит через это устройство. Линия без стрелки — запасной сосед. Это дерево маршрутов, которое строит House Plan, а не путь пакета в эту секунду: подпись на конце стрелки значит, что цель не на этом плане, а отсутствие стрелки — что путь неизвестен. Данные из последней загрузки и устаревают, связи видны только при работе мышью.",help_aria:"Справка: связи Zigbee",admin_only:"Данные топологии доступны только администраторам Home Assistant.",save_first:"Сохраните настройку перед загрузкой данных топологии.",zha:"ZHA",zha_read:"Прочитать данные ZHA",zha_hint:"Читает сохранённую топологию ZHA и не запускает радио-сканирование.",z2m:"Zigbee2MQTT",z2m_topics:"Базовые топики (по одному в строке)",z2m_update:"Обновить карту",z2m_warning:"Сканирование карты сети занимает от 10 секунд до 2 минут и временно может снизить отзывчивость Zigbee.",status_idle:"Данные не загружены",status_loading:"Загрузка…",status_ready:"Получено: {time}",status_stale:"Получено: {time} · данные устарели",status_partial:"Получено: {time} · часть узлов не показана",status_no_links:"Получено: {time} · наблюдаемые связи не найдены",error_permission:"Нужны права администратора.",error_unsupported:"Провайдер или API Home Assistant недоступен.",error_timeout:"Провайдер не ответил вовремя.",error_invalid_topic:"Проверьте базовый топик Zigbee2MQTT.",error_invalid_payload:"Провайдер вернул неподдерживаемые данные топологии.",error_provider:"Не удалось загрузить данные топологии.",remote_count:"+{n} в других пространствах",route_device_not_on_plan:"устройства нет на плане",route_coordinator_not_on_plan:"координатора нет на плане",route_other_space:"другое пространство"};const a="ab07da35681c15ab6136c323500b69766580ea4a788e399ea88f9e7497549172";export{e as dictionary,a as fingerprint};
@@ -1 +1 @@
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="fd4a405e9c5a21035258c45feca26dca03d59d4cfba4280f89ff5f82675515ac";import{n as t,c as n}from"./zigbee-topology-Co7YPeRf.js";import{aP as e}from"./houseplan-card-CDzf9V5z.js";import"./namespace-language-BPjMJUHI.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 m(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 g(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 h(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,h=null;const y=new Promise(t=>{u=t}),w=new Promise((t,n)=>{p=t,h=n}),b=[];try{const r=await o.call(e,t=>{!0===d(t)?.retain&&m(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=m(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&&h?.(a("invalid_payload"))},{type:"mqtt/subscribe",topic:`${l}/bridge/response/networkmap`});"function"==typeof f&&b.push(f),await g(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 g(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,h as refreshZ2mTopology,u as subscribeZigbeeTopology,l as zigbeeTopologyRuntimeSnapshot};
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="ab07da35681c15ab6136c323500b69766580ea4a788e399ea88f9e7497549172";import{n as t,c as n}from"./zigbee-topology-BG_a6cIb.js";import{aP as e}from"./houseplan-card-BOdiRDFR.js";import"./namespace-language-D86tJUeD.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 m(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 g(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 h(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,h=null;const y=new Promise(t=>{u=t}),w=new Promise((t,n)=>{f=t,h=n}),b=[];try{const r=await o.call(e,t=>{!0===d(t)?.retain&&m(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=m(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&&h?.(a("invalid_payload"))},{type:"mqtt/subscribe",topic:`${l}/bridge/response/networkmap`});"function"==typeof p&&b.push(p),await g(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 g(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,h as refreshZ2mTopology,u as subscribeZigbeeTopology,l as zigbeeTopologyRuntimeSnapshot};
@@ -1 +1 @@
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="fd4a405e9c5a21035258c45feca26dca03d59d4cfba4280f89ff5f82675515ac";try{await import("./houseplan-assets/houseplan-card-CDzf9V5z.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__="ab07da35681c15ab6136c323500b69766580ea4a788e399ea88f9e7497549172";try{await import("./houseplan-assets/houseplan-card-BOdiRDFR.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
+1 -1
View File
@@ -20,5 +20,5 @@
"issue_tracker": "https://github.com/Matysh/houseplan-card/issues",
"requirements": [],
"single_config_entry": true,
"version": "1.79.0-beta.4"
"version": "1.79.0"
}
+20 -12
View File
@@ -25,7 +25,9 @@
* Counters (exact, every sample): geometry/visibility recomputes over 100
* unrelated HA ticks, 100 pan/zoom steps and a colour-only change (0); the
* three LED caches of the shown space — shapes ≤ 50, visibility ≤ 50,
* retained per-emitter fans ≤ 2500 — identical after every cycle (growth 0);
* compact visibility paths ≤ 2500 and retained path text ≤ 4 Mi characters
* (≤ 8 MiB UTF-16) — identical after every cycle (growth 0). The true fan
* count remains diagnostic: #788 removed lossy endpoint/vertex thinning;
* after disconnect 0 retained entries and 0 live LED timers/observers; a
* late import after disconnect restores nothing (one extra cold run with the
* runtime response delayed); LED chunk requests (none without strips, never
@@ -41,6 +43,7 @@ import { mkdirSync, readFileSync, writeFileSync } from 'node:fs';
import { dirname, resolve } from 'node:path';
import { launch } from './serve.mjs';
import { makeLedStripsFixture } from './performance/led-strips-fixture.mjs';
import { ledChunkRequestName } from './performance/led-chunk-request.mjs';
const valueArg = (name) => process.argv.find((arg) => arg.startsWith(`--${name}=`))?.slice(name.length + 3);
const warmupOnly = process.argv.includes('--warmup-only');
@@ -145,7 +148,7 @@ function pageHost() {
window.__ledStats = async (card) => {
const url = performance.getEntriesByType('resource').map((entry) => entry.name)
.find((name) => /led-strip-runtime-[^/]+\\.js/.test(name));
if (!url) return { shapes: 0, visibility: 0, sources: 0, recomputes: 0, loaded: false };
if (!url) return { shapes: 0, visibility: 0, sources: 0, visibilityPaths: 0, pathChars: 0, recomputes: 0, loaded: false };
const runtime = await import(url);
return { ...runtime.ledStats(card), loaded: true };
};
@@ -163,8 +166,8 @@ async function sample() {
await page.emulateMedia({ reducedMotion: 'reduce' });
const requests = [];
page.on('request', (request) => {
const name = request.url().replace(/.*\//, '').replace(/\?.*$/, '');
if (/^led-strip-(runtime|field|editor)-/.test(name)) requests.push(name.replace(/-[^-]+\.js$/, ''));
const name = ledChunkRequestName(request.url());
if (name) requests.push(name);
});
try {
await page.evaluate(installLedLifecycleTracker);
@@ -279,8 +282,8 @@ async function sample() {
if (strips) await until(() => ledStable());
}
await frame();
const { shapes, visibility, sources } = await stats();
return { shapes, visibility, sources };
const { shapes, visibility, sources, visibilityPaths, pathChars } = await stats();
return { shapes, visibility, sources, visibilityPaths, pathChars };
};
await cycle();
await gc();
@@ -295,7 +298,7 @@ async function sample() {
await sleep(600);
const afterDisconnect = await stats();
const liveAfterDisconnect = window.__ledLiveCounts();
const key = (entry) => `${entry.shapes}/${entry.visibility}/${entry.sources}`;
const key = (entry) => `${entry.shapes}/${entry.visibility}/${entry.sources}/${entry.visibilityPaths}/${entry.pathChars}`;
return {
firstStableRenderMs, warmSpaceReadyMs, stateUpdateMs, panZoomMs, panZoomLongTaskMaxMs, cameraSeriesLongTaskMaxMs,
retainedHeapBytes: heapBefore == null || heapAfter == null ? null : Math.max(0, heapAfter - heapBefore),
@@ -306,10 +309,13 @@ async function sample() {
shapes: Math.max(...cycleStats.map((entry) => entry.shapes)),
visibility: Math.max(...cycleStats.map((entry) => entry.visibility)),
sources: Math.max(...cycleStats.map((entry) => entry.sources)),
visibilityPaths: Math.max(...cycleStats.map((entry) => entry.visibilityPaths)),
pathChars: Math.max(...cycleStats.map((entry) => entry.pathChars)),
cacheGrowthOverCycles: new Set(cycleStats.map(key)).size - 1,
} : null,
disconnect: {
retained: afterDisconnect.shapes + afterDisconnect.visibility + afterDisconnect.sources,
retained: afterDisconnect.shapes + afterDisconnect.visibility + afterDisconnect.sources
+ afterDisconnect.visibilityPaths + afterDisconnect.pathChars,
liveBefore: liveBeforeDisconnect,
live: liveAfterDisconnect.timers + liveAfterDisconnect.frames + liveAfterDisconnect.observers,
},
@@ -359,7 +365,7 @@ async function lateImport() {
// The chunk the card asked for, by its URL: the same module instance.
const late = await page.evaluate(async (url) => {
const runtime = url ? await import(url) : null;
return { stats: runtime ? { ...runtime.ledStats(window.__lateCard), loaded: true } : { shapes: 0, visibility: 0, sources: 0, loaded: false },
return { stats: runtime ? { ...runtime.ledStats(window.__lateCard), loaded: true } : { shapes: 0, visibility: 0, sources: 0, visibilityPaths: 0, pathChars: 0, loaded: false },
live: window.__ledLiveCounts() };
}, runtimeUrl);
return { ...result, ...late, held };
@@ -440,14 +446,16 @@ if (STRIPS) {
for (const key of ['recomputesOnHaTicks', 'recomputesOnCamera', 'recomputesOnColour', 'cacheGrowthOverCycles']) {
if (counters[key] !== 0) failures.push(`${key} = ${counters[key]}, expected 0`);
}
for (const key of ['shapes', 'visibility', 'sources']) {
if (counters[key] > caches[key]) failures.push(`${key} cache ${counters[key]} > ${caches[key]}`);
for (const key of ['shapes', 'visibility', 'visibilityPaths', 'pathChars']) {
if (!Number.isFinite(counters[key])) failures.push(`${key} cache metric missing`);
else if (counters[key] > caches[key]) failures.push(`${key} cache ${counters[key]} > ${caches[key]}`);
}
}
if (late) {
if (!late.held || !late.stats.loaded) failures.push('late import: the runtime response was never held or never landed');
if (late.stripesAfterLoad !== late.stripesBeforeLoad) failures.push('late import rendered the gone card');
const retained = late.stats.shapes + late.stats.visibility + late.stats.sources;
const retained = late.stats.shapes + late.stats.visibility + late.stats.sources
+ late.stats.visibilityPaths + late.stats.pathChars;
if (retained) failures.push(`late import restored ${retained} cache entries`);
if (late.live.timers + late.live.frames + late.live.observers) failures.push('late import left LED timers/observers');
} else if (!skipLateImport) failures.push('late import not measured');
+17 -35
View File
@@ -1,48 +1,27 @@
{
"schema": 3,
"matrixVersion": 71,
"acceptedAt": "2026-10-03T07:54:16.450Z",
"sourceFingerprint": "cd698d703d8d3b58af43c32e9d23153a4532650909eadfd43b25ed1969ec4f4a",
"acceptedAt": "2026-10-03T15:57:17.589Z",
"sourceFingerprint": "6cd33bbad3c9a6a101afc1d501a8959df6ad58b693802489873660c043677fa7",
"chromium": "151.0.7922.34",
"capturedOn": "linux",
"acceptedOn": "linux",
"acceptedOn": "win32",
"capture": {
"platform": "linux",
"arch": "x64",
"chromium": "151.0.7922.34",
"buildFingerprint": "cd698d703d8d3b58af43c32e9d23153a4532650909eadfd43b25ed1969ec4f4a",
"ci": null
},
"localAttestation": {
"schema": "houseplan-golden-wsl/v1",
"sha256": "cf474aa1ff676d2262f1c9e442114e7df0e91867c69c78bdc82c923a48355650",
"artifactSha256": "7a410b63ae24027ebe7c77d3e5fe63b2e36cad6d83543bf478c8af183784e2dc",
"createdAt": "2026-10-03T07:53:46.175Z",
"source": {
"buildFingerprint": "6cd33bbad3c9a6a101afc1d501a8959df6ad58b693802489873660c043677fa7",
"ci": {
"repository": "Matysh/houseplan-card",
"branch": "issue/784-led-strip-polish",
"commit": "706eb02d70b6fecaafda0da67e4564e8909606ff",
"tree": "f9331d65ecb02f922720f95f9a6feb6781420f29",
"remoteSha": "706eb02d70b6fecaafda0da67e4564e8909606ff",
"clean": true,
"status": ""
},
"environment": {
"platform": "linux",
"arch": "x64",
"kernel": "6.18.33.2-microsoft-standard-WSL2",
"wsl": true,
"distro": "Ubuntu",
"filesystem": "ext2/ext3"
},
"toolchain": {
"node": "22.23.2",
"npm": "10.9.8",
"playwright": "1.62.0",
"chromiumExecutableSha256": "0b20b130e7edd9dd51873be867761295fe0cfad490c2b9a64f95bd3cfc08fa71"
"run": 37134548622,
"attempt": 1,
"sha": "c142e4f7b5b3ffb46d3a2b88222a9d697e8144b1"
}
},
"foreignCapture": null,
"localAttestation": null,
"foreignCapture": {
"reason": "Owner-authorized #788 acceptance on Windows of Linux CI artifact Validate 37134548622; capture is not Windows (#455)"
},
"witnesses": {
"count": 101,
"floor": 10
@@ -240,10 +219,13 @@
"optimize-orphan-references-light-ru": "332e56edb151a5a820fc307d69ffd4060348978572e48704b0a2c14ba9802720",
"card-editor-invalid-default-floor-light-en": "dbf251ece014cfee252e0dcb2d7c00eda66aa4b5bd125e4c83e248d4319d24b3",
"card-editor-invalid-default-floor-dark-ru": "422b74bb391b87e383350247ef1bc1f10ca48c8f6fe418f75bde94e62e3b8bc0",
"led-strip-design-reference-off-light": "907098bee00d95fdc4b2e93d8fb552ceda8ca34f904dccd66f7cbaecd36fd98a",
"led-strip-design-reference-off-light": "1a558111dbeb1962b10f47baad20b4689248a347510261152f0d6196906044fd",
"led-strip-design-reference-on-light": "16bfb46f2a90c57e95f1307e375e04e5809d41ae677e3b1e1eb56d7e0bc1d8ec",
"lighting-led-strip-glow-dark": "254fe1e39c5bb7bbb7e67527f69c767c8bdb6ed959986a8085b18adb152001d6",
"led-strip-off-light": "588294347c22eecbb9274f97bebdc4826ae97b237f64f291877165b9cbfd464a",
"led-strip-long-zigzag-glow-light": "cd0847c03b6b397c93fa923dcd06b30d7d4a8f6c6db2f006b9f3e20de0e66e91",
"led-strip-endcaps-zoom-light": "57703b53bd9d2eaae1b3142903a8b574e5d12b761b9b7240543ee2463c44c74d",
"led-strip-rectangle-door-zoom-light": "549e9e9110cc3b01537d07bcf6ab89896069a49183a27c22904b89c99e35347c",
"led-strip-off-light": "cbb4f4794c871d592917653e8b5713d87a6be6dfe470b2161da760c2bb3cebdc",
"iso-led-strip-dark": "572728e34f77f911f0ece247c5b7de6653e9c0dfafe04a0ab198b88644081a58"
}
}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 96 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 260 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 185 KiB

+11
View File
@@ -628,6 +628,17 @@ export function prepareGoldenFixture(scenario) {
if (!space) throw new Error(`golden override references missing space: ${scenario.space}`);
return space;
};
if (scenario.ledStripOverride) {
const space = requireSpace();
if (space.id !== 'golden-led' || !Array.isArray(scenario.ledStripOverride.points)
|| scenario.ledStripOverride.points.length < 2) {
throw new Error(`invalid golden ledStripOverride: ${scenario.id}`);
}
space.led_strips = [{
id: 'led-owner-repro', marker: 'demo-led-strip-loop',
points: structuredClone(scenario.ledStripOverride.points),
}];
}
if (scenario.stage3Fixture) {
const contract = scenario.stage3Fixture;
const space = requireSpace();
+20
View File
@@ -1327,6 +1327,26 @@ export const GOLDEN_SCENARIOS = Object.freeze([
mode: 'view', language: 'en', theme: 'light', viewport: { width: 1000, height: 760 }, ...stage },
{ id: 'lighting-led-strip-glow-dark', fixture: 'visual', ledStrips: true, space: 'golden-led',
mode: 'view', fillMode: 'none', language: 'en', theme: 'dark', viewport: { width: 1000, height: 760 }, ...stage },
{ id: 'led-strip-long-zigzag-glow-light', fixture: 'visual', ledStrips: true, space: 'golden-led',
mode: 'view', fillMode: 'none', language: 'en', theme: 'light', viewport: { width: 1000, height: 760 },
// A free diagonal joins a wall-face run and returns to free floor. Before
// #785 the active visibility clip kept only the wall fans and dropped both
// free diagonals because SVG clip paths ignore open-path strokes.
ledStripOverride: { points: [[0.12, 0.15], [0.551667, 0.35], [0.551667, 0.55], [0.16, 0.45]] }, ...stage },
{ id: 'led-strip-endcaps-zoom-light', fixture: 'visual', ledStrips: true, space: 'golden-led',
mode: 'view', fillMode: 'none', language: 'en', theme: 'light', viewport: { width: 1000, height: 760 },
// #786: at 4× the free end and the end inside one Glow radius of masonry
// must keep the same smooth circular rim; the wall still clips its side.
zoom: 4, zoomCenter: [500, 380],
ledStripOverride: { points: [[0.43, 0.35], [0.535, 0.35]] }, ...stage },
{ id: 'led-strip-rectangle-door-zoom-light', fixture: 'visual', ledStrips: true, space: 'golden-led',
mode: 'view', fillMode: 'none', language: 'en', theme: 'light', viewport: { width: 1000, height: 760 },
// #787: four stored corners must remain four straight visible sides. The
// right side crosses led-door: the opening is optically open, but neither
// the stripe nor its emitter line may step back to the wall axis there.
zoom: 1.15, zoomCenter: [310, 350],
ledStripOverride: { points: [[0.068333, 0.088333], [0.551667, 0.088333],
[0.551667, 0.611667], [0.068333, 0.611667], [0.068333, 0.088333]] }, ...stage },
{ id: 'led-strip-off-light', fixture: 'visual', ledStrips: true, space: 'golden-led',
mode: 'view', fillMode: 'none', stateOverrides: LED_STRIPS_OFF, language: 'en', theme: 'light',
viewport: { width: 1000, height: 760 }, ...stage },
+10 -2
View File
@@ -442,7 +442,8 @@ scenario and of a 100-step series, one wheel step per frame — retained heap
after 20 A→B→C→A cycles 64 MiB — and on exact counters: zero field geometry
recomputes over 100 unrelated HA ticks, 100 camera steps and a colour-only
change; the three caches of the shown space (`ledStats` of the runtime chunk)
— shapes ≤ 50, visibility ≤ 50, retained per-emitter fans ≤ 2500 — identical
— shapes ≤ 50, visibility ≤ 50, compact visibility batches ≤ 2500 and
retained SVG path text ≤ 4 Mi characters — identical
after every cycle; after disconnect 0 retained entries and 0 live LED
timers/frames/observers (tracked by creation stack in the page); one extra
cold run holds the runtime response, removes the card meanwhile and requires
@@ -455,4 +456,11 @@ samples after one warm-up enforced on the merged set. Base predates the
strips, so there is no relative comparison; the zero-LED View remains judged
by the relative `large-house-interaction-v1` profile. Exact-SHA Linux output
of the full performance workflow (`led-strips` matrix entry) is the gate
evidence; a local report is diagnostic.
evidence; a local report is diagnostic. Since #788 the actual emitter-fan
count remains reported but is not capped by dropping required endpoints or
corners: that old limit hid visible holes. Five fans are retained per compact
batch; all batches render as one positive-winding clip path per strip. The
4 Mi-character bound (at most 8 MiB UTF-16 text) explicitly measures cached
paths, excluding the joined Lit/DOM clip string. Timing and the 64 MiB
warm-cycle heap-growth limit are unchanged; that is not an absolute browser
or GPU memory bound.
+3 -2
View File
@@ -1,11 +1,12 @@
{
"profile": "led-strips-v1",
"issue": 780,
"note": "ТЗ #780 §13.2: absolute limits applied to median and p95; 10x5 rests on the interaction profile's absolute ceilings, 50x50 are the acceptance bounds set in the ТЗ. The no-strip control is judged by the existing interaction profile against base. Caches of the shown space (ТЗ §13.2): 50 shapes, 50 visibility entries, 2500 retained per-emitter fans; 0 after disconnect.",
"note": "#780 timing/heap limits unchanged. #788: preserve every end/vertex; compact positive-winding fans into paths without discarding geometry. Bound actual retained representation: 50 shapes/entries, 2500 compact clip paths, 4 Mi SVG characters (at most 8 MiB UTF-16, one eighth of the unchanged 64 MiB heap budget). Actual fan count is still reported, never relabelled as path count. No growth/recomputes, zero after disconnect.",
"caches": {
"shapes": 50,
"visibility": 50,
"sources": 2500
"visibilityPaths": 2500,
"pathChars": 4194304
},
"sizes": {
"10x5": {
+7
View File
@@ -0,0 +1,7 @@
/** Stable LED chunk identity for request accounting, independent of its hash. */
export function ledChunkRequestName(url) {
const name = url.replace(/[?#].*$/, '').replace(/.*\//, '');
// Rollup's base64url hashes may themselves contain '-' (even first).
// Capture the known prefix instead of removing a last-hyphen suffix.
return /^(led-strip-(?:runtime|field|editor))-[\w-]+\.js$/.exec(name)?.[1] ?? null;
}
+104
View File
@@ -0,0 +1,104 @@
/** #788: test the painted light, not SVG node counts. The card renders each
* synthetic strip through the ordinary config event. Rasterise its actual
* field DOM at several pixel densities and compare unobstructed floor pixels
* with the independently calculated distance to the stored polyline. This
* catches missing end/vertex emitters, winding cancellation and hard rims.
* Household exports are deliberately NOT fixtures in this public test.
*/
import { launch, check, finish } from './serve.mjs';
const { page, browser } = await launch({ width: 1000, height: 820 }, 1);
const cases = [
{ name: 'short residual end', points: [[0.25, 0.35], [0.36225, 0.35]] },
{ name: 'diagonal residual end', points: [[0.25, 0.3], [0.341, 0.365625]] },
{ name: 'acute outer turn', points: [[0.3, 0.25], [0.32, 0.38], [0.35, 0.25]] },
{ name: 'reflected acute turn', points: [[0.3, 0.48], [0.32, 0.35], [0.35, 0.48]] },
{ name: 'decimal closed loop', points: [[0.2301, 0.2202], [0.3803, 0.2202], [0.3803, 0.4204], [0.2301, 0.4204], [0.2301, 0.2202]] },
{ name: 'intersecting path', points: [[0.3, 0.25], [0.4, 0.45], [0.3, 0.45], [0.4, 0.25]] },
{ name: 'mixed free and blocked fans', points: [[0.35, 0.35], [0.585, 0.45]], wall: true },
];
const results = [];
for (const scenario of cases) {
for (const radiusCm of [30, 60, 120]) {
for (const reversed of [false, true]) {
const points = reversed ? [...scenario.points].reverse() : scenario.points;
await page.evaluate(async ({ points, wall, radiusCm }) => {
await window.__hpTest.setServerConfig(cfg => ({ ...cfg,
spaces: [{ id: 'led-oracle', title: 'LED field oracle', cell_cm: 5,
rooms: [{ id: 'room', name: 'Room', poly: [[0.08, 0.08], [0.92, 0.08], [0.92, 0.72], [0.08, 0.72]] }],
partitions: wall ? [{ id: 'barrier', a: [0.6, 0.1], b: [0.6, 0.7], cm: 12 }] : [],
wall_segments: [], openings: [], decor: [], wall_columns: [],
settings: { glow_enabled: true, fill_mode: 'none' },
led_strips: [{ id: 'oracle', marker: 'oracle-light', points }] }],
markers: [{ id: 'oracle-light', binding: 'virtual', is_light: true,
space: 'led-oracle', room_id: 'room', glow_radius_cm: radiusCm,
glow_color: { c: '#ffffff', bri: 1 } }],
}));
}, { points, wall: scenario.wall, radiusCm });
await page.waitForFunction(() => window.__card.shadowRoot.querySelector('[data-led-field="oracle"]'));
await page.waitForTimeout(550);
const raster = await page.evaluate(async ({ points, wall, radiusCm }) => {
const source = window.__card.shadowRoot.querySelector('.led-fields').cloneNode(true);
// Isolate geometry/falloff from colour/brightness/animation, whose
// user-facing lifecycle is independently covered by smoke_led_strip_glow.
source.querySelectorAll('.led-pool').forEach(el => {
el.setAttribute('fill', '#ffffff'); el.setAttribute('fill-opacity', '1');
});
const path = points.map(p => p.map(v => v * 1000));
const r = radiusCm / 5 * (1000 / 240); // documented physical scale, not read from implementation.
const minX = Math.floor(Math.min(...path.map(p => p[0])) - r - 2);
const minY = Math.floor(Math.min(...path.map(p => p[1])) - r - 2);
const w = Math.ceil(Math.max(...path.map(p => p[0])) + r + 2 - minX);
const h = Math.ceil(Math.max(...path.map(p => p[1])) + r + 2 - minY);
const distance = (x, y) => Math.min(...path.slice(1).map((b, i) => {
const a = path[i], dx = b[0] - a[0], dy = b[1] - a[1];
const t = Math.max(0, Math.min(1, ((x - a[0]) * dx + (y - a[1]) * dy) / (dx * dx + dy * dy)));
return Math.hypot(x - a[0] - t * dx, y - a[1] - t * dy);
}));
// The documented shared five-stop brightness contract, not a source import.
const stops = [[0, 1], [0.45, 0.88], [0.70, 0.62], [0.86, 0.32], [1, 0]];
const expectedAt = d => {
const f = d / r;
if (f >= 1) return 0;
for (let i = 1; i < stops.length; i++) {
if (f <= stops[i][0]) {
const [x0, y0] = stops[i - 1], [x1, y1] = stops[i];
return y0 + (y1 - y0) * (f - x0) / (x1 - x0);
}
}
return 0;
};
const output = [];
for (const scale of [1, 2, 4]) {
const xml = `<svg xmlns="http://www.w3.org/2000/svg" width="${w * scale}" height="${h * scale}" viewBox="${minX} ${minY} ${w} ${h}"><rect x="${minX}" y="${minY}" width="${w}" height="${h}" fill="black"/>${new XMLSerializer().serializeToString(source)}</svg>`;
const image = new Image();
image.src = `data:image/svg+xml;charset=utf-8,${encodeURIComponent(xml)}`;
await image.decode();
const canvas = document.createElement('canvas'); canvas.width = w * scale; canvas.height = h * scale;
const ctx = canvas.getContext('2d'); ctx.drawImage(image, 0, 0);
const data = ctx.getImageData(0, 0, canvas.width, canvas.height).data;
let worst = 0, bad = 0, checked = 0, witness = null;
for (let py = 2; py < canvas.height - 2; py += 3) {
for (let px = 2; px < canvas.width - 2; px += 3) {
const x = minX + (px + 0.5) / scale, y = minY + (py + 0.5) / scale;
// Left of the long opaque wall every source has clear sight. On
// the far side every source is occluded (no wall ends in this ROI).
if (wall && Math.abs(x - 595) < 2) continue;
const expected = wall && x > 595 ? 0 : expectedAt(distance(x, y));
const actual = data[(py * canvas.width + px) * 4] / 255;
const error = Math.abs(expected - actual);
checked++;
if (error > worst) { worst = error; witness = [x, y, expected, actual]; }
if (error > 0.06) bad++;
}
}
output.push({ scale, checked, bad, worst, witness });
}
return output;
}, { points, wall: scenario.wall, radiusCm });
for (const row of raster) check(`${scenario.name}, radius=${radiusCm}cm, reverse=${reversed}, raster=${row.scale}: smooth field and opaque wall`, row.bad, 0);
results.push({ name: scenario.name, radiusCm, reversed, raster });
}
}
}
await finish(browser, results);
+12 -5
View File
@@ -43,7 +43,9 @@ const setState = (entity, state, attributes = {}) => evaluate(async ([entity, st
const stripe = (marker) => evaluate((marker) => {
const g = window.__card.shadowRoot.querySelector(`[data-led-strip][data-marker="${marker}"]`);
return g ? { state: g.dataset.state, core: g.querySelector('.led-core')?.getAttribute('stroke'),
dash: g.querySelector('.led-core')?.getAttribute('stroke-dasharray') || null } : null;
dash: g.querySelector('.led-core')?.getAttribute('stroke-dasharray') || null,
outlineWidth: Number(g.querySelector('.led-outline')?.getAttribute('stroke-width')),
coreWidth: Number(g.querySelector('.led-core')?.getAttribute('stroke-width')) } : null;
}, marker);
const field = () => evaluate(() => window.__card.shadowRoot.querySelectorAll('[data-led-field]').length);
@@ -80,8 +82,9 @@ check('unbound strip is absent from the View', await evaluate(() => window.__car
check('no round pool at the anchor: the strip is the source', await evaluate(() =>
!window.__card.shadowRoot.querySelector('[data-glow-source="light.ceiling"]')));
check('no auto-slot reserved for the strip’s marker', await evaluate(() => !('d_light1' in (window.__card._defPos || {}))));
check('on with Glow: white core and a field', JSON.stringify([await stripe('d_light1'), await field() > 0]),
JSON.stringify([{ state: 'on', core: '#FFFFFF', dash: null }, true]));
const onStripe = await stripe('d_light1');
check('on with Glow: white core and a field', JSON.stringify([onStripe?.state, onStripe?.core, onStripe?.dash, await field() > 0]),
JSON.stringify(['on', '#FFFFFF', null, true]));
// r1 M1 (ТЗ §5): the strip keeps the device's value badge, passive, at the
// half-length anchor — the icon core, pulse and slot stay suppressed.
@@ -141,8 +144,12 @@ check('a pointer click leaves no selection outline', await evaluate(() => {
}), true);
await page.waitForTimeout(600);
void hit;
check('off: no field, white core', JSON.stringify([await stripe('d_light1'), await field()]),
JSON.stringify([{ state: 'off', core: '#FFFFFF', dash: null }, 0]));
const offStripe = await stripe('d_light1');
check('off: no field, white core', JSON.stringify([offStripe?.state, offStripe?.core, offStripe?.dash, await field()]),
JSON.stringify(['off', '#FFFFFF', null, 0]));
check('#785: switching does not change the physical stripe thickness',
JSON.stringify([offStripe?.outlineWidth, offStripe?.coreWidth]),
JSON.stringify([onStripe?.outlineWidth, onStripe?.coreWidth]));
// A pan along the stripe calls nothing; the next clean click works at once.
const along = (k) => evaluate((k) => {
const el = window.__card.shadowRoot.querySelector('.led-hit');
+156
View File
@@ -0,0 +1,156 @@
/** #788: browser witness for the visible tube, independent of the Glow field.
* Synthetic room-wall fixtures enter through the config-event facade. Expected
* corners come from an analytic inset/line equation below, not LED geometry.
* Both real SVG lengths and raster pixels protect against extra miter hooks,
* backtracking at short subdivisions and a notch through the open doorway.
*/
import { launch, check, finish } from './serve.mjs';
import { fixtureWallKey } from './fixtures/wall-key.mjs';
const { page, browser } = await launch({ width: 1000, height: 820 }, 1);
// All coordinates here are render units. A 12 cm wall at 5 cm/grid cell has
// total thickness 10 units (1000/240 units/cell), hence a 5-unit inner inset.
// This plan is smaller than the documented 1000-unit icon reference floor:
// D=2.5%*1000=25, outline=.12D=3, centreline offset=1.5, core=1.5.
const left = 200.1, top = 180.2, right = 500.3, bottom = 480.4;
const offset = 1.5, outlineWidth = 3, coreWidth = 1.5;
const scenarios = [
{ name: 'decimal rectangle and door', angle: 0, tilt: 0, intermediate: false },
{ name: 'sloped side and short saved subdivision', angle: 0, tilt: 0.545461, intermediate: true },
{ name: 'rotated decimal rectangle and door', angle: 0.137, tilt: 0, intermediate: false },
];
const results = [];
await page.evaluate(async () => {
const card = window.__card;
card.setConfig({ ...card._config, icon_size: 2.5, language: 'en' });
await window.__hpTest.setMode('view');
});
for (const scenario of scenarios) {
const cos = Math.cos(scenario.angle), sin = Math.sin(scenario.angle);
const rotate = ([x, y]) => [400 + (x - 400) * cos - (y - 330) * sin,
330 + (x - 400) * sin + (y - 330) * cos];
const normalise = (point) => rotate(point).map(value => value / 1000);
const rooms = [
{ id: 'tube-room', name: 'Tube room', poly: [[left - 5, top - 5], [right + 5, top - 5],
[right + 5, bottom + 5], [left - 5, bottom + 5]].map(normalise) },
{ id: 'receiving-room', name: 'Receiving room', poly: [[right + 5, top - 5], [755.5, top - 5],
[755.5, bottom + 5], [right + 5, bottom + 5]].map(normalise) },
];
const walls = [];
for (const room of rooms) room.poly.forEach((a, i) => {
const b = room.poly[(i + 1) % room.poly.length], key = fixtureWallKey(a, b);
if (!walls.some(wall => wall.key === key)) walls.push({ key, a, b, cm: 12 });
});
// The doorway begins just .1 unit from the inner corner: its first face
// piece is shorter than the tube's centreline offset. Both rooms exist, so
// this is a real optically open door, not an opaque exterior opening.
const door = normalise([right + 5, top + 40.1]);
const corners = [[left + scenario.tilt, top], [left, bottom], [right, bottom], [right, top]];
const source = [...corners, ...(scenario.intermediate ? [[right - 0.1, top]] : [])].map(normalise);
// The free left side keeps its genuine slope; intersect it analytically
// with y=top+offset and y=bottom-offset instead of silently straightening it.
const expected = [[left + scenario.tilt * (1 - offset / (bottom - top)), top + offset],
[left + scenario.tilt * offset / (bottom - top), bottom - offset],
[right - offset, bottom - offset], [right - offset, top + offset]];
if (!scenario.tilt) { expected[0][0] += offset; expected[1][0] += offset; }
const expectedCorners = expected.map(rotate);
const expectedLength = expectedCorners.reduce((length, a, i) => {
const b = expectedCorners[(i + 1) % expectedCorners.length];
return length + Math.hypot(b[0] - a[0], b[1] - a[1]);
}, 0);
// Move the stored closure seam to every node, including the short saved
// subdivision. The visible result must remain one four-corner tube.
for (let start = 0; start < source.length; start++) for (const reversed of [false, true]) {
const ordered = [...source.slice(start), ...source.slice(0, start)];
if (reversed) ordered.reverse();
const points = [...ordered, ordered[0]];
await page.evaluate(async ({ rooms, walls, door, angle, points }) => {
await window.__hpTest.setServerConfig(cfg => ({ ...cfg,
settings: { ...(cfg.settings || {}), volumetric_view: false },
spaces: [{ id: 'tube-oracle', title: 'Tube oracle', cell_cm: 5, view_box: [0, 0, 1, 0.7],
rooms, walls, wall_segments: [], partitions: [], wall_columns: [], decor: [],
openings: [{ id: 'tube-door', type: 'door', x: door[0], y: door[1],
angle: 90 + angle * 180 / Math.PI, length: 0.08 }],
settings: { glow_enabled: true, fill_mode: 'none', show_names: false, sun_rays: false },
led_strips: [{ id: 'tube', marker: 'd_light1', points }] }],
markers: [{ id: 'd_light1', binding: 'device:d_light1', space: 'tube-oracle',
room_id: 'tube-room', is_light: true, glow_radius_cm: 30 }],
}));
}, { rooms, walls, door, angle: scenario.angle, points });
let viewShape = null;
for (const mode of ['view', 'devices']) {
await page.evaluate(mode => window.__hpTest.setMode(mode), mode);
let onShape = null;
for (const state of ['on', 'off']) {
// Public HA state input, not a write to the card's private resolver.
await page.evaluate(async state => {
const card = window.__card, previous = card.hass.states['light.ceiling'];
card.hass = { ...card.hass, states: { ...card.hass.states,
'light.ceiling': { ...previous, state } } };
await window.__hpTest.settled();
}, state);
await page.waitForFunction(state => window.__card.shadowRoot
.querySelector('[data-led-strip="tube"]')?.dataset.state === state, state);
const actual = await page.evaluate(async ({ expectedCorners, outlineWidth, coreWidth }) => {
const group = window.__card.shadowRoot.querySelector('[data-led-strip="tube"]');
const outline = group.querySelector('.led-outline'), core = group.querySelector('.led-core');
const d = outline.getAttribute('d');
const corners = [...d.matchAll(/[ML]\s*([-+\d.e]+)[,\s]+([-+\d.e]+)/gi)]
.map(match => [Number(match[1]), Number(match[2])]);
const expectedD = expectedCorners.map((p, i) => `${i ? 'L' : 'M'}${p[0]} ${p[1]}`).join(' ') + ' Z';
const minX = Math.floor(Math.min(...expectedCorners.map(p => p[0])) - 8);
const minY = Math.floor(Math.min(...expectedCorners.map(p => p[1])) - 8);
const width = Math.ceil(Math.max(...expectedCorners.map(p => p[0])) - minX + 8);
const height = Math.ceil(Math.max(...expectedCorners.map(p => p[1])) - minY + 8);
const raster = async body => {
const image = new Image();
const xml = `<svg xmlns="http://www.w3.org/2000/svg" width="${width * 2}" height="${height * 2}" viewBox="${minX} ${minY} ${width} ${height}">${body}</svg>`;
image.src = `data:image/svg+xml;charset=utf-8,${encodeURIComponent(xml)}`;
await image.decode();
const canvas = document.createElement('canvas'); canvas.width = width * 2; canvas.height = height * 2;
const context = canvas.getContext('2d'); context.drawImage(image, 0, 0);
return context.getImageData(0, 0, canvas.width, canvas.height).data;
};
const expectedMarkup = `<path d="${expectedD}" fill="none" stroke="#383838" stroke-width="${outlineWidth}" stroke-linecap="round" stroke-linejoin="round"/><path d="${expectedD}" fill="none" stroke="#FFFFFF" stroke-width="${coreWidth}" stroke-linecap="round" stroke-linejoin="round"/>`;
const [painted, reference] = await Promise.all([
raster(new XMLSerializer().serializeToString(outline) + new XMLSerializer().serializeToString(core)),
raster(expectedMarkup),
]);
let badPixels = 0;
for (let i = 0; i < painted.length; i += 4) {
if ([0, 1, 2, 3].some(channel => Math.abs(painted[i + channel] - reference[i + channel]) > 16)) badPixels++;
}
return { d, corners, closed: /Z\s*$/i.test(d), length: outline.getTotalLength(),
widths: [Number(outline.getAttribute('stroke-width')), Number(core.getAttribute('stroke-width'))],
coreD: core.getAttribute('d'), badPixels,
openingPresent: !!window.__card.shadowRoot.querySelector('[data-hp="opening"][data-id="tube-door"][data-kind="door"]'),
saved: window.__card._serverCfg.spaces[0].led_strips[0].points };
}, { expectedCorners, outlineWidth, coreWidth });
const label = `${scenario.name}, start=${start}, reverse=${reversed}, ${mode}, ${state}`;
check(`${label}: four closed visible corners`, actual.closed && actual.corners.length === 4);
check(`${label}: fixture includes the real mounted door`, actual.openingPresent);
check(`${label}: analytical corner positions`, expectedCorners.every(p =>
actual.corners.some(q => Math.hypot(p[0] - q[0], p[1] - q[1]) < 1e-4)));
check(`${label}: no extra travel from a hook, backtrack or door notch`, Math.abs(actual.length - expectedLength) < 0.003);
check(`${label}: expected tube pixels`, actual.badPixels, 0);
check(`${label}: outline/core share geometry`, actual.coreD, actual.d);
check(`${label}: physical outline/core widths`, actual.widths, [outlineWidth, coreWidth]);
check(`${label}: saved geometry is untouched`, actual.saved, points);
const shape = { d: actual.d, widths: actual.widths };
if (state === 'on') onShape = shape;
else check(`${label}: off keeps the on shape and thickness`, shape, onShape);
if (mode === 'view' && state === 'on') viewShape = shape;
if (mode === 'devices') check(`${label}: Devices keeps View tube geometry`, shape, viewShape);
results.push({ scenario: scenario.name, start, reversed, mode, state,
corners: actual.corners.length, badPixels: actual.badPixels, lengthError: actual.length - expectedLength });
}
}
}
}
await finish(browser, results);
+280 -280
View File
@@ -1,598 +1,598 @@
{
"schema": 1,
"fingerprint": "fd4a405e9c5a21035258c45feca26dca03d59d4cfba4280f89ff5f82675515ac",
"fingerprint": "ab07da35681c15ab6136c323500b69766580ea4a788e399ea88f9e7497549172",
"entry": "houseplan-card.js",
"panelEntry": "houseplan-panel.js",
"initialViewFiles": [
"houseplan-assets/houseplan-card-CDzf9V5z.js",
"houseplan-assets/houseplan-card-BOdiRDFR.js",
"houseplan-card.js"
],
"initialViewGzipBytes": 300069,
"initialViewGzipBytes": 300133,
"initialPanelFiles": [
"houseplan-assets/houseplan-card-CDzf9V5z.js",
"houseplan-assets/houseplan-card-BOdiRDFR.js",
"houseplan-panel.js"
],
"initialPanelGzipBytes": 301590,
"initialPanelGzipBytes": 301657,
"initialPanelOnlyFiles": [
"houseplan-panel.js"
],
"initialPanelOnlyGzipBytes": 2324,
"initialPanelOnlyGzipBytes": 2328,
"lazyFiles": [
"houseplan-assets/backdrop-pick-361D_NhT.js",
"houseplan-assets/de-wSrjkMCX.js",
"houseplan-assets/editor-CAHVNjOb.js",
"houseplan-assets/form-kit.styles-Dq1Y4tz1.js",
"houseplan-assets/fr-Cb7RjPXv.js",
"houseplan-assets/furniture-plan-art.generated-DHB0O8RC.js",
"houseplan-assets/houseplan-editor-runtime-D7Nrak81.js",
"houseplan-assets/houseplan-onboarding-runtime-BDfCLIiS.js",
"houseplan-assets/hp-zigbee-topology-overlay-W_gG_T_A.js",
"houseplan-assets/iso-scene-render-CBGc0yON.js",
"houseplan-assets/led-strip-editor-55w_99OW.js",
"houseplan-assets/led-strip-geometry-BcPfXtN-.js",
"houseplan-assets/led-strip-runtime-C0OS8_qS.js",
"houseplan-assets/live-interaction-runtime-CgDUYt60.js",
"houseplan-assets/moon-runtime-DkqNfOp0.js",
"houseplan-assets/namespace-language-BPjMJUHI.js",
"houseplan-assets/pdf-export-UdR2EXb9.js",
"houseplan-assets/space-editor-N5uYQl3H.js",
"houseplan-assets/summary-panel-runtime-loaded-BcDAIp5L.js",
"houseplan-assets/zigbee-topology-Co7YPeRf.js",
"houseplan-assets/zigbee-topology-runtime-ByS3kW9n.js"
"houseplan-assets/backdrop-pick-DHF8oaNH.js",
"houseplan-assets/de-C4xCvmYr.js",
"houseplan-assets/editor-CFo6BxSe.js",
"houseplan-assets/form-kit.styles-B6HsmMPA.js",
"houseplan-assets/fr-BJJefRIG.js",
"houseplan-assets/furniture-plan-art.generated-XIg9ZqQe.js",
"houseplan-assets/houseplan-editor-runtime-CqreRULk.js",
"houseplan-assets/houseplan-onboarding-runtime-DOfjrx0M.js",
"houseplan-assets/hp-zigbee-topology-overlay-BAaZNyAl.js",
"houseplan-assets/iso-scene-render-CR7lxY-w.js",
"houseplan-assets/led-strip-editor-kcNyoue_.js",
"houseplan-assets/led-strip-geometry-DaLifxqY.js",
"houseplan-assets/led-strip-runtime-Bx6qpdWk.js",
"houseplan-assets/live-interaction-runtime-C1983oH8.js",
"houseplan-assets/moon-runtime-Ca1mxhJl.js",
"houseplan-assets/namespace-language-D86tJUeD.js",
"houseplan-assets/pdf-export-C-Y4BSVu.js",
"houseplan-assets/space-editor-EDOQT48H.js",
"houseplan-assets/summary-panel-runtime-loaded-CcLP5B5v.js",
"houseplan-assets/zigbee-topology-BG_a6cIb.js",
"houseplan-assets/zigbee-topology-runtime-CynQ2m3K.js"
],
"lazyGzipBytes": 477990,
"lazyGzipBytes": 478817,
"lazyEditorFiles": [
"houseplan-assets/backdrop-pick-361D_NhT.js",
"houseplan-assets/editor-CAHVNjOb.js",
"houseplan-assets/form-kit.styles-Dq1Y4tz1.js",
"houseplan-assets/furniture-plan-art.generated-DHB0O8RC.js",
"houseplan-assets/houseplan-editor-runtime-D7Nrak81.js",
"houseplan-assets/namespace-language-BPjMJUHI.js",
"houseplan-assets/zigbee-topology-Co7YPeRf.js"
"houseplan-assets/backdrop-pick-DHF8oaNH.js",
"houseplan-assets/editor-CFo6BxSe.js",
"houseplan-assets/form-kit.styles-B6HsmMPA.js",
"houseplan-assets/furniture-plan-art.generated-XIg9ZqQe.js",
"houseplan-assets/houseplan-editor-runtime-CqreRULk.js",
"houseplan-assets/namespace-language-D86tJUeD.js",
"houseplan-assets/zigbee-topology-BG_a6cIb.js"
],
"lazyEditorGzipBytes": 240863,
"lazyEditorGzipBytes": 240843,
"lazyOnboardingFiles": [
"houseplan-assets/backdrop-pick-361D_NhT.js",
"houseplan-assets/form-kit.styles-Dq1Y4tz1.js",
"houseplan-assets/houseplan-onboarding-runtime-BDfCLIiS.js",
"houseplan-assets/namespace-language-BPjMJUHI.js"
"houseplan-assets/backdrop-pick-DHF8oaNH.js",
"houseplan-assets/form-kit.styles-B6HsmMPA.js",
"houseplan-assets/houseplan-onboarding-runtime-DOfjrx0M.js",
"houseplan-assets/namespace-language-D86tJUeD.js"
],
"lazyOnboardingGzipBytes": 28403,
"lazyOnboardingGzipBytes": 28402,
"lazyLocaleFiles": [
"houseplan-assets/de-wSrjkMCX.js",
"houseplan-assets/fr-Cb7RjPXv.js"
"houseplan-assets/de-C4xCvmYr.js",
"houseplan-assets/fr-BJJefRIG.js"
],
"lazyLocaleGzipBytes": 53859,
"lazyLocaleGzipBytes": 53876,
"lazyIsometricFiles": [
"houseplan-assets/iso-scene-render-CBGc0yON.js"
"houseplan-assets/iso-scene-render-CR7lxY-w.js"
],
"lazyIsometricGzipBytes": 12345,
"lazyIsometricGzipBytes": 12348,
"lazyFurnitureArtFiles": [
"houseplan-assets/furniture-plan-art.generated-DHB0O8RC.js"
"houseplan-assets/furniture-plan-art.generated-XIg9ZqQe.js"
],
"lazyFurnitureArtGzipBytes": 16940,
"lazyFurnitureArtGzipBytes": 16936,
"lazyPdfFiles": [
"houseplan-assets/furniture-plan-art.generated-DHB0O8RC.js",
"houseplan-assets/pdf-export-UdR2EXb9.js"
"houseplan-assets/furniture-plan-art.generated-XIg9ZqQe.js",
"houseplan-assets/pdf-export-C-Y4BSVu.js"
],
"lazyPdfGzipBytes": 126938,
"lazyPdfGzipBytes": 126934,
"lazyMoonFiles": [
"houseplan-assets/moon-runtime-DkqNfOp0.js"
"houseplan-assets/moon-runtime-Ca1mxhJl.js"
],
"lazyMoonGzipBytes": 11713,
"lazyLedFiles": [
"houseplan-assets/led-strip-field-DvtQ7tpM.js",
"houseplan-assets/led-strip-geometry-BcPfXtN-.js",
"houseplan-assets/led-strip-runtime-C0OS8_qS.js"
"houseplan-assets/led-strip-field-ObbckCkp.js",
"houseplan-assets/led-strip-geometry-DaLifxqY.js",
"houseplan-assets/led-strip-runtime-Bx6qpdWk.js"
],
"lazyLedGzipBytes": 9544,
"lazyLedGzipBytes": 10613,
"lazyLedEditorFiles": [
"houseplan-assets/led-strip-editor-55w_99OW.js",
"houseplan-assets/led-strip-geometry-BcPfXtN-.js",
"houseplan-assets/namespace-language-BPjMJUHI.js"
"houseplan-assets/led-strip-editor-kcNyoue_.js",
"houseplan-assets/led-strip-geometry-DaLifxqY.js",
"houseplan-assets/namespace-language-D86tJUeD.js"
],
"lazyLedEditorGzipBytes": 10033,
"lazyLedEditorGzipBytes": 10707,
"lazyNamespaceLocaleFiles": [
"houseplan-assets/led-de-D8AOGwO9.js",
"houseplan-assets/led-fr-Dyd_xJWH.js",
"houseplan-assets/led-ru-DxKs7cgH.js",
"houseplan-assets/settings-de-hkfrpcmk.js",
"houseplan-assets/settings-fr-CTDbCfmV.js",
"houseplan-assets/settings-ru-_XLAbOEk.js",
"houseplan-assets/support-de-DF73IEHL.js",
"houseplan-assets/support-fr-BBhMT3I0.js",
"houseplan-assets/support-ru-Bd7vkOXI.js",
"houseplan-assets/tools-de-DwmzTHwi.js",
"houseplan-assets/tools-fr-Dp5JXY-G.js",
"houseplan-assets/tools-ru-CAQB2Qhv.js",
"houseplan-assets/topology-de-DFY0lBO-.js",
"houseplan-assets/topology-fr-DbNDk6Er.js",
"houseplan-assets/topology-ru-BNVYY-_i.js"
"houseplan-assets/led-de-yp1GefDC.js",
"houseplan-assets/led-fr-CHODsRJm.js",
"houseplan-assets/led-ru-D2-9Yy6l.js",
"houseplan-assets/settings-de-ZP6F6dIF.js",
"houseplan-assets/settings-fr-doqd_TsB.js",
"houseplan-assets/settings-ru-CQ1W2gik.js",
"houseplan-assets/support-de-haZQ7q8i.js",
"houseplan-assets/support-fr-DnRyZ_Ga.js",
"houseplan-assets/support-ru-B7zzXsuL.js",
"houseplan-assets/tools-de-CYXPPfUH.js",
"houseplan-assets/tools-fr-DvygRB10.js",
"houseplan-assets/tools-ru-2xmu2w_8.js",
"houseplan-assets/topology-de-COda8n9n.js",
"houseplan-assets/topology-fr-BT9yhzay.js",
"houseplan-assets/topology-ru-C-d06yvD.js"
],
"lazyNamespaceLocaleGzipBytes": 30051,
"lazyNamespaceLocaleGzipBytes": 30082,
"files": [
{
"path": "houseplan-assets/backdrop-pick-361D_NhT.js",
"sha256": "8d80eb83488438a96d33410716b91398f1aa7456884d8e9e9094165a830ec9c0",
"path": "houseplan-assets/backdrop-pick-DHF8oaNH.js",
"sha256": "7262c67e3f88f44ee6c6a0973073d1f7c3c9f177ff8254758a21c4e3867c5b06",
"rawBytes": 55329,
"gzipBytes": 18026,
"gzipBytes": 18027,
"isEntry": false,
"imports": [
"houseplan-assets/form-kit.styles-Dq1Y4tz1.js",
"houseplan-assets/houseplan-card-CDzf9V5z.js",
"houseplan-assets/namespace-language-BPjMJUHI.js"
"houseplan-assets/form-kit.styles-B6HsmMPA.js",
"houseplan-assets/houseplan-card-BOdiRDFR.js",
"houseplan-assets/namespace-language-D86tJUeD.js"
],
"dynamicImports": [
"houseplan-assets/settings-de-hkfrpcmk.js",
"houseplan-assets/settings-fr-CTDbCfmV.js",
"houseplan-assets/settings-ru-_XLAbOEk.js"
"houseplan-assets/settings-de-ZP6F6dIF.js",
"houseplan-assets/settings-fr-doqd_TsB.js",
"houseplan-assets/settings-ru-CQ1W2gik.js"
]
},
{
"path": "houseplan-assets/de-wSrjkMCX.js",
"sha256": "b6873407a3663932da1261fb151e3c81c78e4cfda3ad3d88946e076c524e2e27",
"path": "houseplan-assets/de-C4xCvmYr.js",
"sha256": "e3778d3139c05e075281f96460e15a6aaafe8dd9200306b0a3799a1bc5710828",
"rawBytes": 89873,
"gzipBytes": 27163,
"gzipBytes": 27169,
"isEntry": false,
"imports": [],
"dynamicImports": []
},
{
"path": "houseplan-assets/editor-CAHVNjOb.js",
"sha256": "29b283f4d700ecf0256cb09f858a3944f9722c40711ad3ed9d9fee90d5a2175f",
"path": "houseplan-assets/editor-CFo6BxSe.js",
"sha256": "81d90441a06989a01a09c19e8c73567b80cd4d6ba52e4ea4796e096e1e5b7aa4",
"rawBytes": 3833,
"gzipBytes": 1583,
"gzipBytes": 1584,
"isEntry": false,
"imports": [
"houseplan-assets/houseplan-card-CDzf9V5z.js"
"houseplan-assets/houseplan-card-BOdiRDFR.js"
],
"dynamicImports": []
},
{
"path": "houseplan-assets/form-kit.styles-Dq1Y4tz1.js",
"sha256": "57078cb29919b2d801225f1f15f59fcac028907b7126b5a684a5ab89b50ace38",
"path": "houseplan-assets/form-kit.styles-B6HsmMPA.js",
"sha256": "d18d3eb8bf1dd9dda6d6fdeed84edc16d3945e8a7e23b1d88e5f2edcef0a0af6",
"rawBytes": 25605,
"gzipBytes": 5058,
"gzipBytes": 5059,
"isEntry": false,
"imports": [],
"dynamicImports": []
},
{
"path": "houseplan-assets/fr-Cb7RjPXv.js",
"sha256": "f04f19f0f56a70d201c521b74be3a6f7f3b687a93bd91785d50f0984c68508cb",
"path": "houseplan-assets/fr-BJJefRIG.js",
"sha256": "4932ff13f6fdc339e9d67123105f9bd97f051395a3c3310240fc07b119d87024",
"rawBytes": 92266,
"gzipBytes": 26696,
"gzipBytes": 26707,
"isEntry": false,
"imports": [],
"dynamicImports": []
},
{
"path": "houseplan-assets/furniture-plan-art.generated-DHB0O8RC.js",
"sha256": "1f693cbcb7992e269d7a7602962fcce33f21230e7b0edce7c0359942230da941",
"path": "houseplan-assets/furniture-plan-art.generated-XIg9ZqQe.js",
"sha256": "10a0b09e4b1513bd02ffba047d6931add1d1106c453af03f6b3c778b5bb55e15",
"rawBytes": 52035,
"gzipBytes": 16940,
"gzipBytes": 16936,
"isEntry": false,
"imports": [],
"dynamicImports": []
},
{
"path": "houseplan-assets/houseplan-card-CDzf9V5z.js",
"sha256": "43829456356d3d4d59efa17ccbb75326350ad79fc4413862dfa50ec98c1ca24e",
"rawBytes": 1056226,
"gzipBytes": 299266,
"path": "houseplan-assets/houseplan-card-BOdiRDFR.js",
"sha256": "37c784960d53789a66988a4e4ab8a8afe88aeddb80c5f244f3d453ef86c3ba8c",
"rawBytes": 1056405,
"gzipBytes": 299329,
"isEntry": false,
"imports": [],
"dynamicImports": [
"houseplan-assets/de-wSrjkMCX.js",
"houseplan-assets/editor-CAHVNjOb.js",
"houseplan-assets/fr-Cb7RjPXv.js",
"houseplan-assets/furniture-plan-art.generated-DHB0O8RC.js",
"houseplan-assets/houseplan-editor-runtime-D7Nrak81.js",
"houseplan-assets/houseplan-onboarding-runtime-BDfCLIiS.js",
"houseplan-assets/hp-zigbee-topology-overlay-W_gG_T_A.js",
"houseplan-assets/iso-scene-render-CBGc0yON.js",
"houseplan-assets/led-strip-editor-55w_99OW.js",
"houseplan-assets/led-strip-runtime-C0OS8_qS.js",
"houseplan-assets/live-interaction-runtime-CgDUYt60.js",
"houseplan-assets/moon-runtime-DkqNfOp0.js",
"houseplan-assets/pdf-export-UdR2EXb9.js",
"houseplan-assets/space-editor-N5uYQl3H.js",
"houseplan-assets/summary-panel-runtime-loaded-BcDAIp5L.js"
"houseplan-assets/de-C4xCvmYr.js",
"houseplan-assets/editor-CFo6BxSe.js",
"houseplan-assets/fr-BJJefRIG.js",
"houseplan-assets/furniture-plan-art.generated-XIg9ZqQe.js",
"houseplan-assets/houseplan-editor-runtime-CqreRULk.js",
"houseplan-assets/houseplan-onboarding-runtime-DOfjrx0M.js",
"houseplan-assets/hp-zigbee-topology-overlay-BAaZNyAl.js",
"houseplan-assets/iso-scene-render-CR7lxY-w.js",
"houseplan-assets/led-strip-editor-kcNyoue_.js",
"houseplan-assets/led-strip-runtime-Bx6qpdWk.js",
"houseplan-assets/live-interaction-runtime-C1983oH8.js",
"houseplan-assets/moon-runtime-Ca1mxhJl.js",
"houseplan-assets/pdf-export-C-Y4BSVu.js",
"houseplan-assets/space-editor-EDOQT48H.js",
"houseplan-assets/summary-panel-runtime-loaded-CcLP5B5v.js"
]
},
{
"path": "houseplan-assets/houseplan-editor-runtime-D7Nrak81.js",
"sha256": "ba4c1682823b15bce834bd41d0bc0d7fc4327fc6cc099175eb5651c285f9a938",
"path": "houseplan-assets/houseplan-editor-runtime-CqreRULk.js",
"sha256": "772b538d5b87265a0e88117f01034a3ccadd5f4e928ced77cb99254ab74e299a",
"rawBytes": 695353,
"gzipBytes": 194544,
"gzipBytes": 194530,
"isEntry": false,
"imports": [
"houseplan-assets/backdrop-pick-361D_NhT.js",
"houseplan-assets/form-kit.styles-Dq1Y4tz1.js",
"houseplan-assets/furniture-plan-art.generated-DHB0O8RC.js",
"houseplan-assets/houseplan-card-CDzf9V5z.js",
"houseplan-assets/namespace-language-BPjMJUHI.js",
"houseplan-assets/zigbee-topology-Co7YPeRf.js"
"houseplan-assets/backdrop-pick-DHF8oaNH.js",
"houseplan-assets/form-kit.styles-B6HsmMPA.js",
"houseplan-assets/furniture-plan-art.generated-XIg9ZqQe.js",
"houseplan-assets/houseplan-card-BOdiRDFR.js",
"houseplan-assets/namespace-language-D86tJUeD.js",
"houseplan-assets/zigbee-topology-BG_a6cIb.js"
],
"dynamicImports": [
"houseplan-assets/support-de-DF73IEHL.js",
"houseplan-assets/support-fr-BBhMT3I0.js",
"houseplan-assets/support-ru-Bd7vkOXI.js",
"houseplan-assets/tools-de-DwmzTHwi.js",
"houseplan-assets/tools-fr-Dp5JXY-G.js",
"houseplan-assets/tools-ru-CAQB2Qhv.js",
"houseplan-assets/zigbee-topology-runtime-ByS3kW9n.js"
"houseplan-assets/support-de-haZQ7q8i.js",
"houseplan-assets/support-fr-DnRyZ_Ga.js",
"houseplan-assets/support-ru-B7zzXsuL.js",
"houseplan-assets/tools-de-CYXPPfUH.js",
"houseplan-assets/tools-fr-DvygRB10.js",
"houseplan-assets/tools-ru-2xmu2w_8.js",
"houseplan-assets/zigbee-topology-runtime-CynQ2m3K.js"
]
},
{
"path": "houseplan-assets/houseplan-onboarding-runtime-BDfCLIiS.js",
"sha256": "89044bd3a7f52fc1f1b373b31576dc1d7180a011c1eeef264f79c6f5d00023e0",
"path": "houseplan-assets/houseplan-onboarding-runtime-DOfjrx0M.js",
"sha256": "242ae570916ec2a000a8a0079a948826faeb45c0968cc1006e9670f9d3c4088b",
"rawBytes": 15886,
"gzipBytes": 4910,
"gzipBytes": 4907,
"isEntry": false,
"imports": [
"houseplan-assets/backdrop-pick-361D_NhT.js",
"houseplan-assets/form-kit.styles-Dq1Y4tz1.js",
"houseplan-assets/houseplan-card-CDzf9V5z.js",
"houseplan-assets/namespace-language-BPjMJUHI.js"
"houseplan-assets/backdrop-pick-DHF8oaNH.js",
"houseplan-assets/form-kit.styles-B6HsmMPA.js",
"houseplan-assets/houseplan-card-BOdiRDFR.js",
"houseplan-assets/namespace-language-D86tJUeD.js"
],
"dynamicImports": []
},
{
"path": "houseplan-assets/hp-zigbee-topology-overlay-W_gG_T_A.js",
"sha256": "673cd02181555b4849ebe42fd3053ce67b7f97dcd14fcfc61e81c119be120c5b",
"path": "houseplan-assets/hp-zigbee-topology-overlay-BAaZNyAl.js",
"sha256": "8cb7c3f010cf7ef792a676bfd994c4498f31222dd12ded79e3e2f37dfae4f52e",
"rawBytes": 10958,
"gzipBytes": 3768,
"isEntry": false,
"imports": [
"houseplan-assets/houseplan-card-CDzf9V5z.js",
"houseplan-assets/namespace-language-BPjMJUHI.js",
"houseplan-assets/zigbee-topology-Co7YPeRf.js",
"houseplan-assets/zigbee-topology-runtime-ByS3kW9n.js"
"houseplan-assets/houseplan-card-BOdiRDFR.js",
"houseplan-assets/namespace-language-D86tJUeD.js",
"houseplan-assets/zigbee-topology-BG_a6cIb.js",
"houseplan-assets/zigbee-topology-runtime-CynQ2m3K.js"
],
"dynamicImports": []
},
{
"path": "houseplan-assets/iso-scene-render-CBGc0yON.js",
"sha256": "1f2456f515056c6fba882cbd6b510635bdb1c12d63cb648b741c4e61b13e6197",
"path": "houseplan-assets/iso-scene-render-CR7lxY-w.js",
"sha256": "1986dd43c8b76580f893c1629d494f7747f02aa8d544baff20d56fe10b470bb5",
"rawBytes": 36700,
"gzipBytes": 12345,
"gzipBytes": 12348,
"isEntry": false,
"imports": [
"houseplan-assets/houseplan-card-CDzf9V5z.js"
"houseplan-assets/houseplan-card-BOdiRDFR.js"
],
"dynamicImports": []
},
{
"path": "houseplan-assets/led-de-D8AOGwO9.js",
"sha256": "cc7a9e048e16ad6c7869d7f72a0e4d7bde6451d29eb8fd5ec205a887fec62d97",
"path": "houseplan-assets/led-de-yp1GefDC.js",
"sha256": "eb9ce8bb536ac20e11cf4fe925d68f28b1ba8a5ea02c61abf9c3bb939de0a4c4",
"rawBytes": 1907,
"gzipBytes": 919,
"gzipBytes": 921,
"isEntry": false,
"imports": [],
"dynamicImports": []
},
{
"path": "houseplan-assets/led-fr-Dyd_xJWH.js",
"sha256": "e293c332b3bb877683b7781c16e0fad2cb6a72f271d779c7a398af29b2497027",
"path": "houseplan-assets/led-fr-CHODsRJm.js",
"sha256": "adb428bd63b6157ef0a5d749badf94e95204c9c3b83e5f3022accf65d304435e",
"rawBytes": 1886,
"gzipBytes": 905,
"gzipBytes": 906,
"isEntry": false,
"imports": [],
"dynamicImports": []
},
{
"path": "houseplan-assets/led-ru-DxKs7cgH.js",
"sha256": "06d0b17e3954e65270dcb7356f6672923185e8b5af38632eebbe99b5af1aab50",
"path": "houseplan-assets/led-ru-D2-9Yy6l.js",
"sha256": "bc5575139b30d6e93e07673f47865c332e71011796929a52043645a904d6df31",
"rawBytes": 2525,
"gzipBytes": 1105,
"gzipBytes": 1106,
"isEntry": false,
"imports": [],
"dynamicImports": []
},
{
"path": "houseplan-assets/led-strip-editor-55w_99OW.js",
"sha256": "77ee4a59643984f94f1ff57f96013858e2cdc258b13ae01497b46f4057f62442",
"path": "houseplan-assets/led-strip-editor-kcNyoue_.js",
"sha256": "dac9fdcaae6444caa1773a07384155cc92b916d2ebf3498e1dfc1b3525a84753",
"rawBytes": 21704,
"gzipBytes": 7380,
"gzipBytes": 7381,
"isEntry": false,
"imports": [
"houseplan-assets/houseplan-card-CDzf9V5z.js",
"houseplan-assets/led-strip-geometry-BcPfXtN-.js",
"houseplan-assets/namespace-language-BPjMJUHI.js"
"houseplan-assets/houseplan-card-BOdiRDFR.js",
"houseplan-assets/led-strip-geometry-DaLifxqY.js",
"houseplan-assets/namespace-language-D86tJUeD.js"
],
"dynamicImports": [
"houseplan-assets/led-de-D8AOGwO9.js",
"houseplan-assets/led-fr-Dyd_xJWH.js",
"houseplan-assets/led-ru-DxKs7cgH.js"
"houseplan-assets/led-de-yp1GefDC.js",
"houseplan-assets/led-fr-CHODsRJm.js",
"houseplan-assets/led-ru-D2-9Yy6l.js"
]
},
{
"path": "houseplan-assets/led-strip-field-DvtQ7tpM.js",
"sha256": "6b3bf5cf737a4b3136d65951e57bc93d07664fc34cc2ddc7ba502a1c567496d3",
"rawBytes": 7384,
"gzipBytes": 3073,
"path": "houseplan-assets/led-strip-field-ObbckCkp.js",
"sha256": "b85d8de01906a7e70f28baff534cf1a211216c99b72005b6d77a0d19cbb5ce8f",
"rawBytes": 7920,
"gzipBytes": 3321,
"isEntry": false,
"imports": [
"houseplan-assets/houseplan-card-CDzf9V5z.js",
"houseplan-assets/led-strip-geometry-BcPfXtN-.js"
"houseplan-assets/houseplan-card-BOdiRDFR.js",
"houseplan-assets/led-strip-geometry-DaLifxqY.js"
],
"dynamicImports": []
},
{
"path": "houseplan-assets/led-strip-geometry-BcPfXtN-.js",
"sha256": "96e1f3dce530f9e05d7b55bc32c9b998c8e9d291bef92c7c2b78d57948ece933",
"rawBytes": 5231,
"gzipBytes": 2244,
"path": "houseplan-assets/led-strip-geometry-DaLifxqY.js",
"sha256": "2dfbe1509da809008c9a525a7ed02226c026aaa5c0dafcb9f3dc1c44151ed63e",
"rawBytes": 7055,
"gzipBytes": 2917,
"isEntry": false,
"imports": [],
"dynamicImports": []
},
{
"path": "houseplan-assets/led-strip-runtime-C0OS8_qS.js",
"sha256": "933125d5e1f0504e56291e5289237630a79f5502f9b5701dc3d76f2dc470aed6",
"rawBytes": 10760,
"gzipBytes": 4227,
"path": "houseplan-assets/led-strip-runtime-Bx6qpdWk.js",
"sha256": "6fd2d3578e550dfbe8c38308923e21f9fddeb469f64e8fcf295dc292949ddf32",
"rawBytes": 11179,
"gzipBytes": 4375,
"isEntry": false,
"imports": [
"houseplan-assets/houseplan-card-CDzf9V5z.js",
"houseplan-assets/led-strip-geometry-BcPfXtN-.js"
"houseplan-assets/houseplan-card-BOdiRDFR.js",
"houseplan-assets/led-strip-geometry-DaLifxqY.js"
],
"dynamicImports": [
"houseplan-assets/led-strip-field-DvtQ7tpM.js"
"houseplan-assets/led-strip-field-ObbckCkp.js"
]
},
{
"path": "houseplan-assets/live-interaction-runtime-CgDUYt60.js",
"sha256": "5e3ea0225cba5931aa51cd398062f5cb17d82f0f33bee9101fa61ed455b40fdb",
"path": "houseplan-assets/live-interaction-runtime-C1983oH8.js",
"sha256": "04be552ac07f99c03713f162ce0b6129c8491dfd89da9cd8e07cd71866fe309c",
"rawBytes": 8370,
"gzipBytes": 3280,
"gzipBytes": 3281,
"isEntry": false,
"imports": [
"houseplan-assets/houseplan-card-CDzf9V5z.js"
"houseplan-assets/houseplan-card-BOdiRDFR.js"
],
"dynamicImports": []
},
{
"path": "houseplan-assets/moon-runtime-DkqNfOp0.js",
"sha256": "1d6df38c7320b9f9cff3b9f3afa152f4c295109fe2c0b94924d5d2e606468962",
"path": "houseplan-assets/moon-runtime-Ca1mxhJl.js",
"sha256": "97b9f55cb8e2915acb5eaa260f21e2103bc08f0e654c1c0b03c3000604319730",
"rawBytes": 30292,
"gzipBytes": 11713,
"isEntry": false,
"imports": [
"houseplan-assets/houseplan-card-CDzf9V5z.js"
"houseplan-assets/houseplan-card-BOdiRDFR.js"
],
"dynamicImports": []
},
{
"path": "houseplan-assets/namespace-language-BPjMJUHI.js",
"sha256": "d108e467e8a0e61c1f9cf0ba408f01d9415920c3e843219144f19ab0634cbb1b",
"path": "houseplan-assets/namespace-language-D86tJUeD.js",
"sha256": "012aa30cbf8bbbb2eff6b7ef05970ff90fb2b4b576910578e3527b75e68ffda6",
"rawBytes": 675,
"gzipBytes": 409,
"isEntry": false,
"imports": [
"houseplan-assets/houseplan-card-CDzf9V5z.js"
"houseplan-assets/houseplan-card-BOdiRDFR.js"
],
"dynamicImports": []
},
{
"path": "houseplan-assets/pdf-export-UdR2EXb9.js",
"sha256": "839a0cb681cfcb67b74899d306b3e09e8b7fae59f46283b335c671c845554242",
"path": "houseplan-assets/pdf-export-C-Y4BSVu.js",
"sha256": "fba700bc14c66c695f1b3de3e82abdf5fb6b14b70773c3d0f0e185dcf2989491",
"rawBytes": 236714,
"gzipBytes": 109998,
"isEntry": false,
"imports": [
"houseplan-assets/furniture-plan-art.generated-DHB0O8RC.js",
"houseplan-assets/houseplan-card-CDzf9V5z.js"
"houseplan-assets/furniture-plan-art.generated-XIg9ZqQe.js",
"houseplan-assets/houseplan-card-BOdiRDFR.js"
],
"dynamicImports": []
},
{
"path": "houseplan-assets/settings-de-hkfrpcmk.js",
"sha256": "7430bf272d66366ca4e7f3d6c8178cda97f2bc65112a475aeb98388338726c6d",
"path": "houseplan-assets/settings-de-ZP6F6dIF.js",
"sha256": "12dd3028d2de2e4fc3bfcf2299e45e253075ca23b95235436ef1cf9156738a3e",
"rawBytes": 8886,
"gzipBytes": 3408,
"gzipBytes": 3411,
"isEntry": false,
"imports": [],
"dynamicImports": []
},
{
"path": "houseplan-assets/settings-fr-CTDbCfmV.js",
"sha256": "e00be71088032b53b6d81e3a690c5ff178dfbf21745c21e63fc20c1f7c5a82b7",
"path": "houseplan-assets/settings-fr-doqd_TsB.js",
"sha256": "0c1f01b69c2b1704ddd29e99dd7609ad679655b5241b3e2b8921057198005ff3",
"rawBytes": 9297,
"gzipBytes": 3381,
"gzipBytes": 3385,
"isEntry": false,
"imports": [],
"dynamicImports": []
},
{
"path": "houseplan-assets/settings-ru-_XLAbOEk.js",
"sha256": "410a961660d4ac60f59f9301d651a98e14617de88af04ea728b7cd819b08630b",
"path": "houseplan-assets/settings-ru-CQ1W2gik.js",
"sha256": "bad5c925aac84429d0831a1036ea3162ead8d4431db35ea577b0e806c8fbdbf1",
"rawBytes": 12284,
"gzipBytes": 3898,
"gzipBytes": 3900,
"isEntry": false,
"imports": [],
"dynamicImports": []
},
{
"path": "houseplan-assets/space-editor-N5uYQl3H.js",
"sha256": "6382ce5fca7f70735041e35b3db96e3f1e4feeed35abacc46f1311c3a60465db",
"path": "houseplan-assets/space-editor-EDOQT48H.js",
"sha256": "47339ab7329ffd1a0cbd21980c1cf2a2041d7a514ed5992e73a07abdce6fb764",
"rawBytes": 2619,
"gzipBytes": 1127,
"gzipBytes": 1130,
"isEntry": false,
"imports": [
"houseplan-assets/houseplan-card-CDzf9V5z.js"
"houseplan-assets/houseplan-card-BOdiRDFR.js"
],
"dynamicImports": []
},
{
"path": "houseplan-assets/summary-panel-editor-CgZXeEXz.js",
"sha256": "ca0343b11e17cb8a871630e11e00a9def2ba99290339abbd79e577f2dd3e3bd6",
"rawBytes": 14867,
"gzipBytes": 3429,
"path": "houseplan-assets/summary-panel-editor-BZnGwuVh.js",
"sha256": "516e3462d3896a9ca782ee0f2f3266a4da6e6b6664e92a619a23b8991e600795",
"rawBytes": 14862,
"gzipBytes": 3427,
"isEntry": false,
"imports": [
"houseplan-assets/form-kit.styles-Dq1Y4tz1.js",
"houseplan-assets/houseplan-card-CDzf9V5z.js",
"houseplan-assets/summary-panel-runtime-loaded-BcDAIp5L.js"
"houseplan-assets/form-kit.styles-B6HsmMPA.js",
"houseplan-assets/houseplan-card-BOdiRDFR.js",
"houseplan-assets/summary-panel-runtime-loaded-CcLP5B5v.js"
],
"dynamicImports": []
},
{
"path": "houseplan-assets/summary-panel-metrics-DpgEBDDi.js",
"sha256": "ffe7025d0d913a2c27825836e263fedec5fd4c6671087654a80a826bf8e9ac63",
"path": "houseplan-assets/summary-panel-metrics-D_ZXPJxz.js",
"sha256": "3be26833b041416cef359e4c7086a0b0e6788680dda8f1583ae76d9256f944fa",
"rawBytes": 2701,
"gzipBytes": 1345,
"gzipBytes": 1348,
"isEntry": false,
"imports": [
"houseplan-assets/houseplan-card-CDzf9V5z.js"
"houseplan-assets/houseplan-card-BOdiRDFR.js"
],
"dynamicImports": []
},
{
"path": "houseplan-assets/summary-panel-runtime-loaded-BcDAIp5L.js",
"sha256": "82d20ca0d38461911e5fc0a9aa44da29fdd680fceaa82927f1044df649698fa2",
"path": "houseplan-assets/summary-panel-runtime-loaded-CcLP5B5v.js",
"sha256": "7db94205b54996355041487465d6bade0530e5ac0d13a0eb9b7645086171ce58",
"rawBytes": 73476,
"gzipBytes": 20486,
"gzipBytes": 20491,
"isEntry": false,
"imports": [
"houseplan-assets/form-kit.styles-Dq1Y4tz1.js",
"houseplan-assets/houseplan-card-CDzf9V5z.js"
"houseplan-assets/form-kit.styles-B6HsmMPA.js",
"houseplan-assets/houseplan-card-BOdiRDFR.js"
],
"dynamicImports": [
"houseplan-assets/summary-panel-editor-CgZXeEXz.js",
"houseplan-assets/summary-panel-metrics-DpgEBDDi.js"
"houseplan-assets/summary-panel-editor-BZnGwuVh.js",
"houseplan-assets/summary-panel-metrics-D_ZXPJxz.js"
]
},
{
"path": "houseplan-assets/support-de-DF73IEHL.js",
"sha256": "8407d526294bc1a2f2a83da0b70bf03c2d28d37daac7b0b2b7c561f32e52ed12",
"path": "houseplan-assets/support-de-haZQ7q8i.js",
"sha256": "f377e9d552978c850f069eeb05b20c7572f81c7a8c7b2d60838a7907f1c2b3ef",
"rawBytes": 6167,
"gzipBytes": 2396,
"gzipBytes": 2400,
"isEntry": false,
"imports": [],
"dynamicImports": []
},
{
"path": "houseplan-assets/support-fr-BBhMT3I0.js",
"sha256": "59eb34e74a98bac8905fd10e02eecd955a9cf7727685d3a70d8657f739457af0",
"path": "houseplan-assets/support-fr-DnRyZ_Ga.js",
"sha256": "bb66f839f3b63a74212dc83d273db535dd4597e5f43c5c1b35f0e1fac401e424",
"rawBytes": 6333,
"gzipBytes": 2430,
"gzipBytes": 2433,
"isEntry": false,
"imports": [],
"dynamicImports": []
},
{
"path": "houseplan-assets/support-ru-Bd7vkOXI.js",
"sha256": "0c32195ce4c911d2fb90831144b44ac7d406f6adc80555210d1e1d1ee1d5dd37",
"path": "houseplan-assets/support-ru-B7zzXsuL.js",
"sha256": "63ec59059f3a10c994e4292c4c2b125bb7b2916326dbae27f9975c14be008822",
"rawBytes": 8376,
"gzipBytes": 2876,
"gzipBytes": 2878,
"isEntry": false,
"imports": [],
"dynamicImports": []
},
{
"path": "houseplan-assets/tools-de-DwmzTHwi.js",
"sha256": "3d296ea3821fbe12df454c6042745746b9db49090cbfb10afe9ace758c7ccc06",
"path": "houseplan-assets/tools-de-CYXPPfUH.js",
"sha256": "411c98cf876e42d7255882d0faa486602453f871d443b0c2b59c22e3b2552efb",
"rawBytes": 4130,
"gzipBytes": 1375,
"gzipBytes": 1378,
"isEntry": false,
"imports": [],
"dynamicImports": []
},
{
"path": "houseplan-assets/tools-fr-Dp5JXY-G.js",
"sha256": "31b0111901af3654a491997ff9d993ec907a48a90fa193bcc70026ba063e2cf4",
"path": "houseplan-assets/tools-fr-DvygRB10.js",
"sha256": "f7d35402d5f3504baa8c00dc8bd5170487535c1b87f9a8367a28e332cda92bf2",
"rawBytes": 4136,
"gzipBytes": 1358,
"gzipBytes": 1360,
"isEntry": false,
"imports": [],
"dynamicImports": []
},
{
"path": "houseplan-assets/tools-ru-CAQB2Qhv.js",
"sha256": "c6bf82ded09db3f8238f44d138467839a3483de829d26a7be2e51c42240fcbcb",
"path": "houseplan-assets/tools-ru-2xmu2w_8.js",
"sha256": "14e6c4c22d615293903fc4f25d831f0af042b4e48234d4f2e114ef7d8817d57a",
"rawBytes": 5633,
"gzipBytes": 1695,
"gzipBytes": 1697,
"isEntry": false,
"imports": [],
"dynamicImports": []
},
{
"path": "houseplan-assets/topology-de-DFY0lBO-.js",
"sha256": "562f694c384b9e9df72b61f1b4d2ec05f7bc410576e46ea422f1eeab6c1dbd8e",
"path": "houseplan-assets/topology-de-COda8n9n.js",
"sha256": "88ff4a8cccc94e3eba040af628d9a85db664cbf20586f95704e0823a6215c1f9",
"rawBytes": 2698,
"gzipBytes": 1337,
"gzipBytes": 1336,
"isEntry": false,
"imports": [],
"dynamicImports": []
},
{
"path": "houseplan-assets/topology-fr-DbNDk6Er.js",
"sha256": "282a3d6bbd74abb3aa2a675d2b73793a41de1beef18b1e85298919985b6347d6",
"path": "houseplan-assets/topology-fr-BT9yhzay.js",
"sha256": "60cb68c5c9086ec5f4901627a6baa3e3c8cdfda430b0977622b260984122fcfa",
"rawBytes": 2718,
"gzipBytes": 1354,
"gzipBytes": 1356,
"isEntry": false,
"imports": [],
"dynamicImports": []
},
{
"path": "houseplan-assets/topology-ru-BNVYY-_i.js",
"sha256": "4ce8c7f4383b7724a1b0aff888b57ff1ca8d477df125a3b57f522dea2319ea23",
"path": "houseplan-assets/topology-ru-C-d06yvD.js",
"sha256": "ca9a68f252b8275c954ae7ff7ea56d07a8ea5cf14f18eaac285fd0c63a7bad8f",
"rawBytes": 3669,
"gzipBytes": 1614,
"gzipBytes": 1615,
"isEntry": false,
"imports": [],
"dynamicImports": []
},
{
"path": "houseplan-assets/zigbee-topology-Co7YPeRf.js",
"sha256": "16d9fe1e49fa01d791803f5753c238716e1a3f6da5103c6291c9618f89ac63a0",
"path": "houseplan-assets/zigbee-topology-BG_a6cIb.js",
"sha256": "98d8e54ec59e2d1810b124a0a0c6c2f528c112ab17d12bc3c0a129e13c456c72",
"rawBytes": 10958,
"gzipBytes": 4303,
"gzipBytes": 4298,
"isEntry": false,
"imports": [
"houseplan-assets/houseplan-card-CDzf9V5z.js",
"houseplan-assets/namespace-language-BPjMJUHI.js"
"houseplan-assets/houseplan-card-BOdiRDFR.js",
"houseplan-assets/namespace-language-D86tJUeD.js"
],
"dynamicImports": [
"houseplan-assets/topology-de-DFY0lBO-.js",
"houseplan-assets/topology-fr-DbNDk6Er.js",
"houseplan-assets/topology-ru-BNVYY-_i.js"
"houseplan-assets/topology-de-COda8n9n.js",
"houseplan-assets/topology-fr-BT9yhzay.js",
"houseplan-assets/topology-ru-C-d06yvD.js"
]
},
{
"path": "houseplan-assets/zigbee-topology-runtime-ByS3kW9n.js",
"sha256": "64f6de7adc3876b915c7472f31d0ffad421271c48161a29e8390b10d85519e1e",
"path": "houseplan-assets/zigbee-topology-runtime-CynQ2m3K.js",
"sha256": "966ef9fa87888f0ed561d1061b36f0192c27700f040305ae038fe9509c7a7e33",
"rawBytes": 3983,
"gzipBytes": 1790,
"gzipBytes": 1789,
"isEntry": false,
"imports": [
"houseplan-assets/houseplan-card-CDzf9V5z.js",
"houseplan-assets/namespace-language-BPjMJUHI.js",
"houseplan-assets/zigbee-topology-Co7YPeRf.js"
"houseplan-assets/houseplan-card-BOdiRDFR.js",
"houseplan-assets/namespace-language-D86tJUeD.js",
"houseplan-assets/zigbee-topology-BG_a6cIb.js"
],
"dynamicImports": []
},
{
"path": "houseplan-card.js",
"sha256": "b22eafb488fd6cdc7ff797b48887d9c469f0aed1868da22b21ed992fa2187bdc",
"sha256": "80338f4a64b84431f95438482aeabe1cc6b0f399ccb0c600b318c0f6e6cccc38",
"rawBytes": 1205,
"gzipBytes": 803,
"gzipBytes": 804,
"isEntry": true,
"imports": [
"houseplan-assets/houseplan-card-CDzf9V5z.js"
"houseplan-assets/houseplan-card-BOdiRDFR.js"
],
"dynamicImports": []
},
{
"path": "houseplan-panel.js",
"sha256": "5295cb11c681c7c7f0d97bb4b9d3ab22ee16735463b7af56d6c59a67622a811c",
"sha256": "ce8c313af85073d1c54ccc74e2111c1f14c5d8e3e8539bc59ec436d6d3e0d574",
"rawBytes": 6165,
"gzipBytes": 2324,
"gzipBytes": 2328,
"isEntry": true,
"imports": [
"houseplan-assets/houseplan-card-CDzf9V5z.js"
"houseplan-assets/houseplan-card-BOdiRDFR.js"
],
"dynamicImports": []
}
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1,14 +1,14 @@
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="fd4a405e9c5a21035258c45feca26dca03d59d4cfba4280f89ff5f82675515ac";import{aG as e,l as o,aJ as t,eD as s,A as a,eE as i,eF as l,eG as n,E as r,c}from"./houseplan-card-CDzf9V5z.js";class f 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,f={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")},h=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__="ab07da35681c15ab6136c323500b69766580ea4a788e399ea88f9e7497549172";import{aG as e,l as o,aJ as t,eE as s,A as a,eF as i,eG as l,eH as n,E as r,c}from"./houseplan-card-BOdiRDFR.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")},_=this._schema,f=function(e,o,t){if(!t||null===o)return null;const s="string"==typeof e?.default_floor?e.default_floor:"";return!s||o.some(e=>e.value===s)?null:s}(this._config,this._spaces,this._spacesAuthoritative),u=e=>c`<ha-form
.hass=${this.hass}
.data=${this._formData}
.schema=${e}
.computeLabel=${e=>f[e.name]||e.name}
.computeLabel=${e=>h[e.name]||e.name}
@value-changed=${this._valueChanged}
></ha-form>`;return c`
${d(h.slice(0,3))}
${_?c`<div class="default-floor-error" role="alert"
${u(_.slice(0,3))}
${f?c`<div class="default-floor-error" role="alert"
style="color:var(--error-color,#db4437);margin:-4px 0 12px;overflow-wrap:anywhere">
${t(s,"editor.default_floor_missing",{id:_})}
${t(s,"editor.default_floor_missing",{id:f})}
</div>`:a}
${d(h.slice(3))}
`}_valueChanged(e){const o={...this._config,...e.detail.value};""===o.floor?delete o.floor:o.floor===this._floorToken&&(o.floor=this._config?.floor);const t=new Event("config-changed",{bubbles:!0,composed:!0});t.detail={config:o},this.dispatchEvent(t)}}f.properties={hass:{attribute:!1},_config:{state:!0},_spaces:{state:!0}},customElements.get("houseplan-card-editor")||customElements.define("houseplan-card-editor",f);
${u(_.slice(3))}
`}_valueChanged(e){const o={...this._config,...e.detail.value};""===o.floor?delete o.floor:o.floor===this._floorToken&&(o.floor=this._config?.floor);const t=new Event("config-changed",{bubbles:!0,composed:!0});t.detail={config:o},this.dispatchEvent(t)}}h.properties={hass:{attribute:!1},_config:{state:!0},_spaces:{state:!0}},customElements.get("houseplan-card-editor")||customElements.define("houseplan-card-editor",h);
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 +1 @@
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="fd4a405e9c5a21035258c45feca26dca03d59d4cfba4280f89ff5f82675515ac";var e={"led.tool":"LED-Streifen","led.hint":"Zeichnen Sie den Streifen Punkt für Punkt entlang der Wandflächen oder über den Boden; er rastet am Raster und an Wandflächen ein. Danach wählen Sie das Gerät, das er darstellt.","led.start":"Klicken, um den Streifen zu beginnen","led.start_touch":"Tippen, um den Streifen zu beginnen","led.points":"Punkte: {n} · Umschalt — 45°-Schritte · Esc — fertig · Strg+Z — Punkt entfernen","led.points_touch":"Punkte: {n} · Werkzeug wechseln zum Beenden","led.finish":"Fertig","led.stopped":"Der Streifen stößt an eine Wand","led.unbound":"Streifen ist mit keinem Gerät verbunden","led.bind":"Gerät verbinden","led.change":"Gerät wechseln","led.later":"Später","led.unbind":"Trennen","led.delete":"Streifen löschen","led.settings":"Geräteeinstellungen","led.type_note":"LED-Streifen: Form im Geräte-Editor auf dem Plan bearbeiten","led.show_strip":"Als LED-Streifen zeigen","led.show_icon":"Als Symbol zeigen","led.cancel":"Abbrechen","led.taken":"Bereits mit einem anderen LED-Streifen verbunden","led.space":"Zuerst den LED-Streifen lösen: Er gehört zu seinem Bereich","led.limit_points":"Höchstens 50 Punkte pro Streifen","led.limit_strips":"Höchstens 50 Streifen pro Bereich","led.pick_title":"Gerät für den Streifen wählen","led.pick_new":"Neues Gerät…","led.pick_empty":"Auf diesem Plan gibt es noch keine freien Geräte.","led.saved":"LED-Streifen gespeichert","led.save_failed":"Streifen nicht gespeichert: {err}","led.history_draw":"LED-Streifen","led.history_shape":"Form des LED-Streifens","led.history_view":"Darstellung des Geräts","led.optimize_walls":"Streifen durch Wände: {n} ({spaces})"};const n="fd4a405e9c5a21035258c45feca26dca03d59d4cfba4280f89ff5f82675515ac";export{e as dictionary,n as fingerprint};
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="ab07da35681c15ab6136c323500b69766580ea4a788e399ea88f9e7497549172";var e={"led.tool":"LED-Streifen","led.hint":"Zeichnen Sie den Streifen Punkt für Punkt entlang der Wandflächen oder über den Boden; er rastet am Raster und an Wandflächen ein. Danach wählen Sie das Gerät, das er darstellt.","led.start":"Klicken, um den Streifen zu beginnen","led.start_touch":"Tippen, um den Streifen zu beginnen","led.points":"Punkte: {n} · Umschalt — 45°-Schritte · Esc — fertig · Strg+Z — Punkt entfernen","led.points_touch":"Punkte: {n} · Werkzeug wechseln zum Beenden","led.finish":"Fertig","led.stopped":"Der Streifen stößt an eine Wand","led.unbound":"Streifen ist mit keinem Gerät verbunden","led.bind":"Gerät verbinden","led.change":"Gerät wechseln","led.later":"Später","led.unbind":"Trennen","led.delete":"Streifen löschen","led.settings":"Geräteeinstellungen","led.type_note":"LED-Streifen: Form im Geräte-Editor auf dem Plan bearbeiten","led.show_strip":"Als LED-Streifen zeigen","led.show_icon":"Als Symbol zeigen","led.cancel":"Abbrechen","led.taken":"Bereits mit einem anderen LED-Streifen verbunden","led.space":"Zuerst den LED-Streifen lösen: Er gehört zu seinem Bereich","led.limit_points":"Höchstens 50 Punkte pro Streifen","led.limit_strips":"Höchstens 50 Streifen pro Bereich","led.pick_title":"Gerät für den Streifen wählen","led.pick_new":"Neues Gerät…","led.pick_empty":"Auf diesem Plan gibt es noch keine freien Geräte.","led.saved":"LED-Streifen gespeichert","led.save_failed":"Streifen nicht gespeichert: {err}","led.history_draw":"LED-Streifen","led.history_shape":"Form des LED-Streifens","led.history_view":"Darstellung des Geräts","led.optimize_walls":"Streifen durch Wände: {n} ({spaces})"};const n="ab07da35681c15ab6136c323500b69766580ea4a788e399ea88f9e7497549172";export{e as dictionary,n as fingerprint};
@@ -1 +1 @@
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="fd4a405e9c5a21035258c45feca26dca03d59d4cfba4280f89ff5f82675515ac";var e={"led.tool":"Ruban LED","led.hint":"Tracez le ruban point par point le long des faces des murs ou sur le sol ; il s’aimante à la grille et aux faces des murs. Ensuite, choisissez l’appareil qu’il représente.","led.start":"Cliquez pour commencer le ruban","led.start_touch":"Touchez pour commencer le ruban","led.points":"Points : {n} · Maj — pas de 45° · Échap — terminer · Ctrl+Z — retirer le point","led.points_touch":"Points : {n} · changez d’outil pour terminer","led.finish":"Terminer","led.stopped":"Le ruban bute contre un mur","led.unbound":"Ruban non lié à un appareil","led.bind":"Lier un appareil","led.change":"Changer d’appareil","led.later":"Plus tard","led.unbind":"Délier","led.delete":"Supprimer le ruban","led.settings":"Réglages de l’appareil","led.type_note":"Ruban LED : modifiez sa forme sur le plan dans l’éditeur d’appareils","led.show_strip":"Afficher en ruban LED","led.show_icon":"Afficher en icône","led.cancel":"Annuler","led.taken":"Déjà lié à un autre ruban LED","led.space":"Détachez d’abord le ruban LED : il appartient à son espace","led.limit_points":"50 points au maximum par ruban","led.limit_strips":"50 rubans au maximum par espace","led.pick_title":"Choisissez l’appareil du ruban","led.pick_new":"Nouvel appareil…","led.pick_empty":"Aucun appareil libre sur ce plan pour l’instant.","led.saved":"Ruban LED enregistré","led.save_failed":"Ruban non enregistré : {err}","led.history_draw":"Ruban LED","led.history_shape":"Forme du ruban LED","led.history_view":"Représentation de l’appareil","led.optimize_walls":"Rubans traversant des murs : {n} ({spaces})"};const a="fd4a405e9c5a21035258c45feca26dca03d59d4cfba4280f89ff5f82675515ac";export{e as dictionary,a as fingerprint};
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="ab07da35681c15ab6136c323500b69766580ea4a788e399ea88f9e7497549172";var e={"led.tool":"Ruban LED","led.hint":"Tracez le ruban point par point le long des faces des murs ou sur le sol ; il s’aimante à la grille et aux faces des murs. Ensuite, choisissez l’appareil qu’il représente.","led.start":"Cliquez pour commencer le ruban","led.start_touch":"Touchez pour commencer le ruban","led.points":"Points : {n} · Maj — pas de 45° · Échap — terminer · Ctrl+Z — retirer le point","led.points_touch":"Points : {n} · changez d’outil pour terminer","led.finish":"Terminer","led.stopped":"Le ruban bute contre un mur","led.unbound":"Ruban non lié à un appareil","led.bind":"Lier un appareil","led.change":"Changer d’appareil","led.later":"Plus tard","led.unbind":"Délier","led.delete":"Supprimer le ruban","led.settings":"Réglages de l’appareil","led.type_note":"Ruban LED : modifiez sa forme sur le plan dans l’éditeur d’appareils","led.show_strip":"Afficher en ruban LED","led.show_icon":"Afficher en icône","led.cancel":"Annuler","led.taken":"Déjà lié à un autre ruban LED","led.space":"Détachez d’abord le ruban LED : il appartient à son espace","led.limit_points":"50 points au maximum par ruban","led.limit_strips":"50 rubans au maximum par espace","led.pick_title":"Choisissez l’appareil du ruban","led.pick_new":"Nouvel appareil…","led.pick_empty":"Aucun appareil libre sur ce plan pour l’instant.","led.saved":"Ruban LED enregistré","led.save_failed":"Ruban non enregistré : {err}","led.history_draw":"Ruban LED","led.history_shape":"Forme du ruban LED","led.history_view":"Représentation de l’appareil","led.optimize_walls":"Rubans traversant des murs : {n} ({spaces})"};const a="ab07da35681c15ab6136c323500b69766580ea4a788e399ea88f9e7497549172";export{e as dictionary,a as fingerprint};
@@ -1 +1 @@
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="fd4a405e9c5a21035258c45feca26dca03d59d4cfba4280f89ff5f82675515ac";var e={"led.tool":"LED-лента","led.hint":"Нарисуйте ленту по точкам вдоль граней стен или по полу — она прилипает к сетке и граням. После завершения выберите устройство, которое она показывает.","led.start":"Нажмите, чтобы начать ленту","led.start_touch":"Коснитесь, чтобы начать ленту","led.points":"Точек: {n} · Shift — шаг 45° · Esc — завершить · Ctrl+Z — убрать точку","led.points_touch":"Точек: {n} · смените инструмент, чтобы завершить","led.finish":"Завершить","led.stopped":"Лента упёрлась в стену","led.unbound":"Лента не привязана к устройству","led.bind":"Привязать устройство","led.change":"Сменить устройство","led.later":"Позже","led.unbind":"Отвязать","led.delete":"Удалить ленту","led.settings":"Настройки устройства","led.type_note":"LED-лента: форма редактируется на плане в редакторе устройств","led.show_strip":"Показывать LED-лентой","led.show_icon":"Показывать значком","led.cancel":"Отмена","led.taken":"Уже привязано к другой LED-ленте","led.space":"Сначала отвяжите LED-ленту: она принадлежит своему пространству","led.limit_points":"Не более 50 точек в ленте","led.limit_strips":"Не более 50 лент в пространстве","led.pick_title":"Выберите устройство для ленты","led.pick_new":"Новое устройство…","led.pick_empty":"На этом плане пока нет свободных устройств.","led.saved":"LED-лента сохранена","led.save_failed":"Лента не сохранена: {err}","led.history_draw":"LED-лента","led.history_shape":"Форма LED-ленты","led.history_view":"Вид устройства","led.optimize_walls":"Лент, проходящих сквозь стены: {n} ({spaces})"};const d="fd4a405e9c5a21035258c45feca26dca03d59d4cfba4280f89ff5f82675515ac";export{e as dictionary,d as fingerprint};
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="ab07da35681c15ab6136c323500b69766580ea4a788e399ea88f9e7497549172";var e={"led.tool":"LED-лента","led.hint":"Нарисуйте ленту по точкам вдоль граней стен или по полу — она прилипает к сетке и граням. После завершения выберите устройство, которое она показывает.","led.start":"Нажмите, чтобы начать ленту","led.start_touch":"Коснитесь, чтобы начать ленту","led.points":"Точек: {n} · Shift — шаг 45° · Esc — завершить · Ctrl+Z — убрать точку","led.points_touch":"Точек: {n} · смените инструмент, чтобы завершить","led.finish":"Завершить","led.stopped":"Лента упёрлась в стену","led.unbound":"Лента не привязана к устройству","led.bind":"Привязать устройство","led.change":"Сменить устройство","led.later":"Позже","led.unbind":"Отвязать","led.delete":"Удалить ленту","led.settings":"Настройки устройства","led.type_note":"LED-лента: форма редактируется на плане в редакторе устройств","led.show_strip":"Показывать LED-лентой","led.show_icon":"Показывать значком","led.cancel":"Отмена","led.taken":"Уже привязано к другой LED-ленте","led.space":"Сначала отвяжите LED-ленту: она принадлежит своему пространству","led.limit_points":"Не более 50 точек в ленте","led.limit_strips":"Не более 50 лент в пространстве","led.pick_title":"Выберите устройство для ленты","led.pick_new":"Новое устройство…","led.pick_empty":"На этом плане пока нет свободных устройств.","led.saved":"LED-лента сохранена","led.save_failed":"Лента не сохранена: {err}","led.history_draw":"LED-лента","led.history_shape":"Форма LED-ленты","led.history_view":"Вид устройства","led.optimize_walls":"Лент, проходящих сквозь стены: {n} ({spaces})"};const l="ab07da35681c15ab6136c323500b69766580ea4a788e399ea88f9e7497549172";export{e as dictionary,l as fingerprint};
File diff suppressed because one or more lines are too long
-31
View File
@@ -1,31 +0,0 @@
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="fd4a405e9c5a21035258c45feca26dca03d59d4cfba4280f89ff5f82675515ac";import{eT as e,eU as t,az as s,eV as n,eW as a,eO as i,A as r,eX as o,eY as c,eZ as l,e as p,i as d,E as h}from"./houseplan-card-CDzf9V5z.js";import{i as u,k as f,m as $}from"./led-strip-geometry-BcPfXtN-.js";const g=p(class extends d{constructor(e){super(e),this.deps=null}render(e,t){return t()}update(e,[t,s]){return this.deps&&this.deps.length===t.length&&t.every((e,t)=>e===this.deps[t])?h:(this.deps=t,s())}}),m="fd4a405e9c5a21035258c45feca26dca03d59d4cfba4280f89ff5f82675515ac",w=48,M=e=>e.map(e=>[e[0],e[1]]);class k{constructor(e=50){this.limit=e,this.entries=new Map,this.space="",this.recomputes=0,this.ids=new Map}get size(){return this.entries.size}id(e){let t=this.ids.get(e);return null==t&&(t=this.ids.size+1,this.ids.set(e,t)),t}forSpace(e){e!==this.space&&(this.entries.clear(),this.ids.clear(),this.space=e)}read(e,t){if(this.entries.has(e)){const t=this.entries.get(e)??null;return this.entries.delete(e),this.entries.set(e,t),t}this.recomputes+=1;const s=t();for(this.entries.set(e,s);this.entries.size>this.limit;){const e=this.entries.keys().next().value;if(void 0===e)break;this.entries.delete(e)}return s}clear(){this.entries.clear(),this.ids.clear(),this.space=""}get sources(){let e=0;for(const t of this.entries.values())for(const s of t?.pieces||[])e+=s.clip?.length??0;return e}}const y=e=>{const t=Math.round(1e4*e)/1e4;return Object.is(t,-0)?"0":String(t)},x=e=>`${e.map((e,t)=>`${t?"L":"M"}${y(e[0])} ${y(e[1])}`).join(" ")} Z`;function v(e,t,s){const n=1.01*t;return s.occluders.some(t=>t?.length>=4&&e.some(e=>((e,t)=>{const s=t[2]-t[0],n=t[3]-t[1],a=s*s+n*n,i=a?Math.max(0,Math.min(1,((e[0]-t[0])*s+(e[1]-t[1])*n)/a)):0;return Math.hypot(e[0]-t[0]-i*s,e[1]-t[1]-i*n)})(e,t)<n))?e.map(e=>o([e[0],e[1]],t,s.occluders,12)).filter(e=>e.length>=3).map(x):null}const b=new WeakMap;function I(e){const t=u(M(e.points));if(t.length<2||!(e.radius>0))return null;const s=e.radius,n=f(t),a=`${(n?t.slice(0,-1):t).map((e,t)=>`${t?"L":"M"}${y(e[0])} ${y(e[1])}`).join(" ")}${n?" Z":""}`,i=[];let r=[t[0]],o=s;for(let e=1;e<t.length;e++){let n=t[e-1];const a=t[e];let c=Math.hypot(a[0]-n[0],a[1]-n[1]);for(;c>o+1e-12;){const e=o/c,t=[n[0]+(a[0]-n[0])*e,n[1]+(a[1]-n[1])*e];r.push(t),i.push(r),r=[t],n=t,c-=o,o=s}r.push(a),o-=c}r.length>1&&i.push(r);const c=[];let l=1/0,p=1/0,d=-1/0,h=-1/0;for(const t of i){const n=[];for(const a of $(t,e.faces,s/4)){const e=n[n.length-1];(!e||Math.hypot(a[0]-e[0],a[1]-e[1])>=s/4)&&n.push(a)}if(!n.length)continue;let a;try{a=v(n,s,e.scene)}catch{continue}if(!a||a.length){c.push({d:t.map((e,t)=>`${t?"L":"M"}${y(e[0])} ${y(e[1])}`).join(" "),clip:a});for(const e of t)l=Math.min(l,e[0]),p=Math.min(p,e[1]),d=Math.max(d,e[0]),h=Math.max(h,e[1])}}return c.length?{d:a,pieces:c,box:{x:l-s,y:p-s,w:d-l+2*s,h:h-p+2*s}}:null}function U(t){const s=100*Math.max(0,Math.min(1,t));for(let t=1;t<e.length;t++){const[n,a]=e[t-1],[i,r]=e[t];if(s<=i)return a+(r-a)*(s-n)/Math.max(1e-9,i-n)}return 0}const j=new WeakMap,z=new WeakMap;function S(e){j.get(e)?.clear(),j.delete(e);const s=z.get(e);s&&t(s.state,s.host),z.delete(e)}function q(e){return!!z.get(e)?.state.renderedSources.size}function C(e){const t=j.get(e);return{visibility:t?.size??0,sources:t?.sources??0,recomputes:t?.recomputes??0}}function P(e){let t=j.get(e);return t||(t=new k,j.set(e,t)),t}function _(e){if(!e.scene)return s``;const t=P(e.owner);t.forSpace(e.spaceId);const o=function(e){let t=z.get(e.owner);if(t)t.callbacks.requestUpdate=e.requestUpdate,t.callbacks.isConnected=e.isConnected,t.callbacks.reducedMotion=e.reducedMotion;else{const s={requestUpdate:e.requestUpdate,isConnected:e.isConnected,reducedMotion:e.reducedMotion},n={window:()=>window,isConnected:()=>s.isConnected(),requestUpdate:()=>s.requestUpdate(),reducedMotion:()=>s.reducedMotion?.()??window.matchMedia?.("(prefers-reduced-motion: reduce)").matches??!1};t={state:c(),host:n,callbacks:s,spaceId:""},z.set(e.owner,t)}return t.spaceId&&t.spaceId!==e.spaceId&&l(t.state,t.host,t.spaceId),t.spaceId=e.spaceId,t}(e),p=e.scene,d=new Set,h=e.views.flatMap(s=>{const a=`${e.spaceId}|${s.strip.id}`;d.add(a);const i=s.glow&&"on"===s.state&&!!s.appearance,r=n(o.state,o.host,a,i);if(!r)return[];i&&s.appearance&&o.state.lastAppearance.set(a,s.appearance);const c=i?s.appearance:o.state.lastAppearance.get(a)??null;if(!c)return[];const l=`${s.strip.id}|${h=s.strip.points,h.map(e=>`${e[0].toFixed(5)},${e[1].toFixed(5)}`).join(";")}|${s.radius.toFixed(5)}|${p.fingerprint}`;var h;const u=t.read(l,()=>I({points:s.strip.points,radius:s.radius,scene:p,polygons:e.polygons,faces:e.faces,spaceId:e.spaceId}));return u?[{view:{...s,appearance:c},geometry:u,transition:r}]:[]});if(a(o.state,o.host,e.spaceId,d),!h.length)return s``;const u=Array.from({length:48},(e,t)=>{const s=1-t/48;return{half:s,value:U((s+(1-(t+1)/48))/2)}});return s`<g class="led-fields" pointer-events="none" aria-hidden="true"
data-led-cache="${t.size}" data-led-recomputes="${t.recomputes}">
<defs><clipPath id="hp-led-floor">${function(e){let t=b.get(e);return t||(t=e.floor.filter(e=>e.length>=3).map(x),b.set(e,t)),t}(p).map(e=>s`<path d="${e}"></path>`)}</clipPath></defs>
<g clip-path="url(#hp-led-floor)">
${i(h,({view:e})=>e.strip.id,({view:e,geometry:n,transition:a})=>{const i=`${t.id(e.strip.id)}`,o=e.radius,c=n.box,l=f(M(e.strip.points)),p=n.pieces.filter(e=>!!e.clip),d=n.pieces.filter(e=>!e.clip),h=p.length>0;return g([n,a.entering,a.leaving,e.appearance.c,e.appearance.alpha,o,i],()=>s`<g
class="glow-spot led-field ${a.entering?"is-entering":""} ${a.leaving?"is-leaving":""}"
data-led-field="${e.strip.id}" data-led-phase="${a.entering?"entering":a.leaving?"leaving":"visible"}"
data-pieces="${n.pieces.length}" data-bands="${48}"
data-closed="${l?"true":"false"}">
<defs>
${h?s`<clipPath id="hp-led-visible-${i}">
${d.map(e=>s`<path d="${e.d}" fill="none" stroke="white"
stroke-width="${2*o}" stroke-linecap="round" stroke-linejoin="round"></path>`)}
${p.map(e=>s`<path d="${e.clip.join(" ")}"></path>`)}
</clipPath>`:r}
<mask id="hp-led-mask-${i}" maskUnits="userSpaceOnUse"
x="${c.x}" y="${c.y}" width="${c.w}" height="${c.h}"
color-interpolation="sRGB" style="mask-type:luminance">
<rect x="${c.x}" y="${c.y}" width="${c.w}" height="${c.h}" fill="black"></rect>
<g clip-path=${h?`url(#hp-led-visible-${i})`:r}>
${u.map(e=>s`<path d="${n.d}" fill="none" stroke="${(e=>{const t=Math.round(255*Math.max(0,Math.min(1,e)));return`rgb(${t},${t},${t})`})(e.value)}"
stroke-width="${2*e.half*o}" stroke-linecap="round" stroke-linejoin="round"></path>`)}
</g>
</mask>
</defs>
<rect class="glow-pool led-pool" x="${c.x}" y="${c.y}" width="${c.w}" height="${c.h}"
fill="${e.appearance?.c??"transparent"}" fill-opacity="${(e.appearance?.alpha??0).toFixed(4)}"
mask="url(#hp-led-mask-${i})"></rect>
</g>`)})}
</g>
</g>`}export{w as LED_FIELD_BANDS,m as LED_FIELD_FINGERPRINT,k as LedFieldCache,I as buildFieldGeometry,U as falloffAt,q as hasLedField,P as ledFieldCache,C as ledFieldStats,S as releaseLedField,_ as renderLedField};
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
+47
View File
@@ -0,0 +1,47 @@
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="ab07da35681c15ab6136c323500b69766580ea4a788e399ea88f9e7497549172";import{eu as e,eC as t,c6 as o,eJ as s,eK as i,ad as n,ee as a,O as r,eL as l,az as d,ef as c,aL as p,eM as u,eN as h,eO as f,A as m,eP as v}from"./houseplan-card-BOdiRDFR.js";import{L as g,v as w,s as $,a as _,b as y,p as k,c as b,d as C,e as P}from"./led-strip-geometry-DaLifxqY.js";const M="ab07da35681c15ab6136c323500b69766580ea4a788e399ea88f9e7497549172";let F,L=null,U=null;function x(e,t){return L||U||F===e||""===F||(U=(void 0===F?import("./led-strip-field-ObbckCkp.js"):import(new URL(`./led-strip-field-ObbckCkp.js?${Date.now()}`,import.meta.url).href)).then(e=>{e.LED_FIELD_FINGERPRINT===s?L=e:F=""},()=>{F=e}).finally(()=>{U=null})),L||U?.then(()=>L&&t()),L}const D=e=>e.some(e=>e.glow&&"on"===e.state),R=e=>e.map(e=>[e[0],e[1]]),E="#383838";function A(s,i){if(!s)return null;const n=Array.isArray(s.masonryGeometry)?s.masonryGeometry:[],a=[...e(s.masonryGeometry),...s.opaqueBodies],r=[];for(const e of a)for(let t=0;t<e.length;t++){const o=e[t],s=e[(t+1)%e.length];o&&s&&r.push({a:[o[0],o[1]],b:[s[0],s[1]]})}const l=25,d=new Map;r.forEach((e,t)=>{const o=Math.floor(Math.min(e.a[0],e.b[0])/l),s=Math.floor(Math.max(e.a[0],e.b[0])/l),i=Math.floor(Math.min(e.a[1],e.b[1])/l),n=Math.floor(Math.max(e.a[1],e.b[1])/l);for(let e=o;e<=s;e++)for(let o=i;o<=n;o++){const s=`${e},${o}`,i=d.get(s);i?i.push(t):d.set(s,[t])}});const c=e=>{let t=1/0,o=1/0,s=-1/0,i=-1/0;for(const n of e)t=Math.min(t,n[0]),o=Math.min(o,n[1]),s=Math.max(s,n[0]),i=Math.max(i,n[1]);return[t,o,s,i]},p=(e,t)=>e[0]>=t[0]&&e[0]<=t[2]&&e[1]>=t[1]&&e[1]<=t[3],u=n.filter(e=>e?.[0]?.length).map(e=>({box:c(e[0]),poly:e})),h=s.opaqueBodies.map(e=>({box:c(e),body:e}));return{faces:r,inside:e=>u.some(({box:o,poly:s})=>p(e,o)&&t([e[0],e[1]],[s]))||h.some(({box:t,body:s})=>p(e,t)&&o([e[0],e[1]],s)),epsilon:i,near:e=>{const t=new Set;for(let o=Math.floor(e[0]/l);o<=Math.floor(e[2]/l);o++)for(let s=Math.floor(e[1]/l);s<=Math.floor(e[3]/l);s++)for(const e of d.get(`${o},${s}`)||[])t.add(e);return[...t].map(e=>r[e])}}}function I(e){const t=e.candidate?.sourceEid||e.device.primary||"",o=t?e.hass?.states?.[t]?.state:void 0,s="unavailable"===o||"unknown"===o||!!t&&!!e.hass&&!e.hass.states?.[t]&&!e.device.virtual,i=Number(e.device.marker?.glow_radius_cm),n=Number.isFinite(i)&&i>0?i/e.cellCm*e.gridPitch:e.defaultRadius,a=s?null:e.candidate?.appearance??null;return{strip:e.strip,device:e.device,state:s?"unavailable":a?"on":"off",glow:e.glow,appearance:a,radius:n}}const T=new WeakMap;function j(e,t,o){const s=P*o;const i=T.get(e);if(i&&i.faces===t&&i.epsilon===t?.epsilon&&i.value.t===s&&i.points.length===e.points.length&&i.points.every((t,o)=>t[0]===e.points[o][0]&&t[1]===e.points[o][1]))return i.value;const n=R(e.points),a=y(n,t,s/2),r={t:s,path:a,d:k(a)};return T.set(e,{faces:t,epsilon:t?.epsilon,points:n,value:r}),r}function G(e){if(!e.views.length)return d``;const t=e.handlers,o=[...e.views].sort((e,t)=>e.strip.id<t.strip.id?1:e.strip.id>t.strip.id?-1:0),s=e.iso;return d`<g class="led-strips" data-hp-led-strips="${o.length}"
data-hp-iso=${s?"raised":m}>
${s?d`<defs><filter id="hp-led-iso-shadow" filterUnits="userSpaceOnUse"
x="-100000" y="-100000" width="200000" height="200000">
<feGaussianBlur stdDeviation="${s.shadow.sigma}"></feGaussianBlur></filter></defs>`:m}
<style>
.led-strip .led-focus { fill: none; stroke: transparent; }
.led-strip:has(.led-hit:focus-visible) .led-focus { stroke: var(--primary-color, #03a9f4); }
.led-strip .led-hit { fill: none; stroke: transparent; cursor: pointer; outline: none; }
</style>
${v(o,e=>e.strip.id,o=>{const{t:i,path:n,d:a}=j(o.strip,e.faces,e.d),r="unavailable"===o.state,l=r?"#9e9e9e":"on"===o.state&&!o.glow&&o.appearance?o.appearance.c:"#FFFFFF",c=2*b(i*e.perUnit)/(e.perUnit||1),p=o.device,u=t=>function(e,t,o){const s=e.currentTarget,i=s?.getScreenCTM?.();if(!i||o.views.length<2)return t;const n=i.inverse(),a=[n.a*e.clientX+n.c*e.clientY+n.e,n.b*e.clientX+n.d*e.clientY+n.f],r=o.views.map(e=>{const{t:t,path:s}=j(e.strip,o.faces,o.d);return{id:e.strip.id,points:s.points.map(e=>[e[0]*o.perUnit,e[1]*o.perUnit]),closed:s.closed,thicknessPx:t*o.perUnit}}),l=C([a[0]*o.perUnit,a[1]*o.perUnit],r);return o.views.find(e=>e.strip.id===l)||t}(t,o,e).device,h=s?`translate(0 ${-s.lift})`:m;return d`<g class="led-strip state-${o.state}" data-led-strip="${o.strip.id}"
data-marker="${p.id}" data-state="${o.state}" data-closed="${n.closed?"true":"false"}">
${s?d`<path class="led-iso-shadow" d="${a}" fill="none" stroke="black"
stroke-opacity="${s.shadow.opacity}" stroke-width="${i}" stroke-linecap="round"
stroke-linejoin="round" filter="url(#hp-led-iso-shadow)" pointer-events="none"
transform="translate(${s.shadow.dx} ${s.shadow.dy-s.lift})"></path>
${[1,.5].map(e=>d`<path class="led-iso-edge" d="${a}" fill="none" stroke="${s.edge}"
stroke-width="${i}" stroke-linecap="round" stroke-linejoin="round" pointer-events="none"
transform="translate(0 ${-s.lift+s.depth*e})"></path>`)}`:m}
<g transform=${h}>
<path class="led-outline" d="${a}" fill="none" stroke="${E}" stroke-width="${i}"
stroke-linecap="round" stroke-linejoin="round"
stroke-dasharray=${r?`${2*i} ${1.5*i}`:m}></path>
<path class="led-core" d="${a}" fill="none" stroke="${l}" stroke-width="${i/2}"
stroke-linecap="round" stroke-linejoin="round"
stroke-dasharray=${r?`${2*i} ${1.5*i}`:m}></path>
<path class="led-focus" d="${a}" stroke-width="${1.6*i}" stroke-linecap="round"
stroke-linejoin="round" aria-hidden="true"></path>
${t?d`<path class="led-hit" d="${a}" stroke-width="${c}"
stroke-linecap="round" stroke-linejoin="round" pointer-events="stroke"
role="button" tabindex="0" aria-label="${t.label(p)}"
data-hp="device" data-id="${p.id}"
@click=${e=>t.click(e,u(e))}
@keydown=${e=>t.keydown(e,p)}
@contextmenu=${e=>t.contextmenu(e,u(e))}
@pointerdown=${e=>t.pointerdown(e,u(e))}
@pointermove=${e=>t.pointermove(e,u(e))}
@pointerup=${e=>t.pointerup(e,u(e))}
@pointercancel=${e=>t.pointercancel(e,p)}
@lostpointercapture=${e=>t.pointercancel(e,p)}
@pointerover=${e=>t.pointerover(e,u(e))}
@pointerleave=${()=>t.pointerleave()}
@focus=${e=>t.focus(e,p)}
@blur=${()=>t.blur(p)}></path>`:m}
</g>
</g>`})}
</g>`}function H(e,t,o,s){return(t?e.find(e=>e.id===t):void 0)??(o?e.find(e=>s(o,e)):void 0)}function N(e){const t=new Map(e.devices.map(e=>[e.id,e])),o=g/e.cellCm*e.gridPitch,s=new Map(i({hass:e.hass,devices:e.devices,virtualLights:e.virtualLights,spaceId:e.space.id,defaultColor:e.defaultColor,paletteAlpha:e.paletteAlpha,defaultRadiusUnits:o,cellCm:e.cellCm,gridPitch:e.gridPitch,position:()=>({x:0,y:0})}).map(e=>[e.key,e])),r=[];for(const i of e.space.led_strips||[]){if(!1===i?.active||!i.marker||!w(i.points))continue;const a={...i,points:i.points.map(e=>[e[0]*n,e[1]*n])},l=t.get(a.marker);if(!l||l.space!==e.space.id)continue;if(l.hidden&&!e.showHidden)continue;const d=H(e.space.rooms,l.marker?.room_id,$(R(a.points)),e.inRoom);r.push(I({strip:a,device:l,candidate:s.get(`${e.space.id}|${l.id}`)??null,hass:e.hass,glow:!!d&&e.glowFor(d),defaultRadius:o,cellCm:e.cellCm,gridPitch:e.gridPitch}))}const l=_/e.cellCm*e.gridPitch;return{views:r,faces:A(e.scene,l),d:e.iconPct/100*a(e.space),scene:e.scene,polygons:e.polygons}}const q=new WeakMap;function B(e){for(const t of q.get(e)?.frame.views??[])T.delete(t.strip);q.delete(e),L?.releaseLedField(e)}function S(e){return{shapes:q.get(e)?.frame.views.length??0,...L?.ledFieldStats(e)??{visibility:0,sources:0,visibilityPaths:0,pathChars:0,recomputes:0}}}function O(e,t,o){const s=t.rooms.flatMap(e=>{const t=r(e);return t?[{room:e,poly:t}]:[]}),i=s.length?e._lightBarriers(t,s.map(({room:e,poly:t})=>({r:e,poly:t}))):null,n=[t,e._renderDevices,e._renderPlanHass,o,i,e._mode,e._showAll],a=q.get(e);if(a&&a.key.every((e,t)=>e===n[t]))return a.frame;for(const e of a?.frame.views??[])T.delete(e.strip);const d=e._config?.icon_size??2.5,c=N({space:t,devices:e._renderDevices,hass:e._renderPlanHass,virtualLights:e._virtualLights,defaultColor:e._fillColors.glow_light.c,paletteAlpha:e._fillColors.glow_light.a,cellCm:e._cellCm,gridPitch:e._gridPitch,iconPct:d>8?2.5:d,scene:i,polygons:s,glowFor:e=>l(o,e),inRoom:(t,o)=>e._pointInRoom(t,o),showHidden:"devices"===e._mode&&e._showAll});return!1!==e.isConnected&&q.set(e,{key:n,frame:c}),c}function W(e,t,o,s){const i=O(e,t,o),n=e._stageEl?.clientWidth,a="iso"===e._renderProjection&&"view"===e._mode,r=a?i.d*c:i.d,l="theme-dark"===p(e._renderPlanHass)?"dark":"light",m=!!e._isoLightFloors?.size,v=u(l,m),g=G({views:i.views,d:r,iso:a?{lift:f.lift*r,depth:f.depth*r,edge:h(E,l,m),shadow:{dx:v.dx*r,dy:v.dy*r,sigma:v.sigma*r,opacity:v.opacityWhite}}:null,faces:i.faces,perUnit:n&&s.w?n/s.w:1,handlers:"view"===e._mode?{click:(t,o)=>e._clickDevice(t,o),keydown:(t,o)=>e._keyDevice(t,o),contextmenu:(t,o)=>e._ctxDevice(t,o),pointerdown:(t,o)=>e._pointerDown(t,o),pointermove:(t,o)=>{const s=e._pointerMove(t,o);s&&e._showDeviceTip(t,s)},pointerup:(t,o)=>e._pointerUp(t,o),pointercancel:(t,o)=>e._pointerCancel(t,o),pointerover:(t,o)=>e._showDeviceTip(t,o),pointerleave:()=>e._clearPointerHover(),focus:(t,o)=>e._showDeviceFocusTip(t,o),blur:t=>e._hideDeviceFocusTip(t.id),label:e=>e.name}:null});return"plan"===e._mode||"decor"===e._mode?d`<g class="led-passive" opacity="0.45" pointer-events="none">${g}</g>`:g}function z(e,t,o){if(!1===e.isConnected)return d``;const s=O(e,t,o),i=s.scene&&(D(s.views)||L?.hasLedField(e))?L||x(t.id,()=>!1!==e.isConnected&&e.requestUpdate()):null;return i?i.renderLedField({views:s.views,scene:s.scene,polygons:s.polygons,faces:s.faces,spaceId:t.id,owner:e,requestUpdate:()=>e.requestUpdate(),isConnected:()=>!1!==e.isConnected}):d``}function Y(e){const t=e.space.rooms.flatMap(e=>{const t=r(e);return t?[{room:e,poly:t}]:[]}),o=N({space:e.space,devices:e.devices,hass:e.hass,virtualLights:e.virtualLights,defaultColor:e.defaultColor,paletteAlpha:e.paletteAlpha,cellCm:e.cellCm,gridPitch:e.gridPitch,iconPct:e.iconPct,scene:e.scene,polygons:t,glowFor:e.glowFor,inRoom:e.inRoom,showHidden:!1}),s=e.live?o.views:o.views.map(e=>({...e,state:"off",appearance:null,glow:!1})),i=A({masonryGeometry:e.bodies.masonryGeometry,opaqueBodies:e.bodies.opaqueBodies},_/e.cellCm*e.gridPitch),n=e.scene&&e.live&&(D(s)||L?.hasLedField(e.owner))?x(e.space.id,e.ready):null;return d`${n?n.renderLedField({views:s,scene:e.scene,polygons:t,faces:i,spaceId:e.space.id,owner:e.owner,requestUpdate:e.ready,isConnected:()=>!0}):m}${G({views:s,d:o.d,faces:i,perUnit:e.perUnit,handlers:null})}`}export{M as LED_RUNTIME_FINGERPRINT,A as faceContext,x as ledField,N as ledFrame,O as ledFrameFor,S as ledStats,I as ledStripView,j as ledStripePath,B as releaseLed,z as renderLedFieldFor,W as renderLedLayerFor,G as renderLedStripes,Y as renderStaticLed,H as stripRoom};
-47
View File
@@ -1,47 +0,0 @@
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="fd4a405e9c5a21035258c45feca26dca03d59d4cfba4280f89ff5f82675515ac";import{et as e,eB as t,c6 as o,eI as s,eJ as i,ad as n,ed as a,O as r,eK as l,az as d,ee as c,aL as p,eL as u,eM as h,eN as f,A as m,eO as v}from"./houseplan-card-CDzf9V5z.js";import{L as g,v as w,s as $,a as _,p as y,b as k,c as b,d as C,e as P,f as M}from"./led-strip-geometry-BcPfXtN-.js";const F="fd4a405e9c5a21035258c45feca26dca03d59d4cfba4280f89ff5f82675515ac";let L,U=null,x=null;function D(e,t){return U||x||L===e||""===L||(x=(void 0===L?import("./led-strip-field-DvtQ7tpM.js"):import(new URL(`./led-strip-field-DvtQ7tpM.js?${Date.now()}`,import.meta.url).href)).then(e=>{e.LED_FIELD_FINGERPRINT===s?U=e:L=""},()=>{L=e}).finally(()=>{x=null})),U||x?.then(()=>U&&t()),U}const R=e=>e.some(e=>e.glow&&"on"===e.state),E=e=>e.map(e=>[e[0],e[1]]),A="#383838";function I(s,i){if(!s)return null;const n=Array.isArray(s.masonryGeometry)?s.masonryGeometry:[],a=[...e(s.masonryGeometry),...s.opaqueBodies],r=[];for(const e of a)for(let t=0;t<e.length;t++){const o=e[t],s=e[(t+1)%e.length];o&&s&&r.push({a:[o[0],o[1]],b:[s[0],s[1]]})}const l=25,d=new Map;r.forEach((e,t)=>{const o=Math.floor(Math.min(e.a[0],e.b[0])/l),s=Math.floor(Math.max(e.a[0],e.b[0])/l),i=Math.floor(Math.min(e.a[1],e.b[1])/l),n=Math.floor(Math.max(e.a[1],e.b[1])/l);for(let e=o;e<=s;e++)for(let o=i;o<=n;o++){const s=`${e},${o}`,i=d.get(s);i?i.push(t):d.set(s,[t])}});const c=e=>{let t=1/0,o=1/0,s=-1/0,i=-1/0;for(const n of e)t=Math.min(t,n[0]),o=Math.min(o,n[1]),s=Math.max(s,n[0]),i=Math.max(i,n[1]);return[t,o,s,i]},p=(e,t)=>e[0]>=t[0]&&e[0]<=t[2]&&e[1]>=t[1]&&e[1]<=t[3],u=n.filter(e=>e?.[0]?.length).map(e=>({box:c(e[0]),poly:e})),h=s.opaqueBodies.map(e=>({box:c(e),body:e}));return{faces:r,inside:e=>u.some(({box:o,poly:s})=>p(e,o)&&t([e[0],e[1]],[s]))||h.some(({box:t,body:s})=>p(e,t)&&o([e[0],e[1]],s)),epsilon:i,near:e=>{const t=new Set;for(let o=Math.floor(e[0]/l);o<=Math.floor(e[2]/l);o++)for(let s=Math.floor(e[1]/l);s<=Math.floor(e[3]/l);s++)for(const e of d.get(`${o},${s}`)||[])t.add(e);return[...t].map(e=>r[e])}}}function T(e){const t=e.candidate?.sourceEid||e.device.primary||"",o=t?e.hass?.states?.[t]?.state:void 0,s="unavailable"===o||"unknown"===o||!!t&&!!e.hass&&!e.hass.states?.[t]&&!e.device.virtual,i=Number(e.device.marker?.glow_radius_cm),n=Number.isFinite(i)&&i>0?i/e.cellCm*e.gridPitch:e.defaultRadius,a=s?null:e.candidate?.appearance??null;return{strip:e.strip,device:e.device,state:s?"unavailable":a?"on":"off",glow:e.glow,appearance:a,radius:n}}function j(e,t){const o=function(e,t){return("on"===e.state?P:M)*t}(e,t.d);return{t:o,path:b(E(e.strip.points),t.faces,o/2)}}function B(e){if(!e.views.length)return d``;const t=e.handlers,o=[...e.views].sort((e,t)=>e.strip.id<t.strip.id?1:e.strip.id>t.strip.id?-1:0),s=e.iso;return d`<g class="led-strips" data-hp-led-strips="${o.length}"
data-hp-iso=${s?"raised":m}>
${s?d`<defs><filter id="hp-led-iso-shadow" filterUnits="userSpaceOnUse"
x="-100000" y="-100000" width="200000" height="200000">
<feGaussianBlur stdDeviation="${s.shadow.sigma}"></feGaussianBlur></filter></defs>`:m}
<style>
.led-strip .led-focus { fill: none; stroke: transparent; }
.led-strip:has(.led-hit:focus-visible) .led-focus { stroke: var(--primary-color, #03a9f4); }
.led-strip .led-hit { fill: none; stroke: transparent; cursor: pointer; outline: none; }
</style>
${v(o,e=>e.strip.id,o=>{const{t:i,path:n}=j(o,e),a=y(n),r="unavailable"===o.state,l=r?"#9e9e9e":"on"===o.state&&!o.glow&&o.appearance?o.appearance.c:"#FFFFFF",c=2*k(i*e.perUnit)/(e.perUnit||1),p=o.device,u=t=>function(e,t,o){const s=e.currentTarget,i=s?.getScreenCTM?.();if(!i||o.views.length<2)return t;const n=i.inverse(),a=[n.a*e.clientX+n.c*e.clientY+n.e,n.b*e.clientX+n.d*e.clientY+n.f],r=o.views.map(e=>{const{t:t,path:s}=j(e,o);return{id:e.strip.id,points:s.points.map(e=>[e[0]*o.perUnit,e[1]*o.perUnit]),closed:s.closed,thicknessPx:t*o.perUnit}}),l=C([a[0]*o.perUnit,a[1]*o.perUnit],r);return o.views.find(e=>e.strip.id===l)||t}(t,o,e).device,h=s?`translate(0 ${-s.lift})`:m;return d`<g class="led-strip state-${o.state}" data-led-strip="${o.strip.id}"
data-marker="${p.id}" data-state="${o.state}" data-closed="${n.closed?"true":"false"}">
${s?d`<path class="led-iso-shadow" d="${a}" fill="none" stroke="black"
stroke-opacity="${s.shadow.opacity}" stroke-width="${i}" stroke-linecap="round"
stroke-linejoin="round" filter="url(#hp-led-iso-shadow)" pointer-events="none"
transform="translate(${s.shadow.dx} ${s.shadow.dy-s.lift})"></path>
${[1,.5].map(e=>d`<path class="led-iso-edge" d="${a}" fill="none" stroke="${s.edge}"
stroke-width="${i}" stroke-linecap="round" stroke-linejoin="round" pointer-events="none"
transform="translate(0 ${-s.lift+s.depth*e})"></path>`)}`:m}
<g transform=${h}>
<path class="led-outline" d="${a}" fill="none" stroke="${A}" stroke-width="${i}"
stroke-linecap="round" stroke-linejoin="round"
stroke-dasharray=${r?`${2*i} ${1.5*i}`:m}></path>
<path class="led-core" d="${a}" fill="none" stroke="${l}" stroke-width="${i/2}"
stroke-linecap="round" stroke-linejoin="round"
stroke-dasharray=${r?`${2*i} ${1.5*i}`:m}></path>
<path class="led-focus" d="${a}" stroke-width="${1.6*i}" stroke-linecap="round"
stroke-linejoin="round" aria-hidden="true"></path>
${t?d`<path class="led-hit" d="${a}" stroke-width="${c}"
stroke-linecap="round" stroke-linejoin="round" pointer-events="stroke"
role="button" tabindex="0" aria-label="${t.label(p)}"
data-hp="device" data-id="${p.id}"
@click=${e=>t.click(e,u(e))}
@keydown=${e=>t.keydown(e,p)}
@contextmenu=${e=>t.contextmenu(e,u(e))}
@pointerdown=${e=>t.pointerdown(e,u(e))}
@pointermove=${e=>t.pointermove(e,u(e))}
@pointerup=${e=>t.pointerup(e,u(e))}
@pointercancel=${e=>t.pointercancel(e,p)}
@lostpointercapture=${e=>t.pointercancel(e,p)}
@pointerover=${e=>t.pointerover(e,u(e))}
@pointerleave=${()=>t.pointerleave()}
@focus=${e=>t.focus(e,p)}
@blur=${()=>t.blur(p)}></path>`:m}
</g>
</g>`})}
</g>`}function G(e,t,o,s){return(t?e.find(e=>e.id===t):void 0)??(o?e.find(e=>s(o,e)):void 0)}function H(e){const t=new Map(e.devices.map(e=>[e.id,e])),o=g/e.cellCm*e.gridPitch,s=new Map(i({hass:e.hass,devices:e.devices,virtualLights:e.virtualLights,spaceId:e.space.id,defaultColor:e.defaultColor,paletteAlpha:e.paletteAlpha,defaultRadiusUnits:o,cellCm:e.cellCm,gridPitch:e.gridPitch,position:()=>({x:0,y:0})}).map(e=>[e.key,e])),r=[];for(const i of e.space.led_strips||[]){if(!1===i?.active||!i.marker||!w(i.points))continue;const a={...i,points:i.points.map(e=>[e[0]*n,e[1]*n])},l=t.get(a.marker);if(!l||l.space!==e.space.id)continue;if(l.hidden&&!e.showHidden)continue;const d=G(e.space.rooms,l.marker?.room_id,$(E(a.points)),e.inRoom);r.push(T({strip:a,device:l,candidate:s.get(`${e.space.id}|${l.id}`)??null,hass:e.hass,glow:!!d&&e.glowFor(d),defaultRadius:o,cellCm:e.cellCm,gridPitch:e.gridPitch}))}const l=_/e.cellCm*e.gridPitch;return{views:r,faces:I(e.scene,l),d:e.iconPct/100*a(e.space),scene:e.scene,polygons:e.polygons}}const N=new WeakMap;function q(e){N.delete(e),U?.releaseLedField(e)}function S(e){return{shapes:N.get(e)?.frame.views.length??0,...U?.ledFieldStats(e)??{visibility:0,sources:0,recomputes:0}}}function O(e,t,o){const s=t.rooms.flatMap(e=>{const t=r(e);return t?[{room:e,poly:t}]:[]}),i=s.length?e._lightBarriers(t,s.map(({room:e,poly:t})=>({r:e,poly:t}))):null,n=[t,e._renderDevices,e._renderPlanHass,o,i,e._mode,e._showAll],a=N.get(e);if(a&&a.key.every((e,t)=>e===n[t]))return a.frame;const d=e._config?.icon_size??2.5,c=H({space:t,devices:e._renderDevices,hass:e._renderPlanHass,virtualLights:e._virtualLights,defaultColor:e._fillColors.glow_light.c,paletteAlpha:e._fillColors.glow_light.a,cellCm:e._cellCm,gridPitch:e._gridPitch,iconPct:d>8?2.5:d,scene:i,polygons:s,glowFor:e=>l(o,e),inRoom:(t,o)=>e._pointInRoom(t,o),showHidden:"devices"===e._mode&&e._showAll});return!1!==e.isConnected&&N.set(e,{key:n,frame:c}),c}function z(e,t,o,s){const i=O(e,t,o),n=e._stageEl?.clientWidth,a="iso"===e._renderProjection&&"view"===e._mode,r=a?i.d*c:i.d,l="theme-dark"===p(e._renderPlanHass)?"dark":"light",m=!!e._isoLightFloors?.size,v=u(l,m),g=B({views:i.views,d:r,iso:a?{lift:f.lift*r,depth:f.depth*r,edge:h(A,l,m),shadow:{dx:v.dx*r,dy:v.dy*r,sigma:v.sigma*r,opacity:v.opacityWhite}}:null,faces:i.faces,perUnit:n&&s.w?n/s.w:1,handlers:"view"===e._mode?{click:(t,o)=>e._clickDevice(t,o),keydown:(t,o)=>e._keyDevice(t,o),contextmenu:(t,o)=>e._ctxDevice(t,o),pointerdown:(t,o)=>e._pointerDown(t,o),pointermove:(t,o)=>{const s=e._pointerMove(t,o);s&&e._showDeviceTip(t,s)},pointerup:(t,o)=>e._pointerUp(t,o),pointercancel:(t,o)=>e._pointerCancel(t,o),pointerover:(t,o)=>e._showDeviceTip(t,o),pointerleave:()=>e._clearPointerHover(),focus:(t,o)=>e._showDeviceFocusTip(t,o),blur:t=>e._hideDeviceFocusTip(t.id),label:e=>e.name}:null});return"plan"===e._mode||"decor"===e._mode?d`<g class="led-passive" opacity="0.45" pointer-events="none">${g}</g>`:g}function W(e,t,o){if(!1===e.isConnected)return d``;const s=O(e,t,o),i=s.scene&&(R(s.views)||U?.hasLedField(e))?U||D(t.id,()=>!1!==e.isConnected&&e.requestUpdate()):null;return i?i.renderLedField({views:s.views,scene:s.scene,polygons:s.polygons,faces:s.faces,spaceId:t.id,owner:e,requestUpdate:()=>e.requestUpdate(),isConnected:()=>!1!==e.isConnected}):d``}function Y(e){const t=e.space.rooms.flatMap(e=>{const t=r(e);return t?[{room:e,poly:t}]:[]}),o=H({space:e.space,devices:e.devices,hass:e.hass,virtualLights:e.virtualLights,defaultColor:e.defaultColor,paletteAlpha:e.paletteAlpha,cellCm:e.cellCm,gridPitch:e.gridPitch,iconPct:e.iconPct,scene:e.scene,polygons:t,glowFor:e.glowFor,inRoom:e.inRoom,showHidden:!1}),s=e.live?o.views:o.views.map(e=>({...e,state:"off",appearance:null,glow:!1})),i=I({masonryGeometry:e.bodies.masonryGeometry,opaqueBodies:e.bodies.opaqueBodies},_/e.cellCm*e.gridPitch),n=e.scene&&e.live&&(R(s)||U?.hasLedField(e.owner))?D(e.space.id,e.ready):null;return d`${n?n.renderLedField({views:s,scene:e.scene,polygons:t,faces:i,spaceId:e.space.id,owner:e.owner,requestUpdate:e.ready,isConnected:()=>!0}):m}${B({views:s,d:o.d,faces:i,perUnit:e.perUnit,handlers:null})}`}export{F as LED_RUNTIME_FINGERPRINT,I as faceContext,D as ledField,H as ledFrame,O as ledFrameFor,S as ledStats,T as ledStripView,q as releaseLed,W as renderLedFieldFor,z as renderLedLayerFor,B as renderLedStripes,Y as renderStaticLed,G as stripRoom};
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
-1
View File
@@ -1 +0,0 @@
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="fd4a405e9c5a21035258c45feca26dca03d59d4cfba4280f89ff5f82675515ac";import{eQ as a,eR as e,eF as n}from"./houseplan-card-CDzf9V5z.js";function c(n,c){return new a([{code:"en",dictionary:n},{code:"ru",loadDictionary:c.ru},{code:"de",loadDictionary:c.de},{code:"fr",loadDictionary:c.fr}],"fd4a405e9c5a21035258c45feca26dca03d59d4cfba4280f89ff5f82675515ac",console.warn,e)}function o(a){return function(a,e){return{state:n=>{const c=a.state(n);return"pending"!==c&&e.some(a=>"pending"===a.state(n))?"pending":c},dictionary:e=>a.dictionary(e),ensure:n=>Promise.all([a,...e].map(a=>a.ensure(n))).then(()=>{})}}(n,a)}export{c as n,o as s};
+1
View File
@@ -0,0 +1 @@
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="ab07da35681c15ab6136c323500b69766580ea4a788e399ea88f9e7497549172";import{eR as e,eS as a,eG as n}from"./houseplan-card-BOdiRDFR.js";function o(n,o){return new e([{code:"en",dictionary:n},{code:"ru",loadDictionary:o.ru},{code:"de",loadDictionary:o.de},{code:"fr",loadDictionary:o.fr}],"ab07da35681c15ab6136c323500b69766580ea4a788e399ea88f9e7497549172",console.warn,a)}function r(e){return function(e,a){return{state:n=>{const o=e.state(n);return"pending"!==o&&a.some(e=>"pending"===e.state(n))?"pending":o},dictionary:a=>e.dictionary(a),ensure:n=>Promise.all([e,...a].map(e=>e.ensure(n))).then(()=>{})}}(n,e)}export{o as n,r as s};
File diff suppressed because one or more lines are too long
@@ -1,6 +1,6 @@
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="fd4a405e9c5a21035258c45feca26dca03d59d4cfba4280f89ff5f82675515ac";import{aG as e,l as t,aJ as s,A as a,eE as o,eF as i,eG as n,E as c,eP as l,c as r}from"./houseplan-card-CDzf9V5z.js";class h extends e{constructor(){super(...arguments),this._spaces=null,this._spacesLoading=!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}))}catch{this._spaces=[]}finally{this._spacesLoading=!1}}}get _lang(){return t(this.hass,this._config?.language)}get _schema(){const e=this._spaces||[];return[e.length?{name:"space",selector:{select:{mode:"dropdown",options:e}}}:{name:"space",selector:{text:{}}},{name:"title",selector:{text:{}}},{name:"fit",selector:{select:{mode:"dropdown",options:[{value:"content",label:s(this._lang,"editor.fit_content")},{value:"house",label:s(this._lang,"editor.fit_house")}]}}},{name:"show_button",selector:{boolean:{}}},{name:"button_label",selector:{text:{}}},{name:"button_target",selector:{text:{}}},{name:"icon_size",selector:{number:{min:1,max:6,step:.1,mode:"box"}}},{name:"show_temperature",selector:{boolean:{}}},{name:"live_states",selector:{boolean:{}}},{name:"light_pools",selector:{boolean:{}}},{name:"show_signal",selector:{boolean:{}}}]}render(){if(!this.hass||!this._config)return a;const e=o(this,i,t(this.hass,this._config.language));if("cold"===e)return n();if("warm"===e)return c;this._loadSpaces();const h=this._lang,_={space:s(h,"editor.space"),title:s(h,"editor.title"),fit:s(h,"editor.framing"),show_button:s(h,"editor.show_button"),button_label:s(h,"editor.button_label"),button_target:s(h,"editor.button_target"),icon_size:s(h,"editor.icon_size"),show_temperature:s(h,"editor.show_temperature"),live_states:s(h,"editor.live_states"),light_pools:s(h,"editor.light_pools"),show_signal:s(h,"editor.show_signal")};return r`<ha-form
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="ab07da35681c15ab6136c323500b69766580ea4a788e399ea88f9e7497549172";import{aG as e,l as t,aJ as s,A as a,eF as o,eG as i,eH as n,E as l,eQ as c,c as r}from"./houseplan-card-BOdiRDFR.js";class h extends e{constructor(){super(...arguments),this._spaces=null,this._spacesLoading=!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}))}catch{this._spaces=[]}finally{this._spacesLoading=!1}}}get _lang(){return t(this.hass,this._config?.language)}get _schema(){const e=this._spaces||[];return[e.length?{name:"space",selector:{select:{mode:"dropdown",options:e}}}:{name:"space",selector:{text:{}}},{name:"title",selector:{text:{}}},{name:"fit",selector:{select:{mode:"dropdown",options:[{value:"content",label:s(this._lang,"editor.fit_content")},{value:"house",label:s(this._lang,"editor.fit_house")}]}}},{name:"show_button",selector:{boolean:{}}},{name:"button_label",selector:{text:{}}},{name:"button_target",selector:{text:{}}},{name:"icon_size",selector:{number:{min:1,max:6,step:.1,mode:"box"}}},{name:"show_temperature",selector:{boolean:{}}},{name:"live_states",selector:{boolean:{}}},{name:"light_pools",selector:{boolean:{}}},{name:"show_signal",selector:{boolean:{}}}]}render(){if(!this.hass||!this._config)return a;const e=o(this,i,t(this.hass,this._config.language));if("cold"===e)return n();if("warm"===e)return l;this._loadSpaces();const h=this._lang,_={space:s(h,"editor.space"),title:s(h,"editor.title"),fit:s(h,"editor.framing"),show_button:s(h,"editor.show_button"),button_label:s(h,"editor.button_label"),button_target:s(h,"editor.button_target"),icon_size:s(h,"editor.icon_size"),show_temperature:s(h,"editor.show_temperature"),live_states:s(h,"editor.live_states"),light_pools:s(h,"editor.light_pools"),show_signal:s(h,"editor.show_signal")};return r`<ha-form
.hass=${this.hass}
.data=${{...this._config,fit:l(this._config.fit)}}
.data=${{...this._config,fit:c(this._config.fit)}}
.schema=${this._schema}
.computeLabel=${e=>_[e.name]||e.name}
@value-changed=${this._valueChanged}
@@ -1,4 +1,4 @@
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="fd4a405e9c5a21035258c45feca26dca03d59d4cfba4280f89ff5f82675515ac";import{c as a,A as s}from"./houseplan-card-CDzf9V5z.js";import{s as e,n as t,a as l,m as r,b as o,c as i,d as u}from"./summary-panel-runtime-loaded-BcDAIp5L.js";import"./form-kit.styles-Dq1Y4tz1.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&&!e(t(d.draft),d.base),p=$&&!d.busy&&!y,v=a=>n.find(s=>s.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__="ab07da35681c15ab6136c323500b69766580ea4a788e399ea88f9e7497549172";import{c as a,A as e}from"./houseplan-card-BOdiRDFR.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-CcLP5B5v.js";import"./form-kit.styles-B6HsmMPA.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>
<small id="summary-local-show-hint">${b("summary.show_local_hint")}</small></span>
<input id="summary-local-show" data-summary-local-show type="checkbox"
@@ -10,31 +10,31 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="fd4a405e9c5a21035258c45feca26dca03d5
dismiss-on-scrim aria-busy=${String(d.busy)}
@hp-close=${k}>
<div class="body summary-editor" @click=${()=>m.closeSource()}>
${d.localOnly?a`<p class="summary-local-hint">${b(d.localOnlyHint)}</p>`:s}
${d.localOnly?a`<p class="summary-local-hint">${b(d.localOnlyHint)}</p>`:e}
<section class="summary-general" aria-labelledby="summary-general-title">
<h3 id="summary-general-title">${b("summary.general_settings")}</h3>
<div class="summary-general-grid">
${d.localOnly?s:a`<div class="summary-field">
${d.localOnly?e:a`<div class="summary-field">
<label for="summary-panel-title">${b("summary.panel_title")}</label>
<input id="summary-panel-title" type="text" .value=${d.draft.title}
?disabled=${d.busy}
data-summary-error=${String(d.attempted&&"title"===y?.path)}
aria-invalid=${"error"===v("title")?.kind?"true":"false"}
@input=${a=>m.mutate(s=>{s.title=a.target.value})} />
${v("title")?a`<div class="summary-problem error">${h(v("title"))}</div>`:s}
@input=${a=>m.mutate(e=>{e.title=a.target.value})} />
${v("title")?a`<div class="summary-problem error">${h(v("title"))}</div>`:e}
</div>`}
${g}
${d.localOnly?s:a`<label class="summary-switch" for="summary-mobile-show">
${d.localOnly?e:a`<label class="summary-switch" for="summary-mobile-show">
<span class="summary-switch-caption"><strong>${b("summary.show_mobile")}</strong>
<small id="summary-mobile-show-hint">${b("summary.show_mobile_hint")}</small></span>
<input id="summary-mobile-show" data-summary-mobile-show type="checkbox"
.checked=${d.draft.show_on_mobile} ?disabled=${!d.localShow||d.busy}
aria-label=${b("summary.show_mobile")} aria-describedby="summary-mobile-show-hint"
@change=${a=>m.mutate(s=>{s.show_on_mobile=a.target.checked})} /></label>`}
@change=${a=>m.mutate(e=>{e.show_on_mobile=a.target.checked})} /></label>`}
</div>
${m.storageUnavailable?a`<div class="summary-problem warning">${b("summary.storage_unavailable")}</div>`:s}
${m.storageUnavailable?a`<div class="summary-problem warning">${b("summary.storage_unavailable")}</div>`:e}
</section>
${d.localOnly?s:a`
${d.localOnly?e:a`
<section class="summary-blocks-card" aria-labelledby="summary-blocks-title">
<header class="summary-blocks-heading">
<div><h3 id="summary-blocks-title">${b("summary.blocks")}</h3>
@@ -42,7 +42,7 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="fd4a405e9c5a21035258c45feca26dca03d5
<span class="summary-block-count">${b("summary.block_count").replace("{count}",String(d.draft.blocks.length)).replace("{limit}","10")}</span>
</header>
<div class="summary-editor-blocks">
${d.draft.blocks.map((e,t)=>{const u=`blocks.${t}`,n=v(`${u}.scope`);return a`<article class="summary-editor-block"
${d.draft.blocks.map((s,t)=>{const u=`blocks.${t}`,n=v(`${u}.scope`);return a`<article class="summary-editor-block"
@dragover=${a=>a.preventDefault()}
@drop=${a=>m.drop(a,`block:${t}`)}>
<div class="summary-block-head">
@@ -57,40 +57,40 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="fd4a405e9c5a21035258c45feca26dca03d5
?disabled=${t===d.draft.blocks.length-1||d.busy}
@click=${()=>m.mutate(a=>{a.blocks=r(a.blocks,t,t+1)})}>${l("down")}</button>
</div>
<input class="summary-block-title" type="text" .value=${e.title}
<input class="summary-block-title" type="text" .value=${s.title}
placeholder=${b("summary.block_title")} aria-label=${b("summary.block_title")}
?disabled=${d.busy}
data-summary-error=${String(d.attempted&&y?.path===`${u}.title`)}
aria-invalid=${"error"===v(`${u}.title`)?.kind?"true":"false"}
@input=${a=>m.mutate(s=>{s.blocks[t].title=a.target.value})} />
@input=${a=>m.mutate(e=>{e.blocks[t].title=a.target.value})} />
<button class="summary-icon-button summary-visibility" type="button"
?disabled=${d.busy} aria-pressed=${String(e.visible)}
title=${b(e.visible?"summary.hide_block":"summary.show_block")}
aria-label=${b(e.visible?"summary.hide_block":"summary.show_block")}
@click=${()=>m.mutate(a=>{a.blocks[t].visible=!a.blocks[t].visible})}>${l(e.visible?"eye":"eyeOff")}</button>
${v(`${u}.title`)?a`<div class="summary-problem error summary-block-title-error">${h(v(`${u}.title`))}</div>`:s}
?disabled=${d.busy} aria-pressed=${String(s.visible)}
title=${b(s.visible?"summary.hide_block":"summary.show_block")}
aria-label=${b(s.visible?"summary.hide_block":"summary.show_block")}
@click=${()=>m.mutate(a=>{a.blocks[t].visible=!a.blocks[t].visible})}>${l(s.visible?"eye":"eyeOff")}</button>
${v(`${u}.title`)?a`<div class="summary-problem error summary-block-title-error">${h(v(`${u}.title`))}</div>`:e}
<div class="summary-scope">
<select .value=${e.scope.type} ?disabled=${d.busy}
<select .value=${s.scope.type} ?disabled=${d.busy}
aria-label=${b("summary.scope")}
@change=${a=>m.mutate(s=>{s.blocks[t].scope="space"===a.target.value?{type:"space",space_id:c._space}:{type:"all"}})}>
<option value="all" ?selected=${"all"===e.scope.type}>${b("summary.scope_all")}</option>
<option value="space" ?selected=${"space"===e.scope.type}>${b("summary.scope_space")}</option>
@change=${a=>m.mutate(e=>{e.blocks[t].scope="space"===a.target.value?{type:"space",space_id:c._space}:{type:"all"}})}>
<option value="all" ?selected=${"all"===s.scope.type}>${b("summary.scope_all")}</option>
<option value="space" ?selected=${"space"===s.scope.type}>${b("summary.scope_space")}</option>
</select>
${"space"===e.scope.type?a`<select .value=${e.scope.space_id}
${"space"===s.scope.type?a`<select .value=${s.scope.space_id}
?disabled=${d.busy} aria-label=${b("summary.scope_space")}
data-summary-error=${String(d.attempted&&y?.path===`${u}.scope`)}
aria-invalid=${"error"===n?.kind?"true":"false"}
@change=${a=>m.mutate(s=>{const e=s.blocks[t].scope;"space"===e.type&&(e.space_id=a.target.value)})}>
${c._model.some(a=>a.id===e.scope.space_id)?s:a`<option value=${e.scope.space_id} selected>${e.scope.space_id}</option>`}
${c._model.map(s=>a`<option value=${s.id}
?selected=${s.id===e.scope.space_id}>${s.title}</option>`)}
</select>`:s}
@change=${a=>m.mutate(e=>{const s=e.blocks[t].scope;"space"===s.type&&(s.space_id=a.target.value)})}>
${c._model.some(a=>a.id===s.scope.space_id)?e:a`<option value=${s.scope.space_id} selected>${s.scope.space_id}</option>`}
${c._model.map(e=>a`<option value=${e.id}
?selected=${e.id===s.scope.space_id}>${e.title}</option>`)}
</select>`:e}
</div>
${n?a`<div class="summary-problem summary-scope-problem ${n.kind}">${h(n)}</div>`:s}
${n?a`<div class="summary-problem summary-scope-problem ${n.kind}">${h(n)}</div>`:e}
</div>
<div class="summary-block-body">
<div class="summary-editor-values">
${e.values.map((i,c)=>{const n=`${u}.values.${c}`,$=v(`${n}.source`),p=m.sourceToken(i.source),k=d.activeSource?.blockId===e.id&&d.activeSource.valueId===i.id,g="system"===i.source.type?b(`summary.system.${i.source.key}`):i.source.entity_id?m.entityIndex.labels.get(i.source.entity_id)||i.source.entity_id:b("summary.select_source"),_="system"===i.source.type?b("summary.system_source"):i.source.entity_id,f=k?o(m.entityIndex,d.entityFilter):null,w="entity"===i.source.type&&!!i.source.entity_id&&!m.entityIndex.labels.has(i.source.entity_id),S=`${e.id}\n${i.id}`;return a`<div class="summary-editor-value"
${s.values.map((i,c)=>{const n=`${u}.values.${c}`,$=v(`${n}.source`),p=m.sourceToken(i.source),k=d.activeSource?.blockId===s.id&&d.activeSource.valueId===i.id,g="system"===i.source.type?b(`summary.system.${i.source.key}`):i.source.entity_id?m.entityIndex.labels.get(i.source.entity_id)||i.source.entity_id:b("summary.select_source"),_="system"===i.source.type?b("summary.system_source"):i.source.entity_id,f=k?o(m.entityIndex,d.entityFilter):null,w="entity"===i.source.type&&!!i.source.entity_id&&!m.entityIndex.labels.has(i.source.entity_id),S=`${s.id}\n${i.id}`;return a`<div class="summary-editor-value"
@dragover=${a=>{a.preventDefault(),a.stopPropagation()}}
@drop=${a=>m.drop(a,`value:${t}:${c}`)}>
<span class="summary-drag" draggable=${String(!d.busy)} title=${b("summary.drag")}
@@ -101,7 +101,7 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="fd4a405e9c5a21035258c45feca26dca03d5
@click=${()=>m.mutate(a=>{a.blocks[t].values=r(a.blocks[t].values,c,c-1)})}>${l("up")}</button>
<button class="summary-icon-button" type="button" title=${b("summary.down")}
aria-label=${b("summary.down")}
?disabled=${c===e.values.length-1||d.busy}
?disabled=${c===s.values.length-1||d.busy}
@click=${()=>m.mutate(a=>{a.blocks[t].values=r(a.blocks[t].values,c,c+1)})}>${l("down")}</button>
</div>
<div class="summary-value-label">
@@ -109,8 +109,8 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="fd4a405e9c5a21035258c45feca26dca03d5
placeholder=${b("summary.value_name")} aria-label=${b("summary.value_name")}
data-summary-error=${String(d.attempted&&y?.path===`${n}.label`)}
aria-invalid=${"error"===v(`${n}.label`)?.kind?"true":"false"}
@input=${a=>m.mutate(s=>{s.blocks[t].values[c].label=a.target.value})} />
${v(`${n}.label`)?a`<div class="summary-problem error">${h(v(`${n}.label`))}</div>`:s}
@input=${a=>m.mutate(e=>{e.blocks[t].values[c].label=a.target.value})} />
${v(`${n}.label`)?a`<div class="summary-problem error">${h(v(`${n}.label`))}</div>`:e}
</div>
<div class="summary-source-field">
<button class="summary-source" type="button"
@@ -119,9 +119,9 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="fd4a405e9c5a21035258c45feca26dca03d5
data-summary-error=${String(d.attempted&&y?.path===`${n}.source`)}
aria-invalid=${"error"===$?.kind?"true":"false"}
aria-haspopup="listbox" aria-expanded=${k?"true":"false"}
@click=${a=>{a.stopPropagation(),k?m.closeSource():m.openSource(e.id,i.id)}}>
@click=${a=>{a.stopPropagation(),k?m.closeSource():m.openSource(s.id,i.id)}}>
<span class="summary-source-caption"><strong>${g}</strong>
${_?a`<small>${_}</small>`:s}</span>
${_?a`<small>${_}</small>`:e}</span>
${l("chevron")}
</button>
${k&&f?a`<div class="summary-source-picker"
@@ -135,39 +135,39 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="fd4a405e9c5a21035258c45feca26dca03d5
<div class="summary-source-results" role="listbox"
aria-label=${b("summary.select_source")}>
<div class="summary-source-group">${b("summary.system_group")}</div>
${["device_count","total_area","datetime"].map(s=>a`
${["device_count","total_area","datetime"].map(e=>a`
<button type="button" role="option"
?disabled=${d.busy}
aria-selected=${p===`system:${s}`?"true":"false"}
@click=${()=>m.setSource(e.id,i.id,`system:${s}`)}>
${b(`summary.system.${s}`)}
aria-selected=${p===`system:${e}`?"true":"false"}
@click=${()=>m.setSource(s.id,i.id,`system:${e}`)}>
${b(`summary.system.${e}`)}
</button>`)}
${w?a`<div class="summary-source-group">${b("summary.current_source")}</div>
<button type="button" role="option" class="broken" aria-selected="true"
?disabled=${d.busy}
@click=${()=>m.setSource(e.id,i.id,p)}>
@click=${()=>m.setSource(s.id,i.id,p)}>
${g}
</button>`:s}
</button>`:e}
<div class="summary-source-group">${b("summary.entities_group")}</div>
${f.entries.map(s=>a`<button type="button" role="option"
${f.entries.map(e=>a`<button type="button" role="option"
?disabled=${d.busy}
aria-selected=${p===`entity:${s.id}`?"true":"false"}
@click=${()=>m.setSource(e.id,i.id,`entity:${s.id}`)}>
<span>${s.label}</span><small>${s.id}</small>
aria-selected=${p===`entity:${e.id}`?"true":"false"}
@click=${()=>m.setSource(s.id,i.id,`entity:${e.id}`)}>
<span>${e.label}</span><small>${e.id}</small>
</button>`)}
${f.total?s:a`<div class="summary-empty">${b("summary.no_search_results")}</div>`}
${f.truncated?a`<div class="summary-refine">${b("summary.refine_search")}</div>`:s}
${f.total?e:a`<div class="summary-empty">${b("summary.no_search_results")}</div>`}
${f.truncated?a`<div class="summary-refine">${b("summary.refine_search")}</div>`:e}
</div>
</div>`:s}
${$?a`<div class="summary-problem ${$.kind}">${h($)}</div>`:s}
</div>`:e}
${$?a`<div class="summary-problem ${$.kind}">${h($)}</div>`:e}
</div>
<button class="summary-icon-button summary-value-remove" type="button"
title=${b("btn.delete")} aria-label=${b("btn.delete")} ?disabled=${d.busy}
@click=${()=>m.mutate(a=>{a.blocks[t].values.splice(c,1)})}>${l("close")}</button>
</div>`})}
<button class="summary-add summary-add-value" type="button"
?disabled=${e.values.length>=20||d.busy}
title=${e.values.length>=20?b("summary.limit_values"):""}
?disabled=${s.values.length>=20||d.busy}
title=${s.values.length>=20?b("summary.limit_values"):""}
@click=${()=>m.mutate(a=>{a.blocks[t].values.push(i())})}>
${l("plus")}${b("summary.add_value")}
</button>
@@ -186,11 +186,11 @@ globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="fd4a405e9c5a21035258c45feca26dca03d5
${l("plus")}${b("summary.add_block")}
</button>
</section>
${d.error?a`<div class="summary-problem error" role="alert">${d.error}</div>`:s}
${d.error?a`<div class="summary-problem error" role="alert">${d.error}</div>`:e}
${d.conflict?a`<button class="btn ghost summary-reload" type="button"
?disabled=${d.busy} @click=${()=>m.reload()}>
<ha-icon icon="mdi:reload"></ha-icon>${b("summary.reload_current")}
</button>`:s}
</button>`:e}
`}
</div>
<div class="row summary-editor-footer" slot="footer">
@@ -1 +1 @@
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="fd4a405e9c5a21035258c45feca26dca03d59d4cfba4280f89ff5f82675515ac";import{e_ as e,O as t,b5 as n,M as i,af as o,ad as r,ce as s,e$ as a,cd as c,b4 as l,b3 as d,b6 as u,f0 as f,f1 as m,cg as g,f2 as v}from"./houseplan-card-CDzf9V5z.js";function y(e){if(!e.registry.authoritative)return null;const t=new Set,n=u(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 _(e,t){return e?.length?t?.length?v(e,t):e:t}function h(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:d(e.rooms,t.walls,t.openCuts,i,t.cellCm,o,r)}}function*p(l,d,u=h){try{let f=0;for(const m of d){const d=l.spaces.find(e=>String(e?.id)===m.id);if(!d)continue;const g=e(d,m),v=u(m,g);let y=null;for(const e of m.rooms){if(!e.id)continue;const a=t(e);if(!a)continue;const c=n(m.rooms,e.id,g.walls,g.openCuts,i,g.cellCm,o,r,v.roomGeom,v.multiWallNodes)||a;y=_(y,s(c,g.physicalBodies)),yield}const h=a(y||[],m.stairs);let p=h.next();for(;!p.done;)yield,p=h.next();y=p.value;const b=g.cellCm/o;f+=c(y)*b*b/1e4}return f}catch{return null}}function b(e,t,n=h){const i=p(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:g(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 C(e,t){const n=e?.states?.[t];if(!n)return null;const i=f(e,t);return i?m(i,String(n.attributes?.unit_of_measurement||"")):null}export{p as cleanFloorAreaSteps,y as representedHaDeviceIds,h as spaceWallGeometry,C as summaryEntityValue,S as summarySystemValue,b as totalCleanFloorAreaM2};
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="ab07da35681c15ab6136c323500b69766580ea4a788e399ea88f9e7497549172";import{e$ as e,O as t,b5 as n,M as i,af as o,ad as r,cf as s,f0 as a,ce as l,b4 as c,b3 as u,b6 as d,f1 as f,f2 as m,ch as g,f3 as v}from"./houseplan-card-BOdiRDFR.js";function y(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,l="entity"===r?e.registry.entities?.[s]:null,c="device"===r?s:l?.device_id,u="device"===r?a?.area_id:l?.area_id||c&&e.registry.devices?.[c]?.area_id,d="string"==typeof i.room_id&&i.room_id.length>0&&null===i.area?"":i.area||u||"",f=d&&e.areaToSpace[d]||i.space||e.firstSpaceId;c&&e.registry.devices?.[c]&&e.spaceIds.has(f)&&(!n.devices.has(c)||"entity"===r&&n.liveEntities.has(s))&&t.add(c)}return t}function _(e,t){return e?.length?t?.length?v(e,t):e:t}function h(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:u(e.rooms,t.walls,t.openCuts,i,t.cellCm,o,r)}}function*p(c,u,d=h){try{let f=0;for(const m of u){const u=c.spaces.find(e=>String(e?.id)===m.id);if(!u)continue;const g=e(u,m),v=d(m,g);let y=null;for(const e of m.rooms){if(!e.id)continue;const a=t(e);if(!a)continue;const l=n(m.rooms,e.id,g.walls,g.openCuts,i,g.cellCm,o,r,v.roomGeom,v.multiWallNodes)||a;y=_(y,s(l,g.physicalBodies)),yield}const h=a(y||[],m.stairs);let p=h.next();for(;!p.done;)yield,p=h.next();y=p.value;const b=g.cellCm/o;f+=l(y)*b*b/1e4}return f}catch{return null}}function b(e,t,n=h){const i=p(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:g(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 C(e,t){const n=e?.states?.[t];if(!n)return null;const i=f(e,t);return i?m(i,String(n.attributes?.unit_of_measurement||"")):null}export{p as cleanFloorAreaSteps,y as representedHaDeviceIds,h as spaceWallGeometry,C as summaryEntityValue,S as summarySystemValue,b as totalCleanFloorAreaM2};
File diff suppressed because one or more lines are too long

Some files were not shown because too many files have changed in this diff Show More