iobroker.autism-support 0.2.5 → 0.2.7

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.
package/build/main.js CHANGED
@@ -35,6 +35,9 @@ function instanceConfigId(namespace) {
35
35
  function legacyMisplacedInstanceConfigId(namespace) {
36
36
  return `${namespace}.system.adapter.${namespace}`;
37
37
  }
38
+ function nativeConfigEquals(left, right) {
39
+ return JSON.stringify(left != null ? left : null) === JSON.stringify(right != null ? right : null);
40
+ }
38
41
  function secondsToParts(totalSeconds) {
39
42
  const safe = Math.max(0, Math.round(totalSeconds));
40
43
  return {
@@ -60,37 +63,69 @@ class AutismSupport extends utils.Adapter {
60
63
  }
61
64
  async onReady() {
62
65
  var _a;
63
- const maxHours = (_a = this.config.maxDurationHours) != null ? _a : 24;
64
- const defaultSeconds = this.getDefaultDurationSeconds(maxHours);
65
- this.dayPeriods = (0, import_day_periods.dayPeriodsFromConfig)(this.config);
66
- this.weekdayColors = (0, import_weekly_plan.weekdayColorsFromConfig)(this.config);
67
- await this.migrateMisplacedInstanceConfig();
68
- await this.createTimerStates();
69
- await this.ensurePictogramStore();
70
- await this.syncCustomPictogramsConfig();
71
- await this.createScheduleStates();
72
- if (Array.isArray(this.config.weeklyPlanRows) && this.config.weeklyPlanRows.length > 0) {
73
- await this.applyWeeklyPlanRowsFromConfig();
74
- }
75
- await this.syncWeeklyPlansTableToNative();
76
- this.timerManager = new import_timer_manager.TimerManager(
77
- async (snapshot) => {
78
- await this.publishTimerSnapshot(snapshot);
79
- },
80
- {
81
- setInterval: (handler, ms) => this.setInterval(handler, ms),
82
- clearInterval: (handle) => this.clearInterval(handle)
66
+ try {
67
+ const maxHours = (_a = this.config.maxDurationHours) != null ? _a : 24;
68
+ const defaultSeconds = this.getDefaultDurationSeconds(maxHours);
69
+ this.dayPeriods = (0, import_day_periods.dayPeriodsFromConfig)(this.config);
70
+ this.weekdayColors = (0, import_weekly_plan.weekdayColorsFromConfig)(this.config);
71
+ await this.migrateMisplacedInstanceConfig();
72
+ await this.createTimerStates();
73
+ await this.ensurePictogramStore();
74
+ await this.syncCustomPictogramsConfig();
75
+ await this.createScheduleStates();
76
+ if (Array.isArray(this.config.weeklyPlanRows) && this.config.weeklyPlanRows.length > 0) {
77
+ await this.applyWeeklyPlanRowsFromConfig();
83
78
  }
84
- );
85
- await this.timerManager.setDuration(defaultSeconds, maxHours);
86
- await this.publishTimerSnapshot(this.timerManager.getSnapshot());
87
- await this.publishScheduleRuntime();
88
- this.subscribeStates(`${this.namespace}.${TIMER_CHANNEL}.*`);
89
- this.subscribeStates(`${this.namespace}.${SCHEDULE_CHANNEL}.*`);
90
- this.scheduleTick = this.setInterval(() => {
91
- void this.publishScheduleRuntime();
92
- }, 3e4);
93
- this.log.info("Autism Support adapter ready \u2013 Visual Countdown + Weekly Schedule");
79
+ await this.syncWeeklyPlansTableToNative();
80
+ this.timerManager = new import_timer_manager.TimerManager(
81
+ async (snapshot) => {
82
+ await this.publishTimerSnapshot(snapshot);
83
+ },
84
+ {
85
+ setInterval: (handler, ms) => this.setInterval(handler, ms),
86
+ clearInterval: (handle) => this.clearInterval(handle)
87
+ }
88
+ );
89
+ await this.timerManager.setDuration(defaultSeconds, maxHours);
90
+ await this.publishTimerSnapshot(this.timerManager.getSnapshot());
91
+ await this.publishScheduleRuntime();
92
+ this.subscribeStates(`${this.namespace}.${TIMER_CHANNEL}.*`);
93
+ this.subscribeStates(`${this.namespace}.${SCHEDULE_CHANNEL}.*`);
94
+ this.scheduleTick = this.setInterval(() => {
95
+ void this.publishScheduleRuntime();
96
+ }, 3e4);
97
+ this.log.info("Autism Support adapter ready \u2013 Visual Countdown + Weekly Schedule");
98
+ } catch (error) {
99
+ this.log.error(`Startup failed: ${error.message}`);
100
+ throw error;
101
+ }
102
+ }
103
+ /**
104
+ * Write instance native config only when changed — avoids restart loop on every boot.
105
+ *
106
+ * @param patch Native fields to compare and optionally write.
107
+ */
108
+ async patchInstanceNativeIfChanged(patch) {
109
+ const id = instanceConfigId(this.namespace);
110
+ const current = await this.getForeignObjectAsync(id);
111
+ const currentNative = (current == null ? void 0 : current.native) || {};
112
+ const nextNative = {};
113
+ let changed = false;
114
+ for (const key of Object.keys(patch)) {
115
+ const value = patch[key];
116
+ if (value === void 0) {
117
+ continue;
118
+ }
119
+ if (!nativeConfigEquals(currentNative[key], value)) {
120
+ nextNative[key] = value;
121
+ changed = true;
122
+ }
123
+ }
124
+ if (!changed) {
125
+ return false;
126
+ }
127
+ await this.extendForeignObjectAsync(id, { native: nextNative });
128
+ return true;
94
129
  }
95
130
  getDefaultDurationSeconds(maxHours) {
96
131
  var _a, _b;
@@ -239,7 +274,7 @@ class AutismSupport extends utils.Adapter {
239
274
  patch.weeklyPlanRows = native.weeklyPlanRows;
240
275
  }
241
276
  if (Object.keys(patch).length) {
242
- await this.extendForeignObjectAsync(instanceConfigId(this.namespace), { native: patch });
277
+ await this.patchInstanceNativeIfChanged(patch);
243
278
  if (patch.customPictograms) {
244
279
  this.config.customPictograms = patch.customPictograms;
245
280
  }
@@ -469,9 +504,7 @@ class AutismSupport extends utils.Adapter {
469
504
  }
470
505
  async syncCustomPictogramsConfig() {
471
506
  const rows = await this.buildCustomPictogramRows();
472
- await this.extendForeignObjectAsync(instanceConfigId(this.namespace), {
473
- native: { customPictograms: rows }
474
- });
507
+ await this.patchInstanceNativeIfChanged({ customPictograms: rows });
475
508
  this.config.customPictograms = rows;
476
509
  await this.publishPictogramLibrary();
477
510
  }
@@ -506,8 +539,18 @@ class AutismSupport extends utils.Adapter {
506
539
  }
507
540
  try {
508
541
  const hint = "Piktogramm-Bilder (PNG, JPEG, GIF, WebP, SVG) hier hochladen.\nKeine neuen Ordner anlegen (Dateimanager zeigt dann oft \u201Edoppelter Name\u201C).\nStattdessen oben auf Hochladen klicken und Bilder in DIESEN Ordner legen.\n";
509
- await this.writeFileAsync(import_pictogram_library.PICTOGRAM_FILE_ADAPTER, `${import_pictogram_library.PICTOGRAM_DIR}/${import_pictogram_library.PICTOGRAM_PLACEHOLDER_FILE}`, hint);
510
- this.log.info(`Ensured vis-2 pictogram folder ${import_pictogram_library.PICTOGRAM_FILE_ADAPTER}/${import_pictogram_library.PICTOGRAM_DIR}`);
542
+ const placeholderPath = `${import_pictogram_library.PICTOGRAM_DIR}/${import_pictogram_library.PICTOGRAM_PLACEHOLDER_FILE}`;
543
+ let needsWrite = true;
544
+ try {
545
+ const existing = await this.readFileAsync(import_pictogram_library.PICTOGRAM_FILE_ADAPTER, placeholderPath);
546
+ const current = typeof existing.file === "string" ? existing.file : Buffer.from(existing.file).toString("utf8");
547
+ needsWrite = current !== hint;
548
+ } catch {
549
+ }
550
+ if (needsWrite) {
551
+ await this.writeFileAsync(import_pictogram_library.PICTOGRAM_FILE_ADAPTER, placeholderPath, hint);
552
+ this.log.info(`Ensured vis-2 pictogram folder ${import_pictogram_library.PICTOGRAM_FILE_ADAPTER}/${import_pictogram_library.PICTOGRAM_DIR}`);
553
+ }
511
554
  } catch (error) {
512
555
  this.log.error(
513
556
  `Could not write ${import_pictogram_library.PICTOGRAM_FILE_ADAPTER}/${import_pictogram_library.PICTOGRAM_DIR}/${import_pictogram_library.PICTOGRAM_PLACEHOLDER_FILE}: ${error.message}`
@@ -563,9 +606,7 @@ class AutismSupport extends utils.Adapter {
563
606
  async syncWeeklyPlansTableToNative() {
564
607
  const library = await this.getWeeklyPlansLibrary();
565
608
  const rows = (0, import_weekly_plan.weeklyPlanRowsFromLibrary)(library);
566
- await this.extendForeignObjectAsync(instanceConfigId(this.namespace), {
567
- native: { weeklyPlanRows: rows }
568
- });
609
+ await this.patchInstanceNativeIfChanged({ weeklyPlanRows: rows });
569
610
  this.config.weeklyPlanRows = rows;
570
611
  }
571
612
  async applyWeeklyPlanRowsFromConfig() {
@@ -773,9 +814,7 @@ class AutismSupport extends utils.Adapter {
773
814
  if (obj.command === "syncPictogramTable") {
774
815
  await this.ensurePictogramStore();
775
816
  const rows = await this.buildCustomPictogramRows();
776
- await this.extendForeignObjectAsync(instanceConfigId(this.namespace), {
777
- native: { customPictograms: rows }
778
- });
817
+ await this.patchInstanceNativeIfChanged({ customPictograms: rows });
779
818
  this.config.customPictograms = rows;
780
819
  await this.publishPictogramLibrary();
781
820
  this.reply(obj, { ok: true, native: { customPictograms: rows } });
package/build/main.js.map CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/main.ts"],
4
- "sourcesContent": ["/*\n * ioBroker.autism-support \u2013 Visual Countdown + Daily Schedule\n */\n\nimport * as utils from \"@iobroker/adapter-core\";\nimport { TimerManager } from \"./lib/timer-manager\";\nimport {\n\tdayPeriodsFromConfig,\n\tfindCurrentPeriod,\n\tparseTimeToMinutes,\n\ttype DayPeriodDefinition,\n} from \"./lib/day-periods\";\nimport { findCurrentItemIndex, isPlanFullyExpired, parseSchedulePlan, type SchedulePlan } from \"./lib/schedule-types\";\nimport {\n\tADAPTER_LIBRARY_FILE,\n\tPICTOGRAM_DIR,\n\tPICTOGRAM_FILE_ADAPTER,\n\tPICTOGRAM_PLACEHOLDER_FILE,\n\tLEGACY_VIS_LIBRARY_FILE,\n\temptyLibrary,\n\tisIgnoredPictogramFile,\n\tlibraryFromNativeRows,\n\tmatchesPictogramKey,\n\tmergePictogramSources,\n\tnormalizeTags,\n\tparseLibrary,\n\tpictogramPublicUrl,\n\tpictogramStoragePath,\n\tsyncCustomPictogramRows,\n\tuniquePictogramFilename,\n\ttype CustomPictogram,\n\ttype PictogramLibrary,\n} from \"./lib/pictogram-library\";\nimport {\n\tapplyWeeklyPlanRowsToLibrary,\n\tcreateEmptyWeeklyPlan,\n\tparseWeeklyPlan,\n\tparseWeeklyPlansLibrary,\n\tschedulePlansEqual,\n\tweekdayColorsFromConfig,\n\tweekdayKeyFromDate,\n\tweeklyPlanRowsFromLibrary,\n\ttype WeekdayColors,\n\ttype WeekdayKey,\n\ttype WeeklyPlanData,\n\ttype WeeklyPlansLibrary,\n} from \"./lib/weekly-plan\";\n\nconst TIMER_CHANNEL = \"timer\";\nconst SCHEDULE_CHANNEL = \"schedule\";\n\nfunction instanceConfigId(namespace: string): string {\n\treturn `system.adapter.${namespace}`;\n}\n\nfunction legacyMisplacedInstanceConfigId(namespace: string): string {\n\treturn `${namespace}.system.adapter.${namespace}`;\n}\n\nfunction secondsToParts(totalSeconds: number): { hours: number; minutes: number } {\n\tconst safe = Math.max(0, Math.round(totalSeconds));\n\treturn {\n\t\thours: Math.floor(safe / 3600),\n\t\tminutes: Math.floor((safe % 3600) / 60),\n\t};\n}\n\nclass AutismSupport extends utils.Adapter {\n\tprivate timerManager: TimerManager | null = null;\n\tprivate scheduleTick: ioBroker.Interval | undefined | null = null;\n\tprivate dayPeriods: DayPeriodDefinition[] = [];\n\tprivate weekdayColors: WeekdayColors = weekdayColorsFromConfig({} as ioBroker.AdapterConfig);\n\tprivate lastAppliedWeekday: WeekdayKey | null = null;\n\n\tpublic constructor(options: Partial<utils.AdapterOptions> = {}) {\n\t\tsuper({\n\t\t\t...options,\n\t\t\tname: \"autism-support\",\n\t\t});\n\t\tthis.on(\"ready\", this.onReady.bind(this));\n\t\tthis.on(\"stateChange\", this.onStateChange.bind(this));\n\t\tthis.on(\"message\", this.onMessage.bind(this));\n\t\tthis.on(\"unload\", this.onUnload.bind(this));\n\t}\n\n\tprivate async onReady(): Promise<void> {\n\t\tconst maxHours = this.config.maxDurationHours ?? 24;\n\t\tconst defaultSeconds = this.getDefaultDurationSeconds(maxHours);\n\t\tthis.dayPeriods = dayPeriodsFromConfig(this.config);\n\t\tthis.weekdayColors = weekdayColorsFromConfig(this.config);\n\n\t\tawait this.migrateMisplacedInstanceConfig();\n\t\tawait this.createTimerStates();\n\t\tawait this.ensurePictogramStore();\n\t\tawait this.syncCustomPictogramsConfig();\n\t\tawait this.createScheduleStates();\n\t\t// Only apply Admin name/delete edits when the table already lists plans (avoid wiping on first boot).\n\t\tif (Array.isArray(this.config.weeklyPlanRows) && this.config.weeklyPlanRows.length > 0) {\n\t\t\tawait this.applyWeeklyPlanRowsFromConfig();\n\t\t}\n\t\tawait this.syncWeeklyPlansTableToNative();\n\n\t\tthis.timerManager = new TimerManager(\n\t\t\tasync snapshot => {\n\t\t\t\tawait this.publishTimerSnapshot(snapshot);\n\t\t\t},\n\t\t\t{\n\t\t\t\tsetInterval: (handler, ms) => this.setInterval(handler, ms),\n\t\t\t\tclearInterval: handle => this.clearInterval(handle as ioBroker.Interval),\n\t\t\t},\n\t\t);\n\n\t\tawait this.timerManager.setDuration(defaultSeconds, maxHours);\n\t\tawait this.publishTimerSnapshot(this.timerManager.getSnapshot());\n\t\tawait this.publishScheduleRuntime();\n\n\t\tthis.subscribeStates(`${this.namespace}.${TIMER_CHANNEL}.*`);\n\t\tthis.subscribeStates(`${this.namespace}.${SCHEDULE_CHANNEL}.*`);\n\n\t\tthis.scheduleTick = this.setInterval(() => {\n\t\t\tvoid this.publishScheduleRuntime();\n\t\t}, 30_000);\n\n\t\tthis.log.info(\"Autism Support adapter ready \u2013 Visual Countdown + Weekly Schedule\");\n\t}\n\n\tprivate getDefaultDurationSeconds(maxHours: number): number {\n\t\tconst hours = Math.min(maxHours, Math.max(0, this.config.defaultDurationHours ?? 1));\n\t\tconst minutes = Math.min(59, Math.max(0, this.config.defaultDurationMinutes ?? 0));\n\t\tconst total = hours * 3600 + minutes * 60;\n\t\treturn Math.max(60, Math.min(maxHours * 3600, total));\n\t}\n\n\tprivate async createTimerStates(): Promise<void> {\n\t\tawait this.setObjectNotExistsAsync(TIMER_CHANNEL, {\n\t\t\ttype: \"channel\",\n\t\t\tcommon: { name: \"Visual Countdown\" },\n\t\t\tnative: {},\n\t\t});\n\n\t\tconst states: Record<\n\t\t\tstring,\n\t\t\t{\n\t\t\t\ttype: \"number\" | \"boolean\";\n\t\t\t\trole: string;\n\t\t\t\tname: string;\n\t\t\t\tread: boolean;\n\t\t\t\twrite: boolean;\n\t\t\t\tunit?: string;\n\t\t\t\tmin?: number;\n\t\t\t\tmax?: number;\n\t\t\t}\n\t\t> = {\n\t\t\tduration: {\n\t\t\t\ttype: \"number\",\n\t\t\t\trole: \"level.timer\",\n\t\t\t\tname: \"Timer duration (seconds)\",\n\t\t\t\tread: true,\n\t\t\t\twrite: true,\n\t\t\t\tunit: \"s\",\n\t\t\t\tmin: 60,\n\t\t\t\tmax: 86400,\n\t\t\t},\n\t\t\tremaining: {\n\t\t\t\ttype: \"number\",\n\t\t\t\trole: \"value.timer\",\n\t\t\t\tname: \"Timer remaining (seconds)\",\n\t\t\t\tread: true,\n\t\t\t\twrite: false,\n\t\t\t\tunit: \"s\",\n\t\t\t},\n\t\t\telapsed: {\n\t\t\t\ttype: \"number\",\n\t\t\t\trole: \"value.timer\",\n\t\t\t\tname: \"Timer elapsed (seconds)\",\n\t\t\t\tread: true,\n\t\t\t\twrite: false,\n\t\t\t\tunit: \"s\",\n\t\t\t},\n\t\t\trunning: {\n\t\t\t\ttype: \"boolean\",\n\t\t\t\trole: \"indicator\",\n\t\t\t\tname: \"Timer running\",\n\t\t\t\tread: true,\n\t\t\t\twrite: false,\n\t\t\t},\n\t\t\tpaused: {\n\t\t\t\ttype: \"boolean\",\n\t\t\t\trole: \"indicator\",\n\t\t\t\tname: \"Timer paused\",\n\t\t\t\tread: true,\n\t\t\t\twrite: false,\n\t\t\t},\n\t\t\tfinished: {\n\t\t\t\ttype: \"boolean\",\n\t\t\t\trole: \"indicator\",\n\t\t\t\tname: \"Timer finished\",\n\t\t\t\tread: true,\n\t\t\t\twrite: false,\n\t\t\t},\n\t\t\tstart: {\n\t\t\t\ttype: \"boolean\",\n\t\t\t\trole: \"button.start\",\n\t\t\t\tname: \"Start timer\",\n\t\t\t\tread: false,\n\t\t\t\twrite: true,\n\t\t\t},\n\t\t\tpause: {\n\t\t\t\ttype: \"boolean\",\n\t\t\t\trole: \"button.pause\",\n\t\t\t\tname: \"Pause timer\",\n\t\t\t\tread: false,\n\t\t\t\twrite: true,\n\t\t\t},\n\t\t\tresume: {\n\t\t\t\ttype: \"boolean\",\n\t\t\t\trole: \"button.start\",\n\t\t\t\tname: \"Resume timer\",\n\t\t\t\tread: false,\n\t\t\t\twrite: true,\n\t\t\t},\n\t\t\tstop: {\n\t\t\t\ttype: \"boolean\",\n\t\t\t\trole: \"button.stop\",\n\t\t\t\tname: \"Stop timer\",\n\t\t\t\tread: false,\n\t\t\t\twrite: true,\n\t\t\t},\n\t\t\tsetDurationHours: {\n\t\t\t\ttype: \"number\",\n\t\t\t\trole: \"level\",\n\t\t\t\tname: \"Set timer duration (hours)\",\n\t\t\t\tread: true,\n\t\t\t\twrite: true,\n\t\t\t\tunit: \"h\",\n\t\t\t\tmin: 0,\n\t\t\t\tmax: 24,\n\t\t\t},\n\t\t\tsetDurationMinutes: {\n\t\t\t\ttype: \"number\",\n\t\t\t\trole: \"level\",\n\t\t\t\tname: \"Set timer duration (minutes)\",\n\t\t\t\tread: true,\n\t\t\t\twrite: true,\n\t\t\t\tunit: \"min\",\n\t\t\t\tmin: 0,\n\t\t\t\tmax: 59,\n\t\t\t},\n\t\t};\n\n\t\tfor (const [id, def] of Object.entries(states)) {\n\t\t\tawait this.setObjectNotExistsAsync(`${TIMER_CHANNEL}.${id}`, {\n\t\t\t\ttype: \"state\",\n\t\t\t\tcommon: {\n\t\t\t\t\tname: def.name,\n\t\t\t\t\ttype: def.type,\n\t\t\t\t\trole: def.role,\n\t\t\t\t\tread: def.read,\n\t\t\t\t\twrite: def.write,\n\t\t\t\t\tunit: def.unit,\n\t\t\t\t\tmin: def.min,\n\t\t\t\t\tmax: def.max,\n\t\t\t\t},\n\t\t\t\tnative: {},\n\t\t\t});\n\t\t}\n\n\t\tawait this.migrateTimerStateRoles();\n\t}\n\n\t/**\n\t * Earlier versions used extendObject() for system.adapter.* which ioBroker resolves\n\t * relative to the instance namespace (autism-support.0.system.adapter...).\n\t */\n\tprivate async migrateMisplacedInstanceConfig(): Promise<void> {\n\t\tconst legacyId = legacyMisplacedInstanceConfigId(this.namespace);\n\t\tconst legacy = await this.getObjectAsync(legacyId);\n\t\tif (!legacy?.native) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst native = legacy.native as {\n\t\t\tcustomPictograms?: ioBroker.AdapterConfig[\"customPictograms\"];\n\t\t\tweeklyPlanRows?: ioBroker.AdapterConfig[\"weeklyPlanRows\"];\n\t\t};\n\t\tconst patch: Partial<ioBroker.AdapterConfig> = {};\n\t\tif (Array.isArray(native.customPictograms)) {\n\t\t\tpatch.customPictograms = native.customPictograms;\n\t\t}\n\t\tif (Array.isArray(native.weeklyPlanRows)) {\n\t\t\tpatch.weeklyPlanRows = native.weeklyPlanRows;\n\t\t}\n\t\tif (Object.keys(patch).length) {\n\t\t\tawait this.extendForeignObjectAsync(instanceConfigId(this.namespace), { native: patch });\n\t\t\tif (patch.customPictograms) {\n\t\t\t\tthis.config.customPictograms = patch.customPictograms;\n\t\t\t}\n\t\t\tif (patch.weeklyPlanRows) {\n\t\t\t\tthis.config.weeklyPlanRows = patch.weeklyPlanRows;\n\t\t\t}\n\t\t\tthis.log.info(`Migrated instance native config from misplaced object ${legacyId}`);\n\t\t}\n\n\t\tawait this.delObjectAsync(legacyId);\n\t\tfor (const folderId of [`${this.namespace}.system.adapter`, `${this.namespace}.system`]) {\n\t\t\ttry {\n\t\t\t\tawait this.delObjectAsync(folderId);\n\t\t\t} catch {\n\t\t\t\t// folder may not exist or is not empty\n\t\t\t}\n\t\t}\n\t}\n\n\t/** Update roles/read flags on existing timer states (object-structure compliance). */\n\tprivate async migrateTimerStateRoles(): Promise<void> {\n\t\tconst patches: Record<string, { role?: string; read?: boolean }> = {\n\t\t\tduration: { role: \"level.timer\" },\n\t\t\tremaining: { role: \"value.timer\" },\n\t\t\telapsed: { role: \"value.timer\" },\n\t\t\tstart: { read: false },\n\t\t\tpause: { read: false },\n\t\t\tresume: { read: false },\n\t\t\tstop: { read: false },\n\t\t};\n\t\tfor (const [id, patch] of Object.entries(patches)) {\n\t\t\tconst common: Partial<ioBroker.StateCommon> = {};\n\t\t\tif (patch.role) {\n\t\t\t\tcommon.role = patch.role;\n\t\t\t}\n\t\t\tif (patch.read !== undefined) {\n\t\t\t\tcommon.read = patch.read;\n\t\t\t}\n\t\t\tawait this.extendObjectAsync(`${TIMER_CHANNEL}.${id}`, { common });\n\t\t}\n\t}\n\n\tprivate async createScheduleStates(): Promise<void> {\n\t\tawait this.setObjectNotExistsAsync(SCHEDULE_CHANNEL, {\n\t\t\ttype: \"channel\",\n\t\t\tcommon: { name: \"Daily schedule\" },\n\t\t\tnative: {},\n\t\t});\n\n\t\tawait this.setObjectNotExistsAsync(`${SCHEDULE_CHANNEL}.plan`, {\n\t\t\ttype: \"state\",\n\t\t\tcommon: {\n\t\t\t\tname: \"Schedule plan (JSON)\",\n\t\t\t\ttype: \"string\",\n\t\t\t\trole: \"json\",\n\t\t\t\tread: true,\n\t\t\t\twrite: true,\n\t\t\t\tdef: JSON.stringify({ version: 1, items: [] }),\n\t\t\t},\n\t\t\tnative: {},\n\t\t});\n\n\t\tawait this.setObjectNotExistsAsync(`${SCHEDULE_CHANNEL}.periods`, {\n\t\t\ttype: \"state\",\n\t\t\tcommon: {\n\t\t\t\tname: \"Day periods from admin (JSON)\",\n\t\t\t\ttype: \"string\",\n\t\t\t\trole: \"json\",\n\t\t\t\tread: true,\n\t\t\t\twrite: false,\n\t\t\t},\n\t\t\tnative: {},\n\t\t});\n\n\t\tawait this.setObjectNotExistsAsync(`${SCHEDULE_CHANNEL}.periodOverrides`, {\n\t\t\ttype: \"state\",\n\t\t\tcommon: {\n\t\t\t\tname: \"Day period on/off overrides from schedule config (JSON)\",\n\t\t\t\ttype: \"string\",\n\t\t\t\trole: \"json\",\n\t\t\t\tread: true,\n\t\t\t\twrite: true,\n\t\t\t\tdef: \"{}\",\n\t\t\t},\n\t\t\tnative: {},\n\t\t});\n\n\t\tawait this.setObjectNotExistsAsync(`${SCHEDULE_CHANNEL}.nowMinutes`, {\n\t\t\ttype: \"state\",\n\t\t\tcommon: {\n\t\t\t\tname: \"Minutes since midnight (local)\",\n\t\t\t\ttype: \"number\",\n\t\t\t\trole: \"value\",\n\t\t\t\tread: true,\n\t\t\t\twrite: false,\n\t\t\t\tunit: \"min\",\n\t\t\t\tmin: 0,\n\t\t\t\tmax: 1439,\n\t\t\t},\n\t\t\tnative: {},\n\t\t});\n\n\t\tawait this.setObjectNotExistsAsync(`${SCHEDULE_CHANNEL}.currentPeriod`, {\n\t\t\ttype: \"state\",\n\t\t\tcommon: {\n\t\t\t\tname: \"Current day period id\",\n\t\t\t\ttype: \"string\",\n\t\t\t\trole: \"text\",\n\t\t\t\tread: true,\n\t\t\t\twrite: false,\n\t\t\t},\n\t\t\tnative: {},\n\t\t});\n\n\t\tawait this.setObjectNotExistsAsync(`${SCHEDULE_CHANNEL}.currentItemIndex`, {\n\t\t\ttype: \"state\",\n\t\t\tcommon: {\n\t\t\t\tname: \"Index of active schedule item (-1 = none)\",\n\t\t\t\ttype: \"number\",\n\t\t\t\trole: \"value\",\n\t\t\t\tread: true,\n\t\t\t\twrite: false,\n\t\t\t\tmin: -1,\n\t\t\t},\n\t\t\tnative: {},\n\t\t});\n\n\t\tawait this.setObjectNotExistsAsync(`${SCHEDULE_CHANNEL}.clearAfterLast`, {\n\t\t\ttype: \"state\",\n\t\t\tcommon: {\n\t\t\t\tname: \"Clear plan automatically after last pictogram ends\",\n\t\t\t\ttype: \"boolean\",\n\t\t\t\trole: \"switch\",\n\t\t\t\tread: true,\n\t\t\t\twrite: true,\n\t\t\t\tdef: false,\n\t\t\t},\n\t\t\tnative: {},\n\t\t});\n\n\t\tawait this.setObjectNotExistsAsync(`${SCHEDULE_CHANNEL}.pictogramLibrary`, {\n\t\t\ttype: \"state\",\n\t\t\tcommon: {\n\t\t\t\tname: \"Custom pictogram library (JSON)\",\n\t\t\t\ttype: \"string\",\n\t\t\t\trole: \"json\",\n\t\t\t\tread: true,\n\t\t\t\twrite: false,\n\t\t\t},\n\t\t\tnative: {},\n\t\t});\n\n\t\tawait this.setObjectNotExistsAsync(`${SCHEDULE_CHANNEL}.weeklyPlan`, {\n\t\t\ttype: \"state\",\n\t\t\tcommon: {\n\t\t\t\tname: \"Active weekly plan (JSON, Mon\u2013Sun)\",\n\t\t\t\ttype: \"string\",\n\t\t\t\trole: \"json\",\n\t\t\t\tread: true,\n\t\t\t\twrite: true,\n\t\t\t\tdef: JSON.stringify(createEmptyWeeklyPlan()),\n\t\t\t},\n\t\t\tnative: {},\n\t\t});\n\n\t\tawait this.setObjectNotExistsAsync(`${SCHEDULE_CHANNEL}.weeklyPlansLibrary`, {\n\t\t\ttype: \"state\",\n\t\t\tcommon: {\n\t\t\t\tname: \"Saved weekly plans library (JSON)\",\n\t\t\t\ttype: \"string\",\n\t\t\t\trole: \"json\",\n\t\t\t\tread: true,\n\t\t\t\twrite: true,\n\t\t\t\tdef: JSON.stringify({ version: 1, activeId: null, plans: [] }),\n\t\t\t},\n\t\t\tnative: {},\n\t\t});\n\n\t\tawait this.setObjectNotExistsAsync(`${SCHEDULE_CHANNEL}.loadDailyFromWeekly`, {\n\t\t\ttype: \"state\",\n\t\t\tcommon: {\n\t\t\t\tname: \"Load daily plan from active weekly plan each day\",\n\t\t\t\ttype: \"boolean\",\n\t\t\t\trole: \"switch\",\n\t\t\t\tread: true,\n\t\t\t\twrite: true,\n\t\t\t\tdef: false,\n\t\t\t},\n\t\t\tnative: {},\n\t\t});\n\n\t\tawait this.setObjectNotExistsAsync(`${SCHEDULE_CHANNEL}.weekdayColors`, {\n\t\t\ttype: \"state\",\n\t\t\tcommon: {\n\t\t\t\tname: \"Weekday background colors from admin (JSON)\",\n\t\t\t\ttype: \"string\",\n\t\t\t\trole: \"json\",\n\t\t\t\tread: true,\n\t\t\t\twrite: false,\n\t\t\t},\n\t\t\tnative: {},\n\t\t});\n\n\t\tconst planState = await this.getStateAsync(`${SCHEDULE_CHANNEL}.plan`);\n\t\tif (planState?.val == null || planState.val === \"\") {\n\t\t\tawait this.setState(`${SCHEDULE_CHANNEL}.plan`, JSON.stringify({ version: 1, items: [] }), true);\n\t\t}\n\t\tconst overridesState = await this.getStateAsync(`${SCHEDULE_CHANNEL}.periodOverrides`);\n\t\tif (overridesState?.val == null || overridesState.val === \"\") {\n\t\t\tawait this.setState(`${SCHEDULE_CHANNEL}.periodOverrides`, \"{}\", true);\n\t\t}\n\t\tconst clearAfterState = await this.getStateAsync(`${SCHEDULE_CHANNEL}.clearAfterLast`);\n\t\tif (clearAfterState?.val == null) {\n\t\t\tawait this.setState(`${SCHEDULE_CHANNEL}.clearAfterLast`, false, true);\n\t\t}\n\t\tconst loadDailyState = await this.getStateAsync(`${SCHEDULE_CHANNEL}.loadDailyFromWeekly`);\n\t\tif (loadDailyState?.val == null) {\n\t\t\tawait this.setState(`${SCHEDULE_CHANNEL}.loadDailyFromWeekly`, false, true);\n\t\t}\n\n\t\tconst weeklyState = await this.getStateAsync(`${SCHEDULE_CHANNEL}.weeklyPlan`);\n\t\tif (weeklyState?.val == null || weeklyState.val === \"\") {\n\t\t\tconst seed = parseSchedulePlan(planState?.val);\n\t\t\tawait this.setState(\n\t\t\t\t`${SCHEDULE_CHANNEL}.weeklyPlan`,\n\t\t\t\tJSON.stringify(createEmptyWeeklyPlan(seed.items.length ? seed : undefined)),\n\t\t\t\ttrue,\n\t\t\t);\n\t\t}\n\t\tconst libraryState = await this.getStateAsync(`${SCHEDULE_CHANNEL}.weeklyPlansLibrary`);\n\t\tif (libraryState?.val == null || libraryState.val === \"\") {\n\t\t\tawait this.setState(\n\t\t\t\t`${SCHEDULE_CHANNEL}.weeklyPlansLibrary`,\n\t\t\t\tJSON.stringify({ version: 1, activeId: null, plans: [] }),\n\t\t\t\ttrue,\n\t\t\t);\n\t\t}\n\n\t\t// Publish admin period definitions once at start (times/colors); overrides stay separate.\n\t\tawait this.setState(`${SCHEDULE_CHANNEL}.periods`, JSON.stringify(this.dayPeriods), true);\n\t\tawait this.setState(`${SCHEDULE_CHANNEL}.weekdayColors`, JSON.stringify(this.weekdayColors), true);\n\t\tawait this.publishPictogramLibrary();\n\t}\n\n\tprivate async buildCustomPictogramRows(): Promise<Array<{ file: string; label: string; tags: string }>> {\n\t\tconst files = await this.listPictogramFiles();\n\t\treturn syncCustomPictogramRows(files || [], this.config.customPictograms);\n\t}\n\n\tprivate async syncCustomPictogramsConfig(): Promise<void> {\n\t\tconst rows = await this.buildCustomPictogramRows();\n\t\tawait this.extendForeignObjectAsync(instanceConfigId(this.namespace), {\n\t\t\tnative: { customPictograms: rows },\n\t\t});\n\t\tthis.config.customPictograms = rows;\n\t\tawait this.publishPictogramLibrary();\n\t}\n\n\tprivate async ensurePictogramStore(): Promise<void> {\n\t\ttry {\n\t\t\tawait this.readFileAsync(this.namespace, ADAPTER_LIBRARY_FILE);\n\t\t} catch {\n\t\t\ttry {\n\t\t\t\tawait this.writeFileAsync(\n\t\t\t\t\tthis.namespace,\n\t\t\t\t\tADAPTER_LIBRARY_FILE,\n\t\t\t\t\tJSON.stringify(emptyLibrary(), null, 2),\n\t\t\t\t);\n\t\t\t\tthis.log.info(`Created adapter pictogram library ${this.namespace}/${ADAPTER_LIBRARY_FILE}`);\n\t\t\t} catch (error) {\n\t\t\t\tthis.log.error(`Could not create adapter pictogram library: ${(error as Error).message}`);\n\t\t\t}\n\t\t}\n\n\t\ttry {\n\t\t\tconst legacy = await this.readFileAsync(PICTOGRAM_FILE_ADAPTER, LEGACY_VIS_LIBRARY_FILE);\n\t\t\tconst raw = typeof legacy.file === \"string\" ? legacy.file : Buffer.from(legacy.file).toString(\"utf8\");\n\t\t\tconst migrated = parseLibrary(raw);\n\t\t\tif (migrated.items.length) {\n\t\t\t\tawait this.writeFileAsync(this.namespace, ADAPTER_LIBRARY_FILE, JSON.stringify(migrated, null, 2));\n\t\t\t\tthis.log.info(`Migrated pictogram library from vis-2 to ${this.namespace}`);\n\t\t\t}\n\t\t} catch {\n\t\t\t// no legacy library in vis-2\n\t\t}\n\n\t\ttry {\n\t\t\tawait this.unlinkAsync(PICTOGRAM_FILE_ADAPTER, LEGACY_VIS_LIBRARY_FILE);\n\t\t} catch {\n\t\t\t// ignore\n\t\t}\n\n\t\ttry {\n\t\t\tconst hint =\n\t\t\t\t\"Piktogramm-Bilder (PNG, JPEG, GIF, WebP, SVG) hier hochladen.\\n\" +\n\t\t\t\t\"Keine neuen Ordner anlegen (Dateimanager zeigt dann oft \u201Edoppelter Name\u201C).\\n\" +\n\t\t\t\t\"Stattdessen oben auf Hochladen klicken und Bilder in DIESEN Ordner legen.\\n\";\n\t\t\tawait this.writeFileAsync(PICTOGRAM_FILE_ADAPTER, `${PICTOGRAM_DIR}/${PICTOGRAM_PLACEHOLDER_FILE}`, hint);\n\t\t\tthis.log.info(`Ensured vis-2 pictogram folder ${PICTOGRAM_FILE_ADAPTER}/${PICTOGRAM_DIR}`);\n\t\t} catch (error) {\n\t\t\tthis.log.error(\n\t\t\t\t`Could not write ${PICTOGRAM_FILE_ADAPTER}/${PICTOGRAM_DIR}/${PICTOGRAM_PLACEHOLDER_FILE}: ${(error as Error).message}`,\n\t\t\t);\n\t\t}\n\t}\n\n\tprivate async getPublishedPictogramLibrary(): Promise<PictogramLibrary> {\n\t\treturn mergePictogramSources(\n\t\t\tawait this.getMergedPictogramLibrary(),\n\t\t\tlibraryFromNativeRows(this.config.customPictograms),\n\t\t);\n\t}\n\n\tprivate async publishPictogramLibrary(): Promise<void> {\n\t\tconst library = await this.getPublishedPictogramLibrary();\n\t\tawait this.setState(`${SCHEDULE_CHANNEL}.pictogramLibrary`, JSON.stringify(library), true);\n\t}\n\n\tprivate async publishTimerSnapshot(snapshot: {\n\t\tduration: number;\n\t\tremaining: number;\n\t\telapsed: number;\n\t\trunning: boolean;\n\t\tpaused: boolean;\n\t\tfinished: boolean;\n\t}): Promise<void> {\n\t\tawait this.setState(`${TIMER_CHANNEL}.duration`, snapshot.duration, true);\n\t\tawait this.setState(`${TIMER_CHANNEL}.remaining`, snapshot.remaining, true);\n\t\tawait this.setState(`${TIMER_CHANNEL}.elapsed`, snapshot.elapsed, true);\n\t\tawait this.setState(`${TIMER_CHANNEL}.running`, snapshot.running, true);\n\t\tawait this.setState(`${TIMER_CHANNEL}.paused`, snapshot.paused, true);\n\t\tawait this.setState(`${TIMER_CHANNEL}.finished`, snapshot.finished, true);\n\t}\n\n\tprivate async getPlan(): Promise<SchedulePlan> {\n\t\tconst state = await this.getStateAsync(`${SCHEDULE_CHANNEL}.plan`);\n\t\treturn parseSchedulePlan(state?.val);\n\t}\n\n\tprivate async getPeriodOverrides(): Promise<Record<string, boolean>> {\n\t\tconst state = await this.getStateAsync(`${SCHEDULE_CHANNEL}.periodOverrides`);\n\t\ttry {\n\t\t\tconst raw = typeof state?.val === \"string\" ? JSON.parse(state.val) : state?.val;\n\t\t\treturn raw && typeof raw === \"object\" ? (raw as Record<string, boolean>) : {};\n\t\t} catch {\n\t\t\treturn {};\n\t\t}\n\t}\n\n\tprivate async getEffectivePeriods(): Promise<DayPeriodDefinition[]> {\n\t\tconst overrides = await this.getPeriodOverrides();\n\t\treturn this.dayPeriods.map(period => ({\n\t\t\t...period,\n\t\t\tenabled: overrides[period.id] === undefined ? period.enabled : Boolean(overrides[period.id]),\n\t\t}));\n\t}\n\n\tprivate async getWeeklyPlan(): Promise<WeeklyPlanData> {\n\t\tconst state = await this.getStateAsync(`${SCHEDULE_CHANNEL}.weeklyPlan`);\n\t\treturn parseWeeklyPlan(state?.val);\n\t}\n\n\tprivate async getWeeklyPlansLibrary(): Promise<WeeklyPlansLibrary> {\n\t\tconst state = await this.getStateAsync(`${SCHEDULE_CHANNEL}.weeklyPlansLibrary`);\n\t\treturn parseWeeklyPlansLibrary(state?.val);\n\t}\n\n\tprivate async syncWeeklyPlansTableToNative(): Promise<void> {\n\t\tconst library = await this.getWeeklyPlansLibrary();\n\t\tconst rows = weeklyPlanRowsFromLibrary(library);\n\t\tawait this.extendForeignObjectAsync(instanceConfigId(this.namespace), {\n\t\t\tnative: { weeklyPlanRows: rows },\n\t\t});\n\t\tthis.config.weeklyPlanRows = rows;\n\t}\n\n\tprivate async applyWeeklyPlanRowsFromConfig(): Promise<void> {\n\t\tconst library = await this.getWeeklyPlansLibrary();\n\t\tconst next = applyWeeklyPlanRowsToLibrary(library, this.config.weeklyPlanRows);\n\t\tif (JSON.stringify(next) !== JSON.stringify(library)) {\n\t\t\tawait this.setState(`${SCHEDULE_CHANNEL}.weeklyPlansLibrary`, JSON.stringify(next), true);\n\t\t}\n\t}\n\n\tprivate async maybeApplyWeeklyToDaily(): Promise<void> {\n\t\tconst loadState = await this.getStateAsync(`${SCHEDULE_CHANNEL}.loadDailyFromWeekly`);\n\t\tif (!loadState?.val) {\n\t\t\treturn;\n\t\t}\n\t\tconst weekday = weekdayKeyFromDate(new Date());\n\t\tconst weekly = await this.getWeeklyPlan();\n\t\tconst dayPlan = weekly.days[weekday];\n\t\tconst current = await this.getPlan();\n\t\tif (this.lastAppliedWeekday === weekday && schedulePlansEqual(current, dayPlan)) {\n\t\t\treturn;\n\t\t}\n\t\tawait this.setState(`${SCHEDULE_CHANNEL}.plan`, JSON.stringify(dayPlan), true);\n\t\tthis.lastAppliedWeekday = weekday;\n\t\tthis.log.debug(`Daily plan loaded from weekly plan (${weekday})`);\n\t}\n\n\tprivate async publishScheduleRuntime(): Promise<void> {\n\t\tawait this.maybeApplyWeeklyToDaily();\n\n\t\tconst now = new Date();\n\t\tconst minutes = now.getHours() * 60 + now.getMinutes();\n\t\tconst periods = await this.getEffectivePeriods();\n\t\tconst period = findCurrentPeriod(minutes, periods);\n\t\tlet plan = await this.getPlan();\n\n\t\tconst clearAfterState = await this.getStateAsync(`${SCHEDULE_CHANNEL}.clearAfterLast`);\n\t\tconst clearAfterLast = Boolean(clearAfterState?.val);\n\t\tif (clearAfterLast && isPlanFullyExpired(plan, minutes, parseTimeToMinutes)) {\n\t\t\tplan = { version: 1, items: [] };\n\t\t\tawait this.setState(`${SCHEDULE_CHANNEL}.plan`, JSON.stringify(plan), true);\n\t\t\tthis.log.info(\"Schedule plan cleared automatically after last pictogram ended\");\n\t\t}\n\n\t\tconst itemIndex = findCurrentItemIndex(plan, minutes, parseTimeToMinutes);\n\n\t\t// Keep admin period metadata available; do not wipe Config overrides.\n\t\tawait this.setState(`${SCHEDULE_CHANNEL}.periods`, JSON.stringify(this.dayPeriods), true);\n\t\tawait this.setState(`${SCHEDULE_CHANNEL}.weekdayColors`, JSON.stringify(this.weekdayColors), true);\n\t\tawait this.setState(`${SCHEDULE_CHANNEL}.nowMinutes`, minutes, true);\n\t\tawait this.setState(`${SCHEDULE_CHANNEL}.currentPeriod`, period?.id ?? \"\", true);\n\t\tawait this.setState(`${SCHEDULE_CHANNEL}.currentItemIndex`, itemIndex, true);\n\t}\n\n\tprivate async onStateChange(id: string, state: ioBroker.State | null | undefined): Promise<void> {\n\t\tif (!state || state.ack) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (id.startsWith(`${this.namespace}.${SCHEDULE_CHANNEL}.`)) {\n\t\t\tconst localId = id.replace(`${this.namespace}.${SCHEDULE_CHANNEL}.`, \"\");\n\t\t\tif (localId === \"plan\") {\n\t\t\t\tconst plan = parseSchedulePlan(state.val);\n\t\t\t\tawait this.setState(`${SCHEDULE_CHANNEL}.plan`, JSON.stringify(plan), true);\n\t\t\t\tawait this.publishScheduleRuntime();\n\t\t\t} else if (localId === \"periodOverrides\") {\n\t\t\t\ttry {\n\t\t\t\t\tconst raw = typeof state.val === \"string\" ? JSON.parse(String(state.val)) : state.val;\n\t\t\t\t\tconst cleaned = raw && typeof raw === \"object\" ? (raw as Record<string, boolean>) : {};\n\t\t\t\t\tawait this.setState(`${SCHEDULE_CHANNEL}.periodOverrides`, JSON.stringify(cleaned), true);\n\t\t\t\t\tawait this.publishScheduleRuntime();\n\t\t\t\t} catch (error) {\n\t\t\t\t\tthis.log.error(`Invalid periodOverrides: ${(error as Error).message}`);\n\t\t\t\t}\n\t\t\t} else if (localId === \"clearAfterLast\") {\n\t\t\t\tawait this.setState(`${SCHEDULE_CHANNEL}.clearAfterLast`, Boolean(state.val), true);\n\t\t\t\tawait this.publishScheduleRuntime();\n\t\t\t} else if (localId === \"weeklyPlan\") {\n\t\t\t\tconst weekly = parseWeeklyPlan(state.val);\n\t\t\t\tawait this.setState(`${SCHEDULE_CHANNEL}.weeklyPlan`, JSON.stringify(weekly), true);\n\t\t\t\tthis.lastAppliedWeekday = null;\n\t\t\t\tawait this.publishScheduleRuntime();\n\t\t\t} else if (localId === \"weeklyPlansLibrary\") {\n\t\t\t\tconst library = parseWeeklyPlansLibrary(state.val);\n\t\t\t\tawait this.setState(`${SCHEDULE_CHANNEL}.weeklyPlansLibrary`, JSON.stringify(library), true);\n\t\t\t\tawait this.syncWeeklyPlansTableToNative();\n\t\t\t} else if (localId === \"loadDailyFromWeekly\") {\n\t\t\t\tawait this.setState(`${SCHEDULE_CHANNEL}.loadDailyFromWeekly`, Boolean(state.val), true);\n\t\t\t\tthis.lastAppliedWeekday = null;\n\t\t\t\tawait this.publishScheduleRuntime();\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\tif (!this.timerManager || !id.startsWith(`${this.namespace}.${TIMER_CHANNEL}.`)) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst localId = id.replace(`${this.namespace}.${TIMER_CHANNEL}.`, \"\");\n\t\tconst maxHours = this.config.maxDurationHours ?? 24;\n\n\t\ttry {\n\t\t\tswitch (localId) {\n\t\t\t\tcase \"start\":\n\t\t\t\t\tif (state.val === true) {\n\t\t\t\t\t\tawait this.timerManager.start();\n\t\t\t\t\t}\n\t\t\t\t\tawait this.setState(`${TIMER_CHANNEL}.start`, false, true);\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"pause\":\n\t\t\t\t\tif (state.val === true) {\n\t\t\t\t\t\tawait this.timerManager.pause();\n\t\t\t\t\t}\n\t\t\t\t\tawait this.setState(`${TIMER_CHANNEL}.pause`, false, true);\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"resume\":\n\t\t\t\t\tif (state.val === true) {\n\t\t\t\t\t\tawait this.timerManager.resume();\n\t\t\t\t\t}\n\t\t\t\t\tawait this.setState(`${TIMER_CHANNEL}.resume`, false, true);\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"stop\":\n\t\t\t\t\tif (state.val === true) {\n\t\t\t\t\t\tawait this.timerManager.stop();\n\t\t\t\t\t}\n\t\t\t\t\tawait this.setState(`${TIMER_CHANNEL}.stop`, false, true);\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"duration\":\n\t\t\t\t\tif (typeof state.val === \"number\") {\n\t\t\t\t\t\tawait this.timerManager.setDuration(state.val, maxHours);\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"setDurationHours\":\n\t\t\t\t\tif (typeof state.val === \"number\") {\n\t\t\t\t\t\tawait this.applyDurationParts(Math.round(state.val), undefined, maxHours);\n\t\t\t\t\t}\n\t\t\t\t\tawait this.setState(`${TIMER_CHANNEL}.setDurationHours`, 0, true);\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"setDurationMinutes\":\n\t\t\t\t\tif (typeof state.val === \"number\") {\n\t\t\t\t\t\tawait this.applyDurationParts(undefined, Math.round(state.val), maxHours);\n\t\t\t\t\t}\n\t\t\t\t\tawait this.setState(`${TIMER_CHANNEL}.setDurationMinutes`, 0, true);\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tthis.log.error(`Timer command failed (${localId}): ${(error as Error).message}`);\n\t\t}\n\t}\n\n\tprivate reply(obj: ioBroker.Message, payload: unknown): void {\n\t\tif (obj.callback) {\n\t\t\tthis.sendTo(obj.from, obj.command, payload, obj.callback);\n\t\t}\n\t}\n\n\tprivate async loadPictogramLibrary(): Promise<PictogramLibrary> {\n\t\ttry {\n\t\t\tconst file = await this.readFileAsync(this.namespace, ADAPTER_LIBRARY_FILE);\n\t\t\tconst raw = typeof file.file === \"string\" ? file.file : Buffer.from(file.file).toString(\"utf8\");\n\t\t\treturn parseLibrary(raw);\n\t\t} catch {\n\t\t\treturn emptyLibrary();\n\t\t}\n\t}\n\n\tprivate async savePictogramLibrary(library: PictogramLibrary): Promise<void> {\n\t\tawait this.writeFileAsync(this.namespace, ADAPTER_LIBRARY_FILE, JSON.stringify(library, null, 2));\n\t\tawait this.setState(`${SCHEDULE_CHANNEL}.pictogramLibrary`, JSON.stringify(library), true);\n\t}\n\n\tprivate async listPictogramFiles(): Promise<string[] | null> {\n\t\ttry {\n\t\t\tconst result = await this.readDirAsync(PICTOGRAM_FILE_ADAPTER, PICTOGRAM_DIR);\n\t\t\treturn (result || [])\n\t\t\t\t.filter(entry => !entry.isDir && !isIgnoredPictogramFile(entry.file))\n\t\t\t\t.map(entry => entry.file);\n\t\t} catch {\n\t\t\treturn null;\n\t\t}\n\t}\n\n\tprivate async getMergedPictogramLibrary(): Promise<PictogramLibrary> {\n\t\tconst library = await this.loadPictogramLibrary();\n\t\tconst files = await this.listPictogramFiles();\n\t\tif (!files) {\n\t\t\treturn library;\n\t\t}\n\t\tconst known = new Set(library.items.map(item => item.filename));\n\t\tfor (const filename of files) {\n\t\t\tif (known.has(filename)) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tlibrary.items.push({\n\t\t\t\tid: filename,\n\t\t\t\tfilename,\n\t\t\t\tpath: pictogramStoragePath(filename),\n\t\t\t\tlabel: filename.replace(/\\.[^.]+$/, \"\").replace(/-\\d+$/, \"\"),\n\t\t\t\ttags: [],\n\t\t\t\toriginalName: filename,\n\t\t\t\tmime: \"\",\n\t\t\t\tuploadedAt: 0,\n\t\t\t});\n\t\t}\n\t\tlibrary.items = library.items.filter(item => files.includes(item.filename));\n\t\tlibrary.items.sort((a, b) => (b.uploadedAt || 0) - (a.uploadedAt || 0));\n\t\treturn library;\n\t}\n\n\t/**\n\t * Custom pictogram library (user-owned images only).\n\t * ARASAAC images must never be uploaded here \u2013 use external IDs only.\n\t *\n\t * @param obj\n\t */\n\tprivate async onMessage(obj: ioBroker.Message): Promise<void> {\n\t\tif (!obj?.command) {\n\t\t\treturn;\n\t\t}\n\n\t\ttry {\n\t\t\tif (obj.command === \"syncPictogramTable\") {\n\t\t\t\tawait this.ensurePictogramStore();\n\t\t\t\tconst rows = await this.buildCustomPictogramRows();\n\t\t\t\tawait this.extendForeignObjectAsync(instanceConfigId(this.namespace), {\n\t\t\t\t\tnative: { customPictograms: rows },\n\t\t\t\t});\n\t\t\t\tthis.config.customPictograms = rows;\n\t\t\t\tawait this.publishPictogramLibrary();\n\t\t\t\tthis.reply(obj, { ok: true, native: { customPictograms: rows } });\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (obj.command === \"syncWeeklyPlansTable\") {\n\t\t\t\tconst nativeMsg = obj.message as {\n\t\t\t\t\tweeklyPlanRows?: Array<{ id?: string; name?: string; active?: string }>;\n\t\t\t\t};\n\t\t\t\tif (Array.isArray(nativeMsg?.weeklyPlanRows)) {\n\t\t\t\t\tthis.config.weeklyPlanRows = nativeMsg.weeklyPlanRows;\n\t\t\t\t\tawait this.applyWeeklyPlanRowsFromConfig();\n\t\t\t\t}\n\t\t\t\tawait this.syncWeeklyPlansTableToNative();\n\t\t\t\tconst library = await this.getWeeklyPlansLibrary();\n\t\t\t\tthis.reply(obj, {\n\t\t\t\t\tok: true,\n\t\t\t\t\tnative: { weeklyPlanRows: this.config.weeklyPlanRows || [] },\n\t\t\t\t\tactiveId: library.activeId,\n\t\t\t\t});\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (obj.command === \"uploadPictogram\") {\n\t\t\t\tconst payload = obj.message as {\n\t\t\t\t\tfilename?: string;\n\t\t\t\t\tbase64?: string;\n\t\t\t\t\tmime?: string;\n\t\t\t\t\tlabel?: string;\n\t\t\t\t\ttags?: string[] | string;\n\t\t\t\t};\n\t\t\t\tconst originalName = String(payload?.filename || \"image.png\");\n\t\t\t\tconst filename = uniquePictogramFilename(originalName);\n\t\t\t\tconst base64 = String(payload?.base64 || \"\");\n\t\t\t\tif (!base64) {\n\t\t\t\t\tthrow new Error(\"filename and base64 required\");\n\t\t\t\t}\n\t\t\t\tif (!/\\.(png|jpe?g|gif|webp|svg)$/i.test(filename)) {\n\t\t\t\t\tthrow new Error(\"unsupported file type\");\n\t\t\t\t}\n\t\t\t\tconst buffer = Buffer.from(base64.replace(/^data:[^;]+;base64,/, \"\"), \"base64\");\n\t\t\t\tif (!buffer.length) {\n\t\t\t\t\tthrow new Error(\"empty file\");\n\t\t\t\t}\n\t\t\t\tif (buffer.length > 5 * 1024 * 1024) {\n\t\t\t\t\tthrow new Error(\"file too large (max 5 MB)\");\n\t\t\t\t}\n\t\t\t\tconst path = pictogramStoragePath(filename);\n\t\t\t\tawait this.writeFileAsync(PICTOGRAM_FILE_ADAPTER, path, buffer);\n\t\t\t\tconst library = await this.getMergedPictogramLibrary();\n\t\t\t\tconst entry: CustomPictogram = {\n\t\t\t\t\tid: filename,\n\t\t\t\t\tfilename,\n\t\t\t\t\tpath,\n\t\t\t\t\tlabel: String(payload?.label || originalName.replace(/\\.[^.]+$/, \"\")),\n\t\t\t\t\ttags: normalizeTags(payload?.tags),\n\t\t\t\t\toriginalName,\n\t\t\t\t\tmime: String(payload?.mime || \"\"),\n\t\t\t\t\tuploadedAt: Date.now(),\n\t\t\t\t};\n\t\t\t\tlibrary.items = [entry, ...library.items.filter(item => item.filename !== filename)];\n\t\t\t\tawait this.savePictogramLibrary(library);\n\t\t\t\tawait this.syncCustomPictogramsConfig();\n\t\t\t\tthis.log.info(`Custom pictogram stored: ${PICTOGRAM_FILE_ADAPTER}/${path} (${buffer.length} bytes)`);\n\t\t\t\tthis.reply(obj, {\n\t\t\t\t\tok: true,\n\t\t\t\t\tpath,\n\t\t\t\t\turl: pictogramPublicUrl(path),\n\t\t\t\t\titem: entry,\n\t\t\t\t\tlibrary,\n\t\t\t\t\tadapter: PICTOGRAM_FILE_ADAPTER,\n\t\t\t\t});\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (obj.command === \"listPictograms\") {\n\t\t\t\tconst library = await this.getPublishedPictogramLibrary();\n\t\t\t\tthis.reply(obj, {\n\t\t\t\t\tok: true,\n\t\t\t\t\tfiles: library.items.map(item => item.filename),\n\t\t\t\t\tlibrary,\n\t\t\t\t});\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (obj.command === \"updatePictogram\") {\n\t\t\t\tconst payload = obj.message as {\n\t\t\t\t\tpath?: string;\n\t\t\t\t\tfilename?: string;\n\t\t\t\t\tlabel?: string;\n\t\t\t\t\ttags?: string[] | string;\n\t\t\t\t};\n\t\t\t\tconst key = String(payload?.path || payload?.filename || \"\");\n\t\t\t\tif (!key) {\n\t\t\t\t\tthrow new Error(\"path required\");\n\t\t\t\t}\n\t\t\t\tconst library = await this.getMergedPictogramLibrary();\n\t\t\t\tconst item = library.items.find(entry => matchesPictogramKey(entry, key));\n\t\t\t\tif (!item) {\n\t\t\t\t\tthrow new Error(\"pictogram not found\");\n\t\t\t\t}\n\t\t\t\tif (payload.label !== undefined) {\n\t\t\t\t\titem.label = String(payload.label);\n\t\t\t\t}\n\t\t\t\tif (payload.tags !== undefined) {\n\t\t\t\t\titem.tags = normalizeTags(payload.tags);\n\t\t\t\t}\n\t\t\t\tawait this.savePictogramLibrary(library);\n\t\t\t\tthis.reply(obj, { ok: true, item, library });\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (obj.command === \"deletePictogram\") {\n\t\t\t\tconst payload = obj.message as { path?: string; filename?: string };\n\t\t\t\tconst key = String(payload?.path || payload?.filename || \"\");\n\t\t\t\tif (!key) {\n\t\t\t\t\tthrow new Error(\"path required\");\n\t\t\t\t}\n\t\t\t\tconst library = await this.getMergedPictogramLibrary();\n\t\t\t\tconst item = library.items.find(entry => matchesPictogramKey(entry, key));\n\t\t\t\tif (!item) {\n\t\t\t\t\tthrow new Error(\"pictogram not found\");\n\t\t\t\t}\n\t\t\t\ttry {\n\t\t\t\t\tawait this.unlinkAsync(PICTOGRAM_FILE_ADAPTER, item.path);\n\t\t\t\t} catch (error) {\n\t\t\t\t\tthis.log.warn(`Could not delete pictogram file ${item.path}: ${(error as Error).message}`);\n\t\t\t\t}\n\t\t\t\tlibrary.items = library.items.filter(entry => entry.filename !== item.filename);\n\t\t\t\tawait this.savePictogramLibrary(library);\n\t\t\t\tthis.reply(obj, { ok: true, library });\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tthis.log.error(`Pictogram command ${obj.command} failed: ${(error as Error).message}`);\n\t\t\tthis.reply(obj, { ok: false, error: (error as Error).message });\n\t\t}\n\t}\n\n\tprivate async applyDurationParts(\n\t\thours: number | undefined,\n\t\tminutes: number | undefined,\n\t\tmaxHours: number,\n\t): Promise<void> {\n\t\tif (!this.timerManager) {\n\t\t\treturn;\n\t\t}\n\t\tconst snapshot = this.timerManager.getSnapshot();\n\t\tconst current = secondsToParts(snapshot.duration);\n\t\tconst nextHours = hours ?? current.hours;\n\t\tconst nextMinutes = minutes ?? current.minutes;\n\t\tconst totalSeconds = nextHours * 3600 + nextMinutes * 60;\n\t\tawait this.timerManager.setDuration(totalSeconds, maxHours);\n\t}\n\n\tprivate onUnload(callback: () => void): void {\n\t\tif (this.scheduleTick !== undefined && this.scheduleTick !== null) {\n\t\t\tthis.clearInterval(this.scheduleTick);\n\t\t\tthis.scheduleTick = null;\n\t\t}\n\t\tthis.timerManager?.destroy();\n\t\tthis.timerManager = null;\n\t\tcallback();\n\t}\n}\n\nif (require.main !== module) {\n\tmodule.exports = (options: Partial<utils.AdapterOptions> | undefined) => new AutismSupport(options);\n} else {\n\t(() => new AutismSupport())();\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["/*\n * ioBroker.autism-support \u2013 Visual Countdown + Daily Schedule\n */\n\nimport * as utils from \"@iobroker/adapter-core\";\nimport { TimerManager } from \"./lib/timer-manager\";\nimport {\n\tdayPeriodsFromConfig,\n\tfindCurrentPeriod,\n\tparseTimeToMinutes,\n\ttype DayPeriodDefinition,\n} from \"./lib/day-periods\";\nimport { findCurrentItemIndex, isPlanFullyExpired, parseSchedulePlan, type SchedulePlan } from \"./lib/schedule-types\";\nimport {\n\tADAPTER_LIBRARY_FILE,\n\tPICTOGRAM_DIR,\n\tPICTOGRAM_FILE_ADAPTER,\n\tPICTOGRAM_PLACEHOLDER_FILE,\n\tLEGACY_VIS_LIBRARY_FILE,\n\temptyLibrary,\n\tisIgnoredPictogramFile,\n\tlibraryFromNativeRows,\n\tmatchesPictogramKey,\n\tmergePictogramSources,\n\tnormalizeTags,\n\tparseLibrary,\n\tpictogramPublicUrl,\n\tpictogramStoragePath,\n\tsyncCustomPictogramRows,\n\tuniquePictogramFilename,\n\ttype CustomPictogram,\n\ttype PictogramLibrary,\n} from \"./lib/pictogram-library\";\nimport {\n\tapplyWeeklyPlanRowsToLibrary,\n\tcreateEmptyWeeklyPlan,\n\tparseWeeklyPlan,\n\tparseWeeklyPlansLibrary,\n\tschedulePlansEqual,\n\tweekdayColorsFromConfig,\n\tweekdayKeyFromDate,\n\tweeklyPlanRowsFromLibrary,\n\ttype WeekdayColors,\n\ttype WeekdayKey,\n\ttype WeeklyPlanData,\n\ttype WeeklyPlansLibrary,\n} from \"./lib/weekly-plan\";\n\nconst TIMER_CHANNEL = \"timer\";\nconst SCHEDULE_CHANNEL = \"schedule\";\n\nfunction instanceConfigId(namespace: string): string {\n\treturn `system.adapter.${namespace}`;\n}\n\nfunction legacyMisplacedInstanceConfigId(namespace: string): string {\n\treturn `${namespace}.system.adapter.${namespace}`;\n}\n\nfunction nativeConfigEquals(left: unknown, right: unknown): boolean {\n\treturn JSON.stringify(left ?? null) === JSON.stringify(right ?? null);\n}\n\nfunction secondsToParts(totalSeconds: number): { hours: number; minutes: number } {\n\tconst safe = Math.max(0, Math.round(totalSeconds));\n\treturn {\n\t\thours: Math.floor(safe / 3600),\n\t\tminutes: Math.floor((safe % 3600) / 60),\n\t};\n}\n\nclass AutismSupport extends utils.Adapter {\n\tprivate timerManager: TimerManager | null = null;\n\tprivate scheduleTick: ioBroker.Interval | undefined | null = null;\n\tprivate dayPeriods: DayPeriodDefinition[] = [];\n\tprivate weekdayColors: WeekdayColors = weekdayColorsFromConfig({} as ioBroker.AdapterConfig);\n\tprivate lastAppliedWeekday: WeekdayKey | null = null;\n\n\tpublic constructor(options: Partial<utils.AdapterOptions> = {}) {\n\t\tsuper({\n\t\t\t...options,\n\t\t\tname: \"autism-support\",\n\t\t});\n\t\tthis.on(\"ready\", this.onReady.bind(this));\n\t\tthis.on(\"stateChange\", this.onStateChange.bind(this));\n\t\tthis.on(\"message\", this.onMessage.bind(this));\n\t\tthis.on(\"unload\", this.onUnload.bind(this));\n\t}\n\n\tprivate async onReady(): Promise<void> {\n\t\ttry {\n\t\t\tconst maxHours = this.config.maxDurationHours ?? 24;\n\t\t\tconst defaultSeconds = this.getDefaultDurationSeconds(maxHours);\n\t\t\tthis.dayPeriods = dayPeriodsFromConfig(this.config);\n\t\t\tthis.weekdayColors = weekdayColorsFromConfig(this.config);\n\n\t\t\tawait this.migrateMisplacedInstanceConfig();\n\t\t\tawait this.createTimerStates();\n\t\t\tawait this.ensurePictogramStore();\n\t\t\tawait this.syncCustomPictogramsConfig();\n\t\t\tawait this.createScheduleStates();\n\t\t\t// Only apply Admin name/delete edits when the table already lists plans (avoid wiping on first boot).\n\t\t\tif (Array.isArray(this.config.weeklyPlanRows) && this.config.weeklyPlanRows.length > 0) {\n\t\t\t\tawait this.applyWeeklyPlanRowsFromConfig();\n\t\t\t}\n\t\t\tawait this.syncWeeklyPlansTableToNative();\n\n\t\t\tthis.timerManager = new TimerManager(\n\t\t\t\tasync snapshot => {\n\t\t\t\t\tawait this.publishTimerSnapshot(snapshot);\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tsetInterval: (handler, ms) => this.setInterval(handler, ms),\n\t\t\t\t\tclearInterval: handle => this.clearInterval(handle as ioBroker.Interval),\n\t\t\t\t},\n\t\t\t);\n\n\t\t\tawait this.timerManager.setDuration(defaultSeconds, maxHours);\n\t\t\tawait this.publishTimerSnapshot(this.timerManager.getSnapshot());\n\t\t\tawait this.publishScheduleRuntime();\n\n\t\t\tthis.subscribeStates(`${this.namespace}.${TIMER_CHANNEL}.*`);\n\t\t\tthis.subscribeStates(`${this.namespace}.${SCHEDULE_CHANNEL}.*`);\n\n\t\t\tthis.scheduleTick = this.setInterval(() => {\n\t\t\t\tvoid this.publishScheduleRuntime();\n\t\t\t}, 30_000);\n\n\t\t\tthis.log.info(\"Autism Support adapter ready \u2013 Visual Countdown + Weekly Schedule\");\n\t\t} catch (error) {\n\t\t\tthis.log.error(`Startup failed: ${(error as Error).message}`);\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\t/**\n\t * Write instance native config only when changed \u2014 avoids restart loop on every boot.\n\t *\n\t * @param patch Native fields to compare and optionally write.\n\t */\n\tprivate async patchInstanceNativeIfChanged(\n\t\tpatch: Partial<Pick<ioBroker.AdapterConfig, \"customPictograms\" | \"weeklyPlanRows\">>,\n\t): Promise<boolean> {\n\t\tconst id = instanceConfigId(this.namespace);\n\t\tconst current = await this.getForeignObjectAsync(id);\n\t\tconst currentNative = (current?.native || {}) as Partial<ioBroker.AdapterConfig>;\n\t\tconst nextNative: Partial<ioBroker.AdapterConfig> = {};\n\t\tlet changed = false;\n\n\t\tfor (const key of Object.keys(patch) as Array<\"customPictograms\" | \"weeklyPlanRows\">) {\n\t\t\tconst value = patch[key];\n\t\t\tif (value === undefined) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (!nativeConfigEquals(currentNative[key], value)) {\n\t\t\t\tnextNative[key] = value;\n\t\t\t\tchanged = true;\n\t\t\t}\n\t\t}\n\n\t\tif (!changed) {\n\t\t\treturn false;\n\t\t}\n\n\t\tawait this.extendForeignObjectAsync(id, { native: nextNative });\n\t\treturn true;\n\t}\n\n\tprivate getDefaultDurationSeconds(maxHours: number): number {\n\t\tconst hours = Math.min(maxHours, Math.max(0, this.config.defaultDurationHours ?? 1));\n\t\tconst minutes = Math.min(59, Math.max(0, this.config.defaultDurationMinutes ?? 0));\n\t\tconst total = hours * 3600 + minutes * 60;\n\t\treturn Math.max(60, Math.min(maxHours * 3600, total));\n\t}\n\n\tprivate async createTimerStates(): Promise<void> {\n\t\tawait this.setObjectNotExistsAsync(TIMER_CHANNEL, {\n\t\t\ttype: \"channel\",\n\t\t\tcommon: { name: \"Visual Countdown\" },\n\t\t\tnative: {},\n\t\t});\n\n\t\tconst states: Record<\n\t\t\tstring,\n\t\t\t{\n\t\t\t\ttype: \"number\" | \"boolean\";\n\t\t\t\trole: string;\n\t\t\t\tname: string;\n\t\t\t\tread: boolean;\n\t\t\t\twrite: boolean;\n\t\t\t\tunit?: string;\n\t\t\t\tmin?: number;\n\t\t\t\tmax?: number;\n\t\t\t}\n\t\t> = {\n\t\t\tduration: {\n\t\t\t\ttype: \"number\",\n\t\t\t\trole: \"level.timer\",\n\t\t\t\tname: \"Timer duration (seconds)\",\n\t\t\t\tread: true,\n\t\t\t\twrite: true,\n\t\t\t\tunit: \"s\",\n\t\t\t\tmin: 60,\n\t\t\t\tmax: 86400,\n\t\t\t},\n\t\t\tremaining: {\n\t\t\t\ttype: \"number\",\n\t\t\t\trole: \"value.timer\",\n\t\t\t\tname: \"Timer remaining (seconds)\",\n\t\t\t\tread: true,\n\t\t\t\twrite: false,\n\t\t\t\tunit: \"s\",\n\t\t\t},\n\t\t\telapsed: {\n\t\t\t\ttype: \"number\",\n\t\t\t\trole: \"value.timer\",\n\t\t\t\tname: \"Timer elapsed (seconds)\",\n\t\t\t\tread: true,\n\t\t\t\twrite: false,\n\t\t\t\tunit: \"s\",\n\t\t\t},\n\t\t\trunning: {\n\t\t\t\ttype: \"boolean\",\n\t\t\t\trole: \"indicator\",\n\t\t\t\tname: \"Timer running\",\n\t\t\t\tread: true,\n\t\t\t\twrite: false,\n\t\t\t},\n\t\t\tpaused: {\n\t\t\t\ttype: \"boolean\",\n\t\t\t\trole: \"indicator\",\n\t\t\t\tname: \"Timer paused\",\n\t\t\t\tread: true,\n\t\t\t\twrite: false,\n\t\t\t},\n\t\t\tfinished: {\n\t\t\t\ttype: \"boolean\",\n\t\t\t\trole: \"indicator\",\n\t\t\t\tname: \"Timer finished\",\n\t\t\t\tread: true,\n\t\t\t\twrite: false,\n\t\t\t},\n\t\t\tstart: {\n\t\t\t\ttype: \"boolean\",\n\t\t\t\trole: \"button.start\",\n\t\t\t\tname: \"Start timer\",\n\t\t\t\tread: false,\n\t\t\t\twrite: true,\n\t\t\t},\n\t\t\tpause: {\n\t\t\t\ttype: \"boolean\",\n\t\t\t\trole: \"button.pause\",\n\t\t\t\tname: \"Pause timer\",\n\t\t\t\tread: false,\n\t\t\t\twrite: true,\n\t\t\t},\n\t\t\tresume: {\n\t\t\t\ttype: \"boolean\",\n\t\t\t\trole: \"button.start\",\n\t\t\t\tname: \"Resume timer\",\n\t\t\t\tread: false,\n\t\t\t\twrite: true,\n\t\t\t},\n\t\t\tstop: {\n\t\t\t\ttype: \"boolean\",\n\t\t\t\trole: \"button.stop\",\n\t\t\t\tname: \"Stop timer\",\n\t\t\t\tread: false,\n\t\t\t\twrite: true,\n\t\t\t},\n\t\t\tsetDurationHours: {\n\t\t\t\ttype: \"number\",\n\t\t\t\trole: \"level\",\n\t\t\t\tname: \"Set timer duration (hours)\",\n\t\t\t\tread: true,\n\t\t\t\twrite: true,\n\t\t\t\tunit: \"h\",\n\t\t\t\tmin: 0,\n\t\t\t\tmax: 24,\n\t\t\t},\n\t\t\tsetDurationMinutes: {\n\t\t\t\ttype: \"number\",\n\t\t\t\trole: \"level\",\n\t\t\t\tname: \"Set timer duration (minutes)\",\n\t\t\t\tread: true,\n\t\t\t\twrite: true,\n\t\t\t\tunit: \"min\",\n\t\t\t\tmin: 0,\n\t\t\t\tmax: 59,\n\t\t\t},\n\t\t};\n\n\t\tfor (const [id, def] of Object.entries(states)) {\n\t\t\tawait this.setObjectNotExistsAsync(`${TIMER_CHANNEL}.${id}`, {\n\t\t\t\ttype: \"state\",\n\t\t\t\tcommon: {\n\t\t\t\t\tname: def.name,\n\t\t\t\t\ttype: def.type,\n\t\t\t\t\trole: def.role,\n\t\t\t\t\tread: def.read,\n\t\t\t\t\twrite: def.write,\n\t\t\t\t\tunit: def.unit,\n\t\t\t\t\tmin: def.min,\n\t\t\t\t\tmax: def.max,\n\t\t\t\t},\n\t\t\t\tnative: {},\n\t\t\t});\n\t\t}\n\n\t\tawait this.migrateTimerStateRoles();\n\t}\n\n\t/**\n\t * Earlier versions used extendObject() for system.adapter.* which ioBroker resolves\n\t * relative to the instance namespace (autism-support.0.system.adapter...).\n\t */\n\tprivate async migrateMisplacedInstanceConfig(): Promise<void> {\n\t\tconst legacyId = legacyMisplacedInstanceConfigId(this.namespace);\n\t\tconst legacy = await this.getObjectAsync(legacyId);\n\t\tif (!legacy?.native) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst native = legacy.native as {\n\t\t\tcustomPictograms?: ioBroker.AdapterConfig[\"customPictograms\"];\n\t\t\tweeklyPlanRows?: ioBroker.AdapterConfig[\"weeklyPlanRows\"];\n\t\t};\n\t\tconst patch: Partial<ioBroker.AdapterConfig> = {};\n\t\tif (Array.isArray(native.customPictograms)) {\n\t\t\tpatch.customPictograms = native.customPictograms;\n\t\t}\n\t\tif (Array.isArray(native.weeklyPlanRows)) {\n\t\t\tpatch.weeklyPlanRows = native.weeklyPlanRows;\n\t\t}\n\t\tif (Object.keys(patch).length) {\n\t\t\tawait this.patchInstanceNativeIfChanged(patch);\n\t\t\tif (patch.customPictograms) {\n\t\t\t\tthis.config.customPictograms = patch.customPictograms;\n\t\t\t}\n\t\t\tif (patch.weeklyPlanRows) {\n\t\t\t\tthis.config.weeklyPlanRows = patch.weeklyPlanRows;\n\t\t\t}\n\t\t\tthis.log.info(`Migrated instance native config from misplaced object ${legacyId}`);\n\t\t}\n\n\t\tawait this.delObjectAsync(legacyId);\n\t\tfor (const folderId of [`${this.namespace}.system.adapter`, `${this.namespace}.system`]) {\n\t\t\ttry {\n\t\t\t\tawait this.delObjectAsync(folderId);\n\t\t\t} catch {\n\t\t\t\t// folder may not exist or is not empty\n\t\t\t}\n\t\t}\n\t}\n\n\t/** Update roles/read flags on existing timer states (object-structure compliance). */\n\tprivate async migrateTimerStateRoles(): Promise<void> {\n\t\tconst patches: Record<string, { role?: string; read?: boolean }> = {\n\t\t\tduration: { role: \"level.timer\" },\n\t\t\tremaining: { role: \"value.timer\" },\n\t\t\telapsed: { role: \"value.timer\" },\n\t\t\tstart: { read: false },\n\t\t\tpause: { read: false },\n\t\t\tresume: { read: false },\n\t\t\tstop: { read: false },\n\t\t};\n\t\tfor (const [id, patch] of Object.entries(patches)) {\n\t\t\tconst common: Partial<ioBroker.StateCommon> = {};\n\t\t\tif (patch.role) {\n\t\t\t\tcommon.role = patch.role;\n\t\t\t}\n\t\t\tif (patch.read !== undefined) {\n\t\t\t\tcommon.read = patch.read;\n\t\t\t}\n\t\t\tawait this.extendObjectAsync(`${TIMER_CHANNEL}.${id}`, { common });\n\t\t}\n\t}\n\n\tprivate async createScheduleStates(): Promise<void> {\n\t\tawait this.setObjectNotExistsAsync(SCHEDULE_CHANNEL, {\n\t\t\ttype: \"channel\",\n\t\t\tcommon: { name: \"Daily schedule\" },\n\t\t\tnative: {},\n\t\t});\n\n\t\tawait this.setObjectNotExistsAsync(`${SCHEDULE_CHANNEL}.plan`, {\n\t\t\ttype: \"state\",\n\t\t\tcommon: {\n\t\t\t\tname: \"Schedule plan (JSON)\",\n\t\t\t\ttype: \"string\",\n\t\t\t\trole: \"json\",\n\t\t\t\tread: true,\n\t\t\t\twrite: true,\n\t\t\t\tdef: JSON.stringify({ version: 1, items: [] }),\n\t\t\t},\n\t\t\tnative: {},\n\t\t});\n\n\t\tawait this.setObjectNotExistsAsync(`${SCHEDULE_CHANNEL}.periods`, {\n\t\t\ttype: \"state\",\n\t\t\tcommon: {\n\t\t\t\tname: \"Day periods from admin (JSON)\",\n\t\t\t\ttype: \"string\",\n\t\t\t\trole: \"json\",\n\t\t\t\tread: true,\n\t\t\t\twrite: false,\n\t\t\t},\n\t\t\tnative: {},\n\t\t});\n\n\t\tawait this.setObjectNotExistsAsync(`${SCHEDULE_CHANNEL}.periodOverrides`, {\n\t\t\ttype: \"state\",\n\t\t\tcommon: {\n\t\t\t\tname: \"Day period on/off overrides from schedule config (JSON)\",\n\t\t\t\ttype: \"string\",\n\t\t\t\trole: \"json\",\n\t\t\t\tread: true,\n\t\t\t\twrite: true,\n\t\t\t\tdef: \"{}\",\n\t\t\t},\n\t\t\tnative: {},\n\t\t});\n\n\t\tawait this.setObjectNotExistsAsync(`${SCHEDULE_CHANNEL}.nowMinutes`, {\n\t\t\ttype: \"state\",\n\t\t\tcommon: {\n\t\t\t\tname: \"Minutes since midnight (local)\",\n\t\t\t\ttype: \"number\",\n\t\t\t\trole: \"value\",\n\t\t\t\tread: true,\n\t\t\t\twrite: false,\n\t\t\t\tunit: \"min\",\n\t\t\t\tmin: 0,\n\t\t\t\tmax: 1439,\n\t\t\t},\n\t\t\tnative: {},\n\t\t});\n\n\t\tawait this.setObjectNotExistsAsync(`${SCHEDULE_CHANNEL}.currentPeriod`, {\n\t\t\ttype: \"state\",\n\t\t\tcommon: {\n\t\t\t\tname: \"Current day period id\",\n\t\t\t\ttype: \"string\",\n\t\t\t\trole: \"text\",\n\t\t\t\tread: true,\n\t\t\t\twrite: false,\n\t\t\t},\n\t\t\tnative: {},\n\t\t});\n\n\t\tawait this.setObjectNotExistsAsync(`${SCHEDULE_CHANNEL}.currentItemIndex`, {\n\t\t\ttype: \"state\",\n\t\t\tcommon: {\n\t\t\t\tname: \"Index of active schedule item (-1 = none)\",\n\t\t\t\ttype: \"number\",\n\t\t\t\trole: \"value\",\n\t\t\t\tread: true,\n\t\t\t\twrite: false,\n\t\t\t\tmin: -1,\n\t\t\t},\n\t\t\tnative: {},\n\t\t});\n\n\t\tawait this.setObjectNotExistsAsync(`${SCHEDULE_CHANNEL}.clearAfterLast`, {\n\t\t\ttype: \"state\",\n\t\t\tcommon: {\n\t\t\t\tname: \"Clear plan automatically after last pictogram ends\",\n\t\t\t\ttype: \"boolean\",\n\t\t\t\trole: \"switch\",\n\t\t\t\tread: true,\n\t\t\t\twrite: true,\n\t\t\t\tdef: false,\n\t\t\t},\n\t\t\tnative: {},\n\t\t});\n\n\t\tawait this.setObjectNotExistsAsync(`${SCHEDULE_CHANNEL}.pictogramLibrary`, {\n\t\t\ttype: \"state\",\n\t\t\tcommon: {\n\t\t\t\tname: \"Custom pictogram library (JSON)\",\n\t\t\t\ttype: \"string\",\n\t\t\t\trole: \"json\",\n\t\t\t\tread: true,\n\t\t\t\twrite: false,\n\t\t\t},\n\t\t\tnative: {},\n\t\t});\n\n\t\tawait this.setObjectNotExistsAsync(`${SCHEDULE_CHANNEL}.weeklyPlan`, {\n\t\t\ttype: \"state\",\n\t\t\tcommon: {\n\t\t\t\tname: \"Active weekly plan (JSON, Mon\u2013Sun)\",\n\t\t\t\ttype: \"string\",\n\t\t\t\trole: \"json\",\n\t\t\t\tread: true,\n\t\t\t\twrite: true,\n\t\t\t\tdef: JSON.stringify(createEmptyWeeklyPlan()),\n\t\t\t},\n\t\t\tnative: {},\n\t\t});\n\n\t\tawait this.setObjectNotExistsAsync(`${SCHEDULE_CHANNEL}.weeklyPlansLibrary`, {\n\t\t\ttype: \"state\",\n\t\t\tcommon: {\n\t\t\t\tname: \"Saved weekly plans library (JSON)\",\n\t\t\t\ttype: \"string\",\n\t\t\t\trole: \"json\",\n\t\t\t\tread: true,\n\t\t\t\twrite: true,\n\t\t\t\tdef: JSON.stringify({ version: 1, activeId: null, plans: [] }),\n\t\t\t},\n\t\t\tnative: {},\n\t\t});\n\n\t\tawait this.setObjectNotExistsAsync(`${SCHEDULE_CHANNEL}.loadDailyFromWeekly`, {\n\t\t\ttype: \"state\",\n\t\t\tcommon: {\n\t\t\t\tname: \"Load daily plan from active weekly plan each day\",\n\t\t\t\ttype: \"boolean\",\n\t\t\t\trole: \"switch\",\n\t\t\t\tread: true,\n\t\t\t\twrite: true,\n\t\t\t\tdef: false,\n\t\t\t},\n\t\t\tnative: {},\n\t\t});\n\n\t\tawait this.setObjectNotExistsAsync(`${SCHEDULE_CHANNEL}.weekdayColors`, {\n\t\t\ttype: \"state\",\n\t\t\tcommon: {\n\t\t\t\tname: \"Weekday background colors from admin (JSON)\",\n\t\t\t\ttype: \"string\",\n\t\t\t\trole: \"json\",\n\t\t\t\tread: true,\n\t\t\t\twrite: false,\n\t\t\t},\n\t\t\tnative: {},\n\t\t});\n\n\t\tconst planState = await this.getStateAsync(`${SCHEDULE_CHANNEL}.plan`);\n\t\tif (planState?.val == null || planState.val === \"\") {\n\t\t\tawait this.setState(`${SCHEDULE_CHANNEL}.plan`, JSON.stringify({ version: 1, items: [] }), true);\n\t\t}\n\t\tconst overridesState = await this.getStateAsync(`${SCHEDULE_CHANNEL}.periodOverrides`);\n\t\tif (overridesState?.val == null || overridesState.val === \"\") {\n\t\t\tawait this.setState(`${SCHEDULE_CHANNEL}.periodOverrides`, \"{}\", true);\n\t\t}\n\t\tconst clearAfterState = await this.getStateAsync(`${SCHEDULE_CHANNEL}.clearAfterLast`);\n\t\tif (clearAfterState?.val == null) {\n\t\t\tawait this.setState(`${SCHEDULE_CHANNEL}.clearAfterLast`, false, true);\n\t\t}\n\t\tconst loadDailyState = await this.getStateAsync(`${SCHEDULE_CHANNEL}.loadDailyFromWeekly`);\n\t\tif (loadDailyState?.val == null) {\n\t\t\tawait this.setState(`${SCHEDULE_CHANNEL}.loadDailyFromWeekly`, false, true);\n\t\t}\n\n\t\tconst weeklyState = await this.getStateAsync(`${SCHEDULE_CHANNEL}.weeklyPlan`);\n\t\tif (weeklyState?.val == null || weeklyState.val === \"\") {\n\t\t\tconst seed = parseSchedulePlan(planState?.val);\n\t\t\tawait this.setState(\n\t\t\t\t`${SCHEDULE_CHANNEL}.weeklyPlan`,\n\t\t\t\tJSON.stringify(createEmptyWeeklyPlan(seed.items.length ? seed : undefined)),\n\t\t\t\ttrue,\n\t\t\t);\n\t\t}\n\t\tconst libraryState = await this.getStateAsync(`${SCHEDULE_CHANNEL}.weeklyPlansLibrary`);\n\t\tif (libraryState?.val == null || libraryState.val === \"\") {\n\t\t\tawait this.setState(\n\t\t\t\t`${SCHEDULE_CHANNEL}.weeklyPlansLibrary`,\n\t\t\t\tJSON.stringify({ version: 1, activeId: null, plans: [] }),\n\t\t\t\ttrue,\n\t\t\t);\n\t\t}\n\n\t\t// Publish admin period definitions once at start (times/colors); overrides stay separate.\n\t\tawait this.setState(`${SCHEDULE_CHANNEL}.periods`, JSON.stringify(this.dayPeriods), true);\n\t\tawait this.setState(`${SCHEDULE_CHANNEL}.weekdayColors`, JSON.stringify(this.weekdayColors), true);\n\t\tawait this.publishPictogramLibrary();\n\t}\n\n\tprivate async buildCustomPictogramRows(): Promise<Array<{ file: string; label: string; tags: string }>> {\n\t\tconst files = await this.listPictogramFiles();\n\t\treturn syncCustomPictogramRows(files || [], this.config.customPictograms);\n\t}\n\n\tprivate async syncCustomPictogramsConfig(): Promise<void> {\n\t\tconst rows = await this.buildCustomPictogramRows();\n\t\tawait this.patchInstanceNativeIfChanged({ customPictograms: rows });\n\t\tthis.config.customPictograms = rows;\n\t\tawait this.publishPictogramLibrary();\n\t}\n\n\tprivate async ensurePictogramStore(): Promise<void> {\n\t\ttry {\n\t\t\tawait this.readFileAsync(this.namespace, ADAPTER_LIBRARY_FILE);\n\t\t} catch {\n\t\t\ttry {\n\t\t\t\tawait this.writeFileAsync(\n\t\t\t\t\tthis.namespace,\n\t\t\t\t\tADAPTER_LIBRARY_FILE,\n\t\t\t\t\tJSON.stringify(emptyLibrary(), null, 2),\n\t\t\t\t);\n\t\t\t\tthis.log.info(`Created adapter pictogram library ${this.namespace}/${ADAPTER_LIBRARY_FILE}`);\n\t\t\t} catch (error) {\n\t\t\t\tthis.log.error(`Could not create adapter pictogram library: ${(error as Error).message}`);\n\t\t\t}\n\t\t}\n\n\t\ttry {\n\t\t\tconst legacy = await this.readFileAsync(PICTOGRAM_FILE_ADAPTER, LEGACY_VIS_LIBRARY_FILE);\n\t\t\tconst raw = typeof legacy.file === \"string\" ? legacy.file : Buffer.from(legacy.file).toString(\"utf8\");\n\t\t\tconst migrated = parseLibrary(raw);\n\t\t\tif (migrated.items.length) {\n\t\t\t\tawait this.writeFileAsync(this.namespace, ADAPTER_LIBRARY_FILE, JSON.stringify(migrated, null, 2));\n\t\t\t\tthis.log.info(`Migrated pictogram library from vis-2 to ${this.namespace}`);\n\t\t\t}\n\t\t} catch {\n\t\t\t// no legacy library in vis-2\n\t\t}\n\n\t\ttry {\n\t\t\tawait this.unlinkAsync(PICTOGRAM_FILE_ADAPTER, LEGACY_VIS_LIBRARY_FILE);\n\t\t} catch {\n\t\t\t// ignore\n\t\t}\n\n\t\ttry {\n\t\t\tconst hint =\n\t\t\t\t\"Piktogramm-Bilder (PNG, JPEG, GIF, WebP, SVG) hier hochladen.\\n\" +\n\t\t\t\t\"Keine neuen Ordner anlegen (Dateimanager zeigt dann oft \u201Edoppelter Name\u201C).\\n\" +\n\t\t\t\t\"Stattdessen oben auf Hochladen klicken und Bilder in DIESEN Ordner legen.\\n\";\n\t\t\tconst placeholderPath = `${PICTOGRAM_DIR}/${PICTOGRAM_PLACEHOLDER_FILE}`;\n\t\t\tlet needsWrite = true;\n\t\t\ttry {\n\t\t\t\tconst existing = await this.readFileAsync(PICTOGRAM_FILE_ADAPTER, placeholderPath);\n\t\t\t\tconst current =\n\t\t\t\t\ttypeof existing.file === \"string\" ? existing.file : Buffer.from(existing.file).toString(\"utf8\");\n\t\t\t\tneedsWrite = current !== hint;\n\t\t\t} catch {\n\t\t\t\t// file missing\n\t\t\t}\n\t\t\tif (needsWrite) {\n\t\t\t\tawait this.writeFileAsync(PICTOGRAM_FILE_ADAPTER, placeholderPath, hint);\n\t\t\t\tthis.log.info(`Ensured vis-2 pictogram folder ${PICTOGRAM_FILE_ADAPTER}/${PICTOGRAM_DIR}`);\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tthis.log.error(\n\t\t\t\t`Could not write ${PICTOGRAM_FILE_ADAPTER}/${PICTOGRAM_DIR}/${PICTOGRAM_PLACEHOLDER_FILE}: ${(error as Error).message}`,\n\t\t\t);\n\t\t}\n\t}\n\n\tprivate async getPublishedPictogramLibrary(): Promise<PictogramLibrary> {\n\t\treturn mergePictogramSources(\n\t\t\tawait this.getMergedPictogramLibrary(),\n\t\t\tlibraryFromNativeRows(this.config.customPictograms),\n\t\t);\n\t}\n\n\tprivate async publishPictogramLibrary(): Promise<void> {\n\t\tconst library = await this.getPublishedPictogramLibrary();\n\t\tawait this.setState(`${SCHEDULE_CHANNEL}.pictogramLibrary`, JSON.stringify(library), true);\n\t}\n\n\tprivate async publishTimerSnapshot(snapshot: {\n\t\tduration: number;\n\t\tremaining: number;\n\t\telapsed: number;\n\t\trunning: boolean;\n\t\tpaused: boolean;\n\t\tfinished: boolean;\n\t}): Promise<void> {\n\t\tawait this.setState(`${TIMER_CHANNEL}.duration`, snapshot.duration, true);\n\t\tawait this.setState(`${TIMER_CHANNEL}.remaining`, snapshot.remaining, true);\n\t\tawait this.setState(`${TIMER_CHANNEL}.elapsed`, snapshot.elapsed, true);\n\t\tawait this.setState(`${TIMER_CHANNEL}.running`, snapshot.running, true);\n\t\tawait this.setState(`${TIMER_CHANNEL}.paused`, snapshot.paused, true);\n\t\tawait this.setState(`${TIMER_CHANNEL}.finished`, snapshot.finished, true);\n\t}\n\n\tprivate async getPlan(): Promise<SchedulePlan> {\n\t\tconst state = await this.getStateAsync(`${SCHEDULE_CHANNEL}.plan`);\n\t\treturn parseSchedulePlan(state?.val);\n\t}\n\n\tprivate async getPeriodOverrides(): Promise<Record<string, boolean>> {\n\t\tconst state = await this.getStateAsync(`${SCHEDULE_CHANNEL}.periodOverrides`);\n\t\ttry {\n\t\t\tconst raw = typeof state?.val === \"string\" ? JSON.parse(state.val) : state?.val;\n\t\t\treturn raw && typeof raw === \"object\" ? (raw as Record<string, boolean>) : {};\n\t\t} catch {\n\t\t\treturn {};\n\t\t}\n\t}\n\n\tprivate async getEffectivePeriods(): Promise<DayPeriodDefinition[]> {\n\t\tconst overrides = await this.getPeriodOverrides();\n\t\treturn this.dayPeriods.map(period => ({\n\t\t\t...period,\n\t\t\tenabled: overrides[period.id] === undefined ? period.enabled : Boolean(overrides[period.id]),\n\t\t}));\n\t}\n\n\tprivate async getWeeklyPlan(): Promise<WeeklyPlanData> {\n\t\tconst state = await this.getStateAsync(`${SCHEDULE_CHANNEL}.weeklyPlan`);\n\t\treturn parseWeeklyPlan(state?.val);\n\t}\n\n\tprivate async getWeeklyPlansLibrary(): Promise<WeeklyPlansLibrary> {\n\t\tconst state = await this.getStateAsync(`${SCHEDULE_CHANNEL}.weeklyPlansLibrary`);\n\t\treturn parseWeeklyPlansLibrary(state?.val);\n\t}\n\n\tprivate async syncWeeklyPlansTableToNative(): Promise<void> {\n\t\tconst library = await this.getWeeklyPlansLibrary();\n\t\tconst rows = weeklyPlanRowsFromLibrary(library);\n\t\tawait this.patchInstanceNativeIfChanged({ weeklyPlanRows: rows });\n\t\tthis.config.weeklyPlanRows = rows;\n\t}\n\n\tprivate async applyWeeklyPlanRowsFromConfig(): Promise<void> {\n\t\tconst library = await this.getWeeklyPlansLibrary();\n\t\tconst next = applyWeeklyPlanRowsToLibrary(library, this.config.weeklyPlanRows);\n\t\tif (JSON.stringify(next) !== JSON.stringify(library)) {\n\t\t\tawait this.setState(`${SCHEDULE_CHANNEL}.weeklyPlansLibrary`, JSON.stringify(next), true);\n\t\t}\n\t}\n\n\tprivate async maybeApplyWeeklyToDaily(): Promise<void> {\n\t\tconst loadState = await this.getStateAsync(`${SCHEDULE_CHANNEL}.loadDailyFromWeekly`);\n\t\tif (!loadState?.val) {\n\t\t\treturn;\n\t\t}\n\t\tconst weekday = weekdayKeyFromDate(new Date());\n\t\tconst weekly = await this.getWeeklyPlan();\n\t\tconst dayPlan = weekly.days[weekday];\n\t\tconst current = await this.getPlan();\n\t\tif (this.lastAppliedWeekday === weekday && schedulePlansEqual(current, dayPlan)) {\n\t\t\treturn;\n\t\t}\n\t\tawait this.setState(`${SCHEDULE_CHANNEL}.plan`, JSON.stringify(dayPlan), true);\n\t\tthis.lastAppliedWeekday = weekday;\n\t\tthis.log.debug(`Daily plan loaded from weekly plan (${weekday})`);\n\t}\n\n\tprivate async publishScheduleRuntime(): Promise<void> {\n\t\tawait this.maybeApplyWeeklyToDaily();\n\n\t\tconst now = new Date();\n\t\tconst minutes = now.getHours() * 60 + now.getMinutes();\n\t\tconst periods = await this.getEffectivePeriods();\n\t\tconst period = findCurrentPeriod(minutes, periods);\n\t\tlet plan = await this.getPlan();\n\n\t\tconst clearAfterState = await this.getStateAsync(`${SCHEDULE_CHANNEL}.clearAfterLast`);\n\t\tconst clearAfterLast = Boolean(clearAfterState?.val);\n\t\tif (clearAfterLast && isPlanFullyExpired(plan, minutes, parseTimeToMinutes)) {\n\t\t\tplan = { version: 1, items: [] };\n\t\t\tawait this.setState(`${SCHEDULE_CHANNEL}.plan`, JSON.stringify(plan), true);\n\t\t\tthis.log.info(\"Schedule plan cleared automatically after last pictogram ended\");\n\t\t}\n\n\t\tconst itemIndex = findCurrentItemIndex(plan, minutes, parseTimeToMinutes);\n\n\t\t// Keep admin period metadata available; do not wipe Config overrides.\n\t\tawait this.setState(`${SCHEDULE_CHANNEL}.periods`, JSON.stringify(this.dayPeriods), true);\n\t\tawait this.setState(`${SCHEDULE_CHANNEL}.weekdayColors`, JSON.stringify(this.weekdayColors), true);\n\t\tawait this.setState(`${SCHEDULE_CHANNEL}.nowMinutes`, minutes, true);\n\t\tawait this.setState(`${SCHEDULE_CHANNEL}.currentPeriod`, period?.id ?? \"\", true);\n\t\tawait this.setState(`${SCHEDULE_CHANNEL}.currentItemIndex`, itemIndex, true);\n\t}\n\n\tprivate async onStateChange(id: string, state: ioBroker.State | null | undefined): Promise<void> {\n\t\tif (!state || state.ack) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (id.startsWith(`${this.namespace}.${SCHEDULE_CHANNEL}.`)) {\n\t\t\tconst localId = id.replace(`${this.namespace}.${SCHEDULE_CHANNEL}.`, \"\");\n\t\t\tif (localId === \"plan\") {\n\t\t\t\tconst plan = parseSchedulePlan(state.val);\n\t\t\t\tawait this.setState(`${SCHEDULE_CHANNEL}.plan`, JSON.stringify(plan), true);\n\t\t\t\tawait this.publishScheduleRuntime();\n\t\t\t} else if (localId === \"periodOverrides\") {\n\t\t\t\ttry {\n\t\t\t\t\tconst raw = typeof state.val === \"string\" ? JSON.parse(String(state.val)) : state.val;\n\t\t\t\t\tconst cleaned = raw && typeof raw === \"object\" ? (raw as Record<string, boolean>) : {};\n\t\t\t\t\tawait this.setState(`${SCHEDULE_CHANNEL}.periodOverrides`, JSON.stringify(cleaned), true);\n\t\t\t\t\tawait this.publishScheduleRuntime();\n\t\t\t\t} catch (error) {\n\t\t\t\t\tthis.log.error(`Invalid periodOverrides: ${(error as Error).message}`);\n\t\t\t\t}\n\t\t\t} else if (localId === \"clearAfterLast\") {\n\t\t\t\tawait this.setState(`${SCHEDULE_CHANNEL}.clearAfterLast`, Boolean(state.val), true);\n\t\t\t\tawait this.publishScheduleRuntime();\n\t\t\t} else if (localId === \"weeklyPlan\") {\n\t\t\t\tconst weekly = parseWeeklyPlan(state.val);\n\t\t\t\tawait this.setState(`${SCHEDULE_CHANNEL}.weeklyPlan`, JSON.stringify(weekly), true);\n\t\t\t\tthis.lastAppliedWeekday = null;\n\t\t\t\tawait this.publishScheduleRuntime();\n\t\t\t} else if (localId === \"weeklyPlansLibrary\") {\n\t\t\t\tconst library = parseWeeklyPlansLibrary(state.val);\n\t\t\t\tawait this.setState(`${SCHEDULE_CHANNEL}.weeklyPlansLibrary`, JSON.stringify(library), true);\n\t\t\t\tawait this.syncWeeklyPlansTableToNative();\n\t\t\t} else if (localId === \"loadDailyFromWeekly\") {\n\t\t\t\tawait this.setState(`${SCHEDULE_CHANNEL}.loadDailyFromWeekly`, Boolean(state.val), true);\n\t\t\t\tthis.lastAppliedWeekday = null;\n\t\t\t\tawait this.publishScheduleRuntime();\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\tif (!this.timerManager || !id.startsWith(`${this.namespace}.${TIMER_CHANNEL}.`)) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst localId = id.replace(`${this.namespace}.${TIMER_CHANNEL}.`, \"\");\n\t\tconst maxHours = this.config.maxDurationHours ?? 24;\n\n\t\ttry {\n\t\t\tswitch (localId) {\n\t\t\t\tcase \"start\":\n\t\t\t\t\tif (state.val === true) {\n\t\t\t\t\t\tawait this.timerManager.start();\n\t\t\t\t\t}\n\t\t\t\t\tawait this.setState(`${TIMER_CHANNEL}.start`, false, true);\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"pause\":\n\t\t\t\t\tif (state.val === true) {\n\t\t\t\t\t\tawait this.timerManager.pause();\n\t\t\t\t\t}\n\t\t\t\t\tawait this.setState(`${TIMER_CHANNEL}.pause`, false, true);\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"resume\":\n\t\t\t\t\tif (state.val === true) {\n\t\t\t\t\t\tawait this.timerManager.resume();\n\t\t\t\t\t}\n\t\t\t\t\tawait this.setState(`${TIMER_CHANNEL}.resume`, false, true);\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"stop\":\n\t\t\t\t\tif (state.val === true) {\n\t\t\t\t\t\tawait this.timerManager.stop();\n\t\t\t\t\t}\n\t\t\t\t\tawait this.setState(`${TIMER_CHANNEL}.stop`, false, true);\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"duration\":\n\t\t\t\t\tif (typeof state.val === \"number\") {\n\t\t\t\t\t\tawait this.timerManager.setDuration(state.val, maxHours);\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"setDurationHours\":\n\t\t\t\t\tif (typeof state.val === \"number\") {\n\t\t\t\t\t\tawait this.applyDurationParts(Math.round(state.val), undefined, maxHours);\n\t\t\t\t\t}\n\t\t\t\t\tawait this.setState(`${TIMER_CHANNEL}.setDurationHours`, 0, true);\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"setDurationMinutes\":\n\t\t\t\t\tif (typeof state.val === \"number\") {\n\t\t\t\t\t\tawait this.applyDurationParts(undefined, Math.round(state.val), maxHours);\n\t\t\t\t\t}\n\t\t\t\t\tawait this.setState(`${TIMER_CHANNEL}.setDurationMinutes`, 0, true);\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tthis.log.error(`Timer command failed (${localId}): ${(error as Error).message}`);\n\t\t}\n\t}\n\n\tprivate reply(obj: ioBroker.Message, payload: unknown): void {\n\t\tif (obj.callback) {\n\t\t\tthis.sendTo(obj.from, obj.command, payload, obj.callback);\n\t\t}\n\t}\n\n\tprivate async loadPictogramLibrary(): Promise<PictogramLibrary> {\n\t\ttry {\n\t\t\tconst file = await this.readFileAsync(this.namespace, ADAPTER_LIBRARY_FILE);\n\t\t\tconst raw = typeof file.file === \"string\" ? file.file : Buffer.from(file.file).toString(\"utf8\");\n\t\t\treturn parseLibrary(raw);\n\t\t} catch {\n\t\t\treturn emptyLibrary();\n\t\t}\n\t}\n\n\tprivate async savePictogramLibrary(library: PictogramLibrary): Promise<void> {\n\t\tawait this.writeFileAsync(this.namespace, ADAPTER_LIBRARY_FILE, JSON.stringify(library, null, 2));\n\t\tawait this.setState(`${SCHEDULE_CHANNEL}.pictogramLibrary`, JSON.stringify(library), true);\n\t}\n\n\tprivate async listPictogramFiles(): Promise<string[] | null> {\n\t\ttry {\n\t\t\tconst result = await this.readDirAsync(PICTOGRAM_FILE_ADAPTER, PICTOGRAM_DIR);\n\t\t\treturn (result || [])\n\t\t\t\t.filter(entry => !entry.isDir && !isIgnoredPictogramFile(entry.file))\n\t\t\t\t.map(entry => entry.file);\n\t\t} catch {\n\t\t\treturn null;\n\t\t}\n\t}\n\n\tprivate async getMergedPictogramLibrary(): Promise<PictogramLibrary> {\n\t\tconst library = await this.loadPictogramLibrary();\n\t\tconst files = await this.listPictogramFiles();\n\t\tif (!files) {\n\t\t\treturn library;\n\t\t}\n\t\tconst known = new Set(library.items.map(item => item.filename));\n\t\tfor (const filename of files) {\n\t\t\tif (known.has(filename)) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tlibrary.items.push({\n\t\t\t\tid: filename,\n\t\t\t\tfilename,\n\t\t\t\tpath: pictogramStoragePath(filename),\n\t\t\t\tlabel: filename.replace(/\\.[^.]+$/, \"\").replace(/-\\d+$/, \"\"),\n\t\t\t\ttags: [],\n\t\t\t\toriginalName: filename,\n\t\t\t\tmime: \"\",\n\t\t\t\tuploadedAt: 0,\n\t\t\t});\n\t\t}\n\t\tlibrary.items = library.items.filter(item => files.includes(item.filename));\n\t\tlibrary.items.sort((a, b) => (b.uploadedAt || 0) - (a.uploadedAt || 0));\n\t\treturn library;\n\t}\n\n\t/**\n\t * Custom pictogram library (user-owned images only).\n\t * ARASAAC images must never be uploaded here \u2013 use external IDs only.\n\t *\n\t * @param obj\n\t */\n\tprivate async onMessage(obj: ioBroker.Message): Promise<void> {\n\t\tif (!obj?.command) {\n\t\t\treturn;\n\t\t}\n\n\t\ttry {\n\t\t\tif (obj.command === \"syncPictogramTable\") {\n\t\t\t\tawait this.ensurePictogramStore();\n\t\t\t\tconst rows = await this.buildCustomPictogramRows();\n\t\t\t\tawait this.patchInstanceNativeIfChanged({ customPictograms: rows });\n\t\t\t\tthis.config.customPictograms = rows;\n\t\t\t\tawait this.publishPictogramLibrary();\n\t\t\t\tthis.reply(obj, { ok: true, native: { customPictograms: rows } });\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (obj.command === \"syncWeeklyPlansTable\") {\n\t\t\t\tconst nativeMsg = obj.message as {\n\t\t\t\t\tweeklyPlanRows?: Array<{ id?: string; name?: string; active?: string }>;\n\t\t\t\t};\n\t\t\t\tif (Array.isArray(nativeMsg?.weeklyPlanRows)) {\n\t\t\t\t\tthis.config.weeklyPlanRows = nativeMsg.weeklyPlanRows;\n\t\t\t\t\tawait this.applyWeeklyPlanRowsFromConfig();\n\t\t\t\t}\n\t\t\t\tawait this.syncWeeklyPlansTableToNative();\n\t\t\t\tconst library = await this.getWeeklyPlansLibrary();\n\t\t\t\tthis.reply(obj, {\n\t\t\t\t\tok: true,\n\t\t\t\t\tnative: { weeklyPlanRows: this.config.weeklyPlanRows || [] },\n\t\t\t\t\tactiveId: library.activeId,\n\t\t\t\t});\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (obj.command === \"uploadPictogram\") {\n\t\t\t\tconst payload = obj.message as {\n\t\t\t\t\tfilename?: string;\n\t\t\t\t\tbase64?: string;\n\t\t\t\t\tmime?: string;\n\t\t\t\t\tlabel?: string;\n\t\t\t\t\ttags?: string[] | string;\n\t\t\t\t};\n\t\t\t\tconst originalName = String(payload?.filename || \"image.png\");\n\t\t\t\tconst filename = uniquePictogramFilename(originalName);\n\t\t\t\tconst base64 = String(payload?.base64 || \"\");\n\t\t\t\tif (!base64) {\n\t\t\t\t\tthrow new Error(\"filename and base64 required\");\n\t\t\t\t}\n\t\t\t\tif (!/\\.(png|jpe?g|gif|webp|svg)$/i.test(filename)) {\n\t\t\t\t\tthrow new Error(\"unsupported file type\");\n\t\t\t\t}\n\t\t\t\tconst buffer = Buffer.from(base64.replace(/^data:[^;]+;base64,/, \"\"), \"base64\");\n\t\t\t\tif (!buffer.length) {\n\t\t\t\t\tthrow new Error(\"empty file\");\n\t\t\t\t}\n\t\t\t\tif (buffer.length > 5 * 1024 * 1024) {\n\t\t\t\t\tthrow new Error(\"file too large (max 5 MB)\");\n\t\t\t\t}\n\t\t\t\tconst path = pictogramStoragePath(filename);\n\t\t\t\tawait this.writeFileAsync(PICTOGRAM_FILE_ADAPTER, path, buffer);\n\t\t\t\tconst library = await this.getMergedPictogramLibrary();\n\t\t\t\tconst entry: CustomPictogram = {\n\t\t\t\t\tid: filename,\n\t\t\t\t\tfilename,\n\t\t\t\t\tpath,\n\t\t\t\t\tlabel: String(payload?.label || originalName.replace(/\\.[^.]+$/, \"\")),\n\t\t\t\t\ttags: normalizeTags(payload?.tags),\n\t\t\t\t\toriginalName,\n\t\t\t\t\tmime: String(payload?.mime || \"\"),\n\t\t\t\t\tuploadedAt: Date.now(),\n\t\t\t\t};\n\t\t\t\tlibrary.items = [entry, ...library.items.filter(item => item.filename !== filename)];\n\t\t\t\tawait this.savePictogramLibrary(library);\n\t\t\t\tawait this.syncCustomPictogramsConfig();\n\t\t\t\tthis.log.info(`Custom pictogram stored: ${PICTOGRAM_FILE_ADAPTER}/${path} (${buffer.length} bytes)`);\n\t\t\t\tthis.reply(obj, {\n\t\t\t\t\tok: true,\n\t\t\t\t\tpath,\n\t\t\t\t\turl: pictogramPublicUrl(path),\n\t\t\t\t\titem: entry,\n\t\t\t\t\tlibrary,\n\t\t\t\t\tadapter: PICTOGRAM_FILE_ADAPTER,\n\t\t\t\t});\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (obj.command === \"listPictograms\") {\n\t\t\t\tconst library = await this.getPublishedPictogramLibrary();\n\t\t\t\tthis.reply(obj, {\n\t\t\t\t\tok: true,\n\t\t\t\t\tfiles: library.items.map(item => item.filename),\n\t\t\t\t\tlibrary,\n\t\t\t\t});\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (obj.command === \"updatePictogram\") {\n\t\t\t\tconst payload = obj.message as {\n\t\t\t\t\tpath?: string;\n\t\t\t\t\tfilename?: string;\n\t\t\t\t\tlabel?: string;\n\t\t\t\t\ttags?: string[] | string;\n\t\t\t\t};\n\t\t\t\tconst key = String(payload?.path || payload?.filename || \"\");\n\t\t\t\tif (!key) {\n\t\t\t\t\tthrow new Error(\"path required\");\n\t\t\t\t}\n\t\t\t\tconst library = await this.getMergedPictogramLibrary();\n\t\t\t\tconst item = library.items.find(entry => matchesPictogramKey(entry, key));\n\t\t\t\tif (!item) {\n\t\t\t\t\tthrow new Error(\"pictogram not found\");\n\t\t\t\t}\n\t\t\t\tif (payload.label !== undefined) {\n\t\t\t\t\titem.label = String(payload.label);\n\t\t\t\t}\n\t\t\t\tif (payload.tags !== undefined) {\n\t\t\t\t\titem.tags = normalizeTags(payload.tags);\n\t\t\t\t}\n\t\t\t\tawait this.savePictogramLibrary(library);\n\t\t\t\tthis.reply(obj, { ok: true, item, library });\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (obj.command === \"deletePictogram\") {\n\t\t\t\tconst payload = obj.message as { path?: string; filename?: string };\n\t\t\t\tconst key = String(payload?.path || payload?.filename || \"\");\n\t\t\t\tif (!key) {\n\t\t\t\t\tthrow new Error(\"path required\");\n\t\t\t\t}\n\t\t\t\tconst library = await this.getMergedPictogramLibrary();\n\t\t\t\tconst item = library.items.find(entry => matchesPictogramKey(entry, key));\n\t\t\t\tif (!item) {\n\t\t\t\t\tthrow new Error(\"pictogram not found\");\n\t\t\t\t}\n\t\t\t\ttry {\n\t\t\t\t\tawait this.unlinkAsync(PICTOGRAM_FILE_ADAPTER, item.path);\n\t\t\t\t} catch (error) {\n\t\t\t\t\tthis.log.warn(`Could not delete pictogram file ${item.path}: ${(error as Error).message}`);\n\t\t\t\t}\n\t\t\t\tlibrary.items = library.items.filter(entry => entry.filename !== item.filename);\n\t\t\t\tawait this.savePictogramLibrary(library);\n\t\t\t\tthis.reply(obj, { ok: true, library });\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tthis.log.error(`Pictogram command ${obj.command} failed: ${(error as Error).message}`);\n\t\t\tthis.reply(obj, { ok: false, error: (error as Error).message });\n\t\t}\n\t}\n\n\tprivate async applyDurationParts(\n\t\thours: number | undefined,\n\t\tminutes: number | undefined,\n\t\tmaxHours: number,\n\t): Promise<void> {\n\t\tif (!this.timerManager) {\n\t\t\treturn;\n\t\t}\n\t\tconst snapshot = this.timerManager.getSnapshot();\n\t\tconst current = secondsToParts(snapshot.duration);\n\t\tconst nextHours = hours ?? current.hours;\n\t\tconst nextMinutes = minutes ?? current.minutes;\n\t\tconst totalSeconds = nextHours * 3600 + nextMinutes * 60;\n\t\tawait this.timerManager.setDuration(totalSeconds, maxHours);\n\t}\n\n\tprivate onUnload(callback: () => void): void {\n\t\tif (this.scheduleTick !== undefined && this.scheduleTick !== null) {\n\t\t\tthis.clearInterval(this.scheduleTick);\n\t\t\tthis.scheduleTick = null;\n\t\t}\n\t\tthis.timerManager?.destroy();\n\t\tthis.timerManager = null;\n\t\tcallback();\n\t}\n}\n\nif (require.main !== module) {\n\tmodule.exports = (options: Partial<utils.AdapterOptions> | undefined) => new AutismSupport(options);\n} else {\n\t(() => new AutismSupport())();\n}\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;;AAIA,YAAuB;AACvB,2BAA6B;AAC7B,yBAKO;AACP,4BAA+F;AAC/F,+BAmBO;AACP,yBAaO;AAEP,MAAM,gBAAgB;AACtB,MAAM,mBAAmB;AAEzB,SAAS,iBAAiB,WAA2B;AACpD,SAAO,kBAAkB,SAAS;AACnC;AAEA,SAAS,gCAAgC,WAA2B;AACnE,SAAO,GAAG,SAAS,mBAAmB,SAAS;AAChD;AAEA,SAAS,mBAAmB,MAAe,OAAyB;AACnE,SAAO,KAAK,UAAU,sBAAQ,IAAI,MAAM,KAAK,UAAU,wBAAS,IAAI;AACrE;AAEA,SAAS,eAAe,cAA0D;AACjF,QAAM,OAAO,KAAK,IAAI,GAAG,KAAK,MAAM,YAAY,CAAC;AACjD,SAAO;AAAA,IACN,OAAO,KAAK,MAAM,OAAO,IAAI;AAAA,IAC7B,SAAS,KAAK,MAAO,OAAO,OAAQ,EAAE;AAAA,EACvC;AACD;AAEA,MAAM,sBAAsB,MAAM,QAAQ;AAAA,EACjC,eAAoC;AAAA,EACpC,eAAqD;AAAA,EACrD,aAAoC,CAAC;AAAA,EACrC,oBAA+B,4CAAwB,CAAC,CAA2B;AAAA,EACnF,qBAAwC;AAAA,EAEzC,YAAY,UAAyC,CAAC,GAAG;AAC/D,UAAM;AAAA,MACL,GAAG;AAAA,MACH,MAAM;AAAA,IACP,CAAC;AACD,SAAK,GAAG,SAAS,KAAK,QAAQ,KAAK,IAAI,CAAC;AACxC,SAAK,GAAG,eAAe,KAAK,cAAc,KAAK,IAAI,CAAC;AACpD,SAAK,GAAG,WAAW,KAAK,UAAU,KAAK,IAAI,CAAC;AAC5C,SAAK,GAAG,UAAU,KAAK,SAAS,KAAK,IAAI,CAAC;AAAA,EAC3C;AAAA,EAEA,MAAc,UAAyB;AAzFxC;AA0FE,QAAI;AACH,YAAM,YAAW,UAAK,OAAO,qBAAZ,YAAgC;AACjD,YAAM,iBAAiB,KAAK,0BAA0B,QAAQ;AAC9D,WAAK,iBAAa,yCAAqB,KAAK,MAAM;AAClD,WAAK,oBAAgB,4CAAwB,KAAK,MAAM;AAExD,YAAM,KAAK,+BAA+B;AAC1C,YAAM,KAAK,kBAAkB;AAC7B,YAAM,KAAK,qBAAqB;AAChC,YAAM,KAAK,2BAA2B;AACtC,YAAM,KAAK,qBAAqB;AAEhC,UAAI,MAAM,QAAQ,KAAK,OAAO,cAAc,KAAK,KAAK,OAAO,eAAe,SAAS,GAAG;AACvF,cAAM,KAAK,8BAA8B;AAAA,MAC1C;AACA,YAAM,KAAK,6BAA6B;AAExC,WAAK,eAAe,IAAI;AAAA,QACvB,OAAM,aAAY;AACjB,gBAAM,KAAK,qBAAqB,QAAQ;AAAA,QACzC;AAAA,QACA;AAAA,UACC,aAAa,CAAC,SAAS,OAAO,KAAK,YAAY,SAAS,EAAE;AAAA,UAC1D,eAAe,YAAU,KAAK,cAAc,MAA2B;AAAA,QACxE;AAAA,MACD;AAEA,YAAM,KAAK,aAAa,YAAY,gBAAgB,QAAQ;AAC5D,YAAM,KAAK,qBAAqB,KAAK,aAAa,YAAY,CAAC;AAC/D,YAAM,KAAK,uBAAuB;AAElC,WAAK,gBAAgB,GAAG,KAAK,SAAS,IAAI,aAAa,IAAI;AAC3D,WAAK,gBAAgB,GAAG,KAAK,SAAS,IAAI,gBAAgB,IAAI;AAE9D,WAAK,eAAe,KAAK,YAAY,MAAM;AAC1C,aAAK,KAAK,uBAAuB;AAAA,MAClC,GAAG,GAAM;AAET,WAAK,IAAI,KAAK,wEAAmE;AAAA,IAClF,SAAS,OAAO;AACf,WAAK,IAAI,MAAM,mBAAoB,MAAgB,OAAO,EAAE;AAC5D,YAAM;AAAA,IACP;AAAA,EACD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAc,6BACb,OACmB;AACnB,UAAM,KAAK,iBAAiB,KAAK,SAAS;AAC1C,UAAM,UAAU,MAAM,KAAK,sBAAsB,EAAE;AACnD,UAAM,iBAAiB,mCAAS,WAAU,CAAC;AAC3C,UAAM,aAA8C,CAAC;AACrD,QAAI,UAAU;AAEd,eAAW,OAAO,OAAO,KAAK,KAAK,GAAmD;AACrF,YAAM,QAAQ,MAAM,GAAG;AACvB,UAAI,UAAU,QAAW;AACxB;AAAA,MACD;AACA,UAAI,CAAC,mBAAmB,cAAc,GAAG,GAAG,KAAK,GAAG;AACnD,mBAAW,GAAG,IAAI;AAClB,kBAAU;AAAA,MACX;AAAA,IACD;AAEA,QAAI,CAAC,SAAS;AACb,aAAO;AAAA,IACR;AAEA,UAAM,KAAK,yBAAyB,IAAI,EAAE,QAAQ,WAAW,CAAC;AAC9D,WAAO;AAAA,EACR;AAAA,EAEQ,0BAA0B,UAA0B;AAxK7D;AAyKE,UAAM,QAAQ,KAAK,IAAI,UAAU,KAAK,IAAI,IAAG,UAAK,OAAO,yBAAZ,YAAoC,CAAC,CAAC;AACnF,UAAM,UAAU,KAAK,IAAI,IAAI,KAAK,IAAI,IAAG,UAAK,OAAO,2BAAZ,YAAsC,CAAC,CAAC;AACjF,UAAM,QAAQ,QAAQ,OAAO,UAAU;AACvC,WAAO,KAAK,IAAI,IAAI,KAAK,IAAI,WAAW,MAAM,KAAK,CAAC;AAAA,EACrD;AAAA,EAEA,MAAc,oBAAmC;AAChD,UAAM,KAAK,wBAAwB,eAAe;AAAA,MACjD,MAAM;AAAA,MACN,QAAQ,EAAE,MAAM,mBAAmB;AAAA,MACnC,QAAQ,CAAC;AAAA,IACV,CAAC;AAED,UAAM,SAYF;AAAA,MACH,UAAU;AAAA,QACT,MAAM;AAAA,QACN,MAAM;AAAA,QACN,MAAM;AAAA,QACN,MAAM;AAAA,QACN,OAAO;AAAA,QACP,MAAM;AAAA,QACN,KAAK;AAAA,QACL,KAAK;AAAA,MACN;AAAA,MACA,WAAW;AAAA,QACV,MAAM;AAAA,QACN,MAAM;AAAA,QACN,MAAM;AAAA,QACN,MAAM;AAAA,QACN,OAAO;AAAA,QACP,MAAM;AAAA,MACP;AAAA,MACA,SAAS;AAAA,QACR,MAAM;AAAA,QACN,MAAM;AAAA,QACN,MAAM;AAAA,QACN,MAAM;AAAA,QACN,OAAO;AAAA,QACP,MAAM;AAAA,MACP;AAAA,MACA,SAAS;AAAA,QACR,MAAM;AAAA,QACN,MAAM;AAAA,QACN,MAAM;AAAA,QACN,MAAM;AAAA,QACN,OAAO;AAAA,MACR;AAAA,MACA,QAAQ;AAAA,QACP,MAAM;AAAA,QACN,MAAM;AAAA,QACN,MAAM;AAAA,QACN,MAAM;AAAA,QACN,OAAO;AAAA,MACR;AAAA,MACA,UAAU;AAAA,QACT,MAAM;AAAA,QACN,MAAM;AAAA,QACN,MAAM;AAAA,QACN,MAAM;AAAA,QACN,OAAO;AAAA,MACR;AAAA,MACA,OAAO;AAAA,QACN,MAAM;AAAA,QACN,MAAM;AAAA,QACN,MAAM;AAAA,QACN,MAAM;AAAA,QACN,OAAO;AAAA,MACR;AAAA,MACA,OAAO;AAAA,QACN,MAAM;AAAA,QACN,MAAM;AAAA,QACN,MAAM;AAAA,QACN,MAAM;AAAA,QACN,OAAO;AAAA,MACR;AAAA,MACA,QAAQ;AAAA,QACP,MAAM;AAAA,QACN,MAAM;AAAA,QACN,MAAM;AAAA,QACN,MAAM;AAAA,QACN,OAAO;AAAA,MACR;AAAA,MACA,MAAM;AAAA,QACL,MAAM;AAAA,QACN,MAAM;AAAA,QACN,MAAM;AAAA,QACN,MAAM;AAAA,QACN,OAAO;AAAA,MACR;AAAA,MACA,kBAAkB;AAAA,QACjB,MAAM;AAAA,QACN,MAAM;AAAA,QACN,MAAM;AAAA,QACN,MAAM;AAAA,QACN,OAAO;AAAA,QACP,MAAM;AAAA,QACN,KAAK;AAAA,QACL,KAAK;AAAA,MACN;AAAA,MACA,oBAAoB;AAAA,QACnB,MAAM;AAAA,QACN,MAAM;AAAA,QACN,MAAM;AAAA,QACN,MAAM;AAAA,QACN,OAAO;AAAA,QACP,MAAM;AAAA,QACN,KAAK;AAAA,QACL,KAAK;AAAA,MACN;AAAA,IACD;AAEA,eAAW,CAAC,IAAI,GAAG,KAAK,OAAO,QAAQ,MAAM,GAAG;AAC/C,YAAM,KAAK,wBAAwB,GAAG,aAAa,IAAI,EAAE,IAAI;AAAA,QAC5D,MAAM;AAAA,QACN,QAAQ;AAAA,UACP,MAAM,IAAI;AAAA,UACV,MAAM,IAAI;AAAA,UACV,MAAM,IAAI;AAAA,UACV,MAAM,IAAI;AAAA,UACV,OAAO,IAAI;AAAA,UACX,MAAM,IAAI;AAAA,UACV,KAAK,IAAI;AAAA,UACT,KAAK,IAAI;AAAA,QACV;AAAA,QACA,QAAQ,CAAC;AAAA,MACV,CAAC;AAAA,IACF;AAEA,UAAM,KAAK,uBAAuB;AAAA,EACnC;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAc,iCAAgD;AAC7D,UAAM,WAAW,gCAAgC,KAAK,SAAS;AAC/D,UAAM,SAAS,MAAM,KAAK,eAAe,QAAQ;AACjD,QAAI,EAAC,iCAAQ,SAAQ;AACpB;AAAA,IACD;AAEA,UAAM,SAAS,OAAO;AAItB,UAAM,QAAyC,CAAC;AAChD,QAAI,MAAM,QAAQ,OAAO,gBAAgB,GAAG;AAC3C,YAAM,mBAAmB,OAAO;AAAA,IACjC;AACA,QAAI,MAAM,QAAQ,OAAO,cAAc,GAAG;AACzC,YAAM,iBAAiB,OAAO;AAAA,IAC/B;AACA,QAAI,OAAO,KAAK,KAAK,EAAE,QAAQ;AAC9B,YAAM,KAAK,6BAA6B,KAAK;AAC7C,UAAI,MAAM,kBAAkB;AAC3B,aAAK,OAAO,mBAAmB,MAAM;AAAA,MACtC;AACA,UAAI,MAAM,gBAAgB;AACzB,aAAK,OAAO,iBAAiB,MAAM;AAAA,MACpC;AACA,WAAK,IAAI,KAAK,yDAAyD,QAAQ,EAAE;AAAA,IAClF;AAEA,UAAM,KAAK,eAAe,QAAQ;AAClC,eAAW,YAAY,CAAC,GAAG,KAAK,SAAS,mBAAmB,GAAG,KAAK,SAAS,SAAS,GAAG;AACxF,UAAI;AACH,cAAM,KAAK,eAAe,QAAQ;AAAA,MACnC,QAAQ;AAAA,MAER;AAAA,IACD;AAAA,EACD;AAAA;AAAA,EAGA,MAAc,yBAAwC;AACrD,UAAM,UAA6D;AAAA,MAClE,UAAU,EAAE,MAAM,cAAc;AAAA,MAChC,WAAW,EAAE,MAAM,cAAc;AAAA,MACjC,SAAS,EAAE,MAAM,cAAc;AAAA,MAC/B,OAAO,EAAE,MAAM,MAAM;AAAA,MACrB,OAAO,EAAE,MAAM,MAAM;AAAA,MACrB,QAAQ,EAAE,MAAM,MAAM;AAAA,MACtB,MAAM,EAAE,MAAM,MAAM;AAAA,IACrB;AACA,eAAW,CAAC,IAAI,KAAK,KAAK,OAAO,QAAQ,OAAO,GAAG;AAClD,YAAM,SAAwC,CAAC;AAC/C,UAAI,MAAM,MAAM;AACf,eAAO,OAAO,MAAM;AAAA,MACrB;AACA,UAAI,MAAM,SAAS,QAAW;AAC7B,eAAO,OAAO,MAAM;AAAA,MACrB;AACA,YAAM,KAAK,kBAAkB,GAAG,aAAa,IAAI,EAAE,IAAI,EAAE,OAAO,CAAC;AAAA,IAClE;AAAA,EACD;AAAA,EAEA,MAAc,uBAAsC;AACnD,UAAM,KAAK,wBAAwB,kBAAkB;AAAA,MACpD,MAAM;AAAA,MACN,QAAQ,EAAE,MAAM,iBAAiB;AAAA,MACjC,QAAQ,CAAC;AAAA,IACV,CAAC;AAED,UAAM,KAAK,wBAAwB,GAAG,gBAAgB,SAAS;AAAA,MAC9D,MAAM;AAAA,MACN,QAAQ;AAAA,QACP,MAAM;AAAA,QACN,MAAM;AAAA,QACN,MAAM;AAAA,QACN,MAAM;AAAA,QACN,OAAO;AAAA,QACP,KAAK,KAAK,UAAU,EAAE,SAAS,GAAG,OAAO,CAAC,EAAE,CAAC;AAAA,MAC9C;AAAA,MACA,QAAQ,CAAC;AAAA,IACV,CAAC;AAED,UAAM,KAAK,wBAAwB,GAAG,gBAAgB,YAAY;AAAA,MACjE,MAAM;AAAA,MACN,QAAQ;AAAA,QACP,MAAM;AAAA,QACN,MAAM;AAAA,QACN,MAAM;AAAA,QACN,MAAM;AAAA,QACN,OAAO;AAAA,MACR;AAAA,MACA,QAAQ,CAAC;AAAA,IACV,CAAC;AAED,UAAM,KAAK,wBAAwB,GAAG,gBAAgB,oBAAoB;AAAA,MACzE,MAAM;AAAA,MACN,QAAQ;AAAA,QACP,MAAM;AAAA,QACN,MAAM;AAAA,QACN,MAAM;AAAA,QACN,MAAM;AAAA,QACN,OAAO;AAAA,QACP,KAAK;AAAA,MACN;AAAA,MACA,QAAQ,CAAC;AAAA,IACV,CAAC;AAED,UAAM,KAAK,wBAAwB,GAAG,gBAAgB,eAAe;AAAA,MACpE,MAAM;AAAA,MACN,QAAQ;AAAA,QACP,MAAM;AAAA,QACN,MAAM;AAAA,QACN,MAAM;AAAA,QACN,MAAM;AAAA,QACN,OAAO;AAAA,QACP,MAAM;AAAA,QACN,KAAK;AAAA,QACL,KAAK;AAAA,MACN;AAAA,MACA,QAAQ,CAAC;AAAA,IACV,CAAC;AAED,UAAM,KAAK,wBAAwB,GAAG,gBAAgB,kBAAkB;AAAA,MACvE,MAAM;AAAA,MACN,QAAQ;AAAA,QACP,MAAM;AAAA,QACN,MAAM;AAAA,QACN,MAAM;AAAA,QACN,MAAM;AAAA,QACN,OAAO;AAAA,MACR;AAAA,MACA,QAAQ,CAAC;AAAA,IACV,CAAC;AAED,UAAM,KAAK,wBAAwB,GAAG,gBAAgB,qBAAqB;AAAA,MAC1E,MAAM;AAAA,MACN,QAAQ;AAAA,QACP,MAAM;AAAA,QACN,MAAM;AAAA,QACN,MAAM;AAAA,QACN,MAAM;AAAA,QACN,OAAO;AAAA,QACP,KAAK;AAAA,MACN;AAAA,MACA,QAAQ,CAAC;AAAA,IACV,CAAC;AAED,UAAM,KAAK,wBAAwB,GAAG,gBAAgB,mBAAmB;AAAA,MACxE,MAAM;AAAA,MACN,QAAQ;AAAA,QACP,MAAM;AAAA,QACN,MAAM;AAAA,QACN,MAAM;AAAA,QACN,MAAM;AAAA,QACN,OAAO;AAAA,QACP,KAAK;AAAA,MACN;AAAA,MACA,QAAQ,CAAC;AAAA,IACV,CAAC;AAED,UAAM,KAAK,wBAAwB,GAAG,gBAAgB,qBAAqB;AAAA,MAC1E,MAAM;AAAA,MACN,QAAQ;AAAA,QACP,MAAM;AAAA,QACN,MAAM;AAAA,QACN,MAAM;AAAA,QACN,MAAM;AAAA,QACN,OAAO;AAAA,MACR;AAAA,MACA,QAAQ,CAAC;AAAA,IACV,CAAC;AAED,UAAM,KAAK,wBAAwB,GAAG,gBAAgB,eAAe;AAAA,MACpE,MAAM;AAAA,MACN,QAAQ;AAAA,QACP,MAAM;AAAA,QACN,MAAM;AAAA,QACN,MAAM;AAAA,QACN,MAAM;AAAA,QACN,OAAO;AAAA,QACP,KAAK,KAAK,cAAU,0CAAsB,CAAC;AAAA,MAC5C;AAAA,MACA,QAAQ,CAAC;AAAA,IACV,CAAC;AAED,UAAM,KAAK,wBAAwB,GAAG,gBAAgB,uBAAuB;AAAA,MAC5E,MAAM;AAAA,MACN,QAAQ;AAAA,QACP,MAAM;AAAA,QACN,MAAM;AAAA,QACN,MAAM;AAAA,QACN,MAAM;AAAA,QACN,OAAO;AAAA,QACP,KAAK,KAAK,UAAU,EAAE,SAAS,GAAG,UAAU,MAAM,OAAO,CAAC,EAAE,CAAC;AAAA,MAC9D;AAAA,MACA,QAAQ,CAAC;AAAA,IACV,CAAC;AAED,UAAM,KAAK,wBAAwB,GAAG,gBAAgB,wBAAwB;AAAA,MAC7E,MAAM;AAAA,MACN,QAAQ;AAAA,QACP,MAAM;AAAA,QACN,MAAM;AAAA,QACN,MAAM;AAAA,QACN,MAAM;AAAA,QACN,OAAO;AAAA,QACP,KAAK;AAAA,MACN;AAAA,MACA,QAAQ,CAAC;AAAA,IACV,CAAC;AAED,UAAM,KAAK,wBAAwB,GAAG,gBAAgB,kBAAkB;AAAA,MACvE,MAAM;AAAA,MACN,QAAQ;AAAA,QACP,MAAM;AAAA,QACN,MAAM;AAAA,QACN,MAAM;AAAA,QACN,MAAM;AAAA,QACN,OAAO;AAAA,MACR;AAAA,MACA,QAAQ,CAAC;AAAA,IACV,CAAC;AAED,UAAM,YAAY,MAAM,KAAK,cAAc,GAAG,gBAAgB,OAAO;AACrE,SAAI,uCAAW,QAAO,QAAQ,UAAU,QAAQ,IAAI;AACnD,YAAM,KAAK,SAAS,GAAG,gBAAgB,SAAS,KAAK,UAAU,EAAE,SAAS,GAAG,OAAO,CAAC,EAAE,CAAC,GAAG,IAAI;AAAA,IAChG;AACA,UAAM,iBAAiB,MAAM,KAAK,cAAc,GAAG,gBAAgB,kBAAkB;AACrF,SAAI,iDAAgB,QAAO,QAAQ,eAAe,QAAQ,IAAI;AAC7D,YAAM,KAAK,SAAS,GAAG,gBAAgB,oBAAoB,MAAM,IAAI;AAAA,IACtE;AACA,UAAM,kBAAkB,MAAM,KAAK,cAAc,GAAG,gBAAgB,iBAAiB;AACrF,SAAI,mDAAiB,QAAO,MAAM;AACjC,YAAM,KAAK,SAAS,GAAG,gBAAgB,mBAAmB,OAAO,IAAI;AAAA,IACtE;AACA,UAAM,iBAAiB,MAAM,KAAK,cAAc,GAAG,gBAAgB,sBAAsB;AACzF,SAAI,iDAAgB,QAAO,MAAM;AAChC,YAAM,KAAK,SAAS,GAAG,gBAAgB,wBAAwB,OAAO,IAAI;AAAA,IAC3E;AAEA,UAAM,cAAc,MAAM,KAAK,cAAc,GAAG,gBAAgB,aAAa;AAC7E,SAAI,2CAAa,QAAO,QAAQ,YAAY,QAAQ,IAAI;AACvD,YAAM,WAAO,yCAAkB,uCAAW,GAAG;AAC7C,YAAM,KAAK;AAAA,QACV,GAAG,gBAAgB;AAAA,QACnB,KAAK,cAAU,0CAAsB,KAAK,MAAM,SAAS,OAAO,MAAS,CAAC;AAAA,QAC1E;AAAA,MACD;AAAA,IACD;AACA,UAAM,eAAe,MAAM,KAAK,cAAc,GAAG,gBAAgB,qBAAqB;AACtF,SAAI,6CAAc,QAAO,QAAQ,aAAa,QAAQ,IAAI;AACzD,YAAM,KAAK;AAAA,QACV,GAAG,gBAAgB;AAAA,QACnB,KAAK,UAAU,EAAE,SAAS,GAAG,UAAU,MAAM,OAAO,CAAC,EAAE,CAAC;AAAA,QACxD;AAAA,MACD;AAAA,IACD;AAGA,UAAM,KAAK,SAAS,GAAG,gBAAgB,YAAY,KAAK,UAAU,KAAK,UAAU,GAAG,IAAI;AACxF,UAAM,KAAK,SAAS,GAAG,gBAAgB,kBAAkB,KAAK,UAAU,KAAK,aAAa,GAAG,IAAI;AACjG,UAAM,KAAK,wBAAwB;AAAA,EACpC;AAAA,EAEA,MAAc,2BAA0F;AACvG,UAAM,QAAQ,MAAM,KAAK,mBAAmB;AAC5C,eAAO,kDAAwB,SAAS,CAAC,GAAG,KAAK,OAAO,gBAAgB;AAAA,EACzE;AAAA,EAEA,MAAc,6BAA4C;AACzD,UAAM,OAAO,MAAM,KAAK,yBAAyB;AACjD,UAAM,KAAK,6BAA6B,EAAE,kBAAkB,KAAK,CAAC;AAClE,SAAK,OAAO,mBAAmB;AAC/B,UAAM,KAAK,wBAAwB;AAAA,EACpC;AAAA,EAEA,MAAc,uBAAsC;AACnD,QAAI;AACH,YAAM,KAAK,cAAc,KAAK,WAAW,6CAAoB;AAAA,IAC9D,QAAQ;AACP,UAAI;AACH,cAAM,KAAK;AAAA,UACV,KAAK;AAAA,UACL;AAAA,UACA,KAAK,cAAU,uCAAa,GAAG,MAAM,CAAC;AAAA,QACvC;AACA,aAAK,IAAI,KAAK,qCAAqC,KAAK,SAAS,IAAI,6CAAoB,EAAE;AAAA,MAC5F,SAAS,OAAO;AACf,aAAK,IAAI,MAAM,+CAAgD,MAAgB,OAAO,EAAE;AAAA,MACzF;AAAA,IACD;AAEA,QAAI;AACH,YAAM,SAAS,MAAM,KAAK,cAAc,iDAAwB,gDAAuB;AACvF,YAAM,MAAM,OAAO,OAAO,SAAS,WAAW,OAAO,OAAO,OAAO,KAAK,OAAO,IAAI,EAAE,SAAS,MAAM;AACpG,YAAM,eAAW,uCAAa,GAAG;AACjC,UAAI,SAAS,MAAM,QAAQ;AAC1B,cAAM,KAAK,eAAe,KAAK,WAAW,+CAAsB,KAAK,UAAU,UAAU,MAAM,CAAC,CAAC;AACjG,aAAK,IAAI,KAAK,4CAA4C,KAAK,SAAS,EAAE;AAAA,MAC3E;AAAA,IACD,QAAQ;AAAA,IAER;AAEA,QAAI;AACH,YAAM,KAAK,YAAY,iDAAwB,gDAAuB;AAAA,IACvE,QAAQ;AAAA,IAER;AAEA,QAAI;AACH,YAAM,OACL;AAGD,YAAM,kBAAkB,GAAG,sCAAa,IAAI,mDAA0B;AACtE,UAAI,aAAa;AACjB,UAAI;AACH,cAAM,WAAW,MAAM,KAAK,cAAc,iDAAwB,eAAe;AACjF,cAAM,UACL,OAAO,SAAS,SAAS,WAAW,SAAS,OAAO,OAAO,KAAK,SAAS,IAAI,EAAE,SAAS,MAAM;AAC/F,qBAAa,YAAY;AAAA,MAC1B,QAAQ;AAAA,MAER;AACA,UAAI,YAAY;AACf,cAAM,KAAK,eAAe,iDAAwB,iBAAiB,IAAI;AACvE,aAAK,IAAI,KAAK,kCAAkC,+CAAsB,IAAI,sCAAa,EAAE;AAAA,MAC1F;AAAA,IACD,SAAS,OAAO;AACf,WAAK,IAAI;AAAA,QACR,mBAAmB,+CAAsB,IAAI,sCAAa,IAAI,mDAA0B,KAAM,MAAgB,OAAO;AAAA,MACtH;AAAA,IACD;AAAA,EACD;AAAA,EAEA,MAAc,+BAA0D;AACvE,eAAO;AAAA,MACN,MAAM,KAAK,0BAA0B;AAAA,UACrC,gDAAsB,KAAK,OAAO,gBAAgB;AAAA,IACnD;AAAA,EACD;AAAA,EAEA,MAAc,0BAAyC;AACtD,UAAM,UAAU,MAAM,KAAK,6BAA6B;AACxD,UAAM,KAAK,SAAS,GAAG,gBAAgB,qBAAqB,KAAK,UAAU,OAAO,GAAG,IAAI;AAAA,EAC1F;AAAA,EAEA,MAAc,qBAAqB,UAOjB;AACjB,UAAM,KAAK,SAAS,GAAG,aAAa,aAAa,SAAS,UAAU,IAAI;AACxE,UAAM,KAAK,SAAS,GAAG,aAAa,cAAc,SAAS,WAAW,IAAI;AAC1E,UAAM,KAAK,SAAS,GAAG,aAAa,YAAY,SAAS,SAAS,IAAI;AACtE,UAAM,KAAK,SAAS,GAAG,aAAa,YAAY,SAAS,SAAS,IAAI;AACtE,UAAM,KAAK,SAAS,GAAG,aAAa,WAAW,SAAS,QAAQ,IAAI;AACpE,UAAM,KAAK,SAAS,GAAG,aAAa,aAAa,SAAS,UAAU,IAAI;AAAA,EACzE;AAAA,EAEA,MAAc,UAAiC;AAC9C,UAAM,QAAQ,MAAM,KAAK,cAAc,GAAG,gBAAgB,OAAO;AACjE,eAAO,yCAAkB,+BAAO,GAAG;AAAA,EACpC;AAAA,EAEA,MAAc,qBAAuD;AACpE,UAAM,QAAQ,MAAM,KAAK,cAAc,GAAG,gBAAgB,kBAAkB;AAC5E,QAAI;AACH,YAAM,MAAM,QAAO,+BAAO,SAAQ,WAAW,KAAK,MAAM,MAAM,GAAG,IAAI,+BAAO;AAC5E,aAAO,OAAO,OAAO,QAAQ,WAAY,MAAkC,CAAC;AAAA,IAC7E,QAAQ;AACP,aAAO,CAAC;AAAA,IACT;AAAA,EACD;AAAA,EAEA,MAAc,sBAAsD;AACnE,UAAM,YAAY,MAAM,KAAK,mBAAmB;AAChD,WAAO,KAAK,WAAW,IAAI,aAAW;AAAA,MACrC,GAAG;AAAA,MACH,SAAS,UAAU,OAAO,EAAE,MAAM,SAAY,OAAO,UAAU,QAAQ,UAAU,OAAO,EAAE,CAAC;AAAA,IAC5F,EAAE;AAAA,EACH;AAAA,EAEA,MAAc,gBAAyC;AACtD,UAAM,QAAQ,MAAM,KAAK,cAAc,GAAG,gBAAgB,aAAa;AACvE,eAAO,oCAAgB,+BAAO,GAAG;AAAA,EAClC;AAAA,EAEA,MAAc,wBAAqD;AAClE,UAAM,QAAQ,MAAM,KAAK,cAAc,GAAG,gBAAgB,qBAAqB;AAC/E,eAAO,4CAAwB,+BAAO,GAAG;AAAA,EAC1C;AAAA,EAEA,MAAc,+BAA8C;AAC3D,UAAM,UAAU,MAAM,KAAK,sBAAsB;AACjD,UAAM,WAAO,8CAA0B,OAAO;AAC9C,UAAM,KAAK,6BAA6B,EAAE,gBAAgB,KAAK,CAAC;AAChE,SAAK,OAAO,iBAAiB;AAAA,EAC9B;AAAA,EAEA,MAAc,gCAA+C;AAC5D,UAAM,UAAU,MAAM,KAAK,sBAAsB;AACjD,UAAM,WAAO,iDAA6B,SAAS,KAAK,OAAO,cAAc;AAC7E,QAAI,KAAK,UAAU,IAAI,MAAM,KAAK,UAAU,OAAO,GAAG;AACrD,YAAM,KAAK,SAAS,GAAG,gBAAgB,uBAAuB,KAAK,UAAU,IAAI,GAAG,IAAI;AAAA,IACzF;AAAA,EACD;AAAA,EAEA,MAAc,0BAAyC;AACtD,UAAM,YAAY,MAAM,KAAK,cAAc,GAAG,gBAAgB,sBAAsB;AACpF,QAAI,EAAC,uCAAW,MAAK;AACpB;AAAA,IACD;AACA,UAAM,cAAU,uCAAmB,oBAAI,KAAK,CAAC;AAC7C,UAAM,SAAS,MAAM,KAAK,cAAc;AACxC,UAAM,UAAU,OAAO,KAAK,OAAO;AACnC,UAAM,UAAU,MAAM,KAAK,QAAQ;AACnC,QAAI,KAAK,uBAAuB,eAAW,uCAAmB,SAAS,OAAO,GAAG;AAChF;AAAA,IACD;AACA,UAAM,KAAK,SAAS,GAAG,gBAAgB,SAAS,KAAK,UAAU,OAAO,GAAG,IAAI;AAC7E,SAAK,qBAAqB;AAC1B,SAAK,IAAI,MAAM,uCAAuC,OAAO,GAAG;AAAA,EACjE;AAAA,EAEA,MAAc,yBAAwC;AAzuBvD;AA0uBE,UAAM,KAAK,wBAAwB;AAEnC,UAAM,MAAM,oBAAI,KAAK;AACrB,UAAM,UAAU,IAAI,SAAS,IAAI,KAAK,IAAI,WAAW;AACrD,UAAM,UAAU,MAAM,KAAK,oBAAoB;AAC/C,UAAM,aAAS,sCAAkB,SAAS,OAAO;AACjD,QAAI,OAAO,MAAM,KAAK,QAAQ;AAE9B,UAAM,kBAAkB,MAAM,KAAK,cAAc,GAAG,gBAAgB,iBAAiB;AACrF,UAAM,iBAAiB,QAAQ,mDAAiB,GAAG;AACnD,QAAI,sBAAkB,0CAAmB,MAAM,SAAS,qCAAkB,GAAG;AAC5E,aAAO,EAAE,SAAS,GAAG,OAAO,CAAC,EAAE;AAC/B,YAAM,KAAK,SAAS,GAAG,gBAAgB,SAAS,KAAK,UAAU,IAAI,GAAG,IAAI;AAC1E,WAAK,IAAI,KAAK,gEAAgE;AAAA,IAC/E;AAEA,UAAM,gBAAY,4CAAqB,MAAM,SAAS,qCAAkB;AAGxE,UAAM,KAAK,SAAS,GAAG,gBAAgB,YAAY,KAAK,UAAU,KAAK,UAAU,GAAG,IAAI;AACxF,UAAM,KAAK,SAAS,GAAG,gBAAgB,kBAAkB,KAAK,UAAU,KAAK,aAAa,GAAG,IAAI;AACjG,UAAM,KAAK,SAAS,GAAG,gBAAgB,eAAe,SAAS,IAAI;AACnE,UAAM,KAAK,SAAS,GAAG,gBAAgB,mBAAkB,sCAAQ,OAAR,YAAc,IAAI,IAAI;AAC/E,UAAM,KAAK,SAAS,GAAG,gBAAgB,qBAAqB,WAAW,IAAI;AAAA,EAC5E;AAAA,EAEA,MAAc,cAAc,IAAY,OAAyD;AApwBlG;AAqwBE,QAAI,CAAC,SAAS,MAAM,KAAK;AACxB;AAAA,IACD;AAEA,QAAI,GAAG,WAAW,GAAG,KAAK,SAAS,IAAI,gBAAgB,GAAG,GAAG;AAC5D,YAAMA,WAAU,GAAG,QAAQ,GAAG,KAAK,SAAS,IAAI,gBAAgB,KAAK,EAAE;AACvE,UAAIA,aAAY,QAAQ;AACvB,cAAM,WAAO,yCAAkB,MAAM,GAAG;AACxC,cAAM,KAAK,SAAS,GAAG,gBAAgB,SAAS,KAAK,UAAU,IAAI,GAAG,IAAI;AAC1E,cAAM,KAAK,uBAAuB;AAAA,MACnC,WAAWA,aAAY,mBAAmB;AACzC,YAAI;AACH,gBAAM,MAAM,OAAO,MAAM,QAAQ,WAAW,KAAK,MAAM,OAAO,MAAM,GAAG,CAAC,IAAI,MAAM;AAClF,gBAAM,UAAU,OAAO,OAAO,QAAQ,WAAY,MAAkC,CAAC;AACrF,gBAAM,KAAK,SAAS,GAAG,gBAAgB,oBAAoB,KAAK,UAAU,OAAO,GAAG,IAAI;AACxF,gBAAM,KAAK,uBAAuB;AAAA,QACnC,SAAS,OAAO;AACf,eAAK,IAAI,MAAM,4BAA6B,MAAgB,OAAO,EAAE;AAAA,QACtE;AAAA,MACD,WAAWA,aAAY,kBAAkB;AACxC,cAAM,KAAK,SAAS,GAAG,gBAAgB,mBAAmB,QAAQ,MAAM,GAAG,GAAG,IAAI;AAClF,cAAM,KAAK,uBAAuB;AAAA,MACnC,WAAWA,aAAY,cAAc;AACpC,cAAM,aAAS,oCAAgB,MAAM,GAAG;AACxC,cAAM,KAAK,SAAS,GAAG,gBAAgB,eAAe,KAAK,UAAU,MAAM,GAAG,IAAI;AAClF,aAAK,qBAAqB;AAC1B,cAAM,KAAK,uBAAuB;AAAA,MACnC,WAAWA,aAAY,sBAAsB;AAC5C,cAAM,cAAU,4CAAwB,MAAM,GAAG;AACjD,cAAM,KAAK,SAAS,GAAG,gBAAgB,uBAAuB,KAAK,UAAU,OAAO,GAAG,IAAI;AAC3F,cAAM,KAAK,6BAA6B;AAAA,MACzC,WAAWA,aAAY,uBAAuB;AAC7C,cAAM,KAAK,SAAS,GAAG,gBAAgB,wBAAwB,QAAQ,MAAM,GAAG,GAAG,IAAI;AACvF,aAAK,qBAAqB;AAC1B,cAAM,KAAK,uBAAuB;AAAA,MACnC;AACA;AAAA,IACD;AAEA,QAAI,CAAC,KAAK,gBAAgB,CAAC,GAAG,WAAW,GAAG,KAAK,SAAS,IAAI,aAAa,GAAG,GAAG;AAChF;AAAA,IACD;AAEA,UAAM,UAAU,GAAG,QAAQ,GAAG,KAAK,SAAS,IAAI,aAAa,KAAK,EAAE;AACpE,UAAM,YAAW,UAAK,OAAO,qBAAZ,YAAgC;AAEjD,QAAI;AACH,cAAQ,SAAS;AAAA,QAChB,KAAK;AACJ,cAAI,MAAM,QAAQ,MAAM;AACvB,kBAAM,KAAK,aAAa,MAAM;AAAA,UAC/B;AACA,gBAAM,KAAK,SAAS,GAAG,aAAa,UAAU,OAAO,IAAI;AACzD;AAAA,QACD,KAAK;AACJ,cAAI,MAAM,QAAQ,MAAM;AACvB,kBAAM,KAAK,aAAa,MAAM;AAAA,UAC/B;AACA,gBAAM,KAAK,SAAS,GAAG,aAAa,UAAU,OAAO,IAAI;AACzD;AAAA,QACD,KAAK;AACJ,cAAI,MAAM,QAAQ,MAAM;AACvB,kBAAM,KAAK,aAAa,OAAO;AAAA,UAChC;AACA,gBAAM,KAAK,SAAS,GAAG,aAAa,WAAW,OAAO,IAAI;AAC1D;AAAA,QACD,KAAK;AACJ,cAAI,MAAM,QAAQ,MAAM;AACvB,kBAAM,KAAK,aAAa,KAAK;AAAA,UAC9B;AACA,gBAAM,KAAK,SAAS,GAAG,aAAa,SAAS,OAAO,IAAI;AACxD;AAAA,QACD,KAAK;AACJ,cAAI,OAAO,MAAM,QAAQ,UAAU;AAClC,kBAAM,KAAK,aAAa,YAAY,MAAM,KAAK,QAAQ;AAAA,UACxD;AACA;AAAA,QACD,KAAK;AACJ,cAAI,OAAO,MAAM,QAAQ,UAAU;AAClC,kBAAM,KAAK,mBAAmB,KAAK,MAAM,MAAM,GAAG,GAAG,QAAW,QAAQ;AAAA,UACzE;AACA,gBAAM,KAAK,SAAS,GAAG,aAAa,qBAAqB,GAAG,IAAI;AAChE;AAAA,QACD,KAAK;AACJ,cAAI,OAAO,MAAM,QAAQ,UAAU;AAClC,kBAAM,KAAK,mBAAmB,QAAW,KAAK,MAAM,MAAM,GAAG,GAAG,QAAQ;AAAA,UACzE;AACA,gBAAM,KAAK,SAAS,GAAG,aAAa,uBAAuB,GAAG,IAAI;AAClE;AAAA,QACD;AACC;AAAA,MACF;AAAA,IACD,SAAS,OAAO;AACf,WAAK,IAAI,MAAM,yBAAyB,OAAO,MAAO,MAAgB,OAAO,EAAE;AAAA,IAChF;AAAA,EACD;AAAA,EAEQ,MAAM,KAAuB,SAAwB;AAC5D,QAAI,IAAI,UAAU;AACjB,WAAK,OAAO,IAAI,MAAM,IAAI,SAAS,SAAS,IAAI,QAAQ;AAAA,IACzD;AAAA,EACD;AAAA,EAEA,MAAc,uBAAkD;AAC/D,QAAI;AACH,YAAM,OAAO,MAAM,KAAK,cAAc,KAAK,WAAW,6CAAoB;AAC1E,YAAM,MAAM,OAAO,KAAK,SAAS,WAAW,KAAK,OAAO,OAAO,KAAK,KAAK,IAAI,EAAE,SAAS,MAAM;AAC9F,iBAAO,uCAAa,GAAG;AAAA,IACxB,QAAQ;AACP,iBAAO,uCAAa;AAAA,IACrB;AAAA,EACD;AAAA,EAEA,MAAc,qBAAqB,SAA0C;AAC5E,UAAM,KAAK,eAAe,KAAK,WAAW,+CAAsB,KAAK,UAAU,SAAS,MAAM,CAAC,CAAC;AAChG,UAAM,KAAK,SAAS,GAAG,gBAAgB,qBAAqB,KAAK,UAAU,OAAO,GAAG,IAAI;AAAA,EAC1F;AAAA,EAEA,MAAc,qBAA+C;AAC5D,QAAI;AACH,YAAM,SAAS,MAAM,KAAK,aAAa,iDAAwB,sCAAa;AAC5E,cAAQ,UAAU,CAAC,GACjB,OAAO,WAAS,CAAC,MAAM,SAAS,KAAC,iDAAuB,MAAM,IAAI,CAAC,EACnE,IAAI,WAAS,MAAM,IAAI;AAAA,IAC1B,QAAQ;AACP,aAAO;AAAA,IACR;AAAA,EACD;AAAA,EAEA,MAAc,4BAAuD;AACpE,UAAM,UAAU,MAAM,KAAK,qBAAqB;AAChD,UAAM,QAAQ,MAAM,KAAK,mBAAmB;AAC5C,QAAI,CAAC,OAAO;AACX,aAAO;AAAA,IACR;AACA,UAAM,QAAQ,IAAI,IAAI,QAAQ,MAAM,IAAI,UAAQ,KAAK,QAAQ,CAAC;AAC9D,eAAW,YAAY,OAAO;AAC7B,UAAI,MAAM,IAAI,QAAQ,GAAG;AACxB;AAAA,MACD;AACA,cAAQ,MAAM,KAAK;AAAA,QAClB,IAAI;AAAA,QACJ;AAAA,QACA,UAAM,+CAAqB,QAAQ;AAAA,QACnC,OAAO,SAAS,QAAQ,YAAY,EAAE,EAAE,QAAQ,SAAS,EAAE;AAAA,QAC3D,MAAM,CAAC;AAAA,QACP,cAAc;AAAA,QACd,MAAM;AAAA,QACN,YAAY;AAAA,MACb,CAAC;AAAA,IACF;AACA,YAAQ,QAAQ,QAAQ,MAAM,OAAO,UAAQ,MAAM,SAAS,KAAK,QAAQ,CAAC;AAC1E,YAAQ,MAAM,KAAK,CAAC,GAAG,OAAO,EAAE,cAAc,MAAM,EAAE,cAAc,EAAE;AACtE,WAAO;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAc,UAAU,KAAsC;AAC7D,QAAI,EAAC,2BAAK,UAAS;AAClB;AAAA,IACD;AAEA,QAAI;AACH,UAAI,IAAI,YAAY,sBAAsB;AACzC,cAAM,KAAK,qBAAqB;AAChC,cAAM,OAAO,MAAM,KAAK,yBAAyB;AACjD,cAAM,KAAK,6BAA6B,EAAE,kBAAkB,KAAK,CAAC;AAClE,aAAK,OAAO,mBAAmB;AAC/B,cAAM,KAAK,wBAAwB;AACnC,aAAK,MAAM,KAAK,EAAE,IAAI,MAAM,QAAQ,EAAE,kBAAkB,KAAK,EAAE,CAAC;AAChE;AAAA,MACD;AAEA,UAAI,IAAI,YAAY,wBAAwB;AAC3C,cAAM,YAAY,IAAI;AAGtB,YAAI,MAAM,QAAQ,uCAAW,cAAc,GAAG;AAC7C,eAAK,OAAO,iBAAiB,UAAU;AACvC,gBAAM,KAAK,8BAA8B;AAAA,QAC1C;AACA,cAAM,KAAK,6BAA6B;AACxC,cAAM,UAAU,MAAM,KAAK,sBAAsB;AACjD,aAAK,MAAM,KAAK;AAAA,UACf,IAAI;AAAA,UACJ,QAAQ,EAAE,gBAAgB,KAAK,OAAO,kBAAkB,CAAC,EAAE;AAAA,UAC3D,UAAU,QAAQ;AAAA,QACnB,CAAC;AACD;AAAA,MACD;AAEA,UAAI,IAAI,YAAY,mBAAmB;AACtC,cAAM,UAAU,IAAI;AAOpB,cAAM,eAAe,QAAO,mCAAS,aAAY,WAAW;AAC5D,cAAM,eAAW,kDAAwB,YAAY;AACrD,cAAM,SAAS,QAAO,mCAAS,WAAU,EAAE;AAC3C,YAAI,CAAC,QAAQ;AACZ,gBAAM,IAAI,MAAM,8BAA8B;AAAA,QAC/C;AACA,YAAI,CAAC,+BAA+B,KAAK,QAAQ,GAAG;AACnD,gBAAM,IAAI,MAAM,uBAAuB;AAAA,QACxC;AACA,cAAM,SAAS,OAAO,KAAK,OAAO,QAAQ,uBAAuB,EAAE,GAAG,QAAQ;AAC9E,YAAI,CAAC,OAAO,QAAQ;AACnB,gBAAM,IAAI,MAAM,YAAY;AAAA,QAC7B;AACA,YAAI,OAAO,SAAS,IAAI,OAAO,MAAM;AACpC,gBAAM,IAAI,MAAM,2BAA2B;AAAA,QAC5C;AACA,cAAM,WAAO,+CAAqB,QAAQ;AAC1C,cAAM,KAAK,eAAe,iDAAwB,MAAM,MAAM;AAC9D,cAAM,UAAU,MAAM,KAAK,0BAA0B;AACrD,cAAM,QAAyB;AAAA,UAC9B,IAAI;AAAA,UACJ;AAAA,UACA;AAAA,UACA,OAAO,QAAO,mCAAS,UAAS,aAAa,QAAQ,YAAY,EAAE,CAAC;AAAA,UACpE,UAAM,wCAAc,mCAAS,IAAI;AAAA,UACjC;AAAA,UACA,MAAM,QAAO,mCAAS,SAAQ,EAAE;AAAA,UAChC,YAAY,KAAK,IAAI;AAAA,QACtB;AACA,gBAAQ,QAAQ,CAAC,OAAO,GAAG,QAAQ,MAAM,OAAO,UAAQ,KAAK,aAAa,QAAQ,CAAC;AACnF,cAAM,KAAK,qBAAqB,OAAO;AACvC,cAAM,KAAK,2BAA2B;AACtC,aAAK,IAAI,KAAK,4BAA4B,+CAAsB,IAAI,IAAI,KAAK,OAAO,MAAM,SAAS;AACnG,aAAK,MAAM,KAAK;AAAA,UACf,IAAI;AAAA,UACJ;AAAA,UACA,SAAK,6CAAmB,IAAI;AAAA,UAC5B,MAAM;AAAA,UACN;AAAA,UACA,SAAS;AAAA,QACV,CAAC;AACD;AAAA,MACD;AAEA,UAAI,IAAI,YAAY,kBAAkB;AACrC,cAAM,UAAU,MAAM,KAAK,6BAA6B;AACxD,aAAK,MAAM,KAAK;AAAA,UACf,IAAI;AAAA,UACJ,OAAO,QAAQ,MAAM,IAAI,UAAQ,KAAK,QAAQ;AAAA,UAC9C;AAAA,QACD,CAAC;AACD;AAAA,MACD;AAEA,UAAI,IAAI,YAAY,mBAAmB;AACtC,cAAM,UAAU,IAAI;AAMpB,cAAM,MAAM,QAAO,mCAAS,UAAQ,mCAAS,aAAY,EAAE;AAC3D,YAAI,CAAC,KAAK;AACT,gBAAM,IAAI,MAAM,eAAe;AAAA,QAChC;AACA,cAAM,UAAU,MAAM,KAAK,0BAA0B;AACrD,cAAM,OAAO,QAAQ,MAAM,KAAK,eAAS,8CAAoB,OAAO,GAAG,CAAC;AACxE,YAAI,CAAC,MAAM;AACV,gBAAM,IAAI,MAAM,qBAAqB;AAAA,QACtC;AACA,YAAI,QAAQ,UAAU,QAAW;AAChC,eAAK,QAAQ,OAAO,QAAQ,KAAK;AAAA,QAClC;AACA,YAAI,QAAQ,SAAS,QAAW;AAC/B,eAAK,WAAO,wCAAc,QAAQ,IAAI;AAAA,QACvC;AACA,cAAM,KAAK,qBAAqB,OAAO;AACvC,aAAK,MAAM,KAAK,EAAE,IAAI,MAAM,MAAM,QAAQ,CAAC;AAC3C;AAAA,MACD;AAEA,UAAI,IAAI,YAAY,mBAAmB;AACtC,cAAM,UAAU,IAAI;AACpB,cAAM,MAAM,QAAO,mCAAS,UAAQ,mCAAS,aAAY,EAAE;AAC3D,YAAI,CAAC,KAAK;AACT,gBAAM,IAAI,MAAM,eAAe;AAAA,QAChC;AACA,cAAM,UAAU,MAAM,KAAK,0BAA0B;AACrD,cAAM,OAAO,QAAQ,MAAM,KAAK,eAAS,8CAAoB,OAAO,GAAG,CAAC;AACxE,YAAI,CAAC,MAAM;AACV,gBAAM,IAAI,MAAM,qBAAqB;AAAA,QACtC;AACA,YAAI;AACH,gBAAM,KAAK,YAAY,iDAAwB,KAAK,IAAI;AAAA,QACzD,SAAS,OAAO;AACf,eAAK,IAAI,KAAK,mCAAmC,KAAK,IAAI,KAAM,MAAgB,OAAO,EAAE;AAAA,QAC1F;AACA,gBAAQ,QAAQ,QAAQ,MAAM,OAAO,WAAS,MAAM,aAAa,KAAK,QAAQ;AAC9E,cAAM,KAAK,qBAAqB,OAAO;AACvC,aAAK,MAAM,KAAK,EAAE,IAAI,MAAM,QAAQ,CAAC;AAAA,MACtC;AAAA,IACD,SAAS,OAAO;AACf,WAAK,IAAI,MAAM,qBAAqB,IAAI,OAAO,YAAa,MAAgB,OAAO,EAAE;AACrF,WAAK,MAAM,KAAK,EAAE,IAAI,OAAO,OAAQ,MAAgB,QAAQ,CAAC;AAAA,IAC/D;AAAA,EACD;AAAA,EAEA,MAAc,mBACb,OACA,SACA,UACgB;AAChB,QAAI,CAAC,KAAK,cAAc;AACvB;AAAA,IACD;AACA,UAAM,WAAW,KAAK,aAAa,YAAY;AAC/C,UAAM,UAAU,eAAe,SAAS,QAAQ;AAChD,UAAM,YAAY,wBAAS,QAAQ;AACnC,UAAM,cAAc,4BAAW,QAAQ;AACvC,UAAM,eAAe,YAAY,OAAO,cAAc;AACtD,UAAM,KAAK,aAAa,YAAY,cAAc,QAAQ;AAAA,EAC3D;AAAA,EAEQ,SAAS,UAA4B;AA5kC9C;AA6kCE,QAAI,KAAK,iBAAiB,UAAa,KAAK,iBAAiB,MAAM;AAClE,WAAK,cAAc,KAAK,YAAY;AACpC,WAAK,eAAe;AAAA,IACrB;AACA,eAAK,iBAAL,mBAAmB;AACnB,SAAK,eAAe;AACpB,aAAS;AAAA,EACV;AACD;AAEA,IAAI,QAAQ,SAAS,QAAQ;AAC5B,SAAO,UAAU,CAAC,YAAuD,IAAI,cAAc,OAAO;AACnG,OAAO;AACN,GAAC,MAAM,IAAI,cAAc,GAAG;AAC7B;",
6
6
  "names": ["localId"]
7
7
  }
package/io-package.json CHANGED
@@ -1,20 +1,33 @@
1
1
  {
2
2
  "common": {
3
3
  "name": "autism-support",
4
- "version": "0.2.5",
4
+ "version": "0.2.7",
5
5
  "news": {
6
- "0.2.5": {
7
- "en": "Fix system.adapter config path; trim news for ioBroker E1032 (CI release)",
8
- "de": "system.adapter-Konfig-Pfad repariert; News gekürzt für ioBroker E1032 (CI-Release)",
9
- "ru": "Исправлен путь system.adapter; news сокращены для E1032 (CI release)",
10
- "pt": "Corrigido caminho system.adapter; news reduzidas para E1032 (release CI)",
11
- "nl": "system.adapter-pad gerepareerd; news ingekort voor E1032 (CI-release)",
12
- "fr": "Chemin system.adapter corrigé ; news réduites pour E1032 (release CI)",
13
- "it": "Percorso system.adapter corretto; news ridotte per E1032 (release CI)",
14
- "es": "Ruta system.adapter corregida; news recortadas para E1032 (release CI)",
15
- "pl": "Naprawiono ścieżkę system.adapter; news skrócone dla E1032 (release CI)",
16
- "uk": "Виправлено шлях system.adapter; news скорочено для E1032 (CI release)",
17
- "zh-cn": "修复 system.adapter 路径;精简 news 以通过 E1032(CI 发布)"
6
+ "0.2.7": {
7
+ "en": "Fix restart loop (native config diff) and CI lint formatting",
8
+ "de": "Neustart-Schleife behoben (native Diff) und CI-Lint-Formatierung",
9
+ "ru": "Исправлен цикл перезапуска (diff native) и форматирование CI lint",
10
+ "pt": "Corrigido loop de reinício (diff native) e formatação CI lint",
11
+ "nl": "Herstart-lus opgelost (native diff) en CI lint-opmaak",
12
+ "fr": "Boucle redémarrage corrigée (diff native) et formatage CI lint",
13
+ "it": "Corretto loop riavvio (diff native) e formattazione CI lint",
14
+ "es": "Corregido bucle reinicio (diff native) y formato CI lint",
15
+ "pl": "Naprawiono pętlę restartu (diff native) i formatowanie CI lint",
16
+ "uk": "Виправлено цикл перезапуску (diff native) і форматування CI lint",
17
+ "zh-cn": "修复重启循环(native diff)及 CI lint 格式"
18
+ },
19
+ "0.2.6": {
20
+ "en": "Fix restart loop: only write system.adapter native config when data changed",
21
+ "de": "Neustart-Schleife behoben: system.adapter native nur bei Änderung schreiben",
22
+ "ru": "Исправлен цикл перезапуска: запись native system.adapter только при изменениях",
23
+ "pt": "Corrigido loop de reinício: grava native system.adapter só quando alterado",
24
+ "nl": "Herstart-lus opgelost: system.adapter native alleen schrijven bij wijziging",
25
+ "fr": "Boucle de redémarrage corrigée : native system.adapter écrit seulement si modifié",
26
+ "it": "Corretto loop di riavvio: native system.adapter scritto solo se modificato",
27
+ "es": "Corregido bucle de reinicio: native system.adapter solo si cambió",
28
+ "pl": "Naprawiono pętlę restartu: zapis native system.adapter tylko przy zmianie",
29
+ "uk": "Виправлено цикл перезапуску: native system.adapter лише при зміні",
30
+ "zh-cn": "修复重启循环:仅在数据变更时写入 system.adapter native"
18
31
  },
19
32
  "0.2.4": {
20
33
  "en": "Fix instance config path: use extendForeignObject for system.adapter (remove misplaced object)",
@@ -80,19 +93,6 @@
80
93
  "pl": "Zgodność ioBroker: skrócone news, jsonConfig, i18n; gotowy do sprawdzenia",
81
94
  "uk": "Відповідність ioBroker: скорочені news, jsonConfig, i18n; готовність до перевірки",
82
95
  "zh-cn": "ioBroker 合规:精简 news、jsonConfig、i18n;适配器检查就绪"
83
- },
84
- "0.1.26": {
85
- "en": "Config: new pictogram continues after selected; duplicate with max 3 parallel",
86
- "de": "Config: neues Piktogramm schließt an Auswahl an; Duplizieren max. 3 parallel",
87
- "ru": "Config: новый пиктограмма после выбранного; дубликат макс. 3 параллельно",
88
- "pt": "Config: novo pictograma após o selecionado; duplicar com máx. 3 em paralelo",
89
- "nl": "Config: nieuw pictogram na selectie; dupliceren max. 3 parallel",
90
- "fr": "Config : nouveau pictogramme après la sélection ; dupliquer max. 3 en parallèle",
91
- "it": "Config: nuovo pittogramma dopo la selezione; duplica max 3 in parallelo",
92
- "es": "Config: nuevo pictograma tras el seleccionado; duplicar con máx. 3 en paralelo",
93
- "pl": "Config: nowy piktogram po wybranym; duplikuj max. 3 równolegle",
94
- "uk": "Config: новий піктограм після вибраного; дублювання макс. 3 паралельно",
95
- "zh-cn": "Config:新象形图接所选项之后;复制最多 3 个并行"
96
96
  }
97
97
  },
98
98
  "titleLang": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "iobroker.autism-support",
3
- "version": "0.2.5",
3
+ "version": "0.2.7",
4
4
  "description": "Unterstützung für Menschen mit Autismus: Visual Countdown, Bild-Ablaufpläne und Piktogramme",
5
5
  "author": {
6
6
  "name": "Matthias Ulrich",
@@ -1 +1 @@
1
- import"./index-Cg-LdPdj.js";const i={react:async()=>await import("./_virtual_mf___mfe_internal__vis2AutismSupportWidgets__mf_owner__1__loadShare__react__loadShare__.js-N44SxUJn.js").then(t=>t.w),"react/jsx-runtime":async()=>await import("./_virtual_mf___mfe_internal__vis2AutismSupportWidgets__mf_owner__1__loadShare__react_mf_1_jsx_mf_2_runtime__loadShare__.js-ClXoR1ZQ.js").then(t=>t.c),"react-dom":async()=>await import("./_virtual_mf___mfe_internal__vis2AutismSupportWidgets__mf_owner__1__loadShare__react_mf_2_dom__loadShare__.js-T5xrrjVP.js").then(t=>t.c),"@mui/material":async()=>await import("./_virtual_mf___mfe_internal__vis2AutismSupportWidgets__mf_owner__1__loadShare___mf_0_mui_mf_1_material__loadShare__.js-DB9x_eMJ.js").then(t=>t.a2),"@mui/icons-material":async()=>await import("./_virtual_mf___mfe_internal__vis2AutismSupportWidgets__mf_owner__1__loadShare___mf_0_mui_mf_1_icons_mf_2_material__loadShare__.js-CrkGlQnf.js").then(t=>t.al),"@iobroker/adapter-react-v5":async()=>await import("./_virtual_mf___mfe_internal__vis2AutismSupportWidgets__mf_owner__1__prebuild___mf_0_iobroker_mf_1_adapter_mf_2_react_mf_2_v5__prebuild__-CQlsFj2g.js")},o={react:{name:"react",version:"18.3.1",scope:["default"],loaded:!1,materialize:!0,eager:!1,from:"vis2AutismSupportWidgets",canLiveRebind:!0,async get(){o.react.loaded=!0;const{react:r}=i,e={...await r()};return e.__esModule!==!0&&Object.defineProperty(e,"__esModule",{value:!0,enumerable:!1}),function(){return e}},shareConfig:{singleton:!0,requiredVersion:"*",strictVersion:!1,eager:!1}},"react/jsx-runtime":{name:"react/jsx-runtime",version:"18.3.1",scope:["default"],loaded:!1,materialize:!0,eager:!1,from:"vis2AutismSupportWidgets",canLiveRebind:!0,async get(){o["react/jsx-runtime"].loaded=!0;const{"react/jsx-runtime":r}=i,e={...await r()};return e.__esModule!==!0&&Object.defineProperty(e,"__esModule",{value:!0,enumerable:!1}),function(){return e}},shareConfig:{singleton:!0,requiredVersion:"*",strictVersion:!1,eager:!1}},"react-dom":{name:"react-dom",version:"18.3.1",scope:["default"],loaded:!1,materialize:!0,eager:!1,from:"vis2AutismSupportWidgets",canLiveRebind:!0,async get(){o["react-dom"].loaded=!0;const{"react-dom":r}=i,e={...await r()};return e.__esModule!==!0&&Object.defineProperty(e,"__esModule",{value:!0,enumerable:!1}),function(){return e}},shareConfig:{singleton:!0,requiredVersion:"*",strictVersion:!1,eager:!1}},"@mui/material":{name:"@mui/material",version:"6.5.0",scope:["default"],loaded:!1,materialize:!0,eager:!1,from:"vis2AutismSupportWidgets",canLiveRebind:!0,async get(){o["@mui/material"].loaded=!0;const{"@mui/material":r}=i,e={...await r()};return e.__esModule!==!0&&Object.defineProperty(e,"__esModule",{value:!0,enumerable:!1}),function(){return e}},shareConfig:{singleton:!0,requiredVersion:"*",strictVersion:!1,eager:!1}},"@mui/icons-material":{name:"@mui/icons-material",version:"6.5.0",scope:["default"],loaded:!1,materialize:!0,eager:!1,from:"vis2AutismSupportWidgets",canLiveRebind:!0,async get(){o["@mui/icons-material"].loaded=!0;const{"@mui/icons-material":r}=i,e={...await r()};return e.__esModule!==!0&&Object.defineProperty(e,"__esModule",{value:!0,enumerable:!1}),function(){return e}},shareConfig:{singleton:!0,requiredVersion:"*",strictVersion:!1,eager:!1}},"@iobroker/adapter-react-v5":{name:"@iobroker/adapter-react-v5",version:"8.3.2",scope:["default"],loaded:!1,materialize:!0,eager:!1,from:"vis2AutismSupportWidgets",canLiveRebind:!0,async get(){o["@iobroker/adapter-react-v5"].loaded=!0;const{"@iobroker/adapter-react-v5":r}=i,e={...await r()};return e.__esModule!==!0&&Object.defineProperty(e,"__esModule",{value:!0,enumerable:!1}),function(){return e}},shareConfig:{singleton:!0,requiredVersion:"*",strictVersion:!1,eager:!1}}},u=[];export{u as usedRemotes,o as usedShared};
1
+ import"./index-Cg-LdPdj.js";const i={react:async()=>await import("./_virtual_mf___mfe_internal__vis2AutismSupportWidgets__mf_owner__1__loadShare__react__loadShare__.js-N44SxUJn.js").then(t=>t.w),"react/jsx-runtime":async()=>await import("./_virtual_mf___mfe_internal__vis2AutismSupportWidgets__mf_owner__1__loadShare__react_mf_1_jsx_mf_2_runtime__loadShare__.js-ClXoR1ZQ.js").then(t=>t.c),"react-dom":async()=>await import("./_virtual_mf___mfe_internal__vis2AutismSupportWidgets__mf_owner__1__loadShare__react_mf_2_dom__loadShare__.js-T5xrrjVP.js").then(t=>t.c),"@mui/material":async()=>await import("./_virtual_mf___mfe_internal__vis2AutismSupportWidgets__mf_owner__1__loadShare___mf_0_mui_mf_1_material__loadShare__.js-DB9x_eMJ.js").then(t=>t.a2),"@mui/icons-material":async()=>await import("./_virtual_mf___mfe_internal__vis2AutismSupportWidgets__mf_owner__1__loadShare___mf_0_mui_mf_1_icons_mf_2_material__loadShare__.js-CrkGlQnf.js").then(t=>t.al),"@iobroker/adapter-react-v5":async()=>await import("./_virtual_mf___mfe_internal__vis2AutismSupportWidgets__mf_owner__1__prebuild___mf_0_iobroker_mf_1_adapter_mf_2_react_mf_2_v5__prebuild__-D2Xh8SNd.js")},o={react:{name:"react",version:"18.3.1",scope:["default"],loaded:!1,materialize:!0,eager:!1,from:"vis2AutismSupportWidgets",canLiveRebind:!0,async get(){o.react.loaded=!0;const{react:r}=i,e={...await r()};return e.__esModule!==!0&&Object.defineProperty(e,"__esModule",{value:!0,enumerable:!1}),function(){return e}},shareConfig:{singleton:!0,requiredVersion:"*",strictVersion:!1,eager:!1}},"react/jsx-runtime":{name:"react/jsx-runtime",version:"18.3.1",scope:["default"],loaded:!1,materialize:!0,eager:!1,from:"vis2AutismSupportWidgets",canLiveRebind:!0,async get(){o["react/jsx-runtime"].loaded=!0;const{"react/jsx-runtime":r}=i,e={...await r()};return e.__esModule!==!0&&Object.defineProperty(e,"__esModule",{value:!0,enumerable:!1}),function(){return e}},shareConfig:{singleton:!0,requiredVersion:"*",strictVersion:!1,eager:!1}},"react-dom":{name:"react-dom",version:"18.3.1",scope:["default"],loaded:!1,materialize:!0,eager:!1,from:"vis2AutismSupportWidgets",canLiveRebind:!0,async get(){o["react-dom"].loaded=!0;const{"react-dom":r}=i,e={...await r()};return e.__esModule!==!0&&Object.defineProperty(e,"__esModule",{value:!0,enumerable:!1}),function(){return e}},shareConfig:{singleton:!0,requiredVersion:"*",strictVersion:!1,eager:!1}},"@mui/material":{name:"@mui/material",version:"6.5.0",scope:["default"],loaded:!1,materialize:!0,eager:!1,from:"vis2AutismSupportWidgets",canLiveRebind:!0,async get(){o["@mui/material"].loaded=!0;const{"@mui/material":r}=i,e={...await r()};return e.__esModule!==!0&&Object.defineProperty(e,"__esModule",{value:!0,enumerable:!1}),function(){return e}},shareConfig:{singleton:!0,requiredVersion:"*",strictVersion:!1,eager:!1}},"@mui/icons-material":{name:"@mui/icons-material",version:"6.5.0",scope:["default"],loaded:!1,materialize:!0,eager:!1,from:"vis2AutismSupportWidgets",canLiveRebind:!0,async get(){o["@mui/icons-material"].loaded=!0;const{"@mui/icons-material":r}=i,e={...await r()};return e.__esModule!==!0&&Object.defineProperty(e,"__esModule",{value:!0,enumerable:!1}),function(){return e}},shareConfig:{singleton:!0,requiredVersion:"*",strictVersion:!1,eager:!1}},"@iobroker/adapter-react-v5":{name:"@iobroker/adapter-react-v5",version:"8.3.2",scope:["default"],loaded:!1,materialize:!0,eager:!1,from:"vis2AutismSupportWidgets",canLiveRebind:!0,async get(){o["@iobroker/adapter-react-v5"].loaded=!0;const{"@iobroker/adapter-react-v5":r}=i,e={...await r()};return e.__esModule!==!0&&Object.defineProperty(e,"__esModule",{value:!0,enumerable:!1}),function(){return e}},shareConfig:{singleton:!0,requiredVersion:"*",strictVersion:!1,eager:!1}}},u=[];export{u as usedRemotes,o as usedShared};