iobroker.eos-admin 7.9.96 → 7.9.98

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/INSTALL_TEST_V7.9.98.md +39 -0
  2. package/MERGE_UPDATE_README_V7.9.98.md +29 -0
  3. package/NEXOWATT_EOS_BUILD_INFO.json +20 -18
  4. package/PUBLISH_STABLE_V7.9.98.md +33 -0
  5. package/README.md +16 -6
  6. package/README_STABILITY_V7.9.98.md +22 -0
  7. package/RELEASE_ACCEPTANCE_V7.9.98.md +48 -0
  8. package/RELEASE_NOTES_V7.9.98.md +32 -0
  9. package/adminWww/assets/Intro-DkwRiz1n-v84.js +1 -1
  10. package/adminWww/assets/bootstrap-COulQZax-v84.js +3 -3
  11. package/adminWww/assets/index-D2ymscJA-v84.js +1 -1
  12. package/adminWww/css/eos-ems-overview.css +21 -0
  13. package/adminWww/css/nexowatt-native-shell.css +174 -40
  14. package/adminWww/index.html +15 -15
  15. package/adminWww/js/eos-account-management.js +26 -13
  16. package/adminWww/js/eos-assistant.js +1 -1
  17. package/adminWww/js/eos-ems-overview.js +136 -39
  18. package/adminWww/js/eos-role-bootstrap.js +7 -7
  19. package/adminWww/js/eos-role-ui.js +2 -2
  20. package/adminWww/js/nexowatt-native-shell.js +9 -2
  21. package/adminWww/static/js/nexowatt-stable-login.js +28 -62
  22. package/adminWww/static/js/nexowatt-stable-v98.js +33 -0
  23. package/build/lib/web.js +112 -79
  24. package/build/main.js +1 -1
  25. package/io-package.json +15 -5
  26. package/package.json +14 -12
  27. package/tools/nexowatt-account-management-selftest.cjs +16 -57
  28. package/tools/nexowatt-account-password-flow-selftest.cjs +186 -0
  29. package/tools/nexowatt-clean-legacy-runtime.cjs +33 -10
  30. package/tools/nexowatt-login-layout-selftest.cjs +12 -81
  31. package/tools/nexowatt-merge-update-selftest.cjs +3 -1
  32. package/tools/nexowatt-modern-ui-selftest.cjs +2 -2
  33. package/tools/nexowatt-password-write-selftest.cjs +48 -0
  34. package/tools/nexowatt-runtime-cleanup-selftest.cjs +9 -1
  35. package/tools/nexowatt-stable-v98-selftest.cjs +14 -0
  36. package/tools/nexowatt-sync-release-version.cjs +42 -1
  37. package/tools/nexowatt-ui-overview-runtime-selftest.cjs +11 -11
  38. package/tools/nexowatt-validate-package.cjs +20 -11
  39. package/tools/nexowatt-version-sync-selftest.cjs +18 -1
  40. package/INSTALL_TEST_V7.9.96.md +0 -11
  41. package/MERGE_UPDATE_README_V7.9.96.md +0 -5
  42. package/PUBLISH_STABLE_V7.9.96.md +0 -10
  43. package/README_STABILITY_V7.9.96.md +0 -11
  44. package/RELEASE_ACCEPTANCE_V7.9.96.md +0 -10
  45. package/RELEASE_NOTES_V7.9.96.md +0 -12
  46. package/adminWww/static/js/nexowatt-stable-v96.js +0 -82
  47. package/tools/nexowatt-stable-v96-selftest.cjs +0 -13
@@ -0,0 +1,39 @@
1
+ # Installationstest – NexoWatt EOS Admin 7.9.98
2
+
3
+ ## Installation nach der npm-Veröffentlichung
4
+
5
+ ```bash
6
+ cd /opt/iobroker
7
+ iobroker stop eos-admin.0
8
+ npm install --no-save --omit=dev iobroker.eos-admin@7.9.98
9
+ iobroker upload eos-admin
10
+ iobroker restart eos-admin.0
11
+ iobroker restart nexowatt-ui.0
12
+ ```
13
+
14
+ Version prüfen:
15
+
16
+ ```bash
17
+ node -p "require('/opt/iobroker/node_modules/iobroker.eos-admin/package.json').version"
18
+ ```
19
+
20
+ Erwartet:
21
+
22
+ ```text
23
+ 7.9.98
24
+ ```
25
+
26
+ Danach im Browser eine vollständige Aktualisierung mit `Strg + F5` durchführen.
27
+
28
+ ## Installation des geprüften TGZ ohne Registry
29
+
30
+ ```bash
31
+ cd /opt/iobroker
32
+ iobroker stop eos-admin.0
33
+ npm install --no-save --omit=dev /PFAD/iobroker.eos-admin-7.9.98.tgz
34
+ iobroker upload eos-admin
35
+ iobroker restart eos-admin.0
36
+ iobroker restart nexowatt-ui.0
37
+ ```
38
+
39
+ Anschließend die vollständige Abnahme aus `RELEASE_ACCEPTANCE_V7.9.98.md` durchführen.
@@ -0,0 +1,29 @@
1
+ # NexoWatt EOS Admin 7.9.98 – Merge-Update
2
+
3
+ Die Datei `NexoWatt_EOS_Admin_7.9.98_STABLE_MERGE_FLAT.zip` ist absichtlich flach aufgebaut. `package.json`, `io-package.json`, `src-admin`, `adminWww`, `build` und alle übrigen Repository-Dateien liegen direkt auf der ersten ZIP-Ebene.
4
+
5
+ ## Anwendung auf einem vorhandenen Windows-Arbeitsordner
6
+
7
+ 1. Den bestehenden Repository-Ordner sichern oder committen.
8
+ 2. Die flache Merge-ZIP direkt in den vorhandenen Ordner entpacken.
9
+ 3. Bei der Windows-Abfrage **„Dateien im Ziel ersetzen“** wählen.
10
+ 4. Anschließend im Repository ausführen:
11
+
12
+ ```powershell
13
+ .\MERGE_UPDATE.cmd
14
+ ```
15
+
16
+ Alternativ:
17
+
18
+ ```powershell
19
+ .\MERGE_UPDATE.ps1
20
+ ```
21
+
22
+ Das Merge-Skript:
23
+
24
+ - synchronisiert alle Release-Versionen auf `7.9.98`;
25
+ - entfernt alte Stable-Laufzeitdateien wie v97;
26
+ - prüft Paketstruktur, Stabilität, Rollen, Login, Passwortablauf und EMS-Übersicht;
27
+ - führt abschließend einen npm-Pack-Dry-Run aus.
28
+
29
+ Erst nach der grünen Abschlussmeldung veröffentlichen. `.git`, lokale Commit-Historie und `node_modules` werden vom Merge-Skript nicht gelöscht.
@@ -1,26 +1,28 @@
1
1
  {
2
- "version": "7.9.96",
2
+ "version": "7.9.98",
3
3
  "channel": "stable-latest",
4
- "baseFrontend": "validated Admin 7 runtime with native role overview, UI-adapter EMS live diagnosis and first-password repair",
4
+ "baseFrontend": "validated Admin 7 runtime with scrollable native cockpit, clean placeholder login and verified ioBroker password writes",
5
5
  "runtimeEntry": "v84",
6
- "releaseType": "stable-ui-ems-login-hardening",
7
- "release": "stable-ui-ems-login-hardening",
8
- "label": "v96",
6
+ "releaseType": "stable-scroll-login-password-write-fix",
7
+ "release": "stable-scroll-login-password-write-fix",
8
+ "label": "v98",
9
9
  "notes": [
10
- "7.9.96 uses the native Admin overview for Admin, Installer and End User without the obsolete action-tile overlay.",
11
- "The NexoWatt UI info.adminOverview contract is rendered as a read-only live EMS diagnosis tile for every allowed role.",
12
- "The login card is larger and no longer creates internal horizontal or vertical scrollbars.",
13
- "First sign-in with the initial password nexowatt opens the mandatory personal password dialog instead of the security-recovery page."
10
+ "The native cockpit keeps the fixed header and provides an explicit vertical content scrollbar.",
11
+ "The login uses clean placeholder fields without overlapping MUI outline labels and expands for errors.",
12
+ "Password reset writes the real ioBroker user password to nexowatt and forces personal password setup.",
13
+ "First-login password changes are verified through the ioBroker password API before success is shown.",
14
+ "EOS Assist remains disabled until its separate complete redesign."
14
15
  ],
15
16
  "changes": [
16
- "Integrates the complete EMS LIVE DIAGNOSE merge source and runtime contract.",
17
- "Exposes the existing AdminConnection read-only to the overview runtime and polls every five seconds only while visible.",
18
- "Removes the second role-safe overview layer while preserving route, service-reserve and write restrictions.",
19
- "Adds source/build regression tests for login geometry, first-password routing, native role cards and EMS read-only behavior."
17
+ "Normalized system.user.* ids to the short account names expected by setPasswordAsync and checkPasswordAsync.",
18
+ "Separated password hash writes from EOS native metadata updates to prevent stale object replacement.",
19
+ "Relaxed same-host origin handling for reverse proxies while rejecting cross-site requests.",
20
+ "Added a stable vertical scroll surface to the overview and preserved the working EMS live diagnosis.",
21
+ "Removed floating login labels from the productive bundle and introduced clean accessible placeholders."
20
22
  ],
21
- "brandingCacheVersion": 96,
22
- "shellCacheVersion": 96,
23
- "nativeShellVersion": 96,
24
- "shellCacheTag": "96",
25
- "repositoryEntry": "nexowatt-eos-admin-repository-entry-v96.json"
23
+ "brandingCacheVersion": 98,
24
+ "shellCacheVersion": 98,
25
+ "nativeShellVersion": 98,
26
+ "shellCacheTag": "98",
27
+ "repositoryEntry": "nexowatt-eos-admin-repository-entry-v98.json"
26
28
  }
@@ -0,0 +1,33 @@
1
+ # NexoWatt EOS Admin 7.9.98 veröffentlichen
2
+
3
+ ## Empfohlener Weg: geprüftes TGZ veröffentlichen
4
+
5
+ Dadurch können keine alten oder lokal zusätzlich vorhandenen Dateien in das npm-Paket gelangen.
6
+
7
+ ```powershell
8
+ npm login
9
+ npm whoami
10
+ npm publish .\iobroker.eos-admin-7.9.98.tgz --dry-run --tag latest
11
+ npm publish .\iobroker.eos-admin-7.9.98.tgz --tag latest
12
+ ```
13
+
14
+ Der Dry-Run muss mit folgendem Paket enden:
15
+
16
+ ```text
17
+ + iobroker.eos-admin@7.9.98
18
+ ```
19
+
20
+ ## Veröffentlichung direkt aus dem Repository
21
+
22
+ Nur aus einem sauberen Arbeitsordner ausführen:
23
+
24
+ ```powershell
25
+ npm login
26
+ npm whoami
27
+ npm run sync:eos-version
28
+ npm run check:eos-release
29
+ npm publish --dry-run --tag latest
30
+ npm publish --tag latest
31
+ ```
32
+
33
+ Bei einem Fehler nicht veröffentlichen. Insbesondere müssen `package.json`, `package-lock.json`, `io-package.json`, `src-admin/package.json` und `src-admin/src/version.json` dieselbe Version enthalten.
package/README.md CHANGED
@@ -13,11 +13,15 @@ Standard-Port: 8081
13
13
 
14
14
  Damit überschreibt der Adapter den offiziellen `admin`-Adapter nicht mehr. Die alte ioBroker-Admin-Oberfläche kann parallel vorhanden bleiben, während NexoWatt-Systeme über `eos-admin.0` die EOS-Oberfläche nutzen.
15
15
 
16
- ## Aktuelle Stable 7.9.89
16
+ ## Aktueller Stable-Verkaufskandidat 7.9.98
17
17
 
18
- Die Verkaufsversion 7.9.89 verwendet die aktuelle **Übersicht** als Startseite, integriert EOS Assist in den Header und führt Zugangsverwaltung ausschließlich unter **Zugänge & Rechte**. Installer und Guest aktivieren ihr Konto beim ersten Login im normalen Anmeldeformular einmalig ohne Startpasswort und vergeben anschließend ein persönliches Passwort. Admin / Service bleibt unverändert.
18
+ Version 7.9.98 verwendet die native **Übersicht** als Startseite und ergänzt dort die ausschließlich lesende EMS-Live-Diagnose. Der Inhaltsbereich ist vertikal scrollbar, während Header und Hauptnavigation stehen bleiben.
19
19
 
20
- Der interne Admin und die interne BackItUp-Notfallreserve bleiben installiert, sind aber ausschließlich für Admin / Service sichtbar. Für den regulären Betrieb wird die NexoWatt Sicherung verwendet.
20
+ Verwaltete Installateur- und Endkundenkonten verwenden das Startpasswort `nexowatt`. Nach der ersten Anmeldung beziehungsweise nach einem Reset muss unmittelbar ein persönliches Passwort vergeben werden. Der Reset und die persönliche Passwortvergabe schreiben das reale ioBroker-Benutzerkennwort; EOS-Metadaten werden davon getrennt aktualisiert.
21
+
22
+ Admin/Service darf verwaltete Installateur- und Endkundenkonten zurücksetzen. Installateure dürfen ausschließlich ausdrücklich zugeordnete Endkundenkonten zurücksetzen. Admin-, Eigen-, deaktivierte und nicht verwaltete Konten bleiben geschützt.
23
+
24
+ EOS Assist ist in diesem Stand bewusst deaktiviert. Der interne Admin und die interne BackItUp-Notfallreserve bleiben installiert und sind ausschließlich für Admin/Service sichtbar. Für den regulären Betrieb wird die NexoWatt Sicherung verwendet.
21
25
 
22
26
  ## Installation über das NexoWatt Repository
23
27
 
