iobroker.eos-admin 7.10.1 → 7.10.2

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 (33) hide show
  1. package/INSTALL_TEST_V7.10.2.md +22 -0
  2. package/MERGE_UPDATE_README_V7.10.2.md +11 -0
  3. package/NEXOWATT_EOS_BUILD_INFO.json +15 -16
  4. package/NEXOWATT_EOS_PREBUILT_MANIFEST.json +1410 -0
  5. package/PUBLISH_STABLE_V7.10.2.md +21 -0
  6. package/README.md +4 -4
  7. package/README_STABILITY_V7.10.2.md +20 -0
  8. package/RELEASE_ACCEPTANCE_V7.10.2.md +13 -0
  9. package/RELEASE_NOTES_V7.10.2.md +11 -0
  10. package/build/lib/eosAutoUpdate.js +418 -20
  11. package/build/lib/eosAutoUpdate.js.map +1 -0
  12. package/build/lib/eosRequestSecurity.js +4 -1
  13. package/build/lib/eosRequestSecurity.js.map +1 -0
  14. package/build/lib/web.js +40 -9
  15. package/build/lib/web.js.map +1 -1
  16. package/io-package.json +60 -5
  17. package/package.json +22 -16
  18. package/tools/nexowatt-auto-update-selftest.cjs +144 -32
  19. package/tools/nexowatt-backend-runtime-selftest.cjs +147 -0
  20. package/tools/nexowatt-merge-update-selftest.cjs +7 -1
  21. package/tools/nexowatt-prebuilt-release-selftest.cjs +292 -0
  22. package/tools/nexowatt-stable-v7102-selftest.cjs +51 -0
  23. package/tools/nexowatt-validate-package.cjs +35 -11
  24. package/INSTALL_TEST_V7.10.1.md +0 -10
  25. package/MERGE_UPDATE_README_V7.10.1.md +0 -10
  26. package/PUBLISH_STABLE_V7.10.1.md +0 -10
  27. package/README_STABILITY_V7.10.1.md +0 -10
  28. package/RELEASE_ACCEPTANCE_V7.10.1.md +0 -10
  29. package/RELEASE_NOTES_V7.10.1.md +0 -10
  30. package/adminWww/js/eos-release-watch.js +0 -77
  31. package/build/lib/eosPassword.js +0 -72
  32. package/build/lib/nexowattStableAuth.js +0 -74
  33. package/tools/nexowatt-stable-v7101-selftest.cjs +0 -15
@@ -0,0 +1,21 @@
1
+ # Veröffentlichung – NexoWatt EOS Admin 7.10.2
2
+
3
+ Diese Repository-ZIP enthält bereits das vollständig kompilierte und geprüfte Release-Artefakt. Für die Veröffentlichung sind **weder `npm install` noch `npm ci` erforderlich**.
4
+
5
+ Im entpackten Repository zuerst den npm-Trockenlauf ausführen:
6
+
7
+ ```powershell
8
+ npm publish --dry-run
9
+ ```
10
+
11
+ Wenn der Trockenlauf ohne Fehler endet, direkt veröffentlichen:
12
+
13
+ ```powershell
14
+ npm publish
15
+ ```
16
+
17
+ `prepublishOnly` und `prepack` verwenden ausschließlich mitgelieferte Node.js-Prüfskripte. Sie starten weder `tsc` noch `tsx` und laden keine Entwicklungsabhängigkeiten nach. Das versiegelte SHA-256-Manifest kontrolliert, dass Quellstand, Frontend und vorkompiliertes Backend seit der Freigabe nicht verändert wurden. Zusätzlich werden die vollständige lokale Backend-Modulkette, die JavaScript-Syntax und der tatsächliche npm-Paketinhalt geprüft.
18
+
19
+ Nur nach eigenen Änderungen an TypeScript- oder Frontend-Quellen ist ein Entwicklungs-Build erforderlich. Der hier bereitgestellte Release-Stand darf unverändert direkt mit `npm publish` veröffentlicht werden.
20
+
21
+ Die bereits veröffentlichte Version 7.10.1 darf nicht überschrieben werden. Da der Veröffentlichungsversuch von 7.10.2 vor dem Upload im Lifecycle abgebrochen wurde, bleibt dieser reparierte Stand auf Version 7.10.2.
package/README.md CHANGED
@@ -13,9 +13,9 @@ 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
- ## Aktueller Stable-Verkaufskandidat 7.9.98
16
+ ## Aktueller Stable-Verkaufskandidat 7.10.2
17
17
 
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.
18
+ Version 7.10.2 übernimmt die validierte 7.10.1-Oberfläche und repariert den kritischen Start-/Stop-Loop des Stable-Update-Managers. Laufzeitstatus wird ausschließlich in Adapter-States gespeichert, der erste Repository-Abgleich startet verzögert und jedes Release-Paket wird auf eine vollständige Backend-Modulkette geprüft. Die native **Übersicht** bleibt die Startseite; der Inhaltsbereich ist vertikal scrollbar, während Header und Hauptnavigation stehen bleiben.
19
19
 
20
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
21
 
@@ -33,7 +33,7 @@ Minimaler Repository-Eintrag:
33
33
  {
34
34
  "eos-admin": {
35
35
  "name": "eos-admin",
36
- "version": "7.9.98",
36
+ "version": "7.10.2",
37
37
  "title": "NexoWatt EOS Admin",
38
38
  "desc": {
39
39
  "de": "NexoWatt EOS Administrationsoberfläche als eigenständiger Adapter.",
@@ -141,7 +141,7 @@ npm publish --dry-run --tag latest
141
141
  npm publish --tag latest
142
142
  ```
143
143
 
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.
144
+ Die Version muss vor jedem erneuten Publish erhöht werden. Für 7.10.2 ist die Veröffentlichung des separat geprüften `iobroker.eos-admin-7.10.2.tgz` der sicherste Weg.
145
145
 
146
146
  ## Lizenz
147
147
 
@@ -0,0 +1,20 @@
1
+ # NexoWatt EOS Admin 7.10.2 – reparierter Stable-Kandidat
2
+
3
+ Version 7.10.2 ist ein gezieltes Stabilitäts-Hotfix für den fehlerhaften Stand 7.10.1. Die Oberfläche und die bereits freigegebenen Funktionen aus 7.10.1 bleiben erhalten.
4
+
5
+ ## Behobene Fehler
6
+
7
+ - Die automatische NexoWatt-Stable-Updateverwaltung schreibt ihren Laufzeitstatus nicht mehr in `system.adapter.eos-admin.0.native`. Dadurch wird die laufende EOS-Admin-Instanz beim Start nicht mehr fortlaufend neu gestartet.
8
+ - Die erste Synchronisierung der Stable-Update-Richtlinien erfolgt erst nach einer Startschutzzeit. Der HTTP-Server kann JavaScript- und CSS-Dateien vollständig ausliefern, bevor Repository-Richtlinien geprüft werden.
9
+ - Der Update-Manager beendet alle Zeitgeber beim Herunterfahren des Webservers.
10
+ - Das geprüfte Backend ist vollständig vorkompiliert und über ein SHA-256-Manifest versiegelt. `npm publish` und `npm pack` benötigen deshalb keine lokalen TypeScript-/TSX-Entwicklungswerkzeuge und starten weder `tsc` noch `tsx`.
11
+ - Ein Backend-Runtime-Test prüft alle lokalen `require`-/Import-Abhängigkeiten, ihre Syntax und ihre Abdeckung durch die explizite npm-Dateiliste. Er startet dabei keinen verschachtelten `npm pack`-Prozess mehr, damit `npm publish` unter Windows nicht beim Aufruf von `npm.cmd` abbricht.
12
+ - `build/lib/eosRequestSecurity.js` ist fest Bestandteil des geprüften Runtime-Artefakts.
13
+
14
+ ## Unverändert übernommen
15
+
16
+ - Native ioBroker-Passwortverwaltung ohne erzwungene EOS-Erstpasswortseite.
17
+ - Dauerhafter vertikaler Cockpit-Scrollbereich.
18
+ - Bearbeiten-Stift innerhalb des unteren Kartenrasters.
19
+ - Rollen- und Sicherheitssystem des 7.10.1-UI-Baselines.
20
+ - Automatische Stable-Updates ausschließlich für installierte NexoWatt-Adapter; durch Admin/Service abschaltbar.
@@ -0,0 +1,13 @@
1
+ # Release Acceptance – NexoWatt EOS Admin 7.10.2
2
+
3
+ Der Stable-Kandidat ist freigabefähig, wenn alle folgenden Bedingungen erfüllt sind:
4
+
5
+ - Backend-Kompilierung erfolgreich.
6
+ - Paket- und Stabilitätsprüfung vollständig erfolgreich.
7
+ - Backend-Runtime-Abhängigkeitskette vollständig und im npm-Artefakt enthalten.
8
+ - `build/lib/eosRequestSecurity.js` im gepackten Artefakt vorhanden.
9
+ - Auto-Update-Selbsttest bestätigt: kein Schreiben auf `system.adapter.eos-admin.0`.
10
+ - Wiederholter Auto-Update-Abgleich schreibt unveränderte Objektkonfigurationen nicht erneut.
11
+ - Startschutz verhindert Repository-Änderungen während des ersten Browser-Ladevorgangs.
12
+ - Installiertes System zeigt über mindestens 60 Sekunden keine Start-/Stop-Schleife.
13
+ - Browserkonsole bleibt frei von abgebrochenen Chunk-Transfers und Verbindungsverweigerungen auf Port 8081.
@@ -0,0 +1,11 @@
1
+ # Release Notes – NexoWatt EOS Admin 7.10.2
2
+
3
+ ## Kritischer Stabilitätsfix
4
+
5
+ Der in 7.10.1 neu eingeführte Stable-Update-Manager speicherte bei jedem Start einen neuen Zeitstempel in der Native-Konfiguration der laufenden `eos-admin.0`-Instanz. ioBroker behandelt eine Änderung dieser Instanzkonfiguration als Neustartgrund. Dadurch entstand eine permanente Start-/Stop-Schleife. Während dieser Schleife wurden Browser-Bundles nur teilweise übertragen; daraus entstanden `ERR_INCOMPLETE_CHUNKED_ENCODING`, fehlgeschlagene dynamische Imports und `ERR_CONNECTION_REFUSED` für CSS-Dateien.
6
+
7
+ 7.10.2 speichert Einstellung und Laufzeitstatus ausschließlich in quittierten Adapter-States. Der Update-Abgleich startet verzögert und schreibt unveränderte Adapter-/Repository-Richtlinien nicht erneut.
8
+
9
+ ## Paketvollständigkeit
10
+
11
+ Das Backend und das Frontend sind in der Repository-ZIP bereits vollständig kompiliert. Die Release-Lifecycle-Skripte führen vor `npm pack` und `npm publish` ausschließlich dependency-freie Node.js-Prüfungen aus; `tsc`, `tsx`, `npm install` und `npm ci` werden nicht benötigt. Ein SHA-256-Manifest versiegelt den geprüften Quell- und Buildstand. Zusätzlich verfolgt der Backend-Runtime-Test die lokale Modulabhängigkeitskette ab `build/main.js`, führt einen Syntaxcheck aus und verifiziert die Abdeckung jeder Runtime-Datei durch die explizite npm-Dateiliste. Der Test startet innerhalb von `prepublishOnly` keinen verschachtelten `npm pack`-/`npm.cmd`-Prozess mehr; der endgültige Paketinhalt wird separat durch `npm publish --dry-run` geprüft. Damit wird insbesondere ein fehlendes `build/lib/eosRequestSecurity.js` vor einer Veröffentlichung erkannt.
@@ -1,43 +1,441 @@
1
1
  "use strict";
2
+ /**
3
+ * NexoWatt stable adapter auto-update policy manager.
4
+ *
5
+ * This class does not install packages itself. It configures ioBroker's native
6
+ * adapterAutoUpgrade manager so only installed NexoWatt adapters present in the
7
+ * detected Stable repository receive the `major` policy. All other adapters and
8
+ * existing user policies are preserved.
9
+ *
10
+ * Runtime status is deliberately stored in adapter states, never in the native
11
+ * configuration of the running eos-admin instance. Changing an instance native
12
+ * object causes ioBroker to restart that instance. Version 7.10.1 persisted a
13
+ * fresh timestamp there during every startup and therefore created an endless
14
+ * restart loop while the browser was still loading its JavaScript and CSS.
15
+ */
2
16
  Object.defineProperty(exports, "__esModule", { value: true });
3
17
  exports.NexoWattStableUpdateManager = void 0;
4
18
  exports.isNexoWattRepositoryEntry = isNexoWattRepositoryEntry;
5
19
  const ADMIN_USER = 'system.user.admin';
6
20
  const POLICY = 'major';
7
21
  const RECONCILE_INTERVAL_MS = 6 * 60 * 60 * 1000;
22
+ const STARTUP_RECONCILE_DELAY_MS = 30_000;
8
23
  const REPOSITORY_REFRESH_DELAY_MS = 2500;
9
- const clone = value => JSON.parse(JSON.stringify(value));
10
- const normalizedName = value => String(value || '').trim().replace(/^system\.adapter\./, '').replace(/\.\d+$/, '');
11
- const stableVersion = value => /^\d+\.\d+\.\d+$/.test(String(value || '').trim());
24
+ const ENABLED_STATE_ID = 'info.nexowattStableUpdatesEnabled';
25
+ const STATUS_STATE_ID = 'info.nexowattStableUpdatesState';
26
+ const clone = (value) => JSON.parse(JSON.stringify(value));
27
+ const normalizedName = (value) => String(value || '').trim().replace(/^system\.adapter\./, '').replace(/\.\d+$/, '');
28
+ const stableVersion = (value) => /^\d+\.\d+\.\d+$/.test(String(value || '').trim());
12
29
  function isNexoWattRepositoryEntry(name, entry) {
13
30
  const adapterName = normalizedName(entry?.name || name).toLowerCase();
14
31
  if (adapterName === 'eos-admin' || adapterName.startsWith('nexowatt-') || adapterName.startsWith('eos-'))
15
32
  return true;
16
- const evidence = JSON.stringify({ name, adapterName, title: entry?.title, desc: entry?.desc, author: entry?.author, authors: entry?.authors, publisher: entry?.publisher, url: entry?.url, meta: entry?.meta, readme: entry?.readme, extIcon: entry?.extIcon, licenseInformation: entry?.licenseInformation }).toLowerCase();
33
+ const evidence = JSON.stringify({
34
+ name,
35
+ adapterName,
36
+ title: entry?.title,
37
+ desc: entry?.desc,
38
+ author: entry?.author,
39
+ authors: entry?.authors,
40
+ publisher: entry?.publisher,
41
+ url: entry?.url,
42
+ meta: entry?.meta,
43
+ readme: entry?.readme,
44
+ extIcon: entry?.extIcon,
45
+ licenseInformation: entry?.licenseInformation,
46
+ }).toLowerCase();
17
47
  return evidence.includes('nexowatt') || evidence.includes('github.com/nexowatt/');
18
48
  }
19
49
  class NexoWattStableUpdateManager {
20
50
  adapter;
21
51
  timer;
52
+ startupTimer;
22
53
  reconcilePromise;
23
54
  refreshTimer;
24
55
  retryTimer;
25
- constructor(adapter) { this.adapter = adapter; }
56
+ stopped = false;
57
+ cachedEnabled;
58
+ cachedState = {};
59
+ constructor(adapter) {
60
+ this.adapter = adapter;
61
+ }
26
62
  get instanceId() { return `system.adapter.${this.adapter.namespace}`; }
27
- async start() { const status = await this.reconcile('startup'); if (!this.timer) { this.timer = setInterval(() => void this.reconcile('interval'), RECONCILE_INTERVAL_MS); this.timer.unref?.(); } return status; }
28
- stop() { if (this.timer) clearInterval(this.timer); if (this.refreshTimer) clearTimeout(this.refreshTimer); if (this.retryTimer) clearTimeout(this.retryTimer); this.timer = undefined; this.refreshTimer = undefined; this.retryTimer = undefined; }
29
- async getStatus(refresh = false) { if (refresh) return this.reconcile('status'); const instance = await this.adapter.getForeignObjectAsync(this.instanceId); return this.statusFromNative(instance?.native || {}); }
30
- async setEnabled(enabled) { await this.adapter.extendForeignObjectAsync(this.instanceId, { native: { eosNexoWattAutoUpdate: enabled } }, { user: ADMIN_USER }); return this.reconcile(enabled ? 'enabled' : 'disabled'); }
31
- async reconcile(reason = 'manual') { if (this.reconcilePromise) return this.reconcilePromise; this.reconcilePromise = this.reconcileInternal(reason).finally(() => { this.reconcilePromise = undefined; }); return this.reconcilePromise; }
32
- statusFromNative(native) { const state = native.eosNexoWattAutoUpdateState || {}; return { enabled: native.eosNexoWattAutoUpdate !== false, repository: String(state.selectedRepository || ''), managedAdapters: Array.isArray(state.managedAdapters) ? state.managedAdapters.map(String).sort() : [], availableStableAdapters: Array.isArray(state.availableStableAdapters) ? state.availableStableAdapters.map(String).sort() : [], lastSync: Number(state.lastSync || 0), lastRepositoryRefresh: Number(state.lastRepositoryRefresh || 0), error: String(state.error || ''), policy: POLICY, source: 'ioBroker-native-auto-upgrade' }; }
33
- async reconcileInternal(reason) { const instance = await this.adapter.getForeignObjectAsync(this.instanceId); const native = instance?.native || {}; const enabled = native.eosNexoWattAutoUpdate !== false; const state = clone(native.eosNexoWattAutoUpdateState || {}); try { if (!enabled) return await this.disable(state, reason); return await this.enable(state, reason); } catch (error) { const message = error instanceof Error ? error.message : String(error || 'unknownError'); state.error = message; state.lastSync = Date.now(); await this.persist(false, state); this.adapter.log.warn(`[NexoWatt stable updates] ${message}`); return this.statusFromNative({ eosNexoWattAutoUpdate: enabled, eosNexoWattAutoUpdateState: state }); } }
34
- async readInstalledAdapters() { const view = await this.adapter.getObjectViewAsync('system', 'adapter', { startkey: 'system.adapter.', endkey: 'system.adapter.\u9999' }, { user: ADMIN_USER }); const result = new Map(); for (const row of view?.rows || []) { const object = row?.value || row?.doc; const name = normalizedName(object?.common?.name || row?.id || object?._id); if (name && object?.common?.version) result.set(name, object); } return result; }
35
- async readRepositorySelection(systemConfig) { const repositories = await this.adapter.getForeignObjectAsync('system.repositories'); const rows = repositories?.native?.repositories || {}; const active = Array.isArray(systemConfig?.common?.activeRepo) ? systemConfig.common.activeRepo.map(String) : []; const candidates = Object.entries(rows).map(([name, repo]) => { const entries = repo?.json && typeof repo.json === 'object' ? repo.json : {}; const stableNames = Object.entries(entries).filter(([entryName, entry]) => stableVersion(entry?.version) && isNexoWattRepositoryEntry(entryName, entry)).map(([entryName, entry]) => normalizedName(entry?.name || entryName)).filter(Boolean); return { name, entries, stableNames: [...new Set(stableNames)].sort(), activeIndex: active.indexOf(name) }; }).filter(row => row.stableNames.length > 0); if (!candidates.length) throw new Error('nexowattStableRepositoryNotFound'); candidates.sort((a, b) => { const aa = a.activeIndex < 0 ? Number.MAX_SAFE_INTEGER : a.activeIndex; const bb = b.activeIndex < 0 ? Number.MAX_SAFE_INTEGER : b.activeIndex; return aa - bb || b.stableNames.length - a.stableNames.length || a.name.localeCompare(b.name); }); return candidates[0]; }
36
- async enable(state, reason) { const systemConfig = await this.adapter.getForeignObjectAsync('system.config'); if (!systemConfig?.common) throw new Error('systemConfigUnavailable'); const selected = await this.readRepositorySelection(systemConfig); const installed = await this.readInstalledAdapters(); const managedNames = selected.stableNames.filter(name => installed.has(name)).sort(); if (!managedNames.length) throw new Error('noInstalledNexoWattStableAdapters'); state.previousPolicies ||= {}; for (const name of managedNames) { if (!(name in state.previousPolicies)) { const current = installed.get(name)?.common?.automaticUpgrade; state.previousPolicies[name] = current == null ? null : current; } await this.writeAdapterPolicy(name, POLICY); } const common = systemConfig.common; const activeRepo = Array.isArray(common.activeRepo) ? [...common.activeRepo] : []; const auto = common.adapterAutoUpgrade && typeof common.adapterAutoUpgrade === 'object' ? clone(common.adapterAutoUpgrade) : { repositories: {}, defaultPolicy: 'none' }; auto.repositories = auto.repositories && typeof auto.repositories === 'object' ? { ...auto.repositories } : {}; if (state.previousRepositoryEnabled === undefined) state.previousRepositoryEnabled = Object.prototype.hasOwnProperty.call(auto.repositories, selected.name) ? Boolean(auto.repositories[selected.name]) : null; auto.repositories[selected.name] = true; if (!auto.defaultPolicy) auto.defaultPolicy = 'none'; common.adapterAutoUpgrade = auto; if (activeRepo[0] !== selected.name) { if (!state.previousActiveRepo) state.previousActiveRepo = [...activeRepo]; state.ownsActiveRepoOrder = true; common.activeRepo = [selected.name, ...activeRepo.filter(name => name !== selected.name)]; } await this.adapter.setForeignObjectAsync('system.config', systemConfig, { user: ADMIN_USER }); state.selectedRepository = selected.name; state.availableStableAdapters = selected.stableNames; state.managedAdapters = managedNames; state.lastSync = Date.now(); state.error = ''; await this.persist(true, state); this.scheduleRepositoryRefresh(selected.name, state); this.adapter.log.info(`[NexoWatt stable updates] Enabled for ${managedNames.join(', ')} from repository "${selected.name}" (${reason})`); return this.statusFromNative({ eosNexoWattAutoUpdate: true, eosNexoWattAutoUpdateState: state }); }
37
- async disable(state, reason) { for (const [name, previous] of Object.entries(state.previousPolicies || {})) { const current = await this.adapter.getForeignObjectAsync(`system.adapter.${normalizedName(name)}`); if (current?.common?.automaticUpgrade === POLICY) await this.writeAdapterPolicy(name, previous); } const systemConfig = await this.adapter.getForeignObjectAsync('system.config'); if (systemConfig?.common) { const auto = systemConfig.common.adapterAutoUpgrade && typeof systemConfig.common.adapterAutoUpgrade === 'object' ? clone(systemConfig.common.adapterAutoUpgrade) : null; if (auto && state.selectedRepository) { auto.repositories = auto.repositories && typeof auto.repositories === 'object' ? { ...auto.repositories } : {}; if (auto.repositories[state.selectedRepository] === true) { if (state.previousRepositoryEnabled === null || state.previousRepositoryEnabled === undefined) delete auto.repositories[state.selectedRepository]; else auto.repositories[state.selectedRepository] = state.previousRepositoryEnabled; } systemConfig.common.adapterAutoUpgrade = auto; } if (state.ownsActiveRepoOrder && Array.isArray(state.previousActiveRepo) && Array.isArray(systemConfig.common.activeRepo) && systemConfig.common.activeRepo[0] === state.selectedRepository) systemConfig.common.activeRepo = [...state.previousActiveRepo]; await this.adapter.setForeignObjectAsync('system.config', systemConfig, { user: ADMIN_USER }); } state.previousPolicies = {}; state.previousRepositoryEnabled = undefined; state.previousActiveRepo = undefined; state.ownsActiveRepoOrder = false; state.managedAdapters = []; state.lastSync = Date.now(); state.error = ''; await this.persist(false, state); this.adapter.log.info(`[NexoWatt stable updates] Disabled and previous policies restored (${reason})`); return this.statusFromNative({ eosNexoWattAutoUpdate: false, eosNexoWattAutoUpdateState: state }); }
38
- async writeAdapterPolicy(name, policy) { const id = `system.adapter.${normalizedName(name)}`; const object = await this.adapter.getForeignObjectAsync(id); if (!object?.common) return; if (policy === null) delete object.common.automaticUpgrade; else object.common.automaticUpgrade = policy; await this.adapter.setForeignObjectAsync(id, object, { user: ADMIN_USER }); }
39
- async persist(enabled, state) { await this.adapter.extendForeignObjectAsync(this.instanceId, { native: { eosNexoWattAutoUpdate: enabled, eosNexoWattAutoUpdateState: state } }, { user: ADMIN_USER }); }
40
- scheduleRetry() { if (this.retryTimer) clearTimeout(this.retryTimer); this.retryTimer = setTimeout(() => void this.reconcile('retry'), 60000); this.retryTimer.unref?.(); }
41
- scheduleRepositoryRefresh(repository, state) { if (!this.adapter.sendToHostAsync || !this.adapter.host) return; if (this.refreshTimer) clearTimeout(this.refreshTimer); this.refreshTimer = setTimeout(() => { void this.adapter.sendToHostAsync?.(this.adapter.host, 'getRepository', { repo: repository, update: true }).then(async () => { const current = await this.adapter.getForeignObjectAsync(this.instanceId); if (current?.native?.eosNexoWattAutoUpdate === false) return; state.lastRepositoryRefresh = Date.now(); await this.persist(true, state); }).catch(error => this.adapter.log.warn(`[NexoWatt stable updates] Repository refresh failed: ${error instanceof Error ? error.message : error}`)); }, REPOSITORY_REFRESH_DELAY_MS); this.refreshTimer.unref?.(); }
63
+ async start() {
64
+ this.stopped = false;
65
+ const status = await this.getStatus(false);
66
+ this.scheduleStartupReconcile();
67
+ this.ensurePeriodicTimer();
68
+ return status;
69
+ }
70
+ stop() {
71
+ this.stopped = true;
72
+ if (this.timer)
73
+ clearInterval(this.timer);
74
+ if (this.startupTimer)
75
+ clearTimeout(this.startupTimer);
76
+ if (this.refreshTimer)
77
+ clearTimeout(this.refreshTimer);
78
+ if (this.retryTimer)
79
+ clearTimeout(this.retryTimer);
80
+ this.timer = undefined;
81
+ this.startupTimer = undefined;
82
+ this.refreshTimer = undefined;
83
+ this.retryTimer = undefined;
84
+ }
85
+ async getStatus(refresh = false) {
86
+ if (refresh)
87
+ return this.reconcile('status');
88
+ const persisted = await this.readPersisted();
89
+ return this.statusFromPersisted(persisted.enabled, persisted.state);
90
+ }
91
+ async setEnabled(enabled) {
92
+ this.stopped = false;
93
+ if (this.startupTimer) {
94
+ clearTimeout(this.startupTimer);
95
+ this.startupTimer = undefined;
96
+ }
97
+ const persisted = await this.readPersisted();
98
+ await this.persist(enabled, persisted.state);
99
+ const status = await this.reconcile(enabled ? 'enabled' : 'disabled');
100
+ this.ensurePeriodicTimer();
101
+ return status;
102
+ }
103
+ async reconcile(reason = 'manual') {
104
+ if (this.reconcilePromise)
105
+ return this.reconcilePromise;
106
+ this.reconcilePromise = this.reconcileInternal(reason).finally(() => { this.reconcilePromise = undefined; });
107
+ return this.reconcilePromise;
108
+ }
109
+ scheduleStartupReconcile() {
110
+ if (this.startupTimer || this.stopped)
111
+ return;
112
+ this.startupTimer = setTimeout(() => {
113
+ this.startupTimer = undefined;
114
+ if (!this.stopped) {
115
+ void this.reconcile('startup').catch(error => this.adapter.log.warn(`[NexoWatt stable updates] Startup reconciliation failed: ${error instanceof Error ? error.message : error}`));
116
+ }
117
+ }, STARTUP_RECONCILE_DELAY_MS);
118
+ this.startupTimer.unref?.();
119
+ }
120
+ ensurePeriodicTimer() {
121
+ if (this.timer || this.stopped)
122
+ return;
123
+ this.timer = setInterval(() => {
124
+ if (!this.stopped)
125
+ void this.reconcile('interval');
126
+ }, RECONCILE_INTERVAL_MS);
127
+ this.timer.unref?.();
128
+ }
129
+ parseState(value) {
130
+ if (value && typeof value === 'object' && !Array.isArray(value))
131
+ return clone(value);
132
+ if (typeof value !== 'string' || !value.trim())
133
+ return null;
134
+ try {
135
+ const parsed = JSON.parse(value);
136
+ return parsed && typeof parsed === 'object' && !Array.isArray(parsed) ? parsed : null;
137
+ }
138
+ catch {
139
+ return null;
140
+ }
141
+ }
142
+ async readPersisted() {
143
+ // Legacy 7.10.1 values are read once as a migration fallback. They are
144
+ // never written back to the instance native object.
145
+ let legacyNative = {};
146
+ try {
147
+ const instance = await this.adapter.getForeignObjectAsync(this.instanceId);
148
+ legacyNative = instance?.native || {};
149
+ }
150
+ catch (error) {
151
+ this.adapter.log.debug(`[NexoWatt stable updates] Cannot read legacy native state: ${error instanceof Error ? error.message : error}`);
152
+ }
153
+ let enabled = this.cachedEnabled ?? (legacyNative.eosNexoWattAutoUpdate !== false);
154
+ let state = Object.keys(this.cachedState).length
155
+ ? clone(this.cachedState)
156
+ : clone((legacyNative.eosNexoWattAutoUpdateState || {}));
157
+ try {
158
+ const enabledState = await this.adapter.getStateAsync(ENABLED_STATE_ID);
159
+ if (typeof enabledState?.val === 'boolean')
160
+ enabled = enabledState.val;
161
+ }
162
+ catch (error) {
163
+ this.adapter.log.debug(`[NexoWatt stable updates] Cannot read enabled state: ${error instanceof Error ? error.message : error}`);
164
+ }
165
+ try {
166
+ const persistedState = await this.adapter.getStateAsync(STATUS_STATE_ID);
167
+ const parsed = this.parseState(persistedState?.val);
168
+ if (parsed)
169
+ state = parsed;
170
+ }
171
+ catch (error) {
172
+ this.adapter.log.debug(`[NexoWatt stable updates] Cannot read status state: ${error instanceof Error ? error.message : error}`);
173
+ }
174
+ this.cachedEnabled = enabled;
175
+ this.cachedState = clone(state);
176
+ return { enabled, state };
177
+ }
178
+ statusFromPersisted(enabled, state) {
179
+ return {
180
+ enabled,
181
+ repository: String(state.selectedRepository || ''),
182
+ managedAdapters: Array.isArray(state.managedAdapters) ? state.managedAdapters.map(String).sort() : [],
183
+ availableStableAdapters: Array.isArray(state.availableStableAdapters) ? state.availableStableAdapters.map(String).sort() : [],
184
+ lastSync: Number(state.lastSync || 0),
185
+ lastRepositoryRefresh: Number(state.lastRepositoryRefresh || 0),
186
+ error: String(state.error || ''),
187
+ policy: POLICY,
188
+ source: 'ioBroker-native-auto-upgrade',
189
+ };
190
+ }
191
+ async reconcileInternal(reason) {
192
+ const persisted = await this.readPersisted();
193
+ const { enabled } = persisted;
194
+ const state = clone(persisted.state);
195
+ if (this.stopped)
196
+ return this.statusFromPersisted(enabled, state);
197
+ try {
198
+ if (!enabled)
199
+ return await this.disable(state, reason);
200
+ return await this.enable(state, reason);
201
+ }
202
+ catch (error) {
203
+ const message = error instanceof Error ? error.message : String(error || 'unknownError');
204
+ state.error = message;
205
+ state.lastSync = Date.now();
206
+ if (!this.stopped)
207
+ await this.persist(enabled, state);
208
+ if (enabled && !this.stopped)
209
+ this.scheduleRetry();
210
+ if (!this.stopped)
211
+ this.adapter.log.warn(`[NexoWatt stable updates] ${message}`);
212
+ return this.statusFromPersisted(enabled, state);
213
+ }
214
+ }
215
+ async readInstalledAdapters() {
216
+ const view = await this.adapter.getObjectViewAsync('system', 'adapter', {
217
+ startkey: 'system.adapter.',
218
+ endkey: 'system.adapter.\u9999',
219
+ }, { user: ADMIN_USER });
220
+ const result = new Map();
221
+ for (const row of view?.rows || []) {
222
+ const object = row?.value || row?.doc;
223
+ const name = normalizedName(object?.common?.name || row?.id || object?._id);
224
+ if (name && object?.common?.version)
225
+ result.set(name, object);
226
+ }
227
+ return result;
228
+ }
229
+ async readRepositorySelection(systemConfig) {
230
+ const repositories = await this.adapter.getForeignObjectAsync('system.repositories');
231
+ const rows = repositories?.native?.repositories || {};
232
+ const active = Array.isArray(systemConfig?.common?.activeRepo) ? systemConfig.common.activeRepo.map(String) : [];
233
+ const candidates = Object.entries(rows).map(([name, repo]) => {
234
+ const entries = repo?.json && typeof repo.json === 'object' ? repo.json : {};
235
+ const stableNames = Object.entries(entries)
236
+ .filter(([entryName, entry]) => stableVersion(entry?.version) && isNexoWattRepositoryEntry(entryName, entry))
237
+ .map(([entryName, entry]) => normalizedName(entry?.name || entryName))
238
+ .filter(Boolean);
239
+ return { name, entries, stableNames: [...new Set(stableNames)].sort(), activeIndex: active.indexOf(name) };
240
+ }).filter(row => row.stableNames.length > 0);
241
+ if (!candidates.length)
242
+ throw new Error('nexowattStableRepositoryNotFound');
243
+ candidates.sort((a, b) => {
244
+ const aa = a.activeIndex < 0 ? Number.MAX_SAFE_INTEGER : a.activeIndex;
245
+ const bb = b.activeIndex < 0 ? Number.MAX_SAFE_INTEGER : b.activeIndex;
246
+ return aa - bb || b.stableNames.length - a.stableNames.length || a.name.localeCompare(b.name);
247
+ });
248
+ return candidates[0];
249
+ }
250
+ async enable(state, reason) {
251
+ const systemConfig = await this.adapter.getForeignObjectAsync('system.config');
252
+ if (!systemConfig?.common)
253
+ throw new Error('systemConfigUnavailable');
254
+ const selected = await this.readRepositorySelection(systemConfig);
255
+ const installed = await this.readInstalledAdapters();
256
+ const managedNames = selected.stableNames.filter(name => installed.has(name)).sort();
257
+ if (!managedNames.length)
258
+ throw new Error('noInstalledNexoWattStableAdapters');
259
+ if (this.stopped)
260
+ return this.statusFromPersisted(true, state);
261
+ state.previousPolicies ||= {};
262
+ for (const name of managedNames) {
263
+ if (this.stopped)
264
+ return this.statusFromPersisted(true, state);
265
+ if (!(name in state.previousPolicies)) {
266
+ const current = installed.get(name)?.common?.automaticUpgrade;
267
+ state.previousPolicies[name] = current == null ? null : current;
268
+ }
269
+ await this.writeAdapterPolicy(name, POLICY);
270
+ }
271
+ const common = systemConfig.common;
272
+ const activeRepo = Array.isArray(common.activeRepo) ? [...common.activeRepo] : [];
273
+ const auto = common.adapterAutoUpgrade && typeof common.adapterAutoUpgrade === 'object'
274
+ ? clone(common.adapterAutoUpgrade)
275
+ : { repositories: {}, defaultPolicy: 'none' };
276
+ auto.repositories = auto.repositories && typeof auto.repositories === 'object' ? { ...auto.repositories } : {};
277
+ let systemConfigChanged = false;
278
+ if (state.previousRepositoryEnabled === undefined) {
279
+ state.previousRepositoryEnabled = Object.prototype.hasOwnProperty.call(auto.repositories, selected.name)
280
+ ? Boolean(auto.repositories[selected.name])
281
+ : null;
282
+ }
283
+ if (auto.repositories[selected.name] !== true) {
284
+ auto.repositories[selected.name] = true;
285
+ systemConfigChanged = true;
286
+ }
287
+ if (!auto.defaultPolicy) {
288
+ auto.defaultPolicy = 'none';
289
+ systemConfigChanged = true;
290
+ }
291
+ if (JSON.stringify(common.adapterAutoUpgrade) !== JSON.stringify(auto)) {
292
+ common.adapterAutoUpgrade = auto;
293
+ systemConfigChanged = true;
294
+ }
295
+ if (activeRepo[0] !== selected.name) {
296
+ if (!state.previousActiveRepo)
297
+ state.previousActiveRepo = [...activeRepo];
298
+ state.ownsActiveRepoOrder = true;
299
+ common.activeRepo = [selected.name, ...activeRepo.filter((name) => name !== selected.name)];
300
+ systemConfigChanged = true;
301
+ }
302
+ if (systemConfigChanged && !this.stopped) {
303
+ await this.adapter.setForeignObjectAsync('system.config', systemConfig, { user: ADMIN_USER });
304
+ }
305
+ state.selectedRepository = selected.name;
306
+ state.availableStableAdapters = selected.stableNames;
307
+ state.managedAdapters = managedNames;
308
+ state.lastSync = Date.now();
309
+ state.error = '';
310
+ if (!this.stopped)
311
+ await this.persist(true, state);
312
+ if (!this.stopped)
313
+ this.scheduleRepositoryRefresh(selected.name, state);
314
+ if (!this.stopped)
315
+ this.adapter.log.info(`[NexoWatt stable updates] Enabled for ${managedNames.join(', ')} from repository "${selected.name}" (${reason})`);
316
+ return this.statusFromPersisted(true, state);
317
+ }
318
+ async disable(state, reason) {
319
+ for (const [name, previous] of Object.entries(state.previousPolicies || {})) {
320
+ if (this.stopped)
321
+ return this.statusFromPersisted(false, state);
322
+ const current = await this.adapter.getForeignObjectAsync(`system.adapter.${normalizedName(name)}`);
323
+ if (current?.common?.automaticUpgrade === POLICY)
324
+ await this.writeAdapterPolicy(name, previous);
325
+ }
326
+ const systemConfig = await this.adapter.getForeignObjectAsync('system.config');
327
+ if (systemConfig?.common) {
328
+ let systemConfigChanged = false;
329
+ const auto = systemConfig.common.adapterAutoUpgrade && typeof systemConfig.common.adapterAutoUpgrade === 'object'
330
+ ? clone(systemConfig.common.adapterAutoUpgrade)
331
+ : null;
332
+ if (auto && state.selectedRepository) {
333
+ auto.repositories = auto.repositories && typeof auto.repositories === 'object' ? { ...auto.repositories } : {};
334
+ if (auto.repositories[state.selectedRepository] === true) {
335
+ if (state.previousRepositoryEnabled === null || state.previousRepositoryEnabled === undefined) {
336
+ delete auto.repositories[state.selectedRepository];
337
+ }
338
+ else {
339
+ auto.repositories[state.selectedRepository] = state.previousRepositoryEnabled;
340
+ }
341
+ systemConfigChanged = true;
342
+ }
343
+ if (JSON.stringify(systemConfig.common.adapterAutoUpgrade) !== JSON.stringify(auto)) {
344
+ systemConfig.common.adapterAutoUpgrade = auto;
345
+ systemConfigChanged = true;
346
+ }
347
+ }
348
+ if (state.ownsActiveRepoOrder && Array.isArray(state.previousActiveRepo)
349
+ && Array.isArray(systemConfig.common.activeRepo)
350
+ && systemConfig.common.activeRepo[0] === state.selectedRepository) {
351
+ systemConfig.common.activeRepo = [...state.previousActiveRepo];
352
+ systemConfigChanged = true;
353
+ }
354
+ if (systemConfigChanged && !this.stopped) {
355
+ await this.adapter.setForeignObjectAsync('system.config', systemConfig, { user: ADMIN_USER });
356
+ }
357
+ }
358
+ state.previousPolicies = {};
359
+ state.previousRepositoryEnabled = undefined;
360
+ state.previousActiveRepo = undefined;
361
+ state.ownsActiveRepoOrder = false;
362
+ state.managedAdapters = [];
363
+ state.lastSync = Date.now();
364
+ state.error = '';
365
+ if (!this.stopped)
366
+ await this.persist(false, state);
367
+ if (!this.stopped)
368
+ this.adapter.log.info(`[NexoWatt stable updates] Disabled and previous policies restored (${reason})`);
369
+ return this.statusFromPersisted(false, state);
370
+ }
371
+ async writeAdapterPolicy(name, policy) {
372
+ const id = `system.adapter.${normalizedName(name)}`;
373
+ const object = await this.adapter.getForeignObjectAsync(id);
374
+ if (!object?.common || this.stopped)
375
+ return;
376
+ const current = object.common.automaticUpgrade;
377
+ if ((policy === null && current === undefined) || current === policy)
378
+ return;
379
+ if (policy === null)
380
+ delete object.common.automaticUpgrade;
381
+ else
382
+ object.common.automaticUpgrade = policy;
383
+ await this.adapter.setForeignObjectAsync(id, object, { user: ADMIN_USER });
384
+ }
385
+ async persist(enabled, state) {
386
+ if (this.stopped)
387
+ return;
388
+ this.cachedEnabled = enabled;
389
+ this.cachedState = clone(state);
390
+ const currentEnabled = await this.adapter.getStateAsync(ENABLED_STATE_ID).catch(() => null);
391
+ if (currentEnabled?.val !== enabled) {
392
+ await this.adapter.setStateAsync(ENABLED_STATE_ID, enabled, true);
393
+ }
394
+ const serialized = JSON.stringify(state);
395
+ const currentState = await this.adapter.getStateAsync(STATUS_STATE_ID).catch(() => null);
396
+ const currentSerialized = typeof currentState?.val === 'string'
397
+ ? currentState.val
398
+ : currentState?.val == null ? '' : JSON.stringify(currentState.val);
399
+ if (currentSerialized !== serialized) {
400
+ await this.adapter.setStateAsync(STATUS_STATE_ID, serialized, true);
401
+ }
402
+ }
403
+ scheduleRetry() {
404
+ if (this.retryTimer)
405
+ clearTimeout(this.retryTimer);
406
+ this.retryTimer = setTimeout(() => {
407
+ this.retryTimer = undefined;
408
+ if (!this.stopped)
409
+ void this.reconcile('retry');
410
+ }, 60_000);
411
+ this.retryTimer.unref?.();
412
+ }
413
+ scheduleRepositoryRefresh(repository, state) {
414
+ if (!this.adapter.sendToHostAsync || !this.adapter.host || this.stopped)
415
+ return;
416
+ if (this.refreshTimer)
417
+ clearTimeout(this.refreshTimer);
418
+ this.refreshTimer = setTimeout(() => {
419
+ this.refreshTimer = undefined;
420
+ if (this.stopped)
421
+ return;
422
+ void this.adapter.sendToHostAsync?.(this.adapter.host, 'getRepository', { repo: repository, update: true })
423
+ .then(async () => {
424
+ if (this.stopped)
425
+ return;
426
+ const current = await this.readPersisted();
427
+ if (!current.enabled)
428
+ return;
429
+ const nextState = { ...current.state, ...state, lastRepositoryRefresh: Date.now() };
430
+ await this.persist(true, nextState);
431
+ })
432
+ .catch(error => {
433
+ if (!this.stopped)
434
+ this.adapter.log.warn(`[NexoWatt stable updates] Repository refresh failed: ${error instanceof Error ? error.message : error}`);
435
+ });
436
+ }, REPOSITORY_REFRESH_DELAY_MS);
437
+ this.refreshTimer.unref?.();
438
+ }
42
439
  }
43
440
  exports.NexoWattStableUpdateManager = NexoWattStableUpdateManager;
441
+ //# sourceMappingURL=eosAutoUpdate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"eosAutoUpdate.js","sourceRoot":"./src/","sources":["eosAutoUpdate.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;GAaG;;;AAgEH,8DAkBC;AA9BD,MAAM,UAAU,GAAG,mBAAmB,CAAC;AACvC,MAAM,MAAM,GAA6B,OAAO,CAAC;AACjD,MAAM,qBAAqB,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;AACjD,MAAM,0BAA0B,GAAG,MAAM,CAAC;AAC1C,MAAM,2BAA2B,GAAG,IAAI,CAAC;AACzC,MAAM,gBAAgB,GAAG,mCAAmC,CAAC;AAC7D,MAAM,eAAe,GAAG,iCAAiC,CAAC;AAE1D,MAAM,KAAK,GAAG,CAAI,KAAQ,EAAK,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC;AACpE,MAAM,cAAc,GAAG,CAAC,KAAc,EAAU,EAAE,CAAC,MAAM,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,oBAAoB,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;AACtI,MAAM,aAAa,GAAG,CAAC,KAAc,EAAW,EAAE,CAAC,iBAAiB,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;AAEtG,SAAgB,yBAAyB,CAAC,IAAY,EAAE,KAAU;IAC9D,MAAM,WAAW,GAAG,cAAc,CAAC,KAAK,EAAE,IAAI,IAAI,IAAI,CAAC,CAAC,WAAW,EAAE,CAAC;IACtE,IAAI,WAAW,KAAK,WAAW,IAAI,WAAW,CAAC,UAAU,CAAC,WAAW,CAAC,IAAI,WAAW,CAAC,UAAU,CAAC,MAAM,CAAC;QAAE,OAAO,IAAI,CAAC;IACtH,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC;QAC5B,IAAI;QACJ,WAAW;QACX,KAAK,EAAE,KAAK,EAAE,KAAK;QACnB,IAAI,EAAE,KAAK,EAAE,IAAI;QACjB,MAAM,EAAE,KAAK,EAAE,MAAM;QACrB,OAAO,EAAE,KAAK,EAAE,OAAO;QACvB,SAAS,EAAE,KAAK,EAAE,SAAS;QAC3B,GAAG,EAAE,KAAK,EAAE,GAAG;QACf,IAAI,EAAE,KAAK,EAAE,IAAI;QACjB,MAAM,EAAE,KAAK,EAAE,MAAM;QACrB,OAAO,EAAE,KAAK,EAAE,OAAO;QACvB,kBAAkB,EAAE,KAAK,EAAE,kBAAkB;KAChD,CAAC,CAAC,WAAW,EAAE,CAAC;IACjB,OAAO,QAAQ,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,QAAQ,CAAC,QAAQ,CAAC,sBAAsB,CAAC,CAAC;AACtF,CAAC;AAED,MAAa,2BAA2B;IAUP;IATrB,KAAK,CAAkB;IACvB,YAAY,CAAkB;IAC9B,gBAAgB,CAAuC;IACvD,YAAY,CAAkB;IAC9B,UAAU,CAAkB;IAC5B,OAAO,GAAG,KAAK,CAAC;IAChB,aAAa,CAAW;IACxB,WAAW,GAAmB,EAAE,CAAC;IAEzC,YAA6B,OAAkC;QAAlC,YAAO,GAAP,OAAO,CAA2B;IAAG,CAAC;IAEnE,IAAY,UAAU,KAAa,OAAO,kBAAkB,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC;IAEvF,KAAK,CAAC,KAAK;QACP,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC;QACrB,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;QAC3C,IAAI,CAAC,wBAAwB,EAAE,CAAC;QAChC,IAAI,CAAC,mBAAmB,EAAE,CAAC;QAC3B,OAAO,MAAM,CAAC;IAClB,CAAC;IAED,IAAI;QACA,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;QACpB,IAAI,IAAI,CAAC,KAAK;YAAE,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC1C,IAAI,IAAI,CAAC,YAAY;YAAE,YAAY,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QACvD,IAAI,IAAI,CAAC,YAAY;YAAE,YAAY,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QACvD,IAAI,IAAI,CAAC,UAAU;YAAE,YAAY,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QACnD,IAAI,CAAC,KAAK,GAAG,SAAS,CAAC;QACvB,IAAI,CAAC,YAAY,GAAG,SAAS,CAAC;QAC9B,IAAI,CAAC,YAAY,GAAG,SAAS,CAAC;QAC9B,IAAI,CAAC,UAAU,GAAG,SAAS,CAAC;IAChC,CAAC;IAED,KAAK,CAAC,SAAS,CAAC,OAAO,GAAG,KAAK;QAC3B,IAAI,OAAO;YAAE,OAAO,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;QAC7C,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,aAAa,EAAE,CAAC;QAC7C,OAAO,IAAI,CAAC,mBAAmB,CAAC,SAAS,CAAC,OAAO,EAAE,SAAS,CAAC,KAAK,CAAC,CAAC;IACxE,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,OAAgB;QAC7B,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC;QACrB,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;YACpB,YAAY,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;YAChC,IAAI,CAAC,YAAY,GAAG,SAAS,CAAC;QAClC,CAAC;QACD,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,aAAa,EAAE,CAAC;QAC7C,MAAM,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,SAAS,CAAC,KAAK,CAAC,CAAC;QAC7C,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC;QACtE,IAAI,CAAC,mBAAmB,EAAE,CAAC;QAC3B,OAAO,MAAM,CAAC;IAClB,CAAC;IAED,KAAK,CAAC,SAAS,CAAC,MAAM,GAAG,QAAQ;QAC7B,IAAI,IAAI,CAAC,gBAAgB;YAAE,OAAO,IAAI,CAAC,gBAAgB,CAAC;QACxD,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,gBAAgB,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;QAC7G,OAAO,IAAI,CAAC,gBAAgB,CAAC;IACjC,CAAC;IAEO,wBAAwB;QAC5B,IAAI,IAAI,CAAC,YAAY,IAAI,IAAI,CAAC,OAAO;YAAE,OAAO;QAC9C,IAAI,CAAC,YAAY,GAAG,UAAU,CAAC,GAAG,EAAE;YAChC,IAAI,CAAC,YAAY,GAAG,SAAS,CAAC;YAC9B,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;gBAChB,KAAK,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CACzC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,4DAA4D,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CACtI,CAAC;YACN,CAAC;QACL,CAAC,EAAE,0BAA0B,CAAC,CAAC;QAC/B,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,EAAE,CAAC;IAChC,CAAC;IAEO,mBAAmB;QACvB,IAAI,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,OAAO;YAAE,OAAO;QACvC,IAAI,CAAC,KAAK,GAAG,WAAW,CAAC,GAAG,EAAE;YAC1B,IAAI,CAAC,IAAI,CAAC,OAAO;gBAAE,KAAK,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;QACvD,CAAC,EAAE,qBAAqB,CAAC,CAAC;QAC1B,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,EAAE,CAAC;IACzB,CAAC;IAEO,UAAU,CAAC,KAAc;QAC7B,IAAI,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;YAAE,OAAO,KAAK,CAAC,KAAuB,CAAC,CAAC;QACvG,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE;YAAE,OAAO,IAAI,CAAC;QAC5D,IAAI,CAAC;YACD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YACjC,OAAO,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAwB,CAAC,CAAC,CAAC,IAAI,CAAC;QAC5G,CAAC;QAAC,MAAM,CAAC;YACL,OAAO,IAAI,CAAC;QAChB,CAAC;IACL,CAAC;IAEO,KAAK,CAAC,aAAa;QACvB,uEAAuE;QACvE,oDAAoD;QACpD,IAAI,YAAY,GAAwB,EAAE,CAAC;QAC3C,IAAI,CAAC;YACD,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,qBAAqB,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;YAC3E,YAAY,GAAG,QAAQ,EAAE,MAAM,IAAI,EAAE,CAAC;QAC1C,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACb,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,8DAA8D,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC;QAC3I,CAAC;QAED,IAAI,OAAO,GAAG,IAAI,CAAC,aAAa,IAAI,CAAC,YAAY,CAAC,qBAAqB,KAAK,KAAK,CAAC,CAAC;QACnF,IAAI,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,MAAM;YAC5C,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC;YACzB,CAAC,CAAC,KAAK,CAAC,CAAC,YAAY,CAAC,0BAA0B,IAAI,EAAE,CAAmB,CAAC,CAAC;QAE/E,IAAI,CAAC;YACD,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,gBAAgB,CAAC,CAAC;YACxE,IAAI,OAAO,YAAY,EAAE,GAAG,KAAK,SAAS;gBAAE,OAAO,GAAG,YAAY,CAAC,GAAG,CAAC;QAC3E,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACb,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,wDAAwD,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC;QACrI,CAAC;QAED,IAAI,CAAC;YACD,MAAM,cAAc,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,eAAe,CAAC,CAAC;YACzE,MAAM,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC,cAAc,EAAE,GAAG,CAAC,CAAC;YACpD,IAAI,MAAM;gBAAE,KAAK,GAAG,MAAM,CAAC;QAC/B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACb,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,uDAAuD,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC;QACpI,CAAC;QAED,IAAI,CAAC,aAAa,GAAG,OAAO,CAAC;QAC7B,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC;QAChC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;IAC9B,CAAC;IAEO,mBAAmB,CAAC,OAAgB,EAAE,KAAqB;QAC/D,OAAO;YACH,OAAO;YACP,UAAU,EAAE,MAAM,CAAC,KAAK,CAAC,kBAAkB,IAAI,EAAE,CAAC;YAClD,eAAe,EAAE,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,eAAe,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE;YACrG,uBAAuB,EAAE,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,uBAAuB,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,uBAAuB,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE;YAC7H,QAAQ,EAAE,MAAM,CAAC,KAAK,CAAC,QAAQ,IAAI,CAAC,CAAC;YACrC,qBAAqB,EAAE,MAAM,CAAC,KAAK,CAAC,qBAAqB,IAAI,CAAC,CAAC;YAC/D,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,KAAK,IAAI,EAAE,CAAC;YAChC,MAAM,EAAE,MAAM;YACd,MAAM,EAAE,8BAA8B;SACzC,CAAC;IACN,CAAC;IAEO,KAAK,CAAC,iBAAiB,CAAC,MAAc;QAC1C,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,aAAa,EAAE,CAAC;QAC7C,MAAM,EAAE,OAAO,EAAE,GAAG,SAAS,CAAC;QAC9B,MAAM,KAAK,GAAG,KAAK,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;QACrC,IAAI,IAAI,CAAC,OAAO;YAAE,OAAO,IAAI,CAAC,mBAAmB,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;QAClE,IAAI,CAAC;YACD,IAAI,CAAC,OAAO;gBAAE,OAAO,MAAM,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;YACvD,OAAO,MAAM,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;QAC5C,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACb,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,IAAI,cAAc,CAAC,CAAC;YACzF,KAAK,CAAC,KAAK,GAAG,OAAO,CAAC;YACtB,KAAK,CAAC,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YAC5B,IAAI,CAAC,IAAI,CAAC,OAAO;gBAAE,MAAM,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;YACtD,IAAI,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO;gBAAE,IAAI,CAAC,aAAa,EAAE,CAAC;YACnD,IAAI,CAAC,IAAI,CAAC,OAAO;gBAAE,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,6BAA6B,OAAO,EAAE,CAAC,CAAC;YACjF,OAAO,IAAI,CAAC,mBAAmB,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;QACpD,CAAC;IACL,CAAC;IAEO,KAAK,CAAC,qBAAqB;QAC/B,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,kBAAkB,CAAC,QAAQ,EAAE,SAAS,EAAE;YACpE,QAAQ,EAAE,iBAAiB;YAC3B,MAAM,EAAE,uBAAuB;SAClC,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,CAAC;QACzB,MAAM,MAAM,GAAG,IAAI,GAAG,EAA6B,CAAC;QACpD,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,IAAI,IAAI,EAAE,EAAE,CAAC;YACjC,MAAM,MAAM,GAAG,GAAG,EAAE,KAAK,IAAI,GAAG,EAAE,GAAG,CAAC;YACtC,MAAM,IAAI,GAAG,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,IAAI,GAAG,EAAE,EAAE,IAAI,MAAM,EAAE,GAAG,CAAC,CAAC;YAC5E,IAAI,IAAI,IAAI,MAAM,EAAE,MAAM,EAAE,OAAO;gBAAE,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QAClE,CAAC;QACD,OAAO,MAAM,CAAC;IAClB,CAAC;IAEO,KAAK,CAAC,uBAAuB,CAAC,YAAiB;QACnD,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,qBAAqB,CAAC,qBAAqB,CAAC,CAAC;QACrF,MAAM,IAAI,GAAG,YAAY,EAAE,MAAM,EAAE,YAAY,IAAI,EAAE,CAAC;QACtD,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,CAAC,YAAY,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QACjH,MAAM,UAAU,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,IAAI,CAAgB,EAAE,EAAE;YACxE,MAAM,OAAO,GAAG,IAAI,EAAE,IAAI,IAAI,OAAO,IAAI,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;YAC7E,MAAM,WAAW,GAAG,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC;iBACtC,MAAM,CAAC,CAAC,CAAC,SAAS,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,aAAa,CAAE,KAAa,EAAE,OAAO,CAAC,IAAI,yBAAyB,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;iBACrH,GAAG,CAAC,CAAC,CAAC,SAAS,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,cAAc,CAAE,KAAa,EAAE,IAAI,IAAI,SAAS,CAAC,CAAC;iBAC9E,MAAM,CAAC,OAAO,CAAC,CAAC;YACrB,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,WAAW,EAAE,CAAC,GAAG,IAAI,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,WAAW,EAAE,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;QAC/G,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QAC7C,IAAI,CAAC,UAAU,CAAC,MAAM;YAAE,MAAM,IAAI,KAAK,CAAC,kCAAkC,CAAC,CAAC;QAC5E,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;YACrB,MAAM,EAAE,GAAG,CAAC,CAAC,WAAW,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC;YACvE,MAAM,EAAE,GAAG,CAAC,CAAC,WAAW,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC;YACvE,OAAO,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC,CAAC,WAAW,CAAC,MAAM,IAAI,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAClG,CAAC,CAAC,CAAC;QACH,OAAO,UAAU,CAAC,CAAC,CAAC,CAAC;IACzB,CAAC;IAEO,KAAK,CAAC,MAAM,CAAC,KAAqB,EAAE,MAAc;QACtD,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,qBAAqB,CAAC,eAAe,CAAC,CAAC;QAC/E,IAAI,CAAC,YAAY,EAAE,MAAM;YAAE,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC;QACtE,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,uBAAuB,CAAC,YAAY,CAAC,CAAC;QAClE,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,qBAAqB,EAAE,CAAC;QACrD,MAAM,YAAY,GAAG,QAAQ,CAAC,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QACrF,IAAI,CAAC,YAAY,CAAC,MAAM;YAAE,MAAM,IAAI,KAAK,CAAC,mCAAmC,CAAC,CAAC;QAC/E,IAAI,IAAI,CAAC,OAAO;YAAE,OAAO,IAAI,CAAC,mBAAmB,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QAE/D,KAAK,CAAC,gBAAgB,KAAK,EAAE,CAAC;QAC9B,KAAK,MAAM,IAAI,IAAI,YAAY,EAAE,CAAC;YAC9B,IAAI,IAAI,CAAC,OAAO;gBAAE,OAAO,IAAI,CAAC,mBAAmB,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;YAC/D,IAAI,CAAC,CAAC,IAAI,IAAI,KAAK,CAAC,gBAAgB,CAAC,EAAE,CAAC;gBACpC,MAAM,OAAO,GAAG,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,gBAAgB,CAAC;gBAC9D,KAAK,CAAC,gBAAgB,CAAC,IAAI,CAAC,GAAG,OAAO,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,OAAmC,CAAC;YAChG,CAAC;YACD,MAAM,IAAI,CAAC,kBAAkB,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QAChD,CAAC;QAED,MAAM,MAAM,GAAG,YAAY,CAAC,MAAM,CAAC;QACnC,MAAM,UAAU,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAClF,MAAM,IAAI,GAAG,MAAM,CAAC,kBAAkB,IAAI,OAAO,MAAM,CAAC,kBAAkB,KAAK,QAAQ;YACnF,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,kBAAkB,CAAC;YAClC,CAAC,CAAC,EAAE,YAAY,EAAE,EAAE,EAAE,aAAa,EAAE,MAAM,EAAE,CAAC;QAClD,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,YAAY,IAAI,OAAO,IAAI,CAAC,YAAY,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,GAAG,IAAI,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC/G,IAAI,mBAAmB,GAAG,KAAK,CAAC;QAChC,IAAI,KAAK,CAAC,yBAAyB,KAAK,SAAS,EAAE,CAAC;YAChD,KAAK,CAAC,yBAAyB,GAAG,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,QAAQ,CAAC,IAAI,CAAC;gBACpG,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;gBAC3C,CAAC,CAAC,IAAI,CAAC;QACf,CAAC;QACD,IAAI,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC;YAC5C,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;YACxC,mBAAmB,GAAG,IAAI,CAAC;QAC/B,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC;YACtB,IAAI,CAAC,aAAa,GAAG,MAAM,CAAC;YAC5B,mBAAmB,GAAG,IAAI,CAAC;QAC/B,CAAC;QACD,IAAI,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,kBAAkB,CAAC,KAAK,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC;YACrE,MAAM,CAAC,kBAAkB,GAAG,IAAI,CAAC;YACjC,mBAAmB,GAAG,IAAI,CAAC;QAC/B,CAAC;QAED,IAAI,UAAU,CAAC,CAAC,CAAC,KAAK,QAAQ,CAAC,IAAI,EAAE,CAAC;YAClC,IAAI,CAAC,KAAK,CAAC,kBAAkB;gBAAE,KAAK,CAAC,kBAAkB,GAAG,CAAC,GAAG,UAAU,CAAC,CAAC;YAC1E,KAAK,CAAC,mBAAmB,GAAG,IAAI,CAAC;YACjC,MAAM,CAAC,UAAU,GAAG,CAAC,QAAQ,CAAC,IAAI,EAAE,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,IAAY,EAAE,EAAE,CAAC,IAAI,KAAK,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;YACpG,mBAAmB,GAAG,IAAI,CAAC;QAC/B,CAAC;QACD,IAAI,mBAAmB,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;YACvC,MAAM,IAAI,CAAC,OAAO,CAAC,qBAAqB,CAAC,eAAe,EAAE,YAAY,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,CAAC;QAClG,CAAC;QAED,KAAK,CAAC,kBAAkB,GAAG,QAAQ,CAAC,IAAI,CAAC;QACzC,KAAK,CAAC,uBAAuB,GAAG,QAAQ,CAAC,WAAW,CAAC;QACrD,KAAK,CAAC,eAAe,GAAG,YAAY,CAAC;QACrC,KAAK,CAAC,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC5B,KAAK,CAAC,KAAK,GAAG,EAAE,CAAC;QACjB,IAAI,CAAC,IAAI,CAAC,OAAO;YAAE,MAAM,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QACnD,IAAI,CAAC,IAAI,CAAC,OAAO;YAAE,IAAI,CAAC,yBAAyB,CAAC,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QACxE,IAAI,CAAC,IAAI,CAAC,OAAO;YAAE,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,yCAAyC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,qBAAqB,QAAQ,CAAC,IAAI,MAAM,MAAM,GAAG,CAAC,CAAC;QAC5J,OAAO,IAAI,CAAC,mBAAmB,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IACjD,CAAC;IAEO,KAAK,CAAC,OAAO,CAAC,KAAqB,EAAE,MAAc;QACvD,KAAK,MAAM,CAAC,IAAI,EAAE,QAAQ,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,gBAAgB,IAAI,EAAE,CAAC,EAAE,CAAC;YAC1E,IAAI,IAAI,CAAC,OAAO;gBAAE,OAAO,IAAI,CAAC,mBAAmB,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;YAChE,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,qBAAqB,CAAC,kBAAkB,cAAc,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACnG,IAAI,OAAO,EAAE,MAAM,EAAE,gBAAgB,KAAK,MAAM;gBAAE,MAAM,IAAI,CAAC,kBAAkB,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;QACpG,CAAC;QACD,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,qBAAqB,CAAC,eAAe,CAAC,CAAC;QAC/E,IAAI,YAAY,EAAE,MAAM,EAAE,CAAC;YACvB,IAAI,mBAAmB,GAAG,KAAK,CAAC;YAChC,MAAM,IAAI,GAAG,YAAY,CAAC,MAAM,CAAC,kBAAkB,IAAI,OAAO,YAAY,CAAC,MAAM,CAAC,kBAAkB,KAAK,QAAQ;gBAC7G,CAAC,CAAC,KAAK,CAAC,YAAY,CAAC,MAAM,CAAC,kBAAkB,CAAC;gBAC/C,CAAC,CAAC,IAAI,CAAC;YACX,IAAI,IAAI,IAAI,KAAK,CAAC,kBAAkB,EAAE,CAAC;gBACnC,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,YAAY,IAAI,OAAO,IAAI,CAAC,YAAY,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,GAAG,IAAI,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC/G,IAAI,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,kBAAkB,CAAC,KAAK,IAAI,EAAE,CAAC;oBACvD,IAAI,KAAK,CAAC,yBAAyB,KAAK,IAAI,IAAI,KAAK,CAAC,yBAAyB,KAAK,SAAS,EAAE,CAAC;wBAC5F,OAAO,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC;oBACvD,CAAC;yBAAM,CAAC;wBACJ,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,kBAAkB,CAAC,GAAG,KAAK,CAAC,yBAAyB,CAAC;oBAClF,CAAC;oBACD,mBAAmB,GAAG,IAAI,CAAC;gBAC/B,CAAC;gBACD,IAAI,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,MAAM,CAAC,kBAAkB,CAAC,KAAK,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC;oBAClF,YAAY,CAAC,MAAM,CAAC,kBAAkB,GAAG,IAAI,CAAC;oBAC9C,mBAAmB,GAAG,IAAI,CAAC;gBAC/B,CAAC;YACL,CAAC;YACD,IAAI,KAAK,CAAC,mBAAmB,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,kBAAkB,CAAC;mBACjE,KAAK,CAAC,OAAO,CAAC,YAAY,CAAC,MAAM,CAAC,UAAU,CAAC;mBAC7C,YAAY,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,kBAAkB,EAAE,CAAC;gBACpE,YAAY,CAAC,MAAM,CAAC,UAAU,GAAG,CAAC,GAAG,KAAK,CAAC,kBAAkB,CAAC,CAAC;gBAC/D,mBAAmB,GAAG,IAAI,CAAC;YAC/B,CAAC;YACD,IAAI,mBAAmB,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;gBACvC,MAAM,IAAI,CAAC,OAAO,CAAC,qBAAqB,CAAC,eAAe,EAAE,YAAY,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,CAAC;YAClG,CAAC;QACL,CAAC;QACD,KAAK,CAAC,gBAAgB,GAAG,EAAE,CAAC;QAC5B,KAAK,CAAC,yBAAyB,GAAG,SAAS,CAAC;QAC5C,KAAK,CAAC,kBAAkB,GAAG,SAAS,CAAC;QACrC,KAAK,CAAC,mBAAmB,GAAG,KAAK,CAAC;QAClC,KAAK,CAAC,eAAe,GAAG,EAAE,CAAC;QAC3B,KAAK,CAAC,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC5B,KAAK,CAAC,KAAK,GAAG,EAAE,CAAC;QACjB,IAAI,CAAC,IAAI,CAAC,OAAO;YAAE,MAAM,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;QACpD,IAAI,CAAC,IAAI,CAAC,OAAO;YAAE,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,sEAAsE,MAAM,GAAG,CAAC,CAAC;QAC1H,OAAO,IAAI,CAAC,mBAAmB,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;IAClD,CAAC;IAEO,KAAK,CAAC,kBAAkB,CAAC,IAAY,EAAE,MAAuC;QAClF,MAAM,EAAE,GAAG,kBAAkB,cAAc,CAAC,IAAI,CAAC,EAAE,CAAC;QACpD,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,qBAAqB,CAAC,EAAE,CAAC,CAAC;QAC5D,IAAI,CAAC,MAAM,EAAE,MAAM,IAAI,IAAI,CAAC,OAAO;YAAE,OAAO;QAC5C,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC,gBAAwD,CAAC;QACvF,IAAI,CAAC,MAAM,KAAK,IAAI,IAAI,OAAO,KAAK,SAAS,CAAC,IAAI,OAAO,KAAK,MAAM;YAAE,OAAO;QAC7E,IAAI,MAAM,KAAK,IAAI;YAAE,OAAO,MAAM,CAAC,MAAM,CAAC,gBAAgB,CAAC;;YACtD,MAAM,CAAC,MAAM,CAAC,gBAAgB,GAAG,MAAM,CAAC;QAC7C,MAAM,IAAI,CAAC,OAAO,CAAC,qBAAqB,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,CAAC;IAC/E,CAAC;IAEO,KAAK,CAAC,OAAO,CAAC,OAAgB,EAAE,KAAqB;QACzD,IAAI,IAAI,CAAC,OAAO;YAAE,OAAO;QACzB,IAAI,CAAC,aAAa,GAAG,OAAO,CAAC;QAC7B,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC;QAEhC,MAAM,cAAc,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,gBAAgB,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC;QAC5F,IAAI,cAAc,EAAE,GAAG,KAAK,OAAO,EAAE,CAAC;YAClC,MAAM,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,gBAAgB,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC;QACtE,CAAC;QAED,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;QACzC,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,eAAe,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC;QACzF,MAAM,iBAAiB,GAAG,OAAO,YAAY,EAAE,GAAG,KAAK,QAAQ;YAC3D,CAAC,CAAC,YAAY,CAAC,GAAG;YAClB,CAAC,CAAC,YAAY,EAAE,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC;QACxE,IAAI,iBAAiB,KAAK,UAAU,EAAE,CAAC;YACnC,MAAM,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,eAAe,EAAE,UAAU,EAAE,IAAI,CAAC,CAAC;QACxE,CAAC;IACL,CAAC;IAEO,aAAa;QACjB,IAAI,IAAI,CAAC,UAAU;YAAE,YAAY,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QACnD,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC,GAAG,EAAE;YAC9B,IAAI,CAAC,UAAU,GAAG,SAAS,CAAC;YAC5B,IAAI,CAAC,IAAI,CAAC,OAAO;gBAAE,KAAK,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;QACpD,CAAC,EAAE,MAAM,CAAC,CAAC;QACX,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,CAAC;IAC9B,CAAC;IAEO,yBAAyB,CAAC,UAAkB,EAAE,KAAqB;QACvE,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,eAAe,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,IAAI,IAAI,CAAC,OAAO;YAAE,OAAO;QAChF,IAAI,IAAI,CAAC,YAAY;YAAE,YAAY,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QACvD,IAAI,CAAC,YAAY,GAAG,UAAU,CAAC,GAAG,EAAE;YAChC,IAAI,CAAC,YAAY,GAAG,SAAS,CAAC;YAC9B,IAAI,IAAI,CAAC,OAAO;gBAAE,OAAO;YACzB,KAAK,IAAI,CAAC,OAAO,CAAC,eAAe,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,IAAc,EAAE,eAAe,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;iBAChH,IAAI,CAAC,KAAK,IAAI,EAAE;gBACb,IAAI,IAAI,CAAC,OAAO;oBAAE,OAAO;gBACzB,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,aAAa,EAAE,CAAC;gBAC3C,IAAI,CAAC,OAAO,CAAC,OAAO;oBAAE,OAAO;gBAC7B,MAAM,SAAS,GAAG,EAAE,GAAG,OAAO,CAAC,KAAK,EAAE,GAAG,KAAK,EAAE,qBAAqB,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC;gBACpF,MAAM,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;YACxC,CAAC,CAAC;iBACD,KAAK,CAAC,KAAK,CAAC,EAAE;gBACX,IAAI,CAAC,IAAI,CAAC,OAAO;oBAAE,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,wDAAwD,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC;YACvJ,CAAC,CAAC,CAAC;QACX,CAAC,EAAE,2BAA2B,CAAC,CAAC;QAChC,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,EAAE,CAAC;IAChC,CAAC;CACJ;AAjXD,kEAiXC"}