@@ -29,7 +33,7 @@ Minimaler Repository-Eintrag:
29
33
  {
30
34
  "eos-admin": {
31
35
  "name": "eos-admin",
32
- "version": "7.9.89",
36
+ "version": "7.9.98",
33
37
  "title": "NexoWatt EOS Admin",
34
38
  "desc": {
35
39
  "de": "NexoWatt EOS Administrationsoberfläche als eigenständiger Adapter.",
@@ -126,12 +130,18 @@ iobroker restart eos-admin.0
126
130
 
127
131
  ## Veröffentlichung auf npm
128
132
 
133
+ Vor der Veröffentlichung müssen Paket- und Stabilitätsprüfung vollständig grün sein:
134
+
129
135
  ```bash
130
136
  npm login
131
- npm publish
137
+ npm whoami
138
+ npm run sync:eos-version
139
+ npm run check:eos-release
140
+ npm publish --dry-run --tag latest
141
+ npm publish --tag latest
132
142
  ```
133
143
 
134
- Die Version muss vor jedem erneuten Publish erhöht werden.
144
+ Die Version muss vor jedem erneuten Publish erhöht werden. Für 7.9.98 ist die Veröffentlichung des separat geprüften `iobroker.eos-admin-7.9.98.tgz` der sicherste Weg.
135
145
 
136
146
  ## Lizenz
137
147
 
@@ -0,0 +1,22 @@
1
+ # NexoWatt EOS Admin 7.9.98 – Stable-Verkaufskandidat
2
+
3
+ Version 7.9.98 beseitigt die vier zuletzt auf dem realen EOS-Testsystem festgestellten Verkaufsblocker, ohne die funktionierende EMS-Live-Diagnose oder die bestehenden Rollenrechte zu erweitern.
4
+
5
+ ## Korrigierte Bereiche
6
+
7
+ - **Cockpit vollständig bedienbar:** Der Kopf- und Navigationsbereich bleibt stehen; ausschließlich der Inhaltsbereich der Übersicht erhält einen vertikalen Scrollbereich. Dadurch sind auch lange EMS-Ereignislisten und die unteren Adapterkarten erreichbar.
8
+ - **Saubere Anmeldung:** Loginname und Passwort verwenden feste Platzhalter statt kollidierender Floating Labels. Die Karte ist moderat größer, wächst bei Fehlermeldungen automatisch und besitzt keine innere horizontale oder vertikale Scrollleiste.
9
+ - **Reales Kontopasswort beim Reset:** Ein zulässiger Reset schreibt das Startpasswort `nexowatt` mit der ioBroker-Passwortschnittstelle in das tatsächliche Benutzerkonto. Die EOS-Erstanmeldungsmerkmale werden getrennt davon aktualisiert, damit der neue Passwort-Hash nicht wieder überschrieben wird.
10
+ - **Persönliches Passwort nach der ersten Anmeldung:** Das neue Kennwort wird serverseitig validiert, in das reale Benutzerkonto geschrieben, anschließend geprüft und erst danach wird der Erstanmeldungsstatus beendet.
11
+ - **Saubere Rollenbegrenzung:** Admin/Service darf verwaltete Installateur- und Endkundenkonten zurücksetzen. Installateure dürfen ausschließlich ausdrücklich zugeordnete Endkundenkonten zurücksetzen. Admin-, Eigen-, deaktivierte und nicht verwaltete Konten bleiben geschützt.
12
+
13
+ ## Unveränderte Produktregeln
14
+
15
+ - Die EMS-Live-Kachel ist ausschließlich lesend und verändert keine Regelung, Geräte- oder Sollwerte.
16
+ - Der NexoWatt UI Adapter stellt die Diagnosewerte weiterhin unter `nexowatt-ui.*.info.adminOverview.*` bereit.
17
+ - EOS Assist bleibt bis zur vollständigen Neuimplementierung deaktiviert.
18
+ - Standardport des EOS Admin bleibt `8081`.
19
+
20
+ ## Freigabestatus
21
+
22
+ Alle paketinternen Prüfungen, die isolierte Browser-Geometrieprüfung, der simulierte Passwortablauf und der npm-Publish-Dry-Run müssen erfolgreich sein. Vor dem Verkauf ist zusätzlich die Checkliste in `RELEASE_ACCEPTANCE_V7.9.98.md` einmal auf einem realen EOS-Testcontroller abzuarbeiten.
@@ -0,0 +1,48 @@
1
+ # Release-Abnahme – NexoWatt EOS Admin 7.9.98
2
+
3
+ Diese Checkliste ist vor der Verkaufsfreigabe einmal vollständig auf einem realen EOS-Testcontroller abzuarbeiten.
4
+
5
+ ## Installation und Versionsstand
6
+
7
+ - [ ] `iobroker.eos-admin` zeigt Version `7.9.98`.
8
+ - [ ] `eos-admin.0` startet ohne Fehler und ist auf Port `8081` erreichbar.
9
+ - [ ] Nach `Strg + F5` werden ausschließlich die v98-Laufzeitdateien geladen.
10
+ - [ ] Ein kompletter Neustart des EOS-Controllers führt wieder zu einer erreichbaren Oberfläche.
11
+
12
+ ## Anmeldung
13
+
14
+ - [ ] Loginname und Passwort überlappen weder Rahmen noch Beschriftungen.
15
+ - [ ] Die Anmeldekarte besitzt keine innere horizontale oder vertikale Scrollleiste.
16
+ - [ ] Eine absichtlich falsche Anmeldung zeigt die vollständige Fehlermeldung innerhalb der Karte.
17
+ - [ ] Die Karte bleibt bei 1920 × 1080 und 1366 × 768 vollständig bedienbar.
18
+
19
+ ## Übersicht und EMS
20
+
21
+ - [ ] Header und Navigation bleiben stehen.
22
+ - [ ] Der Cockpit-Inhalt lässt sich bis zur letzten Karte vertikal scrollen.
23
+ - [ ] EMS-Budget, Ladeleistung, Speicher, Regelentscheidungen und Ereignisse werden angezeigt.
24
+ - [ ] Die Kachel aktualisiert sich mit realen Werten aus `nexowatt-ui.*.info.adminOverview.*`.
25
+ - [ ] Die EMS-Kachel besitzt keine Schreibfunktion und verändert keine Sollwerte.
26
+
27
+ ## Rollen und Passwort-Reset
28
+
29
+ - [ ] Admin/Service kann `guest`, `user` und `installer` zurücksetzen, sofern diese Konten ausdrücklich einer verwalteten EOS-Rolle zugeordnet sind.
30
+ - [ ] Installateur kann ausschließlich ausdrücklich zugeordnete Endkundenkonten zurücksetzen.
31
+ - [ ] Admin-Konto, eigenes Konto, deaktivierte und nicht verwaltete Konten werden abgewiesen.
32
+ - [ ] Nach dem Reset funktioniert die Anmeldung mit dem Startpasswort `nexowatt`.
33
+ - [ ] Das bisherige persönliche Kennwort ist nach dem Reset nicht mehr gültig.
34
+
35
+ ## Persönliches Passwort
36
+
37
+ - [ ] Die Anmeldung mit `nexowatt` öffnet unmittelbar die Seite „Persönliches Passwort festlegen“.
38
+ - [ ] Zu kurze, nicht übereinstimmende oder zu einfache Kennwörter werden verständlich abgewiesen.
39
+ - [ ] Ein gültiges neues Kennwort wird gespeichert.
40
+ - [ ] Nach erfolgreichem Speichern wird die alte Sitzung beendet.
41
+ - [ ] Die erneute Anmeldung funktioniert ausschließlich mit dem neu vergebenen Kennwort.
42
+ - [ ] Im nativen Benutzereditor ist weiterhin ein Passwort-Hash für das richtige Benutzerkonto vorhanden.
43
+
44
+ ## Abschluss
45
+
46
+ - [ ] EOS Assist bleibt ausgeblendet.
47
+ - [ ] Sicherung, Dienste, Module, Datenpunkte und Systemlogs bleiben erreichbar.
48
+ - [ ] Es treten während der Abnahme keine neuen Fehler im EOS-Admin-Log auf.
@@ -0,0 +1,32 @@
1
+ # Release Notes – NexoWatt EOS Admin 7.9.98
2
+
3
+ ## Übersicht und Bedienung
4
+
5
+ - Der Cockpit-Inhalt kann jetzt bis zum letzten Element vertikal gescrollt werden.
6
+ - Header und Hauptnavigation bleiben währenddessen stehen.
7
+ - Die EMS-Live-Diagnose, aktuelle Regelentscheidungen, Ereignisse und nachfolgende Adapterkarten werden nicht mehr am unteren Fensterrand abgeschnitten.
8
+
9
+ ## Anmeldung
10
+
11
+ - Überlappende MUI-Feldbeschriftungen wurden entfernt.
12
+ - Loginname und Passwort verwenden klar erkennbare Platzhalter.
13
+ - Die Anmeldekarte wurde nur moderat vergrößert und wächst bei einer Fehlermeldung automatisch.
14
+ - Innere horizontale und vertikale Scrollleisten bleiben ausgeschlossen.
15
+
16
+ ## Konten und Kennwörter
17
+
18
+ - Ein Kontoreset schreibt das reale ioBroker-Kontopasswort auf `nexowatt`.
19
+ - Der Passwortschreibvorgang wird mit der Controller-Passwortprüfung verifiziert, bevor Erfolg gemeldet wird.
20
+ - Die EOS-Erstanmeldungsmerkmale werden ausschließlich als Metadaten erweitert; der zuvor geschriebene Passwort-Hash wird nicht durch ein altes Benutzerobjekt überschrieben.
21
+ - Admin/Service darf verwaltete Installateur- und Endkundenkonten zurücksetzen.
22
+ - Installateure dürfen ausschließlich ausdrücklich zugeordnete Endkundenkonten zurücksetzen.
23
+ - Admin-, Eigen-, deaktivierte und nicht verwaltete Konten werden weiterhin abgewiesen.
24
+ - Die persönliche Passwortvergabe nach der Anmeldung mit `nexowatt` schreibt und prüft ebenfalls das reale Benutzerkennwort.
25
+ - Nach erfolgreicher Passwortvergabe werden vorhandene Anmeldesitzungen beendet und der Erstanmeldungsstatus entfernt.
26
+
27
+ ## Stabilität und Aktualisierung
28
+
29
+ - Paket-, Lockfile-, io-package-, Frontend- und Repository-Versionen werden vor der Veröffentlichung auf `7.9.98` synchronisiert.
30
+ - Alte Stable-Laufzeitdateien wie v97 werden beim Merge-Update automatisch entfernt.
31
+ - Die EMS-Live-Diagnose bleibt read-only.
32
+ - EOS Assist bleibt deaktiviert.
@@ -1,2 +1,2 @@
1
- import{j as s}from"./DefaultPropsProvider-BiXBMQYQ.js";import{i as _,a as B}from"./iobroker_admin__loadShare__react__loadShare__-LM7uyL45.js";import{b as S,r as J,c as P,s as w}from"./bootstrap-COulQZax-v84.js";import{i as n,a as f}from"./iobroker_admin__loadShare___mf_0_mui_mf_1_icons_mf_2_material__loadShare__-CJO5yP3h.js";import{i as v}from"./iobroker_admin__loadShare___mf_0_iobroker_mf_1_adapter_mf_2_react_mf_2_v5__loadShare__-LFZoiUTt.js";import{b as $}from"./blue-CagzI6CQ.js";import{g as b,v as M}from"./createTheme-DFX8CY6F.js";import"./_commonjsHelpers-CE1G-McA.js";import"./iobroker_admin__mf_v__runtimeInit__mf_v__-g2X2zhAf.js";import"./emotion-serialize.esm-Q4o_CgeF.js";import"./iobroker_admin__loadShare___mf_0_emotion_mf_1_react__loadShare__-BywLg1Xe.js";import"./ace-DEUjyTIn.js";import"./iobroker_admin__loadShare___mf_0_iobroker_mf_1_json_mf_2_config__loadShare__-CpA7pnS5.js";import"./iobroker_admin__loadShare__leaflet__loadShare__-CNUAG3AH.js";import"./ext-language_tools-ylAoucDh.js";import"./iobroker_admin__loadShare__react_mf_2_dropzone__loadShare__-CwjnV48g.js";import"./iobroker_admin__loadShare__react_mf_2_dom__loadShare__-CVeAXnkk.js";import"./preload-helper-BDBacUwf.js";import"./sdk-C-e-e2gd.js";import"./extends-CF3RwP-h.js";import"./assertThisInitialized-B0aQ9eG_.js";import"./useTheme-Bl-M1DYp.js";import"./index-DcK0RDrH.js";import"./ThemeProvider-BOFFjWAF.js";import"./emotion-cache.browser.esm-BgJfNZJN.js";import"./setYear-3ufv5yRD.js";import"./en-US-DBFJNIH6.js";const L="0 2px 2px 0 rgba(0, 0, 0, .14),0 3px 1px -2px rgba(0, 0, 0, .12),0 1px 5px 0 rgba(0, 0, 0, .2)",A="0 8px 17px 0 rgba(0, 0, 0, .2),0 6px 20px 0 rgba(0, 0, 0, .19)",x={root:g=>({padding:".75rem",[g.breakpoints.up("xl")]:{flex:"0 1 20%"}}),card:{display:"flex",minHeight:"235px",position:"relative",overflow:"hidden",maxHeight:"235p","&:hover":{overflowY:"auto",boxShadow:A}},cardInfo:{display:"flex",minHeight:"235px",position:"relative",overflow:"initial",maxHeight:"235p",flexDirection:"column","&:hover":{boxShadow:A}},cardInfoHead:g=>({position:"sticky",top:0,background:g.palette.background.default,display:"flex",width:"100%",justifyContent:"space-between",borderBottom:"1px solid",padding:"5px 5px 0px 5px"}),edit:{opacity:.6,userSelect:"none",pointerEvents:"none"},media:g=>({backgroundColor:g.palette.mode==="dark"?"#535353":"#e2e2e2",maxWidth:"30%"}),img:{width:120,height:"auto",padding:"2rem .5rem",maxWidth:"100%"},contentContainer:{display:"flex",flexDirection:"column",flex:1},content:{height:"170px",flexGrow:1,overflowY:"hidden"},action:{minHeight:"49px",padding:"16px 24px"},expand:{position:"absolute",right:"10px",bottom:"10px"},collapse:{minHeight:"100%",backgroundColor:"#ffffff",position:"absolute",width:"100%"},enabled:{color:"#ffffff",backgroundColor:$[500],position:"absolute",top:8,right:8,boxShadow:L,"&:hover":{backgroundColor:$[300]},"&:focus":{backgroundColor:$[500]}},disabled:{color:"#ffffff",backgroundColor:b[500],position:"absolute",top:8,right:8,boxShadow:L,"&:hover":{backgroundColor:b[300]},"&:focus":{backgroundColor:b[500]}},editButton:{color:"#ffffff",backgroundColor:b[500],position:"absolute",top:64,right:8,boxShadow:L,"&:hover":{backgroundColor:b[300]},"&:focus":{backgroundColor:b[500]}},deleteButton:{color:"#ffffff",backgroundColor:M[500],position:"absolute",top:120,right:8,boxShadow:L,"&:hover":{backgroundColor:M[300]},"&:focus":{backgroundColor:M[500]}},contentGrid:{height:"100%"},colorOrange:{color:"#ffcc80"},tooltip:{pointerEvents:"none"}};class O extends _.Component{constructor(t){super(t),this.state={expanded:!1}}static getDerivedStateFromProps(t){return t.edit?{expanded:!1}:null}handleExpandClick(){this.setState({expanded:!this.state.expanded})}renderContent(){return this.props.children}openDialog(){}renderDialogs(){return null}render(){var o,i;const t=this.props.edit?x.edit:void 0;let e=this.props.action.text||this.props.t("Link");return typeof e=="object"&&(e=e[this.props.lang]||e.en),s.jsx(n.Grid2,{size:{xs:12,sm:6,md:4,lg:3,xl:2},sx:v.Utils.getStyle(this.props.theme,x.root,this.props.style),style:{maxWidth:500},children:s.jsx(n.Link,{href:!this.props.edit&&this.props.action&&this.props.action.link?this.props.action.link:null,underline:"none",target:"_blank",rel:"noopener noreferrer",children:s.jsxs(n.Card,{sx:x.card,onClick:d=>{d.stopPropagation(),this.openDialog()},children:[this.props.showInfo&&!this.props.offline&&s.jsx(n.Button,{style:{...x.expand,...t},variant:"contained",size:"small",disabled:this.props.disabled,onClick:()=>this.handleExpandClick(),color:"primary",children:this.props.t("Info")}),s.jsxs(n.Box,{component:"div",sx:v.Utils.getStyle(this.props.theme,x.media,t,this.props.color&&{backgroundColor:this.props.color},{display:"flex",flexDirection:"column"}),children:[s.jsx(n.CardMedia,{style:x.img,component:"img",image:this.props.image}),s.jsx("div",{style:{flex:1,display:"flex",paddingBottom:"5px",paddingLeft:"5px"},children:this.props.warning?s.jsx(n.Tooltip,{title:this.props.warning,slotProps:{popper:{sx:x.tooltip}},children:s.jsx(f.Warning,{style:{alignSelf:"end",fontSize:36}})}):null})]}),s.jsxs("div",{style:{...x.contentContainer,...t},children:[s.jsx(n.CardContent,{style:x.content,children:s.jsxs(n.Grid2,{container:!0,direction:"column",wrap:"nowrap",style:x.contentGrid,children:[s.jsx(n.Typography,{gutterBottom:!0,variant:"h5",component:"h5",children:this.props.title}),this.renderContent()]})}),((o=this.props.action)==null?void 0:o.link)&&s.jsx(n.Divider,{}),((i=this.props.action)==null?void 0:i.link)&&s.jsx(n.CardActions,{style:x.action,children:s.jsx("div",{style:x.colorOrange,children:S.getText(e,this.props.lang)})})]}),this.props.showInfo&&s.jsx(n.Collapse,{style:x.collapse,in:this.state.expanded,timeout:"auto",unmountOnExit:!0,children:s.jsxs(n.Card,{sx:x.cardInfo,children:[s.jsxs(n.Box,{component:"div",sx:x.cardInfoHead,children:[s.jsx(n.Typography,{gutterBottom:!0,variant:"h5",component:"h5",children:this.props.t("Info")}),s.jsxs("div",{children:[s.jsx(n.IconButton,{size:"small",onClick:()=>{this.props.getHostDescriptionAll&&v.Utils.copyToClipboard(this.props.getHostDescriptionAll().text),this.props.openSnackBarFunc&&this.props.openSnackBarFunc()},children:s.jsx(v.IconCopy,{})}),s.jsx(n.IconButton,{size:"small",onClick:()=>this.handleExpandClick(),children:s.jsx(f.Close,{})})]})]}),s.jsx(n.CardContent,{children:this.props.getHostDescriptionAll().el})]})}),this.props.edit&&this.props.toggleActivation&&s.jsx(n.IconButton,{size:"large",sx:this.props.enabled?x.enabled:x.disabled,onClick:()=>this.props.toggleActivation(),children:s.jsx(f.Check,{})}),this.props.edit&&this.props.onEdit&&s.jsx(n.IconButton,{size:"large",sx:x.editButton,onClick:()=>this.props.onEdit(),children:s.jsx(f.Create,{})}),this.props.edit&&this.props.onRemove&&s.jsx(n.IconButton,{size:"large",sx:x.deleteButton,onClick:()=>this.props.onRemove(),children:s.jsx(f.Delete,{})}),this.renderDialogs()]})})})}}const I={closeButton:g=>({position:"absolute",right:8,top:8,color:g.palette.grey[500]}),paper:{},typography:{paddingRight:30},img:{width:"100%",height:"100%",objectFit:"contain"}};class R extends _.Component{cameraUpdateTimer;cameraRef;constructor(t){super(t),this.cameraUpdateTimer=null,this.cameraRef=_.createRef()}componentDidMount(){this.props.camera&&this.props.camera!=="text"&&(this.cameraUpdateTimer=setInterval(()=>this.updateCamera(),Math.max(parseInt(this.props.interval,10),500)),this.updateCamera())}componentWillUnmount(){this.cameraUpdateTimer&&(clearInterval(this.cameraUpdateTimer),this.cameraUpdateTimer=null)}updateCamera(){if(this.cameraRef.current)if(this.props.camera==="custom"){let t=this.props.cameraUrl;this.props.addTs&&(t.includes("?")?t+=`&ts=${Date.now()}`:t+=`?ts=${Date.now()}`),this.cameraRef.current.src=t}else{const t=this.props.camera.split("."),e=t.shift(),o=t.shift();this.props.socket.sendTo(`${e}.${o}`,"image",{name:t.pop(),width:this.cameraRef.current.width}).then(i=>{i&&i.data&&this.cameraRef.current&&(this.cameraRef.current.src=`data:image/jpeg;base64,${i.data}`)})}}render(){return s.jsxs(n.Dialog,{onClose:()=>this.props.onClose(),open:!0,maxWidth:"xl",fullWidth:!0,fullScreen:!0,sx:{"& .MuiDialog-paper":I.paper},children:[s.jsx(n.DialogTitle,{children:s.jsxs(n.Typography,{component:"h2",variant:"h6",sx:{"&.MuiTypography-root":I.typography},children:[this.props.name,s.jsx(n.IconButton,{size:"large",sx:I.closeButton,onClick:()=>this.props.onClose(),children:s.jsx(f.Close,{})})]})}),s.jsx(n.DialogContent,{dividers:!0,children:s.jsx("img",{style:I.img,src:"",alt:"camera",ref:this.cameraRef})}),s.jsx(n.DialogActions,{children:s.jsx(n.Button,{variant:"contained",autoFocus:!0,onClick:t=>{t.stopPropagation(),this.props.onClose()},color:"primary",startIcon:s.jsx(f.Close,{}),children:this.props.t("Close")})})]})}}const D={cameraImg:{width:"100%",height:"100%",maxWidth:200,maxHeight:200,objectFit:"contain"},imgContainer:{height:"100%"},hidden:{display:"none"},imgSkeleton:{transform:"initial"}};class E extends O{cameraRef;cameraUpdateTimer;interval;constructor(t){super(t),Object.assign(this.state,{error:!1,dialog:!1,loaded:!1}),this.cameraRef=_.createRef(),this.cameraUpdateTimer=null,this.interval=t.interval}updateCamera(){if(this.cameraRef.current)if(this.props.camera==="custom"){let t=this.props.cameraUrl;this.props.addTs&&(t.includes("?")?t+=`&ts=${Date.now()}`:t+=`?ts=${Date.now()}`),this.cameraRef.current.src=t}else{const t=this.props.camera.split("."),e=t.shift(),o=t.shift();this.props.socket.sendTo(`${e}.${o}`,"image",{name:t.pop(),width:this.cameraRef.current.width}).then(i=>{i!=null&&i.data&&this.cameraRef.current&&(this.cameraRef.current.src=`data:image/jpeg;base64,${i.data}`)}).catch(i=>window.alert(`Cannot send to instance: ${i}`))}}componentDidMount(){this.props.camera&&this.props.camera!=="text"&&(this.cameraUpdateTimer=setInterval(()=>this.updateCamera(),Math.max(parseInt(this.props.interval,10),500)),this.updateCamera())}componentWillUnmount(){this.cameraUpdateTimer&&(clearInterval(this.cameraUpdateTimer),this.cameraUpdateTimer=null)}renderDialogs(){return this.state.dialog?s.jsx(R,{socket:this.props.socket,camera:this.props.camera,name:this.props.title,t:this.props.t,onClose:()=>{this.props.camera&&this.props.camera!=="text"&&(this.cameraUpdateTimer&&clearInterval(this.cameraUpdateTimer),this.cameraUpdateTimer=setInterval(()=>this.updateCamera(),Math.max(parseInt(this.props.interval,10),500)),this.updateCamera()),this.setState({dialog:!1})},cameraUrl:this.props.cameraUrl}):null}handleImageLoad(){this.state.loaded||this.setState({loaded:!0,error:!1})}handleImageError(){this.state.error||this.setState({loaded:!1,error:!0})}renderContent(){if(this.props.camera==="custom"){let t=this.props.cameraUrl;return this.props.addTs&&(t.includes("?")?t+=`&ts=${Date.now()}`:t+=`?ts=${Date.now()}`),s.jsxs(n.Grid2,{container:!0,style:D.imgContainer,justifyContent:"center",alignItems:"center",children:[s.jsx("img",{ref:this.cameraRef,src:t,alt:"Camera",style:this.state.loaded&&!this.state.error?D.cameraImg:D.hidden,onLoad:()=>this.handleImageLoad(),onError:()=>this.handleImageError()}),!this.state.loaded&&!this.state.error&&s.jsx(n.Skeleton,{height:"100%",width:"100%",animation:"wave",style:D.imgSkeleton}),this.state.error&&s.jsx(f.Error,{fontSize:"large"})]})}return this.props.camera.startsWith("cameras.")?s.jsx("img",{ref:this.cameraRef,src:"",alt:"camera",style:D.cameraImg}):null}render(){return this.props.camera&&this.props.camera!=="text"?this.interval!==this.props.interval&&(this.interval=this.props.interval,this.cameraUpdateTimer&&clearInterval(this.cameraUpdateTimer),this.cameraUpdateTimer=setInterval(()=>this.updateCamera(),Math.max(parseInt(this.props.interval,10),500))):this.cameraUpdateTimer&&(clearInterval(this.cameraUpdateTimer),this.cameraUpdateTimer=null),super.render()}}const y={formControl:{marginTop:32},rootGrid:{flexGrow:1},closeButton:g=>({position:"absolute",right:8,top:8,color:g.palette.grey[500]}),paper:{},typography:{paddingRight:30},editItem:{marginTop:8},editItemSlider:{marginTop:24},labelSlider:{marginTop:16,fontSize:"1rem"},editColor:{width:"100%"}};class U extends _.Component{constructor(t){super(t),this.state={image:"",name:t.t("New link"),link:"http://",linkName:"",color:"",desc:"",addTs:!0,interval:5e3,camera:"text",cameraList:[],...t.link}}componentDidMount(){this.getCamerasInstances()}getCamerasInstances(){this.props.socket.getAdapterInstances("cameras",!0).then(t=>{const e=[],o=[];t.forEach(i=>{const d=i._id.replace("system.adapter.","");i.common&&i.common.enabled&&o.push(this.props.socket.getState(`${i._id}.alive`).then(r=>r&&r.val&&this.props.socket.sendTo(d,"list",null)).then(r=>r&&r.list&&r.list.forEach(a=>e.push({id:a.id,name:`${a.desc} [${d}/${a.name}]`}))))}),Promise.all(o).then(()=>this.setState({cameraList:e}))})}static getLinkNameFromLink(t){const e=t.trim().match(/^https?:\/\/([^/:]+)(:\d+)?/);return e?e[1]+(e[2]||""):""}render(){return s.jsxs(n.Dialog,{onClose:()=>this.props.onClose(),open:!0,maxWidth:"md",fullWidth:!0,sx:{"& .MuiDialog-paper":y.paper},children:[s.jsx(n.DialogTitle,{children:s.jsxs(n.Typography,{component:"h2",variant:"h6",sx:{"&.MuiTypography-root":y.typography},children:[this.props.isNew?this.props.t("Add new link: "):this.props.t("Edit link"),s.jsx(n.IconButton,{size:"large",sx:y.closeButton,onClick:()=>this.props.onClose(),children:s.jsx(f.Close,{})})]})}),s.jsx(n.DialogContent,{dividers:!0,children:s.jsxs(n.Grid2,{style:y.rootGrid,container:!0,direction:"row",children:[s.jsx(n.Grid2,{size:{xs:12,sm:6,md:8,lg:9},children:s.jsxs(n.Grid2,{container:!0,direction:"column",children:[s.jsxs(n.FormControl,{variant:"standard",style:y.formControl,children:[s.jsx(n.InputLabel,{id:"select-helper-label",children:this.props.t("Link type")}),s.jsxs(n.Select,{variant:"standard",labelId:"select-helper-label",value:this.state.camera,onChange:t=>this.setState({camera:t.target.value}),children:[s.jsx(n.MenuItem,{value:"text",children:s.jsx("em",{children:this.props.t("Description")})},"desc"),this.state.cameraList.map(t=>s.jsx(n.MenuItem,{value:t.id,children:t.name},t.id)),s.jsx(n.MenuItem,{value:"custom",children:this.props.t("Custom camera URL")},"custom")]})]}),s.jsx(n.TextField,{variant:"standard",label:this.props.t("URL"),value:this.state.link,style:y.editItem,onChange:t=>{const e=U.getLinkNameFromLink(this.state.link);e&&(!this.state.linkName||e===this.state.linkName)?this.setState({link:t.target.value,linkName:U.getLinkNameFromLink(t.target.value)}):this.setState({link:t.target.value})},slotProps:{input:{endAdornment:this.state.link?s.jsx(n.InputAdornment,{position:"end",children:s.jsx(n.IconButton,{tabIndex:-1,size:"small",onClick:()=>this.setState({link:""}),children:s.jsx(f.Close,{})})}):null}}}),s.jsx(n.TextField,{variant:"standard",style:y.editItem,label:this.props.t("Name"),value:this.state.name||"",onChange:t=>this.setState({name:t.target.value}),slotProps:{input:{endAdornment:this.state.name?s.jsx(n.InputAdornment,{position:"end",children:s.jsx(n.IconButton,{tabIndex:-1,size:"small",onClick:()=>this.setState({name:""}),children:s.jsx(f.Close,{})})}):null}}}),this.state.link?s.jsx(n.TextField,{variant:"standard",style:y.editItem,label:this.props.t("Link name"),value:this.state.linkName||"",onChange:t=>this.setState({linkName:t.target.value}),slotProps:{input:{endAdornment:this.state.linkName?s.jsx(n.InputAdornment,{position:"end",children:s.jsx(n.IconButton,{tabIndex:-1,size:"small",onClick:()=>this.setState({linkName:""}),children:s.jsx(f.Close,{})})}):null}}}):null,this.state.camera==="custom"||this.state.camera==="text"?s.jsx(n.TextField,{variant:"standard",style:y.editItem,label:this.state.camera==="custom"?this.props.t("Camera URL"):this.props.t("Description"),value:this.state.desc||"",onChange:t=>this.setState({desc:t.target.value}),slotProps:{input:{endAdornment:this.state.desc?s.jsx(n.InputAdornment,{position:"end",children:s.jsx(n.IconButton,{tabIndex:-1,size:"small",onClick:()=>this.setState({desc:""}),children:s.jsx(f.Close,{})})}):null}}}):null,this.state.camera==="custom"?s.jsx(n.FormControlLabel,{style:y.editItem,control:s.jsx(n.Checkbox,{checked:this.state.addTs,onChange:t=>this.setState({addTs:t.target.checked})}),label:this.props.t("Add timestamp to URL")}):null,this.state.camera!=="text"?s.jsx(n.Typography,{style:y.labelSlider,gutterBottom:!0,children:"Polling interval in ms"}):null,this.state.camera!=="text"?s.jsx(n.Slider,{style:y.editItemSlider,value:this.state.interval,getAriaValueText:()=>`${this.state.interval}ms`,onChange:(t,e)=>this.setState({interval:e}),step:100,min:500,max:6e4,valueLabelDisplay:"on"}):null,s.jsx("div",{style:{...y.editItem,width:50},children:s.jsx(n.TextField,{variant:"standard",fullWidth:!0,label:this.props.t("Color"),style:y.editColor,type:"color",value:this.state.color,onChange:t=>this.setState({color:t.target.value})})}),s.jsx(v.UploadImage,{disabled:!1,crop:!0,maxSize:256*1024,icon:this.state.image,removeIconFunc:()=>this.setState({image:""}),onChange:t=>this.setState({image:t})})]})}),s.jsx(n.Grid2,{size:{xs:12,sm:6,md:4,lg:3},children:this.state.camera==="text"?s.jsx(O,{image:this.state.image,title:this.state.name,action:{link:this.state.link,text:this.state.linkName},t:this.props.t,lang:this.props.lang,style:{width:"100% !important",maxWidth:"100% !important",marginLeft:"8px"},color:this.state.color,enabled:!0,theme:this.props.theme,children:this.state.desc}):s.jsx(E,{interval:this.state.interval,camera:this.state.camera,addTs:this.state.addTs,style:{width:"100% !important",maxWidth:"100% !important",marginLeft:"8px"},image:this.state.image,title:this.state.name,socket:this.props.socket,action:{link:this.state.link,text:this.state.linkName},t:this.props.t,lang:this.props.lang,color:this.state.color,enabled:!0,cameraUrl:this.state.desc,theme:this.props.theme})})]})}),s.jsxs(n.DialogActions,{children:[s.jsx(n.Button,{variant:"contained",autoFocus:!0,onClick:()=>{this.props.onClose({link:this.state.link,name:this.state.name,desc:this.state.desc,linkName:this.state.linkName,color:this.state.color,image:this.state.image,addTs:this.state.addTs,camera:this.state.camera,interval:this.state.interval})},color:"primary",startIcon:this.props.isNew?s.jsx(f.Add,{}):s.jsx(f.Check,{}),children:this.props.isNew?this.props.t("Add"):this.props.t("Save")}),s.jsx(n.Button,{variant:"contained",onClick:()=>this.props.onClose(),color:"grey",startIcon:s.jsx(f.Close,{}),children:this.props.t("Close")})]})]})}}class W extends B.Component{constructor(t){super(t),this.state={inProgress:!1,success:!1,error:"",finished:!1}}render(){return s.jsxs(n.Dialog,{open:!0,maxWidth:"lg",fullWidth:!0,children:[s.jsx(n.DialogTitle,{children:v.I18n.t("Node.js upgrade")}),s.jsxs(n.DialogContent,{style:{height:100,padding:"0 20px",overflow:"hidden"},children:[this.state.finished?null:s.jsx(n.Typography,{children:v.I18n.t("Performing this update will restart the js-controller afterwards!")}),this.state.inProgress?s.jsx(n.Box,{sx:{display:"flex",justifyContent:"center"},children:s.jsx(n.CircularProgress,{})}):null,this.state.success?s.jsx(n.Typography,{children:v.I18n.t("Node.js update successful, restarting controller now!")}):null,this.state.error?s.jsx(n.Typography,{sx:{color:"red"},children:v.I18n.t("Node.js update failed: %s",this.state.error)}):null]}),s.jsxs(n.DialogActions,{children:[s.jsx(n.Button,{disabled:this.state.inProgress||this.state.finished,color:"primary",variant:"contained",startIcon:s.jsx(f.Refresh,{}),onClick:()=>this.updateNodeJsVersion(),children:v.I18n.t("Upgrade")}),s.jsx(n.Button,{disabled:this.state.inProgress,variant:"contained",onClick:()=>{this.props.onClose()},color:"primary",startIcon:s.jsx(f.Close,{}),children:v.I18n.t("Close")})]})]})}async updateNodeJsVersion(){this.setState({inProgress:!0});const t=await this.props.socket.upgradeOsPackages(this.props.hostId,[{name:"nodejs"}],!0);this.setState({inProgress:!1,success:t.success,error:t.error,finished:!0})}}const m={button:{position:"absolute",bottom:16,right:16},saveButton:g=>({backgroundColor:g.palette.success.main,right:80,"&:hover":{backgroundColor:g.palette.success.dark}}),addButton:g=>({backgroundColor:g.palette.secondary.main,right:144,"&:hover":{backgroundColor:g.palette.secondary.dark}}),closeButton:g=>({backgroundColor:g.palette.error.main,"&:hover":{backgroundColor:g.palette.error.dark}}),bold:{fontWeight:"bold"},hostOffline:{color:"#bb0000"},updateExists:{color:"#c28700",marginRight:4},updateNo:{color:"#00b204",marginRight:4},nodeUpdate:{opacity:.6},instanceNumber:{opacity:.7,fontSize:16},updateIcon:{cursor:"pointer",fontSize:16},tooltip:{pointerEvents:"none"},viewModeDiv:{display:"flex",flexFlow:"wrap",overflow:"auto",justifyContent:"left"}},T={Uptime:S.formatSeconds,"System uptime":S.formatSeconds,RAM:S.formatRam,Speed:S.formatSpeed,"Disk size":S.formatBytes,"Disk free":S.formatBytes};class C extends B.Component{#t=1800*1e3;#e=300*1e3;#s=60*1e3;introLinksOriginal;deactivatedOriginal;t;getDataTimeout;constructor(t){super(t),this.state={instances:null,deactivated:[],edit:!1,link:null,introLinks:[],editLink:!1,editLinkIndex:-1,openSnackBar:!1,hasUnsavedChanges:!1,reverseProxy:null,alive:{},hostsData:{},hosts:null,hostTimeDiffMap:new Map,hostDataTimestampMap:new Map,nodeUpdateSupported:!1,nodeUpdateDialog:null},this.t=t.t}checkBackendTime(){const t=this.state.hostTimeDiffMap,e=this.state.hostDataTimestampMap,o=Date.now();for(const[i,d]of Object.entries(this.state.hostsData)){const r=Math.abs(d.time-o);t.set(i,r),e.set(i,o)}this.setState({hostTimeDiffMap:t,hostDataTimestampMap:e})}async componentDidMount(){var i;let t=null,e=!1;try{[t,e]=await Promise.all([this.props.socket.getObject(`system.adapter.${this.props.adminInstance}`),this.props.socket.checkFeatureSupported("CONTROLLER_OS_PACKAGE_UPGRADE")])}catch(d){if(String(window.NEXOWATT_EOS_ACCESS_ROLE||"unknown").toLowerCase()==="admin")throw d}const o=((i=t==null?void 0:t.native)==null?void 0:i.reverseProxy)||[];await new Promise(d=>this.setState({reverseProxy:o,nodeUpdateSupported:e},()=>d())),await this.getData(),this.props.instancesWorker.registerHandler(this.getDataDelayed),this.props.hostsWorker.registerHandler(this.updateHosts),this.props.hostsWorker.registerAliveHandler(this.updateHostsAlive),this.checkBackendTime()}componentWillUnmount(){this.getDataTimeout&&(clearTimeout(this.getDataTimeout),this.getDataTimeout=void 0),this.props.instancesWorker.unregisterHandler(this.getDataDelayed),this.props.hostsWorker.unregisterHandler(this.updateHosts),this.props.hostsWorker.unregisterAliveHandler(this.updateHostsAlive)}updateHostsAlive=async t=>{const e=JSON.parse(JSON.stringify(this.state.alive)),o=[];if(t.find(i=>i.type==="deleted")){this.getDataDelayed();return}if(t.forEach(i=>{!!e[i.id]!=!!i.alive&&(e[i.id]=i.alive,o.push(i.id))}),o.length){const i=JSON.parse(JSON.stringify(this.state.hostsData)),d=new Map(this.state.hostDataTimestampMap),r=Date.now();(await Promise.all(o.map(l=>this.getHostData(l,e[l])))).forEach(l=>{i[l.id]=C.preprocessHostData(l.data),d.set(l.id,r)}),this.setState({alive:e,hostsData:i,hostDataTimestampMap:d},()=>this.checkBackendTime())}};updateHosts=t=>{let e=[];if(t.find(o=>!o.obj)){this.getDataDelayed();return}if(e=t.map(o=>o.id),e.length){const o=JSON.parse(JSON.stringify(this.state.hostsData)),i=new Map(this.state.hostDataTimestampMap),d=Date.now();Promise.all(e.map(r=>this.getHostData(r))).then(r=>{r.forEach(a=>{o[a.id]=C.preprocessHostData(a.data),i.set(a.id,d)}),this.setState({hostsData:o,hostDataTimestampMap:i})})}};async activateEditMode(){var i;const t=await this.props.socket.getSystemConfig(!0),e=await this.getInstances(!0,null,t),o=(i=t==null?void 0:t.native)!=null&&i.introLinks?t.native.introLinks:[];this.introLinksOriginal=JSON.stringify(o),this.deactivatedOriginal=JSON.parse(JSON.stringify(e.deactivated)),this.setState({instances:e.instances,deactivated:e.deactivated,edit:!0,introLinks:o,hasUnsavedChanges:!1})}deactivateEditMode(){this.state.hasUnsavedChanges,this.setState({deactivated:this.deactivatedOriginal,introLinks:JSON.parse(this.introLinksOriginal),hasUnsavedChanges:!1,edit:!1},()=>{this.deactivatedOriginal=null,this.introLinksOriginal=null})}toggleCard(t,e){if(!this.state.instances||!this.state.instances.length)return;const o=JSON.parse(JSON.stringify(this.state.deactivated)),i=o.indexOf(`${t}_${e}`);i!==-1?o.splice(i,1):(o.push(`${t}_${e}`),o.sort());const d=JSON.stringify(o)!==JSON.stringify(this.deactivatedOriginal)||JSON.stringify(this.state.introLinks)!==this.introLinksOriginal;this.setState({deactivated:o,hasUnsavedChanges:d})}getInstancesCards(){var t;return(t=this.state.instances)==null?void 0:t.map(e=>{var i,d;const o=!((i=this.state.deactivated)!=null&&i.includes(`${e.id}_${e.linkName}`));if(o||this.state.edit){let r=e.link?e.link.replace(/^https?:\/\//,""):"";if(r=r.split("/")[0],e.id===this.props.adminInstance)return null;let a=window.isFinite(e.id.split(".").pop());a&&(a=!!((d=this.state.instances)!=null&&d.find(k=>k.id!==e.id&&e.name===k.name&&e.id.split(".")[0]===k.id.split(".")[0])));const l=this.state.hostsData?this.state.hostsData[e.id]:null,h=this.state.hostTimeDiffMap.get(e.id)??0,p=this.state.hostDataTimestampMap.get(e.id)??0,u=Date.now()-p<this.#e;return s.jsx(O,{image:e.image,title:s.jsxs(s.Fragment,{children:[s.jsx("span",{style:e.name&&e.name.length>12?{fontSize:"1rem"}:void 0,children:e.name}),a?s.jsxs("span",{style:m.instanceNumber,children:[".",e.id.split(".").pop()]}):null]}),action:{link:e.link,text:r},t:this.props.t,lang:this.props.lang,color:e.color,showInfo:!!e.info,edit:this.state.edit,offline:l&&l.alive===!1,warning:h>this.#t&&u?this.t("Backend time differs by %s minutes",Math.round(h/this.#s).toString()):null,enabled:o,disabled:!l||typeof l!="object",getHostDescriptionAll:()=>this.getHostDescriptionAll(e.id),toggleActivation:()=>this.toggleCard(e.id,e.linkName),openSnackBarFunc:()=>this.setState({openSnackBar:!0}),theme:this.props.theme,children:e.description||this.getHostDescription(e.id)},`${e.id}_${e.link}`)}return null})}toggleLinkCard(t){const e=JSON.parse(JSON.stringify(this.state.introLinks));e[t].enabled=!e[t].enabled;const o=JSON.stringify(this.state.deactivated)!==JSON.stringify(this.deactivatedOriginal)||JSON.stringify(e)!==this.introLinksOriginal;this.setState({introLinks:e,hasUnsavedChanges:o})}getLinkCards(){var t;return(t=this.state.introLinks)==null?void 0:t.map((e,o)=>!e.enabled&&!this.state.edit?null:e.camera==="custom"?s.jsx(E,{image:e.image,title:e.name,action:{link:e.link,text:e.linkName},t:this.props.t,socket:this.props.socket,color:e.color,edit:this.state.edit,interval:e.interval,camera:e.camera,addTs:e.addTs,onEdit:()=>{var i;return this.setState({editLink:!0,editLinkIndex:o,link:JSON.parse(JSON.stringify((i=this.state.introLinks)==null?void 0:i[o]))})},onRemove:()=>{const i=JSON.parse(JSON.stringify(this.state.introLinks));i.splice(o,1);const d=JSON.stringify(this.state.deactivated)!==JSON.stringify(this.deactivatedOriginal)||JSON.stringify(i)!==this.introLinksOriginal;this.setState({introLinks:i,hasUnsavedChanges:d})},enabled:e.enabled,lang:this.props.lang,toggleActivation:()=>this.toggleLinkCard(o),cameraUrl:e.desc,theme:this.props.theme},`link${o}`):s.jsx(O,{image:e.image,title:e.name,action:{link:e.link,text:e.linkName},t:this.props.t,color:e.color,edit:this.state.edit,onEdit:()=>{var i;return this.setState({editLink:!0,editLinkIndex:o,link:JSON.parse(JSON.stringify((i=this.state.introLinks)==null?void 0:i[o]))})},onRemove:()=>{const i=JSON.parse(JSON.stringify(this.state.introLinks));i.splice(o,1);const d=JSON.stringify(this.state.deactivated)!==JSON.stringify(this.deactivatedOriginal)||JSON.stringify(i)!==this.introLinksOriginal;this.setState({introLinks:i,hasUnsavedChanges:d})},enabled:e.enabled,lang:this.props.lang,toggleActivation:()=>this.toggleLinkCard(o),theme:this.props.theme,children:e.desc||""},`link${o}`))}editLinkCard(){return this.state.editLink?s.jsx(U,{link:this.state.link,socket:this.props.socket,isNew:this.state.editLinkIndex===-1,t:this.props.t,lang:this.props.lang,theme:this.props.theme,onClose:t=>{if(t){const e=JSON.parse(JSON.stringify(this.state.introLinks));this.state.editLinkIndex===-1?(t.enabled=!0,e.push(t)):(t.enabled=e[this.state.editLinkIndex].enabled,e[this.state.editLinkIndex]=t);const o=JSON.stringify(this.state.deactivated)!==JSON.stringify(this.deactivatedOriginal)||JSON.stringify(e)!==this.introLinksOriginal;this.setState({introLinks:e,editLink:!1,hasUnsavedChanges:o,link:null})}else this.setState({editLink:!1})}}):null}getButtons(){const t=[];return this.state.edit?(t.push(s.jsx(n.Fab,{color:"primary",size:"small",sx:v.Utils.getStyle(this.props.theme,m.button,m.addButton),onClick:()=>this.setState({editLink:!0,editLinkIndex:-1,link:{}}),children:s.jsx(f.Add,{})},"add")),t.push(s.jsx(n.Fab,{size:"small",color:"primary",disabled:!this.state.hasUnsavedChanges,sx:v.Utils.getStyle(this.props.theme,m.button,m.saveButton),onClick:()=>this.saveCards(),children:s.jsx(f.Check,{})},"save")),t.push(s.jsx(n.Fab,{size:"small",color:"primary",sx:v.Utils.getStyle(this.props.theme,m.button,m.closeButton),onClick:()=>this.deactivateEditMode(),children:s.jsx(f.Close,{})},"close"))):t.push(s.jsx(n.Fab,{color:"primary",size:"small",style:m.button,onClick:()=>this.activateEditMode(),children:s.jsx(f.Create,{})},"edit")),t}async saveCards(){const t=await this.props.socket.getSystemConfig(!0);let e=!1;JSON.stringify(t.common.intro)!==JSON.stringify(this.state.deactivated)&&(t.common.intro=this.state.deactivated,e=!0),!e&&JSON.stringify(t.native.introLinks)!==JSON.stringify(this.state.introLinks)&&(e=!0,t.native.introLinks=this.state.introLinks),e?this.props.socket.setSystemConfig(t).then(()=>this.props.showAlert("Updated","success")).catch(o=>{console.log(o),this.props.showAlert(o,"error")}).then(()=>this.setState({edit:!1})):this.setState({edit:!1})}async getHostData(t,e){let o;if(e!==void 0)o={val:e};else try{o=await this.props.socket.getState(`${t}.alive`)}catch(r){console.error(`Cannot get state ${t}.alive: ${r}`),o={val:!1}}let i={alive:!1};if(o!=null&&o.val)try{i=await this.props.socket.getHostInfo(t,!1,1e4),i&&typeof i=="object"&&i.alive!==!1&&(i.alive=!0)}catch(r){console.error(`Cannot get host info for ${t}: ${r}`),i={alive:!1}}else i={alive:!1};const d=await this.props.socket.getForeignStates(`${t}.versions.*`);return Object.keys(d).forEach(r=>i[`_${r.split(".").pop()}`]=d[r].val),{id:t,data:i}}async getHostsData(t){const e=t.map(l=>this.getHostData(l._id)),o=await Promise.all(e),i={},d={},r=new Map(this.state.hostDataTimestampMap),a=Date.now();return o.forEach(l=>{i[l.id]=C.preprocessHostData(l.data),d[l.id]=l.data.alive,r.set(l.id,a)}),this.setState({hostDataTimestampMap:r}),{hostsData:i,alive:d}}addLinks(t,e,o,i,d,r){const a={id:t.id,name:t.name,description:t.description,color:t.color,image:t.icon,info:""},l=J(t.link,e.name,o,{instances:i,hostname:this.props.hostname,adminInstance:this.props.adminInstance,hosts:d}),h=this.state.reverseProxy;let p=null;if(h!=null&&h.length){const c=window.location.pathname;p=h.find(u=>{if(!u.globalPath)return!1;const k=u.globalPath.endsWith("/")?u.globalPath:`${u.globalPath}/`;return c===k||c.startsWith(k)})||null}if(l.length===1){a.link=l[0].url,a.port=l[0].port,a.link=P(a.link,a.id,i,p)||a.link;const c=r.find(u=>u.link===a.link);c?console.log(`Double links: "${a.id}" and "${c.id}"`):r.push(a)}else l.length>1&&l.forEach(c=>{const u=r.find(k=>k.link===c.url);if(u)console.log(`Double links: "${a.id}" and "${u.id}"`);else{const k={...a,link:c.url,port:c.port};k.link=P(k.link,a.id,i,p)||k.link,r.push(k)}})}static getText(t,e){return t?typeof t=="object"?t[e]||t.en||"":t||"":""}static normalizeLinks(t,e,o){if(!t.common.localLinks&&!t.common.localLink&&!t.common.welcomeScreen&&!t.common.welcomeScreenPro)return null;const i={id:t._id.replace("system.adapter.",""),link:"",name:C.getText(t.common.titleLang||t.common.title||t.common.name,e),order:t.common.order||1e3,intro:!0,description:C.getText(t.common.desc,e),icon:t.common.icon?`adapter/${t.common.name}/${t.common.icon}`:"img/no-image.svg"};let d=[];if(t.common.localLink)if(typeof t.common.localLink=="string")d.push({...i,link:t.common.localLink});else{const r=t.common.localLink;if(r.link){const a={...i,link:r.link};r.color&&(a.color=r.color),r.order!==void 0&&typeof r.order=="number"&&(a.order=r.order),r.icon&&r.img&&(a.icon=r.icon||r.img),d.push(a)}else console.warn(`Unknown localLink structure: ${JSON.stringify(t.common.localLink)}`)}if(t.common.localLinks&&typeof t.common.localLinks=="object"&&Object.keys(t.common.localLinks).forEach(r=>{const a=t.common.localLinks[r];if(typeof a=="string")d.push({...i,link:a});else{const l=a;if(l.link){const h={...i,id:t._id.replace("system.adapter.","")+(r==="_default"?"":` ${r}`),link:l.link,name:i.name+(r==="_default"?"":` ${r}`)};l.color&&(h.color=l.color),l.order!==void 0&&(h.order=parseInt(l.order,10)||1e3),l.icon&&l.img&&(h.icon=l.icon||l.img),l.description&&(h.description=C.getText(l.description,e)),l.pro!==void 0&&(typeof l.pro=="string"?h.pro=l.pro:h.pro=`${t.common.name}/index.html`),l.cloud!==void 0&&(h.cloud=l.cloud),l.intro!==void 0&&(h.intro=l.intro===!0),l.name&&(h.name=C.getText(l.name,e)),r==="_default"&&(h.default=!0),d.push(h)}else console.warn(`Unknown localLinks structure: ${JSON.stringify(a)}`)}}),t.common.welcomeScreen&&typeof t.common.welcomeScreen=="object"&&((Array.isArray(t.common.welcomeScreen)?t.common.welcomeScreen:[t.common.welcomeScreen]).forEach(a=>{if(a.link){const l={...i,id:`${t._id.replace("system.adapter.","")} cloud`,link:`%web_protocol%://%web_bind%:%web_port%/${a.link}`,cloud:a.link};if(a.color&&(l.color=a.color),a.order!==void 0&&typeof a.order=="number"&&(l.order=a.order),a.icon&&a.img&&(l.icon=a.icon||a.img),a.localLinks){const h=t.common.localLinks[a.localLinks];h&&typeof h=="string"?l.link=h:h&&typeof h=="object"&&h.link&&(l.link=h.link)}a.name&&(l.name=C.getText(a.name,e)),d.push(l)}}),t.common.welcomeScreenPro&&typeof t.common.welcomeScreenPro=="object"&&(Array.isArray(t.common.welcomeScreenPro)?t.common.welcomeScreenPro:[t.common.welcomeScreenPro]).forEach(l=>{if(l.link){const h={...i,id:`${t._id.replace("system.adapter.","")} pro`,link:`%web_protocol%://%web_bind%:%web_port%/${l.link}`,pro:l.link};if(l.color&&(h.color=l.color),l.order!==void 0&&typeof l.order=="number"&&(h.order=l.order),l.icon&&l.img&&(h.icon=l.icon||l.img),l.localLinks){const p=t.common.localLinks[l.localLinks];p&&typeof p=="string"?h.link=p:p&&typeof p=="object"&&p.link&&(h.link=p.link)}l.name&&(h.name=C.getText(l.name,e)),d.push(h)}})),d.forEach(r=>{!r.icon.startsWith("adapter/")&&!r.icon.startsWith("data:image/")&&!r.icon.startsWith("http://")&&!r.icon.startsWith("https://")&&r.icon!=="img/no-image.svg"&&(r.icon=`adapter/${t.common.name}/${r.icon}`)}),o){const r={};d.forEach(a=>{r[a.link]?(a.color&&(r[a.link].color=a.color),a.icon&&(r[a.link].icon=a.icon),a.cloud&&(r[a.link].cloud=a.cloud),a.pro&&(r[a.link].pro=a.pro),a.intro!==void 0&&(r[a.link].intro=a.intro),a.name&&typeof a.name=="object"&&(r[a.link].name=a.name),a.order!==void 0&&(r[a.link].order=a.order),a.default&&(r[a.link].default=a.default)):r[a.link]=a}),d=Object.values(r)}return d.sort((r,a)=>r.default===void 0&&a.default===void 0?r.order===void 0&&a.order===void 0?0:r.order===void 0?-1:a.order===void 0?1:r.order-a.order:r.default===void 0?-1:a.default===void 0?1:r.order===void 0&&a.order===void 0?0:r.order===void 0?-1:a.order===void 0?1:r.order-a.order),d}async getInstances(t,e,o){e=e||this.state.hosts;const i={};e.forEach(d=>i[d._id]=d);try{const d=await this.props.socket.getAdapterInstances("",t);let r=o.common.intro||[];Array.isArray(r)||(r=Object.keys(r),r.sort());const a=[],l={};d.forEach(p=>l[p._id]=p),d.forEach(p=>{if(!p)return;const c=p.common||null,u=p._id.split("."),k=parseInt(u.pop(),10);let j;if(c!=null&&c.name&&typeof c.name=="object"){const N=c==null?void 0:c.name;j=N[this.props.lang]||N.en}else j=(c==null?void 0:c.name)||"";if(!(j==="admin"&&c.localLink===(this.props.hostname||""))&&j!=="web"&&!(j&&j!=="vis-web-admin"&&j.match(/^vis-/)&&j!=="vis-2")&&!(j!=null&&j.match(/^icons-/))&&c&&(c.enabled||c.onlyWWW)){const N=C.normalizeLinks(p,this.props.lang,!0);N&&N.forEach(H=>this.addLinks(H,c,k,l,i,a))}}),a.forEach(p=>{p.link&&(p.linkName=p.link.replace("https://","").replace("http://","").replace(/^[^_]+:/,""))}),a.sort((p,c)=>{if(p.order!==void 0||c.order!==void 0){if(p.order=p.order===void 0?1e3:p.order,c.order=c.order===void 0?1e3:c.order,p.order<c.order)return-1;if(p.order>c.order)return 1}return p.id>c.id?1:p.id<c.id?-1:0}),e==null||e.forEach(p=>{const c=p==null?void 0:p.common;let u=c==null?void 0:c.name;if(typeof u=="object"&&u&&(u=u[this.props.lang]||u.en),c){const k={id:p._id,name:u||"",color:"",image:c.icon||"img/no-image.svg",info:this.t("Info"),linkName:""};a.push(k)}});const h=[];return r.forEach(p=>{a.find(c=>p===`${c.id}_${c.linkName}`)&&h.push(p)}),r=h,{instances:a,deactivated:r}}catch(d){return console.log(d),{instances:[],deactivated:[]}}}getHostDescription(t){const e=this.state.hostsData?this.state.hostsData[t]:null;if(e&&e.alive===!1)return s.jsx("div",{style:m.hostOffline,children:this.props.t("Offline")});let o="",i="";if(e){try{e._nodeNewest&&e["Node.js"]&&w.gt(e._nodeNewest,e["Node.js"].replace(/^v/,""))&&(o=e._nodeNewest)}catch{}try{e._nodeNewest!==e._nodeNewestNext&&e._nodeNewestNext&&e["Node.js"]&&e._nodeNewest&&w.gt(e._nodeNewestNext,e["Node.js"].replace(/^v/,""))&&w.gt(e._nodeNewestNext,e._nodeNewest)&&(o+=(o?" / ":"")+e._nodeNewestNext)}catch{}if(o){const d=this.state.nodeUpdateSupported&&e.Platform==="linux";o=s.jsx(n.Tooltip,{title:this.props.t("Some updates available"),slotProps:{popper:{sx:m.tooltip}},children:s.jsxs("span",{style:{...m.nodeUpdate,display:"inline-flex"},children:["(",o,")",d?s.jsx(f.Refresh,{style:m.updateIcon,onClick:()=>this.setState({nodeUpdateDialog:{hostId:t,version:e._nodeNewestNext}})}):null]})})}try{e._npmNewest&&e.NPM&&w.gt(e._npmNewest,e.NPM)&&(i=e._npmNewest)}catch{}try{e._npmNewest!==e._npmNewestNext&&e._npmNewestNext&&e.NPM&&e._npmNewest&&w.gt(e._npmNewestNext,e.NPM)&&w.gt(e._npmNewestNext,e._npmNewest)&&(i+=(i?" / ":"")+e._npmNewestNext)}catch{}i&&(i=s.jsx(n.Tooltip,{title:this.props.t("Some updates available"),slotProps:{popper:{sx:m.tooltip}},children:s.jsxs("span",{style:m.nodeUpdate,children:["(",i,")"]})}))}return e&&typeof e=="object"?s.jsxs("ul",{style:{textTransform:"none"},children:[s.jsx("li",{children:s.jsxs("span",{children:[s.jsxs("span",{style:m.bold,children:[this.t("Platform"),": "]}),e.Platform||"--"]})}),s.jsx("li",{children:s.jsxs("span",{children:[s.jsxs("span",{style:m.bold,children:[this.t("RAM"),": "]}),T.RAM(e.RAM)]})}),s.jsx("li",{children:s.jsxs("span",{children:[s.jsxs("span",{style:m.bold,children:[this.t("Node.js"),": "]}),s.jsx("span",{style:o?m.updateExists:m.updateNo,children:e["Node.js"]||"--"}),o]})}),s.jsx("li",{children:s.jsxs("span",{children:[s.jsxs("span",{style:m.bold,children:[this.t("NPM"),": "]}),s.jsx("span",{className:i?m.updateExists:m.updateNo,children:e.NPM||"--"}),i]})})]}):s.jsxs("ul",{children:[s.jsx(n.Skeleton,{}),s.jsx(n.Skeleton,{}),s.jsx(n.Skeleton,{}),s.jsx(n.Skeleton,{})]})}getHostDescriptionAll(t){const e=this.state.hostsData?this.state.hostsData[t]:null;return{el:s.jsx("ul",{style:{textTransform:"none"},children:e&&typeof e=="object"&&Object.keys(e).filter(o=>!o.startsWith("_")&&e[o]!==null&&e[o]!==void 0).map(o=>s.jsx("li",{children:e&&typeof e=="object"?s.jsxs("span",{children:[s.jsxs("span",{style:m.bold,children:[this.t(o),": "]}),T[o]?T[o](e[o],this.t):(typeof e[o]=="object"?JSON.stringify(e[o]):e[o].toString())||"--"]}):s.jsx(n.Skeleton,{})},o))}),text:e&&typeof e=="object"?Object.keys(e).reduce((o,i)=>`${o}${this.t(i)}:${T[i]?T[i](e[i],this.t):(typeof e[i]=="object"?JSON.stringify(e[i]):e[i])||"--"}
1
+ import{j as s}from"./DefaultPropsProvider-BiXBMQYQ.js";import{i as _,a as B}from"./iobroker_admin__loadShare__react__loadShare__-LM7uyL45.js";import{b as S,r as J,c as P,s as w}from"./bootstrap-COulQZax-v84.js";import{i as n,a as f}from"./iobroker_admin__loadShare___mf_0_mui_mf_1_icons_mf_2_material__loadShare__-CJO5yP3h.js";import{i as v}from"./iobroker_admin__loadShare___mf_0_iobroker_mf_1_adapter_mf_2_react_mf_2_v5__loadShare__-LFZoiUTt.js";import{b as $}from"./blue-CagzI6CQ.js";import{g as b,v as M}from"./createTheme-DFX8CY6F.js";import"./_commonjsHelpers-CE1G-McA.js";import"./iobroker_admin__mf_v__runtimeInit__mf_v__-g2X2zhAf.js";import"./emotion-serialize.esm-Q4o_CgeF.js";import"./iobroker_admin__loadShare___mf_0_emotion_mf_1_react__loadShare__-BywLg1Xe.js";import"./ace-DEUjyTIn.js";import"./iobroker_admin__loadShare___mf_0_iobroker_mf_1_json_mf_2_config__loadShare__-CpA7pnS5.js";import"./iobroker_admin__loadShare__leaflet__loadShare__-CNUAG3AH.js";import"./ext-language_tools-ylAoucDh.js";import"./iobroker_admin__loadShare__react_mf_2_dropzone__loadShare__-CwjnV48g.js";import"./iobroker_admin__loadShare__react_mf_2_dom__loadShare__-CVeAXnkk.js";import"./preload-helper-BDBacUwf.js";import"./sdk-C-e-e2gd.js";import"./extends-CF3RwP-h.js";import"./assertThisInitialized-B0aQ9eG_.js";import"./useTheme-Bl-M1DYp.js";import"./index-DcK0RDrH.js";import"./ThemeProvider-BOFFjWAF.js";import"./emotion-cache.browser.esm-BgJfNZJN.js";import"./setYear-3ufv5yRD.js";import"./en-US-DBFJNIH6.js";const L="0 2px 2px 0 rgba(0, 0, 0, .14),0 3px 1px -2px rgba(0, 0, 0, .12),0 1px 5px 0 rgba(0, 0, 0, .2)",A="0 8px 17px 0 rgba(0, 0, 0, .2),0 6px 20px 0 rgba(0, 0, 0, .19)",x={root:g=>({padding:".75rem",[g.breakpoints.up("xl")]:{flex:"0 1 20%"}}),card:{display:"flex",minHeight:"235px",position:"relative",overflow:"hidden",maxHeight:"235p","&:hover":{overflowY:"auto",boxShadow:A}},cardInfo:{display:"flex",minHeight:"235px",position:"relative",overflow:"initial",maxHeight:"235p",flexDirection:"column","&:hover":{boxShadow:A}},cardInfoHead:g=>({position:"sticky",top:0,background:g.palette.background.default,display:"flex",width:"100%",justifyContent:"space-between",borderBottom:"1px solid",padding:"5px 5px 0px 5px"}),edit:{opacity:.6,userSelect:"none",pointerEvents:"none"},media:g=>({backgroundColor:g.palette.mode==="dark"?"#535353":"#e2e2e2",maxWidth:"30%"}),img:{width:120,height:"auto",padding:"2rem .5rem",maxWidth:"100%"},contentContainer:{display:"flex",flexDirection:"column",flex:1},content:{height:"170px",flexGrow:1,overflowY:"hidden"},action:{minHeight:"49px",padding:"16px 24px"},expand:{position:"absolute",right:"10px",bottom:"10px"},collapse:{minHeight:"100%",backgroundColor:"#ffffff",position:"absolute",width:"100%"},enabled:{color:"#ffffff",backgroundColor:$[500],position:"absolute",top:8,right:8,boxShadow:L,"&:hover":{backgroundColor:$[300]},"&:focus":{backgroundColor:$[500]}},disabled:{color:"#ffffff",backgroundColor:b[500],position:"absolute",top:8,right:8,boxShadow:L,"&:hover":{backgroundColor:b[300]},"&:focus":{backgroundColor:b[500]}},editButton:{color:"#ffffff",backgroundColor:b[500],position:"absolute",top:64,right:8,boxShadow:L,"&:hover":{backgroundColor:b[300]},"&:focus":{backgroundColor:b[500]}},deleteButton:{color:"#ffffff",backgroundColor:M[500],position:"absolute",top:120,right:8,boxShadow:L,"&:hover":{backgroundColor:M[300]},"&:focus":{backgroundColor:M[500]}},contentGrid:{height:"100%"},colorOrange:{color:"#ffcc80"},tooltip:{pointerEvents:"none"}};class O extends _.Component{constructor(t){super(t),this.state={expanded:!1}}static getDerivedStateFromProps(t){return t.edit?{expanded:!1}:null}handleExpandClick(){this.setState({expanded:!this.state.expanded})}renderContent(){return this.props.children}openDialog(){}renderDialogs(){return null}render(){var o,i;const t=this.props.edit?x.edit:void 0;let e=this.props.action.text||this.props.t("Link");return typeof e=="object"&&(e=e[this.props.lang]||e.en),s.jsx(n.Grid2,{size:{xs:12,sm:6,md:4,lg:3,xl:2},sx:v.Utils.getStyle(this.props.theme,x.root,this.props.style),style:{maxWidth:500},children:s.jsx(n.Link,{href:!this.props.edit&&this.props.action&&this.props.action.link?this.props.action.link:null,underline:"none",target:"_blank",rel:"noopener noreferrer",children:s.jsxs(n.Card,{sx:x.card,onClick:d=>{d.stopPropagation(),this.openDialog()},children:[this.props.showInfo&&!this.props.offline&&s.jsx(n.Button,{style:{...x.expand,...t},variant:"contained",size:"small",disabled:this.props.disabled,onClick:()=>this.handleExpandClick(),color:"primary",children:this.props.t("Info")}),s.jsxs(n.Box,{component:"div",sx:v.Utils.getStyle(this.props.theme,x.media,t,this.props.color&&{backgroundColor:this.props.color},{display:"flex",flexDirection:"column"}),children:[s.jsx(n.CardMedia,{style:x.img,component:"img",image:this.props.image}),s.jsx("div",{style:{flex:1,display:"flex",paddingBottom:"5px",paddingLeft:"5px"},children:this.props.warning?s.jsx(n.Tooltip,{title:this.props.warning,slotProps:{popper:{sx:x.tooltip}},children:s.jsx(f.Warning,{style:{alignSelf:"end",fontSize:36}})}):null})]}),s.jsxs("div",{style:{...x.contentContainer,...t},children:[s.jsx(n.CardContent,{style:x.content,children:s.jsxs(n.Grid2,{container:!0,direction:"column",wrap:"nowrap",style:x.contentGrid,children:[s.jsx(n.Typography,{gutterBottom:!0,variant:"h5",component:"h5",children:this.props.title}),this.renderContent()]})}),((o=this.props.action)==null?void 0:o.link)&&s.jsx(n.Divider,{}),((i=this.props.action)==null?void 0:i.link)&&s.jsx(n.CardActions,{style:x.action,children:s.jsx("div",{style:x.colorOrange,children:S.getText(e,this.props.lang)})})]}),this.props.showInfo&&s.jsx(n.Collapse,{style:x.collapse,in:this.state.expanded,timeout:"auto",unmountOnExit:!0,children:s.jsxs(n.Card,{sx:x.cardInfo,children:[s.jsxs(n.Box,{component:"div",sx:x.cardInfoHead,children:[s.jsx(n.Typography,{gutterBottom:!0,variant:"h5",component:"h5",children:this.props.t("Info")}),s.jsxs("div",{children:[s.jsx(n.IconButton,{size:"small",onClick:()=>{this.props.getHostDescriptionAll&&v.Utils.copyToClipboard(this.props.getHostDescriptionAll().text),this.props.openSnackBarFunc&&this.props.openSnackBarFunc()},children:s.jsx(v.IconCopy,{})}),s.jsx(n.IconButton,{size:"small",onClick:()=>this.handleExpandClick(),children:s.jsx(f.Close,{})})]})]}),s.jsx(n.CardContent,{children:this.props.getHostDescriptionAll().el})]})}),this.props.edit&&this.props.toggleActivation&&s.jsx(n.IconButton,{size:"large",sx:this.props.enabled?x.enabled:x.disabled,onClick:()=>this.props.toggleActivation(),children:s.jsx(f.Check,{})}),this.props.edit&&this.props.onEdit&&s.jsx(n.IconButton,{size:"large",sx:x.editButton,onClick:()=>this.props.onEdit(),children:s.jsx(f.Create,{})}),this.props.edit&&this.props.onRemove&&s.jsx(n.IconButton,{size:"large",sx:x.deleteButton,onClick:()=>this.props.onRemove(),children:s.jsx(f.Delete,{})}),this.renderDialogs()]})})})}}const I={closeButton:g=>({position:"absolute",right:8,top:8,color:g.palette.grey[500]}),paper:{},typography:{paddingRight:30},img:{width:"100%",height:"100%",objectFit:"contain"}};class R extends _.Component{cameraUpdateTimer;cameraRef;constructor(t){super(t),this.cameraUpdateTimer=null,this.cameraRef=_.createRef()}componentDidMount(){this.props.camera&&this.props.camera!=="text"&&(this.cameraUpdateTimer=setInterval(()=>this.updateCamera(),Math.max(parseInt(this.props.interval,10),500)),this.updateCamera())}componentWillUnmount(){this.cameraUpdateTimer&&(clearInterval(this.cameraUpdateTimer),this.cameraUpdateTimer=null)}updateCamera(){if(this.cameraRef.current)if(this.props.camera==="custom"){let t=this.props.cameraUrl;this.props.addTs&&(t.includes("?")?t+=`&ts=${Date.now()}`:t+=`?ts=${Date.now()}`),this.cameraRef.current.src=t}else{const t=this.props.camera.split("."),e=t.shift(),o=t.shift();this.props.socket.sendTo(`${e}.${o}`,"image",{name:t.pop(),width:this.cameraRef.current.width}).then(i=>{i&&i.data&&this.cameraRef.current&&(this.cameraRef.current.src=`data:image/jpeg;base64,${i.data}`)})}}render(){return s.jsxs(n.Dialog,{onClose:()=>this.props.onClose(),open:!0,maxWidth:"xl",fullWidth:!0,fullScreen:!0,sx:{"& .MuiDialog-paper":I.paper},children:[s.jsx(n.DialogTitle,{children:s.jsxs(n.Typography,{component:"h2",variant:"h6",sx:{"&.MuiTypography-root":I.typography},children:[this.props.name,s.jsx(n.IconButton,{size:"large",sx:I.closeButton,onClick:()=>this.props.onClose(),children:s.jsx(f.Close,{})})]})}),s.jsx(n.DialogContent,{dividers:!0,children:s.jsx("img",{style:I.img,src:"",alt:"camera",ref:this.cameraRef})}),s.jsx(n.DialogActions,{children:s.jsx(n.Button,{variant:"contained",autoFocus:!0,onClick:t=>{t.stopPropagation(),this.props.onClose()},color:"primary",startIcon:s.jsx(f.Close,{}),children:this.props.t("Close")})})]})}}const D={cameraImg:{width:"100%",height:"100%",maxWidth:200,maxHeight:200,objectFit:"contain"},imgContainer:{height:"100%"},hidden:{display:"none"},imgSkeleton:{transform:"initial"}};class E extends O{cameraRef;cameraUpdateTimer;interval;constructor(t){super(t),Object.assign(this.state,{error:!1,dialog:!1,loaded:!1}),this.cameraRef=_.createRef(),this.cameraUpdateTimer=null,this.interval=t.interval}updateCamera(){if(this.cameraRef.current)if(this.props.camera==="custom"){let t=this.props.cameraUrl;this.props.addTs&&(t.includes("?")?t+=`&ts=${Date.now()}`:t+=`?ts=${Date.now()}`),this.cameraRef.current.src=t}else{const t=this.props.camera.split("."),e=t.shift(),o=t.shift();this.props.socket.sendTo(`${e}.${o}`,"image",{name:t.pop(),width:this.cameraRef.current.width}).then(i=>{i!=null&&i.data&&this.cameraRef.current&&(this.cameraRef.current.src=`data:image/jpeg;base64,${i.data}`)}).catch(i=>window.alert(`Cannot send to instance: ${i}`))}}componentDidMount(){this.props.camera&&this.props.camera!=="text"&&(this.cameraUpdateTimer=setInterval(()=>this.updateCamera(),Math.max(parseInt(this.props.interval,10),500)),this.updateCamera())}componentWillUnmount(){this.cameraUpdateTimer&&(clearInterval(this.cameraUpdateTimer),this.cameraUpdateTimer=null)}renderDialogs(){return this.state.dialog?s.jsx(R,{socket:this.props.socket,camera:this.props.camera,name:this.props.title,t:this.props.t,onClose:()=>{this.props.camera&&this.props.camera!=="text"&&(this.cameraUpdateTimer&&clearInterval(this.cameraUpdateTimer),this.cameraUpdateTimer=setInterval(()=>this.updateCamera(),Math.max(parseInt(this.props.interval,10),500)),this.updateCamera()),this.setState({dialog:!1})},cameraUrl:this.props.cameraUrl}):null}handleImageLoad(){this.state.loaded||this.setState({loaded:!0,error:!1})}handleImageError(){this.state.error||this.setState({loaded:!1,error:!0})}renderContent(){if(this.props.camera==="custom"){let t=this.props.cameraUrl;return this.props.addTs&&(t.includes("?")?t+=`&ts=${Date.now()}`:t+=`?ts=${Date.now()}`),s.jsxs(n.Grid2,{container:!0,style:D.imgContainer,justifyContent:"center",alignItems:"center",children:[s.jsx("img",{ref:this.cameraRef,src:t,alt:"Camera",style:this.state.loaded&&!this.state.error?D.cameraImg:D.hidden,onLoad:()=>this.handleImageLoad(),onError:()=>this.handleImageError()}),!this.state.loaded&&!this.state.error&&s.jsx(n.Skeleton,{height:"100%",width:"100%",animation:"wave",style:D.imgSkeleton}),this.state.error&&s.jsx(f.Error,{fontSize:"large"})]})}return this.props.camera.startsWith("cameras.")?s.jsx("img",{ref:this.cameraRef,src:"",alt:"camera",style:D.cameraImg}):null}render(){return this.props.camera&&this.props.camera!=="text"?this.interval!==this.props.interval&&(this.interval=this.props.interval,this.cameraUpdateTimer&&clearInterval(this.cameraUpdateTimer),this.cameraUpdateTimer=setInterval(()=>this.updateCamera(),Math.max(parseInt(this.props.interval,10),500))):this.cameraUpdateTimer&&(clearInterval(this.cameraUpdateTimer),this.cameraUpdateTimer=null),super.render()}}const y={formControl:{marginTop:32},rootGrid:{flexGrow:1},closeButton:g=>({position:"absolute",right:8,top:8,color:g.palette.grey[500]}),paper:{},typography:{paddingRight:30},editItem:{marginTop:8},editItemSlider:{marginTop:24},labelSlider:{marginTop:16,fontSize:"1rem"},editColor:{width:"100%"}};class U extends _.Component{constructor(t){super(t),this.state={image:"",name:t.t("New link"),link:"http://",linkName:"",color:"",desc:"",addTs:!0,interval:5e3,camera:"text",cameraList:[],...t.link}}componentDidMount(){this.getCamerasInstances()}getCamerasInstances(){this.props.socket.getAdapterInstances("cameras",!0).then(t=>{const e=[],o=[];t.forEach(i=>{const d=i._id.replace("system.adapter.","");i.common&&i.common.enabled&&o.push(this.props.socket.getState(`${i._id}.alive`).then(r=>r&&r.val&&this.props.socket.sendTo(d,"list",null)).then(r=>r&&r.list&&r.list.forEach(a=>e.push({id:a.id,name:`${a.desc} [${d}/${a.name}]`}))))}),Promise.all(o).then(()=>this.setState({cameraList:e}))})}static getLinkNameFromLink(t){const e=t.trim().match(/^https?:\/\/([^/:]+)(:\d+)?/);return e?e[1]+(e[2]||""):""}render(){return s.jsxs(n.Dialog,{onClose:()=>this.props.onClose(),open:!0,maxWidth:"md",fullWidth:!0,sx:{"& .MuiDialog-paper":y.paper},children:[s.jsx(n.DialogTitle,{children:s.jsxs(n.Typography,{component:"h2",variant:"h6",sx:{"&.MuiTypography-root":y.typography},children:[this.props.isNew?this.props.t("Add new link: "):this.props.t("Edit link"),s.jsx(n.IconButton,{size:"large",sx:y.closeButton,onClick:()=>this.props.onClose(),children:s.jsx(f.Close,{})})]})}),s.jsx(n.DialogContent,{dividers:!0,children:s.jsxs(n.Grid2,{style:y.rootGrid,container:!0,direction:"row",children:[s.jsx(n.Grid2,{size:{xs:12,sm:6,md:8,lg:9},children:s.jsxs(n.Grid2,{container:!0,direction:"column",children:[s.jsxs(n.FormControl,{variant:"standard",style:y.formControl,children:[s.jsx(n.InputLabel,{id:"select-helper-label",children:this.props.t("Link type")}),s.jsxs(n.Select,{variant:"standard",labelId:"select-helper-label",value:this.state.camera,onChange:t=>this.setState({camera:t.target.value}),children:[s.jsx(n.MenuItem,{value:"text",children:s.jsx("em",{children:this.props.t("Description")})},"desc"),this.state.cameraList.map(t=>s.jsx(n.MenuItem,{value:t.id,children:t.name},t.id)),s.jsx(n.MenuItem,{value:"custom",children:this.props.t("Custom camera URL")},"custom")]})]}),s.jsx(n.TextField,{variant:"standard",label:this.props.t("URL"),value:this.state.link,style:y.editItem,onChange:t=>{const e=U.getLinkNameFromLink(this.state.link);e&&(!this.state.linkName||e===this.state.linkName)?this.setState({link:t.target.value,linkName:U.getLinkNameFromLink(t.target.value)}):this.setState({link:t.target.value})},slotProps:{input:{endAdornment:this.state.link?s.jsx(n.InputAdornment,{position:"end",children:s.jsx(n.IconButton,{tabIndex:-1,size:"small",onClick:()=>this.setState({link:""}),children:s.jsx(f.Close,{})})}):null}}}),s.jsx(n.TextField,{variant:"standard",style:y.editItem,label:this.props.t("Name"),value:this.state.name||"",onChange:t=>this.setState({name:t.target.value}),slotProps:{input:{endAdornment:this.state.name?s.jsx(n.InputAdornment,{position:"end",children:s.jsx(n.IconButton,{tabIndex:-1,size:"small",onClick:()=>this.setState({name:""}),children:s.jsx(f.Close,{})})}):null}}}),this.state.link?s.jsx(n.TextField,{variant:"standard",style:y.editItem,label:this.props.t("Link name"),value:this.state.linkName||"",onChange:t=>this.setState({linkName:t.target.value}),slotProps:{input:{endAdornment:this.state.linkName?s.jsx(n.InputAdornment,{position:"end",children:s.jsx(n.IconButton,{tabIndex:-1,size:"small",onClick:()=>this.setState({linkName:""}),children:s.jsx(f.Close,{})})}):null}}}):null,this.state.camera==="custom"||this.state.camera==="text"?s.jsx(n.TextField,{variant:"standard",style:y.editItem,label:this.state.camera==="custom"?this.props.t("Camera URL"):this.props.t("Description"),value:this.state.desc||"",onChange:t=>this.setState({desc:t.target.value}),slotProps:{input:{endAdornment:this.state.desc?s.jsx(n.InputAdornment,{position:"end",children:s.jsx(n.IconButton,{tabIndex:-1,size:"small",onClick:()=>this.setState({desc:""}),children:s.jsx(f.Close,{})})}):null}}}):null,this.state.camera==="custom"?s.jsx(n.FormControlLabel,{style:y.editItem,control:s.jsx(n.Checkbox,{checked:this.state.addTs,onChange:t=>this.setState({addTs:t.target.checked})}),label:this.props.t("Add timestamp to URL")}):null,this.state.camera!=="text"?s.jsx(n.Typography,{style:y.labelSlider,gutterBottom:!0,children:"Polling interval in ms"}):null,this.state.camera!=="text"?s.jsx(n.Slider,{style:y.editItemSlider,value:this.state.interval,getAriaValueText:()=>`${this.state.interval}ms`,onChange:(t,e)=>this.setState({interval:e}),step:100,min:500,max:6e4,valueLabelDisplay:"on"}):null,s.jsx("div",{style:{...y.editItem,width:50},children:s.jsx(n.TextField,{variant:"standard",fullWidth:!0,label:this.props.t("Color"),style:y.editColor,type:"color",value:this.state.color,onChange:t=>this.setState({color:t.target.value})})}),s.jsx(v.UploadImage,{disabled:!1,crop:!0,maxSize:256*1024,icon:this.state.image,removeIconFunc:()=>this.setState({image:""}),onChange:t=>this.setState({image:t})})]})}),s.jsx(n.Grid2,{size:{xs:12,sm:6,md:4,lg:3},children:this.state.camera==="text"?s.jsx(O,{image:this.state.image,title:this.state.name,action:{link:this.state.link,text:this.state.linkName},t:this.props.t,lang:this.props.lang,style:{width:"100% !important",maxWidth:"100% !important",marginLeft:"8px"},color:this.state.color,enabled:!0,theme:this.props.theme,children:this.state.desc}):s.jsx(E,{interval:this.state.interval,camera:this.state.camera,addTs:this.state.addTs,style:{width:"100% !important",maxWidth:"100% !important",marginLeft:"8px"},image:this.state.image,title:this.state.name,socket:this.props.socket,action:{link:this.state.link,text:this.state.linkName},t:this.props.t,lang:this.props.lang,color:this.state.color,enabled:!0,cameraUrl:this.state.desc,theme:this.props.theme})})]})}),s.jsxs(n.DialogActions,{children:[s.jsx(n.Button,{variant:"contained",autoFocus:!0,onClick:()=>{this.props.onClose({link:this.state.link,name:this.state.name,desc:this.state.desc,linkName:this.state.linkName,color:this.state.color,image:this.state.image,addTs:this.state.addTs,camera:this.state.camera,interval:this.state.interval})},color:"primary",startIcon:this.props.isNew?s.jsx(f.Add,{}):s.jsx(f.Check,{}),children:this.props.isNew?this.props.t("Add"):this.props.t("Save")}),s.jsx(n.Button,{variant:"contained",onClick:()=>this.props.onClose(),color:"grey",startIcon:s.jsx(f.Close,{}),children:this.props.t("Close")})]})]})}}class W extends B.Component{constructor(t){super(t),this.state={inProgress:!1,success:!1,error:"",finished:!1}}render(){return s.jsxs(n.Dialog,{open:!0,maxWidth:"lg",fullWidth:!0,children:[s.jsx(n.DialogTitle,{children:v.I18n.t("Node.js upgrade")}),s.jsxs(n.DialogContent,{style:{height:100,padding:"0 20px",overflow:"hidden"},children:[this.state.finished?null:s.jsx(n.Typography,{children:v.I18n.t("Performing this update will restart the js-controller afterwards!")}),this.state.inProgress?s.jsx(n.Box,{sx:{display:"flex",justifyContent:"center"},children:s.jsx(n.CircularProgress,{})}):null,this.state.success?s.jsx(n.Typography,{children:v.I18n.t("Node.js update successful, restarting controller now!")}):null,this.state.error?s.jsx(n.Typography,{sx:{color:"red"},children:v.I18n.t("Node.js update failed: %s",this.state.error)}):null]}),s.jsxs(n.DialogActions,{children:[s.jsx(n.Button,{disabled:this.state.inProgress||this.state.finished,color:"primary",variant:"contained",startIcon:s.jsx(f.Refresh,{}),onClick:()=>this.updateNodeJsVersion(),children:v.I18n.t("Upgrade")}),s.jsx(n.Button,{disabled:this.state.inProgress,variant:"contained",onClick:()=>{this.props.onClose()},color:"primary",startIcon:s.jsx(f.Close,{}),children:v.I18n.t("Close")})]})]})}async updateNodeJsVersion(){this.setState({inProgress:!0});const t=await this.props.socket.upgradeOsPackages(this.props.hostId,[{name:"nodejs"}],!0);this.setState({inProgress:!1,success:t.success,error:t.error,finished:!0})}}const m={button:{position:"absolute",bottom:16,right:16},saveButton:g=>({backgroundColor:g.palette.success.main,right:80,"&:hover":{backgroundColor:g.palette.success.dark}}),addButton:g=>({backgroundColor:g.palette.secondary.main,right:144,"&:hover":{backgroundColor:g.palette.secondary.dark}}),closeButton:g=>({backgroundColor:g.palette.error.main,"&:hover":{backgroundColor:g.palette.error.dark}}),bold:{fontWeight:"bold"},hostOffline:{color:"#bb0000"},updateExists:{color:"#c28700",marginRight:4},updateNo:{color:"#00b204",marginRight:4},nodeUpdate:{opacity:.6},instanceNumber:{opacity:.7,fontSize:16},updateIcon:{cursor:"pointer",fontSize:16},tooltip:{pointerEvents:"none"},viewModeDiv:{display:"flex",flexFlow:"wrap",overflow:"auto",justifyContent:"left"}},T={Uptime:S.formatSeconds,"System uptime":S.formatSeconds,RAM:S.formatRam,Speed:S.formatSpeed,"Disk size":S.formatBytes,"Disk free":S.formatBytes};class C extends B.Component{#t=1800*1e3;#e=300*1e3;#s=60*1e3;introLinksOriginal;deactivatedOriginal;t;getDataTimeout;constructor(t){super(t),this.state={instances:null,deactivated:[],edit:!1,link:null,introLinks:[],editLink:!1,editLinkIndex:-1,openSnackBar:!1,hasUnsavedChanges:!1,reverseProxy:null,alive:{},hostsData:{},hosts:null,hostTimeDiffMap:new Map,hostDataTimestampMap:new Map,nodeUpdateSupported:!1,nodeUpdateDialog:null},this.t=t.t}checkBackendTime(){const t=this.state.hostTimeDiffMap,e=this.state.hostDataTimestampMap,o=Date.now();for(const[i,d]of Object.entries(this.state.hostsData)){const r=Math.abs(d.time-o);t.set(i,r),e.set(i,o)}this.setState({hostTimeDiffMap:t,hostDataTimestampMap:e})}async componentDidMount(){var i;window.NEXOWATT_EOS_ADMIN_SOCKET=this.props.socket,window.NEXOWATT_EOS_SOCKET=this.props.socket,window.dispatchEvent(new CustomEvent("nexowatt-eos-admin-socket-ready"));let t=null,e=!1;try{[t,e]=await Promise.all([this.props.socket.getObject(`system.adapter.${this.props.adminInstance}`),this.props.socket.checkFeatureSupported("CONTROLLER_OS_PACKAGE_UPGRADE")])}catch(d){if(String(window.NEXOWATT_EOS_ACCESS_ROLE||"unknown").toLowerCase()==="admin")throw d}const o=((i=t==null?void 0:t.native)==null?void 0:i.reverseProxy)||[];await new Promise(d=>this.setState({reverseProxy:o,nodeUpdateSupported:e},()=>d())),await this.getData(),this.props.instancesWorker.registerHandler(this.getDataDelayed),this.props.hostsWorker.registerHandler(this.updateHosts),this.props.hostsWorker.registerAliveHandler(this.updateHostsAlive),this.checkBackendTime()}componentWillUnmount(){this.getDataTimeout&&(clearTimeout(this.getDataTimeout),this.getDataTimeout=void 0),this.props.instancesWorker.unregisterHandler(this.getDataDelayed),this.props.hostsWorker.unregisterHandler(this.updateHosts),this.props.hostsWorker.unregisterAliveHandler(this.updateHostsAlive)}updateHostsAlive=async t=>{const e=JSON.parse(JSON.stringify(this.state.alive)),o=[];if(t.find(i=>i.type==="deleted")){this.getDataDelayed();return}if(t.forEach(i=>{!!e[i.id]!=!!i.alive&&(e[i.id]=i.alive,o.push(i.id))}),o.length){const i=JSON.parse(JSON.stringify(this.state.hostsData)),d=new Map(this.state.hostDataTimestampMap),r=Date.now();(await Promise.all(o.map(l=>this.getHostData(l,e[l])))).forEach(l=>{i[l.id]=C.preprocessHostData(l.data),d.set(l.id,r)}),this.setState({alive:e,hostsData:i,hostDataTimestampMap:d},()=>this.checkBackendTime())}};updateHosts=t=>{let e=[];if(t.find(o=>!o.obj)){this.getDataDelayed();return}if(e=t.map(o=>o.id),e.length){const o=JSON.parse(JSON.stringify(this.state.hostsData)),i=new Map(this.state.hostDataTimestampMap),d=Date.now();Promise.all(e.map(r=>this.getHostData(r))).then(r=>{r.forEach(a=>{o[a.id]=C.preprocessHostData(a.data),i.set(a.id,d)}),this.setState({hostsData:o,hostDataTimestampMap:i})})}};async activateEditMode(){var i;const t=await this.props.socket.getSystemConfig(!0),e=await this.getInstances(!0,null,t),o=(i=t==null?void 0:t.native)!=null&&i.introLinks?t.native.introLinks:[];this.introLinksOriginal=JSON.stringify(o),this.deactivatedOriginal=JSON.parse(JSON.stringify(e.deactivated)),this.setState({instances:e.instances,deactivated:e.deactivated,edit:!0,introLinks:o,hasUnsavedChanges:!1})}deactivateEditMode(){this.state.hasUnsavedChanges,this.setState({deactivated:this.deactivatedOriginal,introLinks:JSON.parse(this.introLinksOriginal),hasUnsavedChanges:!1,edit:!1},()=>{this.deactivatedOriginal=null,this.introLinksOriginal=null})}toggleCard(t,e){if(!this.state.instances||!this.state.instances.length)return;const o=JSON.parse(JSON.stringify(this.state.deactivated)),i=o.indexOf(`${t}_${e}`);i!==-1?o.splice(i,1):(o.push(`${t}_${e}`),o.sort());const d=JSON.stringify(o)!==JSON.stringify(this.deactivatedOriginal)||JSON.stringify(this.state.introLinks)!==this.introLinksOriginal;this.setState({deactivated:o,hasUnsavedChanges:d})}getInstancesCards(){var t;return(t=this.state.instances)==null?void 0:t.map(e=>{var i,d;const o=String(window.NEXOWATT_EOS_ACCESS_ROLE||"admin").toLowerCase()!=="admin"&&String(window.NEXOWATT_EOS_ACCESS_ROLE||"admin").toLowerCase()!=="service"&&/^nexowatt-ui(?:\.|$)/i.test(e.id)||!((i=this.state.deactivated)!=null&&i.includes(`${e.id}_${e.linkName}`));if(o||this.state.edit){let r=e.link?e.link.replace(/^https?:\/\//,""):"";if(r=r.split("/")[0],e.id===this.props.adminInstance)return null;let a=window.isFinite(e.id.split(".").pop());a&&(a=!!((d=this.state.instances)!=null&&d.find(k=>k.id!==e.id&&e.name===k.name&&e.id.split(".")[0]===k.id.split(".")[0])));const l=this.state.hostsData?this.state.hostsData[e.id]:null,h=this.state.hostTimeDiffMap.get(e.id)??0,p=this.state.hostDataTimestampMap.get(e.id)??0,u=Date.now()-p<this.#e;return s.jsx(O,{image:e.image,title:s.jsxs(s.Fragment,{children:[s.jsx("span",{style:e.name&&e.name.length>12?{fontSize:"1rem"}:void 0,children:e.name}),a?s.jsxs("span",{style:m.instanceNumber,children:[".",e.id.split(".").pop()]}):null]}),action:{link:e.link,text:r},t:this.props.t,lang:this.props.lang,color:e.color,showInfo:!!e.info,edit:this.state.edit,offline:l&&l.alive===!1,warning:h>this.#t&&u?this.t("Backend time differs by %s minutes",Math.round(h/this.#s).toString()):null,enabled:o,disabled:!l||typeof l!="object",getHostDescriptionAll:()=>this.getHostDescriptionAll(e.id),toggleActivation:()=>this.toggleCard(e.id,e.linkName),openSnackBarFunc:()=>this.setState({openSnackBar:!0}),theme:this.props.theme,children:e.description||this.getHostDescription(e.id)},`${e.id}_${e.link}`)}return null})}toggleLinkCard(t){const e=JSON.parse(JSON.stringify(this.state.introLinks));e[t].enabled=!e[t].enabled;const o=JSON.stringify(this.state.deactivated)!==JSON.stringify(this.deactivatedOriginal)||JSON.stringify(e)!==this.introLinksOriginal;this.setState({introLinks:e,hasUnsavedChanges:o})}getLinkCards(){var t;return(t=this.state.introLinks)==null?void 0:t.map((e,o)=>!e.enabled&&!this.state.edit?null:e.camera==="custom"?s.jsx(E,{image:e.image,title:e.name,action:{link:e.link,text:e.linkName},t:this.props.t,socket:this.props.socket,color:e.color,edit:this.state.edit,interval:e.interval,camera:e.camera,addTs:e.addTs,onEdit:()=>{var i;return this.setState({editLink:!0,editLinkIndex:o,link:JSON.parse(JSON.stringify((i=this.state.introLinks)==null?void 0:i[o]))})},onRemove:()=>{const i=JSON.parse(JSON.stringify(this.state.introLinks));i.splice(o,1);const d=JSON.stringify(this.state.deactivated)!==JSON.stringify(this.deactivatedOriginal)||JSON.stringify(i)!==this.introLinksOriginal;this.setState({introLinks:i,hasUnsavedChanges:d})},enabled:e.enabled,lang:this.props.lang,toggleActivation:()=>this.toggleLinkCard(o),cameraUrl:e.desc,theme:this.props.theme},`link${o}`):s.jsx(O,{image:e.image,title:e.name,action:{link:e.link,text:e.linkName},t:this.props.t,color:e.color,edit:this.state.edit,onEdit:()=>{var i;return this.setState({editLink:!0,editLinkIndex:o,link:JSON.parse(JSON.stringify((i=this.state.introLinks)==null?void 0:i[o]))})},onRemove:()=>{const i=JSON.parse(JSON.stringify(this.state.introLinks));i.splice(o,1);const d=JSON.stringify(this.state.deactivated)!==JSON.stringify(this.deactivatedOriginal)||JSON.stringify(i)!==this.introLinksOriginal;this.setState({introLinks:i,hasUnsavedChanges:d})},enabled:e.enabled,lang:this.props.lang,toggleActivation:()=>this.toggleLinkCard(o),theme:this.props.theme,children:e.desc||""},`link${o}`))}editLinkCard(){return this.state.editLink?s.jsx(U,{link:this.state.link,socket:this.props.socket,isNew:this.state.editLinkIndex===-1,t:this.props.t,lang:this.props.lang,theme:this.props.theme,onClose:t=>{if(t){const e=JSON.parse(JSON.stringify(this.state.introLinks));this.state.editLinkIndex===-1?(t.enabled=!0,e.push(t)):(t.enabled=e[this.state.editLinkIndex].enabled,e[this.state.editLinkIndex]=t);const o=JSON.stringify(this.state.deactivated)!==JSON.stringify(this.deactivatedOriginal)||JSON.stringify(e)!==this.introLinksOriginal;this.setState({introLinks:e,editLink:!1,hasUnsavedChanges:o,link:null})}else this.setState({editLink:!1})}}):null}getButtons(){const t=[];return this.state.edit?(t.push(s.jsx(n.Fab,{color:"primary",size:"small",sx:v.Utils.getStyle(this.props.theme,m.button,m.addButton),onClick:()=>this.setState({editLink:!0,editLinkIndex:-1,link:{}}),children:s.jsx(f.Add,{})},"add")),t.push(s.jsx(n.Fab,{size:"small",color:"primary",disabled:!this.state.hasUnsavedChanges,sx:v.Utils.getStyle(this.props.theme,m.button,m.saveButton),onClick:()=>this.saveCards(),children:s.jsx(f.Check,{})},"save")),t.push(s.jsx(n.Fab,{size:"small",color:"primary",sx:v.Utils.getStyle(this.props.theme,m.button,m.closeButton),onClick:()=>this.deactivateEditMode(),children:s.jsx(f.Close,{})},"close"))):t.push(s.jsx(n.Fab,{color:"primary",size:"small",style:m.button,onClick:()=>this.activateEditMode(),children:s.jsx(f.Create,{})},"edit")),t}async saveCards(){const t=await this.props.socket.getSystemConfig(!0);let e=!1;JSON.stringify(t.common.intro)!==JSON.stringify(this.state.deactivated)&&(t.common.intro=this.state.deactivated,e=!0),!e&&JSON.stringify(t.native.introLinks)!==JSON.stringify(this.state.introLinks)&&(e=!0,t.native.introLinks=this.state.introLinks),e?this.props.socket.setSystemConfig(t).then(()=>this.props.showAlert("Updated","success")).catch(o=>{console.log(o),this.props.showAlert(o,"error")}).then(()=>this.setState({edit:!1})):this.setState({edit:!1})}async getHostData(t,e){let o;if(e!==void 0)o={val:e};else try{o=await this.props.socket.getState(`${t}.alive`)}catch(r){console.error(`Cannot get state ${t}.alive: ${r}`),o={val:!1}}let i={alive:!1};if(o!=null&&o.val)try{i=await this.props.socket.getHostInfo(t,!1,1e4),i&&typeof i=="object"&&i.alive!==!1&&(i.alive=!0)}catch(r){console.error(`Cannot get host info for ${t}: ${r}`),i={alive:!1}}else i={alive:!1};const d=await this.props.socket.getForeignStates(`${t}.versions.*`);return Object.keys(d).forEach(r=>i[`_${r.split(".").pop()}`]=d[r].val),{id:t,data:i}}async getHostsData(t){const e=t.map(l=>this.getHostData(l._id)),o=await Promise.all(e),i={},d={},r=new Map(this.state.hostDataTimestampMap),a=Date.now();return o.forEach(l=>{i[l.id]=C.preprocessHostData(l.data),d[l.id]=l.data.alive,r.set(l.id,a)}),this.setState({hostDataTimestampMap:r}),{hostsData:i,alive:d}}addLinks(t,e,o,i,d,r){const a={id:t.id,name:t.name,description:t.description,color:t.color,image:t.icon,info:""},l=J(t.link,e.name,o,{instances:i,hostname:this.props.hostname,adminInstance:this.props.adminInstance,hosts:d}),h=this.state.reverseProxy;let p=null;if(h!=null&&h.length){const c=window.location.pathname;p=h.find(u=>{if(!u.globalPath)return!1;const k=u.globalPath.endsWith("/")?u.globalPath:`${u.globalPath}/`;return c===k||c.startsWith(k)})||null}if(l.length===1){a.link=l[0].url,a.port=l[0].port,a.link=P(a.link,a.id,i,p)||a.link;const c=r.find(u=>u.link===a.link);c?console.log(`Double links: "${a.id}" and "${c.id}"`):r.push(a)}else l.length>1&&l.forEach(c=>{const u=r.find(k=>k.link===c.url);if(u)console.log(`Double links: "${a.id}" and "${u.id}"`);else{const k={...a,link:c.url,port:c.port};k.link=P(k.link,a.id,i,p)||k.link,r.push(k)}})}static getText(t,e){return t?typeof t=="object"?t[e]||t.en||"":t||"":""}static normalizeLinks(t,e,o){if(!t.common.localLinks&&!t.common.localLink&&!t.common.welcomeScreen&&!t.common.welcomeScreenPro)return null;const i={id:t._id.replace("system.adapter.",""),link:"",name:C.getText(t.common.titleLang||t.common.title||t.common.name,e),order:t.common.order||1e3,intro:!0,description:C.getText(t.common.desc,e),icon:t.common.icon?`adapter/${t.common.name}/${t.common.icon}`:"img/no-image.svg"};let d=[];if(t.common.localLink)if(typeof t.common.localLink=="string")d.push({...i,link:t.common.localLink});else{const r=t.common.localLink;if(r.link){const a={...i,link:r.link};r.color&&(a.color=r.color),r.order!==void 0&&typeof r.order=="number"&&(a.order=r.order),r.icon&&r.img&&(a.icon=r.icon||r.img),d.push(a)}else console.warn(`Unknown localLink structure: ${JSON.stringify(t.common.localLink)}`)}if(t.common.localLinks&&typeof t.common.localLinks=="object"&&Object.keys(t.common.localLinks).forEach(r=>{const a=t.common.localLinks[r];if(typeof a=="string")d.push({...i,link:a});else{const l=a;if(l.link){const h={...i,id:t._id.replace("system.adapter.","")+(r==="_default"?"":` ${r}`),link:l.link,name:i.name+(r==="_default"?"":` ${r}`)};l.color&&(h.color=l.color),l.order!==void 0&&(h.order=parseInt(l.order,10)||1e3),l.icon&&l.img&&(h.icon=l.icon||l.img),l.description&&(h.description=C.getText(l.description,e)),l.pro!==void 0&&(typeof l.pro=="string"?h.pro=l.pro:h.pro=`${t.common.name}/index.html`),l.cloud!==void 0&&(h.cloud=l.cloud),l.intro!==void 0&&(h.intro=l.intro===!0),l.name&&(h.name=C.getText(l.name,e)),r==="_default"&&(h.default=!0),d.push(h)}else console.warn(`Unknown localLinks structure: ${JSON.stringify(a)}`)}}),t.common.welcomeScreen&&typeof t.common.welcomeScreen=="object"&&((Array.isArray(t.common.welcomeScreen)?t.common.welcomeScreen:[t.common.welcomeScreen]).forEach(a=>{if(a.link){const l={...i,id:`${t._id.replace("system.adapter.","")} cloud`,link:`%web_protocol%://%web_bind%:%web_port%/${a.link}`,cloud:a.link};if(a.color&&(l.color=a.color),a.order!==void 0&&typeof a.order=="number"&&(l.order=a.order),a.icon&&a.img&&(l.icon=a.icon||a.img),a.localLinks){const h=t.common.localLinks[a.localLinks];h&&typeof h=="string"?l.link=h:h&&typeof h=="object"&&h.link&&(l.link=h.link)}a.name&&(l.name=C.getText(a.name,e)),d.push(l)}}),t.common.welcomeScreenPro&&typeof t.common.welcomeScreenPro=="object"&&(Array.isArray(t.common.welcomeScreenPro)?t.common.welcomeScreenPro:[t.common.welcomeScreenPro]).forEach(l=>{if(l.link){const h={...i,id:`${t._id.replace("system.adapter.","")} pro`,link:`%web_protocol%://%web_bind%:%web_port%/${l.link}`,pro:l.link};if(l.color&&(h.color=l.color),l.order!==void 0&&typeof l.order=="number"&&(h.order=l.order),l.icon&&l.img&&(h.icon=l.icon||l.img),l.localLinks){const p=t.common.localLinks[l.localLinks];p&&typeof p=="string"?h.link=p:p&&typeof p=="object"&&p.link&&(h.link=p.link)}l.name&&(h.name=C.getText(l.name,e)),d.push(h)}})),d.forEach(r=>{!r.icon.startsWith("adapter/")&&!r.icon.startsWith("data:image/")&&!r.icon.startsWith("http://")&&!r.icon.startsWith("https://")&&r.icon!=="img/no-image.svg"&&(r.icon=`adapter/${t.common.name}/${r.icon}`)}),o){const r={};d.forEach(a=>{r[a.link]?(a.color&&(r[a.link].color=a.color),a.icon&&(r[a.link].icon=a.icon),a.cloud&&(r[a.link].cloud=a.cloud),a.pro&&(r[a.link].pro=a.pro),a.intro!==void 0&&(r[a.link].intro=a.intro),a.name&&typeof a.name=="object"&&(r[a.link].name=a.name),a.order!==void 0&&(r[a.link].order=a.order),a.default&&(r[a.link].default=a.default)):r[a.link]=a}),d=Object.values(r)}return d.sort((r,a)=>r.default===void 0&&a.default===void 0?r.order===void 0&&a.order===void 0?0:r.order===void 0?-1:a.order===void 0?1:r.order-a.order:r.default===void 0?-1:a.default===void 0?1:r.order===void 0&&a.order===void 0?0:r.order===void 0?-1:a.order===void 0?1:r.order-a.order),d}async getInstances(t,e,o){e=e||this.state.hosts;const i={};e.forEach(d=>i[d._id]=d);try{const d=await this.props.socket.getAdapterInstances("",t);let r=o.common.intro||[];Array.isArray(r)||(r=Object.keys(r),r.sort());const a=[],l={};d.forEach(p=>l[p._id]=p),d.forEach(p=>{if(!p)return;const c=p.common||null,u=p._id.split("."),k=parseInt(u.pop(),10);let j;if(c!=null&&c.name&&typeof c.name=="object"){const N=c==null?void 0:c.name;j=N[this.props.lang]||N.en}else j=(c==null?void 0:c.name)||"";if(!(j==="admin"&&c.localLink===(this.props.hostname||""))&&j!=="web"&&!(j&&j!=="vis-web-admin"&&j.match(/^vis-/)&&j!=="vis-2")&&!(j!=null&&j.match(/^icons-/))&&c&&(c.enabled||c.onlyWWW)){const N=C.normalizeLinks(p,this.props.lang,!0);N&&N.forEach(H=>this.addLinks(H,c,k,l,i,a))}}),a.forEach(p=>{p.link&&(p.linkName=p.link.replace("https://","").replace("http://","").replace(/^[^_]+:/,""))}),a.sort((p,c)=>{if(p.order!==void 0||c.order!==void 0){if(p.order=p.order===void 0?1e3:p.order,c.order=c.order===void 0?1e3:c.order,p.order<c.order)return-1;if(p.order>c.order)return 1}return p.id>c.id?1:p.id<c.id?-1:0}),e==null||e.forEach(p=>{const c=p==null?void 0:p.common;let u=c==null?void 0:c.name;if(typeof u=="object"&&u&&(u=u[this.props.lang]||u.en),c){const k={id:p._id,name:u||"",color:"",image:c.icon||"img/no-image.svg",info:this.t("Info"),linkName:""};a.push(k)}});const h=[];return r.forEach(p=>{a.find(c=>p===`${c.id}_${c.linkName}`)&&h.push(p)}),r=h,{instances:a,deactivated:r}}catch(d){return console.log(d),{instances:[],deactivated:[]}}}getHostDescription(t){const e=this.state.hostsData?this.state.hostsData[t]:null;if(e&&e.alive===!1)return s.jsx("div",{style:m.hostOffline,children:this.props.t("Offline")});let o="",i="";if(e){try{e._nodeNewest&&e["Node.js"]&&w.gt(e._nodeNewest,e["Node.js"].replace(/^v/,""))&&(o=e._nodeNewest)}catch{}try{e._nodeNewest!==e._nodeNewestNext&&e._nodeNewestNext&&e["Node.js"]&&e._nodeNewest&&w.gt(e._nodeNewestNext,e["Node.js"].replace(/^v/,""))&&w.gt(e._nodeNewestNext,e._nodeNewest)&&(o+=(o?" / ":"")+e._nodeNewestNext)}catch{}if(o){const d=this.state.nodeUpdateSupported&&e.Platform==="linux";o=s.jsx(n.Tooltip,{title:this.props.t("Some updates available"),slotProps:{popper:{sx:m.tooltip}},children:s.jsxs("span",{style:{...m.nodeUpdate,display:"inline-flex"},children:["(",o,")",d?s.jsx(f.Refresh,{style:m.updateIcon,onClick:()=>this.setState({nodeUpdateDialog:{hostId:t,version:e._nodeNewestNext}})}):null]})})}try{e._npmNewest&&e.NPM&&w.gt(e._npmNewest,e.NPM)&&(i=e._npmNewest)}catch{}try{e._npmNewest!==e._npmNewestNext&&e._npmNewestNext&&e.NPM&&e._npmNewest&&w.gt(e._npmNewestNext,e.NPM)&&w.gt(e._npmNewestNext,e._npmNewest)&&(i+=(i?" / ":"")+e._npmNewestNext)}catch{}i&&(i=s.jsx(n.Tooltip,{title:this.props.t("Some updates available"),slotProps:{popper:{sx:m.tooltip}},children:s.jsxs("span",{style:m.nodeUpdate,children:["(",i,")"]})}))}return e&&typeof e=="object"?s.jsxs("ul",{style:{textTransform:"none"},children:[s.jsx("li",{children:s.jsxs("span",{children:[s.jsxs("span",{style:m.bold,children:[this.t("Platform"),": "]}),e.Platform||"--"]})}),s.jsx("li",{children:s.jsxs("span",{children:[s.jsxs("span",{style:m.bold,children:[this.t("RAM"),": "]}),T.RAM(e.RAM)]})}),s.jsx("li",{children:s.jsxs("span",{children:[s.jsxs("span",{style:m.bold,children:[this.t("Node.js"),": "]}),s.jsx("span",{style:o?m.updateExists:m.updateNo,children:e["Node.js"]||"--"}),o]})}),s.jsx("li",{children:s.jsxs("span",{children:[s.jsxs("span",{style:m.bold,children:[this.t("NPM"),": "]}),s.jsx("span",{className:i?m.updateExists:m.updateNo,children:e.NPM||"--"}),i]})})]}):s.jsxs("ul",{children:[s.jsx(n.Skeleton,{}),s.jsx(n.Skeleton,{}),s.jsx(n.Skeleton,{}),s.jsx(n.Skeleton,{})]})}getHostDescriptionAll(t){const e=this.state.hostsData?this.state.hostsData[t]:null;return{el:s.jsx("ul",{style:{textTransform:"none"},children:e&&typeof e=="object"&&Object.keys(e).filter(o=>!o.startsWith("_")&&e[o]!==null&&e[o]!==void 0).map(o=>s.jsx("li",{children:e&&typeof e=="object"?s.jsxs("span",{children:[s.jsxs("span",{style:m.bold,children:[this.t(o),": "]}),T[o]?T[o](e[o],this.t):(typeof e[o]=="object"?JSON.stringify(e[o]):e[o].toString())||"--"]}):s.jsx(n.Skeleton,{})},o))}),text:e&&typeof e=="object"?Object.keys(e).reduce((o,i)=>`${o}${this.t(i)}:${T[i]?T[i](e[i],this.t):(typeof e[i]=="object"?JSON.stringify(e[i]):e[i])||"--"}
2
2
  `):""}}getDataDelayed=t=>{this.getDataTimeout&&clearTimeout(this.getDataTimeout),this.getDataTimeout=setTimeout(()=>{this.getDataTimeout=void 0,this.getData(!0).catch(e=>console.error(`Cannot get data: ${e}`))},300)};async getData(t){try{const e=await this.props.socket.getSystemConfig(t),o=await this.props.socket.getCompactHosts(t),i=await this.getInstances(t,o,e);this.setState({instances:i.instances,hosts:o,deactivated:i.deactivated,introLinks:e&&e.native&&e.native.introLinks?e.native.introLinks:[]});const d=await this.getHostsData(o);await new Promise(r=>{this.setState(d,()=>r())})}catch(e){const o=String(window.NEXOWATT_EOS_ACCESS_ROLE||"unknown").toLowerCase();if(o!=="admin"){try{const i=await this.getInstances(t,[],{common:{intro:[]},native:{introLinks:[]}});this.setState({instances:i.instances,hosts:[],deactivated:i.deactivated,introLinks:[],hostsData:{},alive:{}});return}catch{}this.setState({instances:[],hosts:[],deactivated:[],introLinks:[],hostsData:{},alive:{}});return}window.alert(`Cannot get data: ${e}`)}}renderCopiedToast(){return s.jsx(n.Snackbar,{anchorOrigin:{vertical:"bottom",horizontal:"left"},open:this.state.openSnackBar,autoHideDuration:3e3,onClose:()=>this.setState({openSnackBar:!1}),message:this.t("copied")})}render(){return this.state.instances?s.jsxs(v.TabContainer,{elevation:0,overflow:"visible",children:[this.renderCopiedToast(),this.state.nodeUpdateDialog?s.jsx(W,{onClose:()=>this.setState({nodeUpdateDialog:null}),socket:this.props.socket,...this.state.nodeUpdateDialog}):null,s.jsxs("div",{style:m.viewModeDiv,children:[this.getInstancesCards(),this.getLinkCards()]}),String(window.NEXOWATT_EOS_ACCESS_ROLE||"admin").toLowerCase()==="admin"?this.getButtons():null,String(window.NEXOWATT_EOS_ACCESS_ROLE||"admin").toLowerCase()==="admin"?this.editLinkCard():null]}):s.jsx(n.LinearProgress,{})}static preprocessHostData(t){var e;if((e=t.dockerInformation)!=null&&e.isDocker){let o=t.dockerInformation.isOfficial?"official image":"unofficial image";t.dockerInformation.isOfficial&&(o+=` - ${t.dockerInformation.officialVersion}`),t.Platform=`${t.Platform} (${o})`}return delete t.dockerInformation,t}}export{C as default};