iobroker.time-tracker 0.2.1 → 0.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -14
- package/build/lib/adapter/stateNames.js +520 -0
- package/build/lib/adapter/stateNames.js.map +7 -0
- package/build/lib/adapter/states.js +70 -114
- package/build/lib/adapter/states.js.map +2 -2
- package/io-package.json +14 -1
- package/package.json +1 -1
- package/www/sw.js.map +1 -1
package/README.md
CHANGED
|
@@ -305,6 +305,13 @@ local SQLite file, access is role-based, and every correction is written to an a
|
|
|
305
305
|
|
|
306
306
|
### **WORK IN PROGRESS**
|
|
307
307
|
|
|
308
|
+
### 0.2.2 (2026-09-20)
|
|
309
|
+
|
|
310
|
+
- (Alex) object structure check: every object name carries all **eleven languages** now (`E6001`) and the employee-id
|
|
311
|
+
command uses the role **`level`** instead of `value` (`E1011`). The names live in one place
|
|
312
|
+
(`src/lib/adapter/stateNames.ts`), a unit test keeps them complete, and existing installations receive the new
|
|
313
|
+
names on the next start (`extendObject`)
|
|
314
|
+
|
|
308
315
|
### 0.2.1 (2026-09-20)
|
|
309
316
|
|
|
310
317
|
- (Alex) `common.news` starts fresh after the rename: the new npm package `iobroker.time-tracker` only carries 0.2.0,
|
|
@@ -334,20 +341,6 @@ local SQLite file, access is role-based, and every correction is written to an a
|
|
|
334
341
|
with common.licenseInformation”). The field is removed again, `npm run test:package` is part of the release checklist
|
|
335
342
|
from now on, and `docs/entwicklung.md` records the rule
|
|
336
343
|
|
|
337
|
-
### 0.1.6 (2026-09-19)
|
|
338
|
-
|
|
339
|
-
- (Alex) admin: the raw instance settings show a readable label now — in the language of the display — with the
|
|
340
|
-
technical name in the small line below it, which is what the block promises. The labels are kept short enough that
|
|
341
|
-
the fields do not cut them off
|
|
342
|
-
- (Alex) admin: the block “All instance settings” is much shorter — three fields per line on a wide screen (two on a
|
|
343
|
-
tablet, one on a phone) and the time zone on a line of its own, because its value is the longest
|
|
344
|
-
- (Alex) **rules (automatic)**: the kind **“Clock in automatically”** joins them — an employee who is still missing at
|
|
345
|
-
the configured time gets a punch in (the rule keeps quiet when somebody is clocked in already). Migration 18 rebuilds
|
|
346
|
-
the rule table for the new kind and copies the run log first, because dropping the parent would take it with it
|
|
347
|
-
- (Alex) **holidays**: the seeded days are shown in the language of the display — each one carries a stable key
|
|
348
|
-
(`newYear`, `goodFriday`, …) and the app translates it; a day somebody added by hand keeps its own name
|
|
349
|
-
- (Alex) admin: the two “first start” hints are easier to read — they are rendered as HTML with a larger font
|
|
350
|
-
|
|
351
344
|
Older entries are kept in [`CHANGELOG_OLD.md`](CHANGELOG_OLD.md).
|
|
352
345
|
|
|
353
346
|
## Provenance
|
|
@@ -0,0 +1,520 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var stateNames_exports = {};
|
|
20
|
+
__export(stateNames_exports, {
|
|
21
|
+
STATE_NAMES: () => STATE_NAMES
|
|
22
|
+
});
|
|
23
|
+
module.exports = __toCommonJS(stateNames_exports);
|
|
24
|
+
const STATE_NAMES = {
|
|
25
|
+
/** Channel holding the employees */
|
|
26
|
+
usersChannel: {
|
|
27
|
+
en: "Employees",
|
|
28
|
+
de: "Mitarbeiter",
|
|
29
|
+
ru: "\u0421\u043E\u0442\u0440\u0443\u0434\u043D\u0438\u043A\u0438",
|
|
30
|
+
pt: "Funcion\xE1rios",
|
|
31
|
+
nl: "Medewerkers",
|
|
32
|
+
fr: "Employ\xE9s",
|
|
33
|
+
it: "Dipendenti",
|
|
34
|
+
es: "Empleados",
|
|
35
|
+
pl: "Pracownicy",
|
|
36
|
+
uk: "\u0421\u043F\u0456\u0432\u0440\u043E\u0431\u0456\u0442\u043D\u0438\u043A\u0438",
|
|
37
|
+
"zh-cn": "\u5458\u5DE5"
|
|
38
|
+
},
|
|
39
|
+
/** Channel of one employee */
|
|
40
|
+
employeeChannel: {
|
|
41
|
+
en: "Employee",
|
|
42
|
+
de: "Mitarbeiter",
|
|
43
|
+
ru: "\u0421\u043E\u0442\u0440\u0443\u0434\u043D\u0438\u043A",
|
|
44
|
+
pt: "Funcion\xE1rio",
|
|
45
|
+
nl: "Medewerker",
|
|
46
|
+
fr: "Employ\xE9",
|
|
47
|
+
it: "Dipendente",
|
|
48
|
+
es: "Empleado",
|
|
49
|
+
pl: "Pracownik",
|
|
50
|
+
uk: "\u0421\u043F\u0456\u0432\u0440\u043E\u0431\u0456\u0442\u043D\u0438\u043A",
|
|
51
|
+
"zh-cn": "\u5458\u5DE5"
|
|
52
|
+
},
|
|
53
|
+
/** Channel of the writable commands */
|
|
54
|
+
commandsChannel: {
|
|
55
|
+
en: "Commands",
|
|
56
|
+
de: "Befehle",
|
|
57
|
+
ru: "\u041A\u043E\u043C\u0430\u043D\u0434\u044B",
|
|
58
|
+
pt: "Comandos",
|
|
59
|
+
nl: "Opdrachten",
|
|
60
|
+
fr: "Commandes",
|
|
61
|
+
it: "Comandi",
|
|
62
|
+
es: "Comandos",
|
|
63
|
+
pl: "Polecenia",
|
|
64
|
+
uk: "\u041A\u043E\u043C\u0430\u043D\u0434\u0438",
|
|
65
|
+
"zh-cn": "\u547D\u4EE4"
|
|
66
|
+
},
|
|
67
|
+
/** Channel with the figures of the instance */
|
|
68
|
+
infoChannel: {
|
|
69
|
+
en: "Information",
|
|
70
|
+
de: "Information",
|
|
71
|
+
ru: "\u0418\u043D\u0444\u043E\u0440\u043C\u0430\u0446\u0438\u044F",
|
|
72
|
+
pt: "Informa\xE7\xE3o",
|
|
73
|
+
nl: "Informatie",
|
|
74
|
+
fr: "Informations",
|
|
75
|
+
it: "Informazioni",
|
|
76
|
+
es: "Informaci\xF3n",
|
|
77
|
+
pl: "Informacje",
|
|
78
|
+
uk: "\u0406\u043D\u0444\u043E\u0440\u043C\u0430\u0446\u0456\u044F",
|
|
79
|
+
"zh-cn": "\u4FE1\u606F"
|
|
80
|
+
},
|
|
81
|
+
/** Channel with the figures of the whole company */
|
|
82
|
+
companyChannel: {
|
|
83
|
+
en: "Company",
|
|
84
|
+
de: "Firma",
|
|
85
|
+
ru: "\u041A\u043E\u043C\u043F\u0430\u043D\u0438\u044F",
|
|
86
|
+
pt: "Empresa",
|
|
87
|
+
nl: "Bedrijf",
|
|
88
|
+
fr: "Entreprise",
|
|
89
|
+
it: "Azienda",
|
|
90
|
+
es: "Empresa",
|
|
91
|
+
pl: "Firma",
|
|
92
|
+
uk: "\u041A\u043E\u043C\u043F\u0430\u043D\u0456\u044F",
|
|
93
|
+
"zh-cn": "\u516C\u53F8"
|
|
94
|
+
},
|
|
95
|
+
/** Channel with the newest event of the instance */
|
|
96
|
+
eventsChannel: {
|
|
97
|
+
en: "Events",
|
|
98
|
+
de: "Ereignisse",
|
|
99
|
+
ru: "\u0421\u043E\u0431\u044B\u0442\u0438\u044F",
|
|
100
|
+
pt: "Eventos",
|
|
101
|
+
nl: "Gebeurtenissen",
|
|
102
|
+
fr: "\xC9v\xE9nements",
|
|
103
|
+
it: "Eventi",
|
|
104
|
+
es: "Eventos",
|
|
105
|
+
pl: "Zdarzenia",
|
|
106
|
+
uk: "\u041F\u043E\u0434\u0456\u0457",
|
|
107
|
+
"zh-cn": "\u4E8B\u4EF6"
|
|
108
|
+
},
|
|
109
|
+
/** Shown name of the employee */
|
|
110
|
+
displayName: {
|
|
111
|
+
en: "Name",
|
|
112
|
+
de: "Name",
|
|
113
|
+
ru: "\u0418\u043C\u044F",
|
|
114
|
+
pt: "Nome",
|
|
115
|
+
nl: "Naam",
|
|
116
|
+
fr: "Nom",
|
|
117
|
+
it: "Nome",
|
|
118
|
+
es: "Nombre",
|
|
119
|
+
pl: "Nazwa",
|
|
120
|
+
uk: "\u0406\u043C'\u044F",
|
|
121
|
+
"zh-cn": "\u59D3\u540D"
|
|
122
|
+
},
|
|
123
|
+
/** Writable presence of the employee (working time runs) */
|
|
124
|
+
userPresent: {
|
|
125
|
+
en: "Present (working time is running)",
|
|
126
|
+
de: "Anwesenheit (Arbeitszeit l\xE4uft)",
|
|
127
|
+
ru: "\u041F\u0440\u0438\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u0435 (\u0440\u0430\u0431\u043E\u0447\u0435\u0435 \u0432\u0440\u0435\u043C\u044F \u0438\u0434\u0451\u0442)",
|
|
128
|
+
pt: "Presente (o tempo de trabalho corre)",
|
|
129
|
+
nl: "Aanwezig (werktijd loopt)",
|
|
130
|
+
fr: "Pr\xE9sent (temps de travail en cours)",
|
|
131
|
+
it: "Presente (tempo di lavoro in corso)",
|
|
132
|
+
es: "Presente (tiempo de trabajo en curso)",
|
|
133
|
+
pl: "Obecno\u015B\u0107 (czas pracy trwa)",
|
|
134
|
+
uk: "\u041F\u0440\u0438\u0441\u0443\u0442\u043D\u0456\u0441\u0442\u044C (\u0440\u043E\u0431\u043E\u0447\u0438\u0439 \u0447\u0430\u0441 \u0456\u0434\u0435)",
|
|
135
|
+
"zh-cn": "\u5728\u5C97\uFF08\u5DE5\u4F5C\u65F6\u95F4\u8BA1\u65F6\u4E2D\uFF09"
|
|
136
|
+
},
|
|
137
|
+
/** True while the last punch of the day has no counterpart */
|
|
138
|
+
hasOpenEntry: {
|
|
139
|
+
en: "Punched in",
|
|
140
|
+
de: "Eingestempelt",
|
|
141
|
+
ru: "\u041F\u0440\u0438\u0445\u043E\u0434 \u043E\u0442\u043C\u0435\u0447\u0435\u043D",
|
|
142
|
+
pt: "Entrada registada",
|
|
143
|
+
nl: "Ingeklokt",
|
|
144
|
+
fr: "Pointage d'arriv\xE9e",
|
|
145
|
+
it: "Entrata registrata",
|
|
146
|
+
es: "Entrada registrada",
|
|
147
|
+
pl: "Zarejestrowane wej\u015Bcie",
|
|
148
|
+
uk: "\u0412\u0456\u0434\u043C\u0456\u0447\u0435\u043D\u043E \u043F\u0440\u0438\u0445\u0456\u0434",
|
|
149
|
+
"zh-cn": "\u5DF2\u7B7E\u5230"
|
|
150
|
+
},
|
|
151
|
+
/** Instant of the last punch */
|
|
152
|
+
lastPunch: {
|
|
153
|
+
en: "Last punch",
|
|
154
|
+
de: "Letzte Buchung",
|
|
155
|
+
ru: "\u041F\u043E\u0441\u043B\u0435\u0434\u043D\u044F\u044F \u043E\u0442\u043C\u0435\u0442\u043A\u0430",
|
|
156
|
+
pt: "\xDAltimo registo",
|
|
157
|
+
nl: "Laatste stempeling",
|
|
158
|
+
fr: "Dernier pointage",
|
|
159
|
+
it: "Ultima timbratura",
|
|
160
|
+
es: "\xDAltimo registro",
|
|
161
|
+
pl: "Ostatni wpis",
|
|
162
|
+
uk: "\u041E\u0441\u0442\u0430\u043D\u043D\u044F \u0432\u0456\u0434\u043C\u0456\u0442\u043A\u0430",
|
|
163
|
+
"zh-cn": "\u6700\u540E\u6253\u5361"
|
|
164
|
+
},
|
|
165
|
+
/** Net working time of today */
|
|
166
|
+
todayWorkedMinutes: {
|
|
167
|
+
en: "Worked today",
|
|
168
|
+
de: "Heute gearbeitet",
|
|
169
|
+
ru: "\u041E\u0442\u0440\u0430\u0431\u043E\u0442\u0430\u043D\u043E \u0441\u0435\u0433\u043E\u0434\u043D\u044F",
|
|
170
|
+
pt: "Trabalhado hoje",
|
|
171
|
+
nl: "Vandaag gewerkt",
|
|
172
|
+
fr: "Travaill\xE9 aujourd'hui",
|
|
173
|
+
it: "Lavorato oggi",
|
|
174
|
+
es: "Trabajado hoy",
|
|
175
|
+
pl: "Przepracowane dzi\u015B",
|
|
176
|
+
uk: "\u0412\u0456\u0434\u043F\u0440\u0430\u0446\u044C\u043E\u0432\u0430\u043D\u043E \u0441\u044C\u043E\u0433\u043E\u0434\u043D\u0456",
|
|
177
|
+
"zh-cn": "\u4ECA\u65E5\u5DF2\u5DE5\u4F5C"
|
|
178
|
+
},
|
|
179
|
+
/** Balance of today */
|
|
180
|
+
todayBalanceMinutes: {
|
|
181
|
+
en: "Balance today",
|
|
182
|
+
de: "Saldo heute",
|
|
183
|
+
ru: "\u0411\u0430\u043B\u0430\u043D\u0441 \u0437\u0430 \u0441\u0435\u0433\u043E\u0434\u043D\u044F",
|
|
184
|
+
pt: "Saldo de hoje",
|
|
185
|
+
nl: "Saldo vandaag",
|
|
186
|
+
fr: "Solde du jour",
|
|
187
|
+
it: "Saldo di oggi",
|
|
188
|
+
es: "Saldo de hoy",
|
|
189
|
+
pl: "Saldo dzisiaj",
|
|
190
|
+
uk: "\u0411\u0430\u043B\u0430\u043D\u0441 \u0437\u0430 \u0441\u044C\u043E\u0433\u043E\u0434\u043D\u0456",
|
|
191
|
+
"zh-cn": "\u4ECA\u65E5\u4F59\u989D"
|
|
192
|
+
},
|
|
193
|
+
/** Net working time of the current month */
|
|
194
|
+
monthWorkedMinutes: {
|
|
195
|
+
en: "Worked this month",
|
|
196
|
+
de: "Diesen Monat gearbeitet",
|
|
197
|
+
ru: "\u041E\u0442\u0440\u0430\u0431\u043E\u0442\u0430\u043D\u043E \u0437\u0430 \u043C\u0435\u0441\u044F\u0446",
|
|
198
|
+
pt: "Trabalhado este m\xEAs",
|
|
199
|
+
nl: "Deze maand gewerkt",
|
|
200
|
+
fr: "Travaill\xE9 ce mois",
|
|
201
|
+
it: "Lavorato questo mese",
|
|
202
|
+
es: "Trabajado este mes",
|
|
203
|
+
pl: "Przepracowane w tym miesi\u0105cu",
|
|
204
|
+
uk: "\u0412\u0456\u0434\u043F\u0440\u0430\u0446\u044C\u043E\u0432\u0430\u043D\u043E \u0446\u044C\u043E\u0433\u043E \u043C\u0456\u0441\u044F\u0446\u044F",
|
|
205
|
+
"zh-cn": "\u672C\u6708\u5DF2\u5DE5\u4F5C"
|
|
206
|
+
},
|
|
207
|
+
/** Balance of the current month */
|
|
208
|
+
monthBalanceMinutes: {
|
|
209
|
+
en: "Balance this month",
|
|
210
|
+
de: "Saldo diesen Monat",
|
|
211
|
+
ru: "\u0411\u0430\u043B\u0430\u043D\u0441 \u0437\u0430 \u043C\u0435\u0441\u044F\u0446",
|
|
212
|
+
pt: "Saldo deste m\xEAs",
|
|
213
|
+
nl: "Saldo deze maand",
|
|
214
|
+
fr: "Solde du mois",
|
|
215
|
+
it: "Saldo di questo mese",
|
|
216
|
+
es: "Saldo de este mes",
|
|
217
|
+
pl: "Saldo w tym miesi\u0105cu",
|
|
218
|
+
uk: "\u0411\u0430\u043B\u0430\u043D\u0441 \u0437\u0430 \u0446\u0435\u0439 \u043C\u0456\u0441\u044F\u0446\u044C",
|
|
219
|
+
"zh-cn": "\u672C\u6708\u4F59\u989D"
|
|
220
|
+
},
|
|
221
|
+
/** Balance of the current year */
|
|
222
|
+
yearBalanceMinutes: {
|
|
223
|
+
en: "Balance this year",
|
|
224
|
+
de: "Saldo dieses Jahr",
|
|
225
|
+
ru: "\u0411\u0430\u043B\u0430\u043D\u0441 \u0437\u0430 \u0433\u043E\u0434",
|
|
226
|
+
pt: "Saldo deste ano",
|
|
227
|
+
nl: "Saldo dit jaar",
|
|
228
|
+
fr: "Solde de l'ann\xE9e",
|
|
229
|
+
it: "Saldo di quest'anno",
|
|
230
|
+
es: "Saldo de este a\xF1o",
|
|
231
|
+
pl: "Saldo w tym roku",
|
|
232
|
+
uk: "\u0411\u0430\u043B\u0430\u043D\u0441 \u0437\u0430 \u0446\u0435\u0439 \u0440\u0456\u043A",
|
|
233
|
+
"zh-cn": "\u672C\u5E74\u4F59\u989D"
|
|
234
|
+
},
|
|
235
|
+
/** Punches waiting for a decision */
|
|
236
|
+
openConflicts: {
|
|
237
|
+
en: "Open conflicts",
|
|
238
|
+
de: "Offene Konflikte",
|
|
239
|
+
ru: "\u041E\u0442\u043A\u0440\u044B\u0442\u044B\u0435 \u043A\u043E\u043D\u0444\u043B\u0438\u043A\u0442\u044B",
|
|
240
|
+
pt: "Conflitos em aberto",
|
|
241
|
+
nl: "Openstaande conflicten",
|
|
242
|
+
fr: "Conflits en attente",
|
|
243
|
+
it: "Conflitti aperti",
|
|
244
|
+
es: "Conflictos abiertos",
|
|
245
|
+
pl: "Otwarte konflikty",
|
|
246
|
+
uk: "\u0412\u0456\u0434\u043A\u0440\u0438\u0442\u0456 \u043A\u043E\u043D\u0444\u043B\u0456\u043A\u0442\u0438",
|
|
247
|
+
"zh-cn": "\u672A\u89E3\u51B3\u7684\u51B2\u7A81"
|
|
248
|
+
},
|
|
249
|
+
/** Employee the punch commands apply to */
|
|
250
|
+
punchUserId: {
|
|
251
|
+
en: "Employee id for punch commands",
|
|
252
|
+
de: "Mitarbeiter-Id f\xFCr Stempelbefehle",
|
|
253
|
+
ru: "\u0418\u0434\u0435\u043D\u0442\u0438\u0444\u0438\u043A\u0430\u0442\u043E\u0440 \u0441\u043E\u0442\u0440\u0443\u0434\u043D\u0438\u043A\u0430 \u0434\u043B\u044F \u043A\u043E\u043C\u0430\u043D\u0434",
|
|
254
|
+
pt: "ID do funcion\xE1rio para comandos",
|
|
255
|
+
nl: "Medewerker-id voor opdrachten",
|
|
256
|
+
fr: "Identifiant de l'employ\xE9 pour les commandes",
|
|
257
|
+
it: "ID del dipendente per i comandi",
|
|
258
|
+
es: "ID del empleado para comandos",
|
|
259
|
+
pl: "Identyfikator pracownika dla polece\u0144",
|
|
260
|
+
uk: "\u0406\u0434\u0435\u043D\u0442\u0438\u0444\u0456\u043A\u0430\u0442\u043E\u0440 \u0441\u043F\u0456\u0432\u0440\u043E\u0431\u0456\u0442\u043D\u0438\u043A\u0430 \u0434\u043B\u044F \u043A\u043E\u043C\u0430\u043D\u0434",
|
|
261
|
+
"zh-cn": "\u6253\u5361\u547D\u4EE4\u7684\u5458\u5DE5 ID"
|
|
262
|
+
},
|
|
263
|
+
/** Button: punch in or out */
|
|
264
|
+
punch: {
|
|
265
|
+
en: "Punch in or out",
|
|
266
|
+
de: "Ein- oder ausstempeln",
|
|
267
|
+
ru: "\u041E\u0442\u043C\u0435\u0442\u0438\u0442\u044C\u0441\u044F (\u043F\u0440\u0438\u0445\u043E\u0434 \u0438\u043B\u0438 \u0443\u0445\u043E\u0434)",
|
|
268
|
+
pt: "Marcar entrada ou sa\xEDda",
|
|
269
|
+
nl: "In- of uitklokken",
|
|
270
|
+
fr: "Pointer l'arriv\xE9e ou le d\xE9part",
|
|
271
|
+
it: "Timbrare entrata o uscita",
|
|
272
|
+
es: "Fichar entrada o salida",
|
|
273
|
+
pl: "Zarejestruj wej\u015Bcie lub wyj\u015Bcie",
|
|
274
|
+
uk: "\u0412\u0456\u0434\u043C\u0456\u0442\u0438\u0442\u0438 \u043F\u0440\u0438\u0445\u0456\u0434 \u0430\u0431\u043E \u0432\u0438\u0445\u0456\u0434",
|
|
275
|
+
"zh-cn": "\u4E0A\u73ED\u6216\u4E0B\u73ED\u6253\u5361"
|
|
276
|
+
},
|
|
277
|
+
/** Button: punch and round the time */
|
|
278
|
+
quickPunch: {
|
|
279
|
+
en: "Punch with quick rounding",
|
|
280
|
+
de: "Stempeln mit Schnellrundung",
|
|
281
|
+
ru: "\u041E\u0442\u043C\u0435\u0442\u0438\u0442\u044C\u0441\u044F \u0441 \u0431\u044B\u0441\u0442\u0440\u044B\u043C \u043E\u043A\u0440\u0443\u0433\u043B\u0435\u043D\u0438\u0435\u043C",
|
|
282
|
+
pt: "Marcar com arredondamento r\xE1pido",
|
|
283
|
+
nl: "Klokken met snelle afronding",
|
|
284
|
+
fr: "Pointer avec arrondi rapide",
|
|
285
|
+
it: "Timbrare con arrotondamento rapido",
|
|
286
|
+
es: "Fichar con redondeo r\xE1pido",
|
|
287
|
+
pl: "Zarejestruj z szybkim zaokr\u0105gleniem",
|
|
288
|
+
uk: "\u0412\u0456\u0434\u043C\u0456\u0442\u0438\u0442\u0438 \u0437\u0456 \u0448\u0432\u0438\u0434\u043A\u0438\u043C \u043E\u043A\u0440\u0443\u0433\u043B\u0435\u043D\u043D\u044F\u043C",
|
|
289
|
+
"zh-cn": "\u5FEB\u901F\u53D6\u6574\u6253\u5361"
|
|
290
|
+
},
|
|
291
|
+
/** Month to close */
|
|
292
|
+
closeMonth: {
|
|
293
|
+
en: "Close month (YYYY-MM)",
|
|
294
|
+
de: "Monat abschlie\xDFen (JJJJ-MM)",
|
|
295
|
+
ru: "\u0417\u0430\u043A\u0440\u044B\u0442\u044C \u043C\u0435\u0441\u044F\u0446 (\u0413\u0413\u0413\u0413-\u041C\u041C)",
|
|
296
|
+
pt: "Fechar m\xEAs (AAAA-MM)",
|
|
297
|
+
nl: "Maand afsluiten (JJJJ-MM)",
|
|
298
|
+
fr: "Cl\xF4turer le mois (AAAA-MM)",
|
|
299
|
+
it: "Chiudere il mese (AAAA-MM)",
|
|
300
|
+
es: "Cerrar mes (AAAA-MM)",
|
|
301
|
+
pl: "Zamknij miesi\u0105c (RRRR-MM)",
|
|
302
|
+
uk: "\u0417\u0430\u043A\u0440\u0438\u0442\u0438 \u043C\u0456\u0441\u044F\u0446\u044C (\u0420\u0420\u0420\u0420-\u041C\u041C)",
|
|
303
|
+
"zh-cn": "\u5173\u95ED\u6708\u4EFD\uFF08YYYY-MM\uFF09"
|
|
304
|
+
},
|
|
305
|
+
/** Period to recalculate */
|
|
306
|
+
recalc: {
|
|
307
|
+
en: "Recalculate period (YYYY-MM or YYYY)",
|
|
308
|
+
de: "Zeitraum neu berechnen (JJJJ-MM oder JJJJ)",
|
|
309
|
+
ru: "\u041F\u0435\u0440\u0435\u0441\u0447\u0438\u0442\u0430\u0442\u044C \u043F\u0435\u0440\u0438\u043E\u0434 (\u0413\u0413\u0413\u0413-\u041C\u041C \u0438\u043B\u0438 \u0413\u0413\u0413\u0413)",
|
|
310
|
+
pt: "Recalcular per\xEDodo (AAAA-MM ou AAAA)",
|
|
311
|
+
nl: "Periode opnieuw berekenen (JJJJ-MM of JJJJ)",
|
|
312
|
+
fr: "Recalculer la p\xE9riode (AAAA-MM ou AAAA)",
|
|
313
|
+
it: "Ricalcolare il periodo (AAAA-MM o AAAA)",
|
|
314
|
+
es: "Recalcular periodo (AAAA-MM o AAAA)",
|
|
315
|
+
pl: "Przelicz okres (RRRR-MM lub RRRR)",
|
|
316
|
+
uk: "\u041F\u0435\u0440\u0435\u0440\u0430\u0445\u0443\u0432\u0430\u0442\u0438 \u043F\u0435\u0440\u0456\u043E\u0434 (\u0420\u0420\u0420\u0420-\u041C\u041C \u0430\u0431\u043E \u0420\u0420\u0420\u0420)",
|
|
317
|
+
"zh-cn": "\u91CD\u65B0\u8BA1\u7B97\u671F\u95F4\uFF08YYYY-MM \u6216 YYYY\uFF09"
|
|
318
|
+
},
|
|
319
|
+
/** Button: write a database backup */
|
|
320
|
+
backupCommand: {
|
|
321
|
+
en: "Write a database backup",
|
|
322
|
+
de: "Datenbank-Sicherung schreiben",
|
|
323
|
+
ru: "\u0421\u043E\u0437\u0434\u0430\u0442\u044C \u0440\u0435\u0437\u0435\u0440\u0432\u043D\u0443\u044E \u043A\u043E\u043F\u0438\u044E \u0431\u0430\u0437\u044B",
|
|
324
|
+
pt: "Criar c\xF3pia de seguran\xE7a da base de dados",
|
|
325
|
+
nl: "Databasback-up maken",
|
|
326
|
+
fr: "Cr\xE9er une sauvegarde de la base",
|
|
327
|
+
it: "Creare un backup del database",
|
|
328
|
+
es: "Crear copia de seguridad de la base",
|
|
329
|
+
pl: "Utw\xF3rz kopi\u0119 zapasow\u0105 bazy",
|
|
330
|
+
uk: "\u0421\u0442\u0432\u043E\u0440\u0438\u0442\u0438 \u0440\u0435\u0437\u0435\u0440\u0432\u043D\u0443 \u043A\u043E\u043F\u0456\u044E \u0431\u0430\u0437\u0438",
|
|
331
|
+
"zh-cn": "\u5199\u5165\u6570\u636E\u5E93\u5907\u4EFD"
|
|
332
|
+
},
|
|
333
|
+
/** Version of the adapter */
|
|
334
|
+
version: {
|
|
335
|
+
en: "Adapter version",
|
|
336
|
+
de: "Adapter-Version",
|
|
337
|
+
ru: "\u0412\u0435\u0440\u0441\u0438\u044F \u0430\u0434\u0430\u043F\u0442\u0435\u0440\u0430",
|
|
338
|
+
pt: "Vers\xE3o do adaptador",
|
|
339
|
+
nl: "Adapterversie",
|
|
340
|
+
fr: "Version de l'adaptateur",
|
|
341
|
+
it: "Versione dell'adattatore",
|
|
342
|
+
es: "Versi\xF3n del adaptador",
|
|
343
|
+
pl: "Wersja adaptera",
|
|
344
|
+
uk: "\u0412\u0435\u0440\u0441\u0456\u044F \u0430\u0434\u0430\u043F\u0442\u0435\u0440\u0430",
|
|
345
|
+
"zh-cn": "\u9002\u914D\u5668\u7248\u672C"
|
|
346
|
+
},
|
|
347
|
+
/** Version of the database schema */
|
|
348
|
+
schemaVersion: {
|
|
349
|
+
en: "Database schema version",
|
|
350
|
+
de: "Datenbank-Schemaversion",
|
|
351
|
+
ru: "\u0412\u0435\u0440\u0441\u0438\u044F \u0441\u0445\u0435\u043C\u044B \u0431\u0430\u0437\u044B \u0434\u0430\u043D\u043D\u044B\u0445",
|
|
352
|
+
pt: "Vers\xE3o do esquema da base de dados",
|
|
353
|
+
nl: "Schemaversie van de database",
|
|
354
|
+
fr: "Version du sch\xE9ma de la base",
|
|
355
|
+
it: "Versione dello schema del database",
|
|
356
|
+
es: "Versi\xF3n del esquema de la base",
|
|
357
|
+
pl: "Wersja schematu bazy",
|
|
358
|
+
uk: "\u0412\u0435\u0440\u0441\u0456\u044F \u0441\u0445\u0435\u043C\u0438 \u0431\u0430\u0437\u0438 \u0434\u0430\u043D\u0438\u0445",
|
|
359
|
+
"zh-cn": "\u6570\u636E\u5E93\u67B6\u6784\u7248\u672C"
|
|
360
|
+
},
|
|
361
|
+
/** Size of the database file */
|
|
362
|
+
dbSizeBytes: {
|
|
363
|
+
en: "Database size",
|
|
364
|
+
de: "Datenbank-Gr\xF6\xDFe",
|
|
365
|
+
ru: "\u0420\u0430\u0437\u043C\u0435\u0440 \u0431\u0430\u0437\u044B \u0434\u0430\u043D\u043D\u044B\u0445",
|
|
366
|
+
pt: "Tamanho da base de dados",
|
|
367
|
+
nl: "Grootte van de database",
|
|
368
|
+
fr: "Taille de la base",
|
|
369
|
+
it: "Dimensione del database",
|
|
370
|
+
es: "Tama\xF1o de la base",
|
|
371
|
+
pl: "Rozmiar bazy",
|
|
372
|
+
uk: "\u0420\u043E\u0437\u043C\u0456\u0440 \u0431\u0430\u0437\u0438 \u0434\u0430\u043D\u0438\u0445",
|
|
373
|
+
"zh-cn": "\u6570\u636E\u5E93\u5927\u5C0F"
|
|
374
|
+
},
|
|
375
|
+
/** Last error of the instance */
|
|
376
|
+
lastError: {
|
|
377
|
+
en: "Last error",
|
|
378
|
+
de: "Letzter Fehler",
|
|
379
|
+
ru: "\u041F\u043E\u0441\u043B\u0435\u0434\u043D\u044F\u044F \u043E\u0448\u0438\u0431\u043A\u0430",
|
|
380
|
+
pt: "\xDAltimo erro",
|
|
381
|
+
nl: "Laatste fout",
|
|
382
|
+
fr: "Derni\xE8re erreur",
|
|
383
|
+
it: "Ultimo errore",
|
|
384
|
+
es: "\xDAltimo error",
|
|
385
|
+
pl: "Ostatni b\u0142\u0105d",
|
|
386
|
+
uk: "\u041E\u0441\u0442\u0430\u043D\u043D\u044F \u043F\u043E\u043C\u0438\u043B\u043A\u0430",
|
|
387
|
+
"zh-cn": "\u6700\u540E\u7684\u9519\u8BEF"
|
|
388
|
+
},
|
|
389
|
+
/** Instant of the last backup */
|
|
390
|
+
lastBackup: {
|
|
391
|
+
en: "Last backup",
|
|
392
|
+
de: "Letzte Sicherung",
|
|
393
|
+
ru: "\u041F\u043E\u0441\u043B\u0435\u0434\u043D\u044F\u044F \u0440\u0435\u0437\u0435\u0440\u0432\u043D\u0430\u044F \u043A\u043E\u043F\u0438\u044F",
|
|
394
|
+
pt: "\xDAltima c\xF3pia de seguran\xE7a",
|
|
395
|
+
nl: "Laatste back-up",
|
|
396
|
+
fr: "Derni\xE8re sauvegarde",
|
|
397
|
+
it: "Ultimo backup",
|
|
398
|
+
es: "\xDAltima copia de seguridad",
|
|
399
|
+
pl: "Ostatnia kopia zapasowa",
|
|
400
|
+
uk: "\u041E\u0441\u0442\u0430\u043D\u043D\u044F \u0440\u0435\u0437\u0435\u0440\u0432\u043D\u0430 \u043A\u043E\u043F\u0456\u044F",
|
|
401
|
+
"zh-cn": "\u6700\u540E\u7684\u5907\u4EFD"
|
|
402
|
+
},
|
|
403
|
+
/** Number of employees that are present */
|
|
404
|
+
companyPresentCount: {
|
|
405
|
+
en: "Present employees",
|
|
406
|
+
de: "Anwesende Mitarbeiter",
|
|
407
|
+
ru: "\u041F\u0440\u0438\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u044E\u0449\u0438\u0435 \u0441\u043E\u0442\u0440\u0443\u0434\u043D\u0438\u043A\u0438",
|
|
408
|
+
pt: "Funcion\xE1rios presentes",
|
|
409
|
+
nl: "Aanwezige medewerkers",
|
|
410
|
+
fr: "Employ\xE9s pr\xE9sents",
|
|
411
|
+
it: "Dipendenti presenti",
|
|
412
|
+
es: "Empleados presentes",
|
|
413
|
+
pl: "Obecni pracownicy",
|
|
414
|
+
uk: "\u041F\u0440\u0438\u0441\u0443\u0442\u043D\u0456 \u0441\u043F\u0456\u0432\u0440\u043E\u0431\u0456\u0442\u043D\u0438\u043A\u0438",
|
|
415
|
+
"zh-cn": "\u5728\u5C97\u5458\u5DE5"
|
|
416
|
+
},
|
|
417
|
+
/** Names of the employees that are present */
|
|
418
|
+
companyPresent: {
|
|
419
|
+
en: "Who is present",
|
|
420
|
+
de: "Wer ist anwesend",
|
|
421
|
+
ru: "\u041A\u0442\u043E \u043F\u0440\u0438\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442",
|
|
422
|
+
pt: "Quem est\xE1 presente",
|
|
423
|
+
nl: "Wie is aanwezig",
|
|
424
|
+
fr: "Qui est pr\xE9sent",
|
|
425
|
+
it: "Chi \xE8 presente",
|
|
426
|
+
es: "Qui\xE9n est\xE1 presente",
|
|
427
|
+
pl: "Kto jest obecny",
|
|
428
|
+
uk: "\u0425\u0442\u043E \u043F\u0440\u0438\u0441\u0443\u0442\u043D\u0456\u0439",
|
|
429
|
+
"zh-cn": "\u8C01\u5728\u5C97"
|
|
430
|
+
},
|
|
431
|
+
/** Instant of the newest punch of the company */
|
|
432
|
+
companyLastPunch: {
|
|
433
|
+
en: "Last punch",
|
|
434
|
+
de: "Letzte Buchung",
|
|
435
|
+
ru: "\u041F\u043E\u0441\u043B\u0435\u0434\u043D\u044F\u044F \u043E\u0442\u043C\u0435\u0442\u043A\u0430",
|
|
436
|
+
pt: "\xDAltimo registo",
|
|
437
|
+
nl: "Laatste stempeling",
|
|
438
|
+
fr: "Dernier pointage",
|
|
439
|
+
it: "Ultima timbratura",
|
|
440
|
+
es: "\xDAltimo registro",
|
|
441
|
+
pl: "Ostatni wpis",
|
|
442
|
+
uk: "\u041E\u0441\u0442\u0430\u043D\u043D\u044F \u0432\u0456\u0434\u043C\u0456\u0442\u043A\u0430",
|
|
443
|
+
"zh-cn": "\u6700\u540E\u6253\u5361"
|
|
444
|
+
},
|
|
445
|
+
/** Instant of the newest event */
|
|
446
|
+
lastAt: {
|
|
447
|
+
en: "Last event at",
|
|
448
|
+
de: "Letztes Ereignis um",
|
|
449
|
+
ru: "\u0412\u0440\u0435\u043C\u044F \u043F\u043E\u0441\u043B\u0435\u0434\u043D\u0435\u0433\u043E \u0441\u043E\u0431\u044B\u0442\u0438\u044F",
|
|
450
|
+
pt: "Hora do \xFAltimo evento",
|
|
451
|
+
nl: "Tijdstip laatste gebeurtenis",
|
|
452
|
+
fr: "Heure du dernier \xE9v\xE9nement",
|
|
453
|
+
it: "Ora dell'ultimo evento",
|
|
454
|
+
es: "Hora del \xFAltimo evento",
|
|
455
|
+
pl: "Czas ostatniego zdarzenia",
|
|
456
|
+
uk: "\u0427\u0430\u0441 \u043E\u0441\u0442\u0430\u043D\u043D\u044C\u043E\u0457 \u043F\u043E\u0434\u0456\u0457",
|
|
457
|
+
"zh-cn": "\u6700\u540E\u4E8B\u4EF6\u65F6\u95F4"
|
|
458
|
+
},
|
|
459
|
+
/** Kind of the newest event */
|
|
460
|
+
lastType: {
|
|
461
|
+
en: "Kind of the last event",
|
|
462
|
+
de: "Art des letzten Ereignisses",
|
|
463
|
+
ru: "\u0422\u0438\u043F \u043F\u043E\u0441\u043B\u0435\u0434\u043D\u0435\u0433\u043E \u0441\u043E\u0431\u044B\u0442\u0438\u044F",
|
|
464
|
+
pt: "Tipo do \xFAltimo evento",
|
|
465
|
+
nl: "Soort laatste gebeurtenis",
|
|
466
|
+
fr: "Type du dernier \xE9v\xE9nement",
|
|
467
|
+
it: "Tipo dell'ultimo evento",
|
|
468
|
+
es: "Tipo del \xFAltimo evento",
|
|
469
|
+
pl: "Rodzaj ostatniego zdarzenia",
|
|
470
|
+
uk: "\u0422\u0438\u043F \u043E\u0441\u0442\u0430\u043D\u043D\u044C\u043E\u0457 \u043F\u043E\u0434\u0456\u0457",
|
|
471
|
+
"zh-cn": "\u6700\u540E\u4E8B\u4EF6\u7C7B\u578B"
|
|
472
|
+
},
|
|
473
|
+
/** Employee of the newest event */
|
|
474
|
+
lastUser: {
|
|
475
|
+
en: "Employee of the last event",
|
|
476
|
+
de: "Mitarbeiter des letzten Ereignisses",
|
|
477
|
+
ru: "\u0421\u043E\u0442\u0440\u0443\u0434\u043D\u0438\u043A \u043F\u043E\u0441\u043B\u0435\u0434\u043D\u0435\u0433\u043E \u0441\u043E\u0431\u044B\u0442\u0438\u044F",
|
|
478
|
+
pt: "Funcion\xE1rio do \xFAltimo evento",
|
|
479
|
+
nl: "Medewerker van de laatste gebeurtenis",
|
|
480
|
+
fr: "Employ\xE9 du dernier \xE9v\xE9nement",
|
|
481
|
+
it: "Dipendente dell'ultimo evento",
|
|
482
|
+
es: "Empleado del \xFAltimo evento",
|
|
483
|
+
pl: "Pracownik ostatniego zdarzenia",
|
|
484
|
+
uk: "\u0421\u043F\u0456\u0432\u0440\u043E\u0431\u0456\u0442\u043D\u0438\u043A \u043E\u0441\u0442\u0430\u043D\u043D\u044C\u043E\u0457 \u043F\u043E\u0434\u0456\u0457",
|
|
485
|
+
"zh-cn": "\u6700\u540E\u4E8B\u4EF6\u7684\u5458\u5DE5"
|
|
486
|
+
},
|
|
487
|
+
/** Direction of the newest punch */
|
|
488
|
+
lastDirection: {
|
|
489
|
+
en: "Direction of the last punch",
|
|
490
|
+
de: "Richtung der letzten Buchung",
|
|
491
|
+
ru: "\u041D\u0430\u043F\u0440\u0430\u0432\u043B\u0435\u043D\u0438\u0435 \u043F\u043E\u0441\u043B\u0435\u0434\u043D\u0435\u0439 \u043E\u0442\u043C\u0435\u0442\u043A\u0438",
|
|
492
|
+
pt: "Dire\xE7\xE3o do \xFAltimo registo",
|
|
493
|
+
nl: "Richting van de laatste stempeling",
|
|
494
|
+
fr: "Sens du dernier pointage",
|
|
495
|
+
it: "Direzione dell'ultima timbratura",
|
|
496
|
+
es: "Direcci\xF3n del \xFAltimo registro",
|
|
497
|
+
pl: "Kierunek ostatniego wpisu",
|
|
498
|
+
uk: "\u041D\u0430\u043F\u0440\u044F\u043C\u043E\u043A \u043E\u0441\u0442\u0430\u043D\u043D\u044C\u043E\u0457 \u0432\u0456\u0434\u043C\u0456\u0442\u043A\u0438",
|
|
499
|
+
"zh-cn": "\u6700\u540E\u6253\u5361\u7684\u65B9\u5411"
|
|
500
|
+
},
|
|
501
|
+
/** Source of the newest event */
|
|
502
|
+
lastSource: {
|
|
503
|
+
en: "Source of the last event",
|
|
504
|
+
de: "Quelle des letzten Ereignisses",
|
|
505
|
+
ru: "\u0418\u0441\u0442\u043E\u0447\u043D\u0438\u043A \u043F\u043E\u0441\u043B\u0435\u0434\u043D\u0435\u0433\u043E \u0441\u043E\u0431\u044B\u0442\u0438\u044F",
|
|
506
|
+
pt: "Origem do \xFAltimo evento",
|
|
507
|
+
nl: "Bron van de laatste gebeurtenis",
|
|
508
|
+
fr: "Source du dernier \xE9v\xE9nement",
|
|
509
|
+
it: "Origine dell'ultimo evento",
|
|
510
|
+
es: "Origen del \xFAltimo evento",
|
|
511
|
+
pl: "\u0179r\xF3d\u0142o ostatniego zdarzenia",
|
|
512
|
+
uk: "\u0414\u0436\u0435\u0440\u0435\u043B\u043E \u043E\u0441\u0442\u0430\u043D\u043D\u044C\u043E\u0457 \u043F\u043E\u0434\u0456\u0457",
|
|
513
|
+
"zh-cn": "\u6700\u540E\u4E8B\u4EF6\u7684\u6765\u6E90"
|
|
514
|
+
}
|
|
515
|
+
};
|
|
516
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
517
|
+
0 && (module.exports = {
|
|
518
|
+
STATE_NAMES
|
|
519
|
+
});
|
|
520
|
+
//# sourceMappingURL=stateNames.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/lib/adapter/stateNames.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * Names of the adapter's objects, in the eleven languages ioBroker recommends (checker `E6001`).\n *\n * `states.ts` creates the tree; this module is the single place that carries the texts, so every name has the same\n * set of languages. `states.test.ts` walks the whole tree and fails when a name misses one of the eleven keys \u2014\n * that is how the recommendation stays satisfied without anyone remembering it.\n */\n\n/** One object name: the eleven languages the ioBroker checker recommends. */\nexport interface StateName {\n\t/** English */\n\ten: string;\n\t/** German */\n\tde: string;\n\t/** Russian */\n\tru: string;\n\t/** Portuguese */\n\tpt: string;\n\t/** Dutch */\n\tnl: string;\n\t/** French */\n\tfr: string;\n\t/** Italian */\n\tit: string;\n\t/** Spanish */\n\tes: string;\n\t/** Polish */\n\tpl: string;\n\t/** Ukrainian */\n\tuk: string;\n\t/** Chinese (simplified) */\n\t\"zh-cn\": string;\n}\n\n/** Object names of the adapter, grouped like the state tree. */\nexport const STATE_NAMES = {\n\t/** Channel holding the employees */\n\tusersChannel: {\n\t\ten: \"Employees\",\n\t\tde: \"Mitarbeiter\",\n\t\tru: \"\u0421\u043E\u0442\u0440\u0443\u0434\u043D\u0438\u043A\u0438\",\n\t\tpt: \"Funcion\u00E1rios\",\n\t\tnl: \"Medewerkers\",\n\t\tfr: \"Employ\u00E9s\",\n\t\tit: \"Dipendenti\",\n\t\tes: \"Empleados\",\n\t\tpl: \"Pracownicy\",\n\t\tuk: \"\u0421\u043F\u0456\u0432\u0440\u043E\u0431\u0456\u0442\u043D\u0438\u043A\u0438\",\n\t\t\"zh-cn\": \"\u5458\u5DE5\",\n\t},\n\t/** Channel of one employee */\n\temployeeChannel: {\n\t\ten: \"Employee\",\n\t\tde: \"Mitarbeiter\",\n\t\tru: \"\u0421\u043E\u0442\u0440\u0443\u0434\u043D\u0438\u043A\",\n\t\tpt: \"Funcion\u00E1rio\",\n\t\tnl: \"Medewerker\",\n\t\tfr: \"Employ\u00E9\",\n\t\tit: \"Dipendente\",\n\t\tes: \"Empleado\",\n\t\tpl: \"Pracownik\",\n\t\tuk: \"\u0421\u043F\u0456\u0432\u0440\u043E\u0431\u0456\u0442\u043D\u0438\u043A\",\n\t\t\"zh-cn\": \"\u5458\u5DE5\",\n\t},\n\t/** Channel of the writable commands */\n\tcommandsChannel: {\n\t\ten: \"Commands\",\n\t\tde: \"Befehle\",\n\t\tru: \"\u041A\u043E\u043C\u0430\u043D\u0434\u044B\",\n\t\tpt: \"Comandos\",\n\t\tnl: \"Opdrachten\",\n\t\tfr: \"Commandes\",\n\t\tit: \"Comandi\",\n\t\tes: \"Comandos\",\n\t\tpl: \"Polecenia\",\n\t\tuk: \"\u041A\u043E\u043C\u0430\u043D\u0434\u0438\",\n\t\t\"zh-cn\": \"\u547D\u4EE4\",\n\t},\n\t/** Channel with the figures of the instance */\n\tinfoChannel: {\n\t\ten: \"Information\",\n\t\tde: \"Information\",\n\t\tru: \"\u0418\u043D\u0444\u043E\u0440\u043C\u0430\u0446\u0438\u044F\",\n\t\tpt: \"Informa\u00E7\u00E3o\",\n\t\tnl: \"Informatie\",\n\t\tfr: \"Informations\",\n\t\tit: \"Informazioni\",\n\t\tes: \"Informaci\u00F3n\",\n\t\tpl: \"Informacje\",\n\t\tuk: \"\u0406\u043D\u0444\u043E\u0440\u043C\u0430\u0446\u0456\u044F\",\n\t\t\"zh-cn\": \"\u4FE1\u606F\",\n\t},\n\t/** Channel with the figures of the whole company */\n\tcompanyChannel: {\n\t\ten: \"Company\",\n\t\tde: \"Firma\",\n\t\tru: \"\u041A\u043E\u043C\u043F\u0430\u043D\u0438\u044F\",\n\t\tpt: \"Empresa\",\n\t\tnl: \"Bedrijf\",\n\t\tfr: \"Entreprise\",\n\t\tit: \"Azienda\",\n\t\tes: \"Empresa\",\n\t\tpl: \"Firma\",\n\t\tuk: \"\u041A\u043E\u043C\u043F\u0430\u043D\u0456\u044F\",\n\t\t\"zh-cn\": \"\u516C\u53F8\",\n\t},\n\t/** Channel with the newest event of the instance */\n\teventsChannel: {\n\t\ten: \"Events\",\n\t\tde: \"Ereignisse\",\n\t\tru: \"\u0421\u043E\u0431\u044B\u0442\u0438\u044F\",\n\t\tpt: \"Eventos\",\n\t\tnl: \"Gebeurtenissen\",\n\t\tfr: \"\u00C9v\u00E9nements\",\n\t\tit: \"Eventi\",\n\t\tes: \"Eventos\",\n\t\tpl: \"Zdarzenia\",\n\t\tuk: \"\u041F\u043E\u0434\u0456\u0457\",\n\t\t\"zh-cn\": \"\u4E8B\u4EF6\",\n\t},\n\t/** Shown name of the employee */\n\tdisplayName: {\n\t\ten: \"Name\",\n\t\tde: \"Name\",\n\t\tru: \"\u0418\u043C\u044F\",\n\t\tpt: \"Nome\",\n\t\tnl: \"Naam\",\n\t\tfr: \"Nom\",\n\t\tit: \"Nome\",\n\t\tes: \"Nombre\",\n\t\tpl: \"Nazwa\",\n\t\tuk: \"\u0406\u043C'\u044F\",\n\t\t\"zh-cn\": \"\u59D3\u540D\",\n\t},\n\t/** Writable presence of the employee (working time runs) */\n\tuserPresent: {\n\t\ten: \"Present (working time is running)\",\n\t\tde: \"Anwesenheit (Arbeitszeit l\u00E4uft)\",\n\t\tru: \"\u041F\u0440\u0438\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u0435 (\u0440\u0430\u0431\u043E\u0447\u0435\u0435 \u0432\u0440\u0435\u043C\u044F \u0438\u0434\u0451\u0442)\",\n\t\tpt: \"Presente (o tempo de trabalho corre)\",\n\t\tnl: \"Aanwezig (werktijd loopt)\",\n\t\tfr: \"Pr\u00E9sent (temps de travail en cours)\",\n\t\tit: \"Presente (tempo di lavoro in corso)\",\n\t\tes: \"Presente (tiempo de trabajo en curso)\",\n\t\tpl: \"Obecno\u015B\u0107 (czas pracy trwa)\",\n\t\tuk: \"\u041F\u0440\u0438\u0441\u0443\u0442\u043D\u0456\u0441\u0442\u044C (\u0440\u043E\u0431\u043E\u0447\u0438\u0439 \u0447\u0430\u0441 \u0456\u0434\u0435)\",\n\t\t\"zh-cn\": \"\u5728\u5C97\uFF08\u5DE5\u4F5C\u65F6\u95F4\u8BA1\u65F6\u4E2D\uFF09\",\n\t},\n\t/** True while the last punch of the day has no counterpart */\n\thasOpenEntry: {\n\t\ten: \"Punched in\",\n\t\tde: \"Eingestempelt\",\n\t\tru: \"\u041F\u0440\u0438\u0445\u043E\u0434 \u043E\u0442\u043C\u0435\u0447\u0435\u043D\",\n\t\tpt: \"Entrada registada\",\n\t\tnl: \"Ingeklokt\",\n\t\tfr: \"Pointage d'arriv\u00E9e\",\n\t\tit: \"Entrata registrata\",\n\t\tes: \"Entrada registrada\",\n\t\tpl: \"Zarejestrowane wej\u015Bcie\",\n\t\tuk: \"\u0412\u0456\u0434\u043C\u0456\u0447\u0435\u043D\u043E \u043F\u0440\u0438\u0445\u0456\u0434\",\n\t\t\"zh-cn\": \"\u5DF2\u7B7E\u5230\",\n\t},\n\t/** Instant of the last punch */\n\tlastPunch: {\n\t\ten: \"Last punch\",\n\t\tde: \"Letzte Buchung\",\n\t\tru: \"\u041F\u043E\u0441\u043B\u0435\u0434\u043D\u044F\u044F \u043E\u0442\u043C\u0435\u0442\u043A\u0430\",\n\t\tpt: \"\u00DAltimo registo\",\n\t\tnl: \"Laatste stempeling\",\n\t\tfr: \"Dernier pointage\",\n\t\tit: \"Ultima timbratura\",\n\t\tes: \"\u00DAltimo registro\",\n\t\tpl: \"Ostatni wpis\",\n\t\tuk: \"\u041E\u0441\u0442\u0430\u043D\u043D\u044F \u0432\u0456\u0434\u043C\u0456\u0442\u043A\u0430\",\n\t\t\"zh-cn\": \"\u6700\u540E\u6253\u5361\",\n\t},\n\t/** Net working time of today */\n\ttodayWorkedMinutes: {\n\t\ten: \"Worked today\",\n\t\tde: \"Heute gearbeitet\",\n\t\tru: \"\u041E\u0442\u0440\u0430\u0431\u043E\u0442\u0430\u043D\u043E \u0441\u0435\u0433\u043E\u0434\u043D\u044F\",\n\t\tpt: \"Trabalhado hoje\",\n\t\tnl: \"Vandaag gewerkt\",\n\t\tfr: \"Travaill\u00E9 aujourd'hui\",\n\t\tit: \"Lavorato oggi\",\n\t\tes: \"Trabajado hoy\",\n\t\tpl: \"Przepracowane dzi\u015B\",\n\t\tuk: \"\u0412\u0456\u0434\u043F\u0440\u0430\u0446\u044C\u043E\u0432\u0430\u043D\u043E \u0441\u044C\u043E\u0433\u043E\u0434\u043D\u0456\",\n\t\t\"zh-cn\": \"\u4ECA\u65E5\u5DF2\u5DE5\u4F5C\",\n\t},\n\t/** Balance of today */\n\ttodayBalanceMinutes: {\n\t\ten: \"Balance today\",\n\t\tde: \"Saldo heute\",\n\t\tru: \"\u0411\u0430\u043B\u0430\u043D\u0441 \u0437\u0430 \u0441\u0435\u0433\u043E\u0434\u043D\u044F\",\n\t\tpt: \"Saldo de hoje\",\n\t\tnl: \"Saldo vandaag\",\n\t\tfr: \"Solde du jour\",\n\t\tit: \"Saldo di oggi\",\n\t\tes: \"Saldo de hoy\",\n\t\tpl: \"Saldo dzisiaj\",\n\t\tuk: \"\u0411\u0430\u043B\u0430\u043D\u0441 \u0437\u0430 \u0441\u044C\u043E\u0433\u043E\u0434\u043D\u0456\",\n\t\t\"zh-cn\": \"\u4ECA\u65E5\u4F59\u989D\",\n\t},\n\t/** Net working time of the current month */\n\tmonthWorkedMinutes: {\n\t\ten: \"Worked this month\",\n\t\tde: \"Diesen Monat gearbeitet\",\n\t\tru: \"\u041E\u0442\u0440\u0430\u0431\u043E\u0442\u0430\u043D\u043E \u0437\u0430 \u043C\u0435\u0441\u044F\u0446\",\n\t\tpt: \"Trabalhado este m\u00EAs\",\n\t\tnl: \"Deze maand gewerkt\",\n\t\tfr: \"Travaill\u00E9 ce mois\",\n\t\tit: \"Lavorato questo mese\",\n\t\tes: \"Trabajado este mes\",\n\t\tpl: \"Przepracowane w tym miesi\u0105cu\",\n\t\tuk: \"\u0412\u0456\u0434\u043F\u0440\u0430\u0446\u044C\u043E\u0432\u0430\u043D\u043E \u0446\u044C\u043E\u0433\u043E \u043C\u0456\u0441\u044F\u0446\u044F\",\n\t\t\"zh-cn\": \"\u672C\u6708\u5DF2\u5DE5\u4F5C\",\n\t},\n\t/** Balance of the current month */\n\tmonthBalanceMinutes: {\n\t\ten: \"Balance this month\",\n\t\tde: \"Saldo diesen Monat\",\n\t\tru: \"\u0411\u0430\u043B\u0430\u043D\u0441 \u0437\u0430 \u043C\u0435\u0441\u044F\u0446\",\n\t\tpt: \"Saldo deste m\u00EAs\",\n\t\tnl: \"Saldo deze maand\",\n\t\tfr: \"Solde du mois\",\n\t\tit: \"Saldo di questo mese\",\n\t\tes: \"Saldo de este mes\",\n\t\tpl: \"Saldo w tym miesi\u0105cu\",\n\t\tuk: \"\u0411\u0430\u043B\u0430\u043D\u0441 \u0437\u0430 \u0446\u0435\u0439 \u043C\u0456\u0441\u044F\u0446\u044C\",\n\t\t\"zh-cn\": \"\u672C\u6708\u4F59\u989D\",\n\t},\n\t/** Balance of the current year */\n\tyearBalanceMinutes: {\n\t\ten: \"Balance this year\",\n\t\tde: \"Saldo dieses Jahr\",\n\t\tru: \"\u0411\u0430\u043B\u0430\u043D\u0441 \u0437\u0430 \u0433\u043E\u0434\",\n\t\tpt: \"Saldo deste ano\",\n\t\tnl: \"Saldo dit jaar\",\n\t\tfr: \"Solde de l'ann\u00E9e\",\n\t\tit: \"Saldo di quest'anno\",\n\t\tes: \"Saldo de este a\u00F1o\",\n\t\tpl: \"Saldo w tym roku\",\n\t\tuk: \"\u0411\u0430\u043B\u0430\u043D\u0441 \u0437\u0430 \u0446\u0435\u0439 \u0440\u0456\u043A\",\n\t\t\"zh-cn\": \"\u672C\u5E74\u4F59\u989D\",\n\t},\n\t/** Punches waiting for a decision */\n\topenConflicts: {\n\t\ten: \"Open conflicts\",\n\t\tde: \"Offene Konflikte\",\n\t\tru: \"\u041E\u0442\u043A\u0440\u044B\u0442\u044B\u0435 \u043A\u043E\u043D\u0444\u043B\u0438\u043A\u0442\u044B\",\n\t\tpt: \"Conflitos em aberto\",\n\t\tnl: \"Openstaande conflicten\",\n\t\tfr: \"Conflits en attente\",\n\t\tit: \"Conflitti aperti\",\n\t\tes: \"Conflictos abiertos\",\n\t\tpl: \"Otwarte konflikty\",\n\t\tuk: \"\u0412\u0456\u0434\u043A\u0440\u0438\u0442\u0456 \u043A\u043E\u043D\u0444\u043B\u0456\u043A\u0442\u0438\",\n\t\t\"zh-cn\": \"\u672A\u89E3\u51B3\u7684\u51B2\u7A81\",\n\t},\n\t/** Employee the punch commands apply to */\n\tpunchUserId: {\n\t\ten: \"Employee id for punch commands\",\n\t\tde: \"Mitarbeiter-Id f\u00FCr Stempelbefehle\",\n\t\tru: \"\u0418\u0434\u0435\u043D\u0442\u0438\u0444\u0438\u043A\u0430\u0442\u043E\u0440 \u0441\u043E\u0442\u0440\u0443\u0434\u043D\u0438\u043A\u0430 \u0434\u043B\u044F \u043A\u043E\u043C\u0430\u043D\u0434\",\n\t\tpt: \"ID do funcion\u00E1rio para comandos\",\n\t\tnl: \"Medewerker-id voor opdrachten\",\n\t\tfr: \"Identifiant de l'employ\u00E9 pour les commandes\",\n\t\tit: \"ID del dipendente per i comandi\",\n\t\tes: \"ID del empleado para comandos\",\n\t\tpl: \"Identyfikator pracownika dla polece\u0144\",\n\t\tuk: \"\u0406\u0434\u0435\u043D\u0442\u0438\u0444\u0456\u043A\u0430\u0442\u043E\u0440 \u0441\u043F\u0456\u0432\u0440\u043E\u0431\u0456\u0442\u043D\u0438\u043A\u0430 \u0434\u043B\u044F \u043A\u043E\u043C\u0430\u043D\u0434\",\n\t\t\"zh-cn\": \"\u6253\u5361\u547D\u4EE4\u7684\u5458\u5DE5 ID\",\n\t},\n\t/** Button: punch in or out */\n\tpunch: {\n\t\ten: \"Punch in or out\",\n\t\tde: \"Ein- oder ausstempeln\",\n\t\tru: \"\u041E\u0442\u043C\u0435\u0442\u0438\u0442\u044C\u0441\u044F (\u043F\u0440\u0438\u0445\u043E\u0434 \u0438\u043B\u0438 \u0443\u0445\u043E\u0434)\",\n\t\tpt: \"Marcar entrada ou sa\u00EDda\",\n\t\tnl: \"In- of uitklokken\",\n\t\tfr: \"Pointer l'arriv\u00E9e ou le d\u00E9part\",\n\t\tit: \"Timbrare entrata o uscita\",\n\t\tes: \"Fichar entrada o salida\",\n\t\tpl: \"Zarejestruj wej\u015Bcie lub wyj\u015Bcie\",\n\t\tuk: \"\u0412\u0456\u0434\u043C\u0456\u0442\u0438\u0442\u0438 \u043F\u0440\u0438\u0445\u0456\u0434 \u0430\u0431\u043E \u0432\u0438\u0445\u0456\u0434\",\n\t\t\"zh-cn\": \"\u4E0A\u73ED\u6216\u4E0B\u73ED\u6253\u5361\",\n\t},\n\t/** Button: punch and round the time */\n\tquickPunch: {\n\t\ten: \"Punch with quick rounding\",\n\t\tde: \"Stempeln mit Schnellrundung\",\n\t\tru: \"\u041E\u0442\u043C\u0435\u0442\u0438\u0442\u044C\u0441\u044F \u0441 \u0431\u044B\u0441\u0442\u0440\u044B\u043C \u043E\u043A\u0440\u0443\u0433\u043B\u0435\u043D\u0438\u0435\u043C\",\n\t\tpt: \"Marcar com arredondamento r\u00E1pido\",\n\t\tnl: \"Klokken met snelle afronding\",\n\t\tfr: \"Pointer avec arrondi rapide\",\n\t\tit: \"Timbrare con arrotondamento rapido\",\n\t\tes: \"Fichar con redondeo r\u00E1pido\",\n\t\tpl: \"Zarejestruj z szybkim zaokr\u0105gleniem\",\n\t\tuk: \"\u0412\u0456\u0434\u043C\u0456\u0442\u0438\u0442\u0438 \u0437\u0456 \u0448\u0432\u0438\u0434\u043A\u0438\u043C \u043E\u043A\u0440\u0443\u0433\u043B\u0435\u043D\u043D\u044F\u043C\",\n\t\t\"zh-cn\": \"\u5FEB\u901F\u53D6\u6574\u6253\u5361\",\n\t},\n\t/** Month to close */\n\tcloseMonth: {\n\t\ten: \"Close month (YYYY-MM)\",\n\t\tde: \"Monat abschlie\u00DFen (JJJJ-MM)\",\n\t\tru: \"\u0417\u0430\u043A\u0440\u044B\u0442\u044C \u043C\u0435\u0441\u044F\u0446 (\u0413\u0413\u0413\u0413-\u041C\u041C)\",\n\t\tpt: \"Fechar m\u00EAs (AAAA-MM)\",\n\t\tnl: \"Maand afsluiten (JJJJ-MM)\",\n\t\tfr: \"Cl\u00F4turer le mois (AAAA-MM)\",\n\t\tit: \"Chiudere il mese (AAAA-MM)\",\n\t\tes: \"Cerrar mes (AAAA-MM)\",\n\t\tpl: \"Zamknij miesi\u0105c (RRRR-MM)\",\n\t\tuk: \"\u0417\u0430\u043A\u0440\u0438\u0442\u0438 \u043C\u0456\u0441\u044F\u0446\u044C (\u0420\u0420\u0420\u0420-\u041C\u041C)\",\n\t\t\"zh-cn\": \"\u5173\u95ED\u6708\u4EFD\uFF08YYYY-MM\uFF09\",\n\t},\n\t/** Period to recalculate */\n\trecalc: {\n\t\ten: \"Recalculate period (YYYY-MM or YYYY)\",\n\t\tde: \"Zeitraum neu berechnen (JJJJ-MM oder JJJJ)\",\n\t\tru: \"\u041F\u0435\u0440\u0435\u0441\u0447\u0438\u0442\u0430\u0442\u044C \u043F\u0435\u0440\u0438\u043E\u0434 (\u0413\u0413\u0413\u0413-\u041C\u041C \u0438\u043B\u0438 \u0413\u0413\u0413\u0413)\",\n\t\tpt: \"Recalcular per\u00EDodo (AAAA-MM ou AAAA)\",\n\t\tnl: \"Periode opnieuw berekenen (JJJJ-MM of JJJJ)\",\n\t\tfr: \"Recalculer la p\u00E9riode (AAAA-MM ou AAAA)\",\n\t\tit: \"Ricalcolare il periodo (AAAA-MM o AAAA)\",\n\t\tes: \"Recalcular periodo (AAAA-MM o AAAA)\",\n\t\tpl: \"Przelicz okres (RRRR-MM lub RRRR)\",\n\t\tuk: \"\u041F\u0435\u0440\u0435\u0440\u0430\u0445\u0443\u0432\u0430\u0442\u0438 \u043F\u0435\u0440\u0456\u043E\u0434 (\u0420\u0420\u0420\u0420-\u041C\u041C \u0430\u0431\u043E \u0420\u0420\u0420\u0420)\",\n\t\t\"zh-cn\": \"\u91CD\u65B0\u8BA1\u7B97\u671F\u95F4\uFF08YYYY-MM \u6216 YYYY\uFF09\",\n\t},\n\t/** Button: write a database backup */\n\tbackupCommand: {\n\t\ten: \"Write a database backup\",\n\t\tde: \"Datenbank-Sicherung schreiben\",\n\t\tru: \"\u0421\u043E\u0437\u0434\u0430\u0442\u044C \u0440\u0435\u0437\u0435\u0440\u0432\u043D\u0443\u044E \u043A\u043E\u043F\u0438\u044E \u0431\u0430\u0437\u044B\",\n\t\tpt: \"Criar c\u00F3pia de seguran\u00E7a da base de dados\",\n\t\tnl: \"Databasback-up maken\",\n\t\tfr: \"Cr\u00E9er une sauvegarde de la base\",\n\t\tit: \"Creare un backup del database\",\n\t\tes: \"Crear copia de seguridad de la base\",\n\t\tpl: \"Utw\u00F3rz kopi\u0119 zapasow\u0105 bazy\",\n\t\tuk: \"\u0421\u0442\u0432\u043E\u0440\u0438\u0442\u0438 \u0440\u0435\u0437\u0435\u0440\u0432\u043D\u0443 \u043A\u043E\u043F\u0456\u044E \u0431\u0430\u0437\u0438\",\n\t\t\"zh-cn\": \"\u5199\u5165\u6570\u636E\u5E93\u5907\u4EFD\",\n\t},\n\t/** Version of the adapter */\n\tversion: {\n\t\ten: \"Adapter version\",\n\t\tde: \"Adapter-Version\",\n\t\tru: \"\u0412\u0435\u0440\u0441\u0438\u044F \u0430\u0434\u0430\u043F\u0442\u0435\u0440\u0430\",\n\t\tpt: \"Vers\u00E3o do adaptador\",\n\t\tnl: \"Adapterversie\",\n\t\tfr: \"Version de l'adaptateur\",\n\t\tit: \"Versione dell'adattatore\",\n\t\tes: \"Versi\u00F3n del adaptador\",\n\t\tpl: \"Wersja adaptera\",\n\t\tuk: \"\u0412\u0435\u0440\u0441\u0456\u044F \u0430\u0434\u0430\u043F\u0442\u0435\u0440\u0430\",\n\t\t\"zh-cn\": \"\u9002\u914D\u5668\u7248\u672C\",\n\t},\n\t/** Version of the database schema */\n\tschemaVersion: {\n\t\ten: \"Database schema version\",\n\t\tde: \"Datenbank-Schemaversion\",\n\t\tru: \"\u0412\u0435\u0440\u0441\u0438\u044F \u0441\u0445\u0435\u043C\u044B \u0431\u0430\u0437\u044B \u0434\u0430\u043D\u043D\u044B\u0445\",\n\t\tpt: \"Vers\u00E3o do esquema da base de dados\",\n\t\tnl: \"Schemaversie van de database\",\n\t\tfr: \"Version du sch\u00E9ma de la base\",\n\t\tit: \"Versione dello schema del database\",\n\t\tes: \"Versi\u00F3n del esquema de la base\",\n\t\tpl: \"Wersja schematu bazy\",\n\t\tuk: \"\u0412\u0435\u0440\u0441\u0456\u044F \u0441\u0445\u0435\u043C\u0438 \u0431\u0430\u0437\u0438 \u0434\u0430\u043D\u0438\u0445\",\n\t\t\"zh-cn\": \"\u6570\u636E\u5E93\u67B6\u6784\u7248\u672C\",\n\t},\n\t/** Size of the database file */\n\tdbSizeBytes: {\n\t\ten: \"Database size\",\n\t\tde: \"Datenbank-Gr\u00F6\u00DFe\",\n\t\tru: \"\u0420\u0430\u0437\u043C\u0435\u0440 \u0431\u0430\u0437\u044B \u0434\u0430\u043D\u043D\u044B\u0445\",\n\t\tpt: \"Tamanho da base de dados\",\n\t\tnl: \"Grootte van de database\",\n\t\tfr: \"Taille de la base\",\n\t\tit: \"Dimensione del database\",\n\t\tes: \"Tama\u00F1o de la base\",\n\t\tpl: \"Rozmiar bazy\",\n\t\tuk: \"\u0420\u043E\u0437\u043C\u0456\u0440 \u0431\u0430\u0437\u0438 \u0434\u0430\u043D\u0438\u0445\",\n\t\t\"zh-cn\": \"\u6570\u636E\u5E93\u5927\u5C0F\",\n\t},\n\t/** Last error of the instance */\n\tlastError: {\n\t\ten: \"Last error\",\n\t\tde: \"Letzter Fehler\",\n\t\tru: \"\u041F\u043E\u0441\u043B\u0435\u0434\u043D\u044F\u044F \u043E\u0448\u0438\u0431\u043A\u0430\",\n\t\tpt: \"\u00DAltimo erro\",\n\t\tnl: \"Laatste fout\",\n\t\tfr: \"Derni\u00E8re erreur\",\n\t\tit: \"Ultimo errore\",\n\t\tes: \"\u00DAltimo error\",\n\t\tpl: \"Ostatni b\u0142\u0105d\",\n\t\tuk: \"\u041E\u0441\u0442\u0430\u043D\u043D\u044F \u043F\u043E\u043C\u0438\u043B\u043A\u0430\",\n\t\t\"zh-cn\": \"\u6700\u540E\u7684\u9519\u8BEF\",\n\t},\n\t/** Instant of the last backup */\n\tlastBackup: {\n\t\ten: \"Last backup\",\n\t\tde: \"Letzte Sicherung\",\n\t\tru: \"\u041F\u043E\u0441\u043B\u0435\u0434\u043D\u044F\u044F \u0440\u0435\u0437\u0435\u0440\u0432\u043D\u0430\u044F \u043A\u043E\u043F\u0438\u044F\",\n\t\tpt: \"\u00DAltima c\u00F3pia de seguran\u00E7a\",\n\t\tnl: \"Laatste back-up\",\n\t\tfr: \"Derni\u00E8re sauvegarde\",\n\t\tit: \"Ultimo backup\",\n\t\tes: \"\u00DAltima copia de seguridad\",\n\t\tpl: \"Ostatnia kopia zapasowa\",\n\t\tuk: \"\u041E\u0441\u0442\u0430\u043D\u043D\u044F \u0440\u0435\u0437\u0435\u0440\u0432\u043D\u0430 \u043A\u043E\u043F\u0456\u044F\",\n\t\t\"zh-cn\": \"\u6700\u540E\u7684\u5907\u4EFD\",\n\t},\n\t/** Number of employees that are present */\n\tcompanyPresentCount: {\n\t\ten: \"Present employees\",\n\t\tde: \"Anwesende Mitarbeiter\",\n\t\tru: \"\u041F\u0440\u0438\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u044E\u0449\u0438\u0435 \u0441\u043E\u0442\u0440\u0443\u0434\u043D\u0438\u043A\u0438\",\n\t\tpt: \"Funcion\u00E1rios presentes\",\n\t\tnl: \"Aanwezige medewerkers\",\n\t\tfr: \"Employ\u00E9s pr\u00E9sents\",\n\t\tit: \"Dipendenti presenti\",\n\t\tes: \"Empleados presentes\",\n\t\tpl: \"Obecni pracownicy\",\n\t\tuk: \"\u041F\u0440\u0438\u0441\u0443\u0442\u043D\u0456 \u0441\u043F\u0456\u0432\u0440\u043E\u0431\u0456\u0442\u043D\u0438\u043A\u0438\",\n\t\t\"zh-cn\": \"\u5728\u5C97\u5458\u5DE5\",\n\t},\n\t/** Names of the employees that are present */\n\tcompanyPresent: {\n\t\ten: \"Who is present\",\n\t\tde: \"Wer ist anwesend\",\n\t\tru: \"\u041A\u0442\u043E \u043F\u0440\u0438\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442\",\n\t\tpt: \"Quem est\u00E1 presente\",\n\t\tnl: \"Wie is aanwezig\",\n\t\tfr: \"Qui est pr\u00E9sent\",\n\t\tit: \"Chi \u00E8 presente\",\n\t\tes: \"Qui\u00E9n est\u00E1 presente\",\n\t\tpl: \"Kto jest obecny\",\n\t\tuk: \"\u0425\u0442\u043E \u043F\u0440\u0438\u0441\u0443\u0442\u043D\u0456\u0439\",\n\t\t\"zh-cn\": \"\u8C01\u5728\u5C97\",\n\t},\n\t/** Instant of the newest punch of the company */\n\tcompanyLastPunch: {\n\t\ten: \"Last punch\",\n\t\tde: \"Letzte Buchung\",\n\t\tru: \"\u041F\u043E\u0441\u043B\u0435\u0434\u043D\u044F\u044F \u043E\u0442\u043C\u0435\u0442\u043A\u0430\",\n\t\tpt: \"\u00DAltimo registo\",\n\t\tnl: \"Laatste stempeling\",\n\t\tfr: \"Dernier pointage\",\n\t\tit: \"Ultima timbratura\",\n\t\tes: \"\u00DAltimo registro\",\n\t\tpl: \"Ostatni wpis\",\n\t\tuk: \"\u041E\u0441\u0442\u0430\u043D\u043D\u044F \u0432\u0456\u0434\u043C\u0456\u0442\u043A\u0430\",\n\t\t\"zh-cn\": \"\u6700\u540E\u6253\u5361\",\n\t},\n\t/** Instant of the newest event */\n\tlastAt: {\n\t\ten: \"Last event at\",\n\t\tde: \"Letztes Ereignis um\",\n\t\tru: \"\u0412\u0440\u0435\u043C\u044F \u043F\u043E\u0441\u043B\u0435\u0434\u043D\u0435\u0433\u043E \u0441\u043E\u0431\u044B\u0442\u0438\u044F\",\n\t\tpt: \"Hora do \u00FAltimo evento\",\n\t\tnl: \"Tijdstip laatste gebeurtenis\",\n\t\tfr: \"Heure du dernier \u00E9v\u00E9nement\",\n\t\tit: \"Ora dell'ultimo evento\",\n\t\tes: \"Hora del \u00FAltimo evento\",\n\t\tpl: \"Czas ostatniego zdarzenia\",\n\t\tuk: \"\u0427\u0430\u0441 \u043E\u0441\u0442\u0430\u043D\u043D\u044C\u043E\u0457 \u043F\u043E\u0434\u0456\u0457\",\n\t\t\"zh-cn\": \"\u6700\u540E\u4E8B\u4EF6\u65F6\u95F4\",\n\t},\n\t/** Kind of the newest event */\n\tlastType: {\n\t\ten: \"Kind of the last event\",\n\t\tde: \"Art des letzten Ereignisses\",\n\t\tru: \"\u0422\u0438\u043F \u043F\u043E\u0441\u043B\u0435\u0434\u043D\u0435\u0433\u043E \u0441\u043E\u0431\u044B\u0442\u0438\u044F\",\n\t\tpt: \"Tipo do \u00FAltimo evento\",\n\t\tnl: \"Soort laatste gebeurtenis\",\n\t\tfr: \"Type du dernier \u00E9v\u00E9nement\",\n\t\tit: \"Tipo dell'ultimo evento\",\n\t\tes: \"Tipo del \u00FAltimo evento\",\n\t\tpl: \"Rodzaj ostatniego zdarzenia\",\n\t\tuk: \"\u0422\u0438\u043F \u043E\u0441\u0442\u0430\u043D\u043D\u044C\u043E\u0457 \u043F\u043E\u0434\u0456\u0457\",\n\t\t\"zh-cn\": \"\u6700\u540E\u4E8B\u4EF6\u7C7B\u578B\",\n\t},\n\t/** Employee of the newest event */\n\tlastUser: {\n\t\ten: \"Employee of the last event\",\n\t\tde: \"Mitarbeiter des letzten Ereignisses\",\n\t\tru: \"\u0421\u043E\u0442\u0440\u0443\u0434\u043D\u0438\u043A \u043F\u043E\u0441\u043B\u0435\u0434\u043D\u0435\u0433\u043E \u0441\u043E\u0431\u044B\u0442\u0438\u044F\",\n\t\tpt: \"Funcion\u00E1rio do \u00FAltimo evento\",\n\t\tnl: \"Medewerker van de laatste gebeurtenis\",\n\t\tfr: \"Employ\u00E9 du dernier \u00E9v\u00E9nement\",\n\t\tit: \"Dipendente dell'ultimo evento\",\n\t\tes: \"Empleado del \u00FAltimo evento\",\n\t\tpl: \"Pracownik ostatniego zdarzenia\",\n\t\tuk: \"\u0421\u043F\u0456\u0432\u0440\u043E\u0431\u0456\u0442\u043D\u0438\u043A \u043E\u0441\u0442\u0430\u043D\u043D\u044C\u043E\u0457 \u043F\u043E\u0434\u0456\u0457\",\n\t\t\"zh-cn\": \"\u6700\u540E\u4E8B\u4EF6\u7684\u5458\u5DE5\",\n\t},\n\t/** Direction of the newest punch */\n\tlastDirection: {\n\t\ten: \"Direction of the last punch\",\n\t\tde: \"Richtung der letzten Buchung\",\n\t\tru: \"\u041D\u0430\u043F\u0440\u0430\u0432\u043B\u0435\u043D\u0438\u0435 \u043F\u043E\u0441\u043B\u0435\u0434\u043D\u0435\u0439 \u043E\u0442\u043C\u0435\u0442\u043A\u0438\",\n\t\tpt: \"Dire\u00E7\u00E3o do \u00FAltimo registo\",\n\t\tnl: \"Richting van de laatste stempeling\",\n\t\tfr: \"Sens du dernier pointage\",\n\t\tit: \"Direzione dell'ultima timbratura\",\n\t\tes: \"Direcci\u00F3n del \u00FAltimo registro\",\n\t\tpl: \"Kierunek ostatniego wpisu\",\n\t\tuk: \"\u041D\u0430\u043F\u0440\u044F\u043C\u043E\u043A \u043E\u0441\u0442\u0430\u043D\u043D\u044C\u043E\u0457 \u0432\u0456\u0434\u043C\u0456\u0442\u043A\u0438\",\n\t\t\"zh-cn\": \"\u6700\u540E\u6253\u5361\u7684\u65B9\u5411\",\n\t},\n\t/** Source of the newest event */\n\tlastSource: {\n\t\ten: \"Source of the last event\",\n\t\tde: \"Quelle des letzten Ereignisses\",\n\t\tru: \"\u0418\u0441\u0442\u043E\u0447\u043D\u0438\u043A \u043F\u043E\u0441\u043B\u0435\u0434\u043D\u0435\u0433\u043E \u0441\u043E\u0431\u044B\u0442\u0438\u044F\",\n\t\tpt: \"Origem do \u00FAltimo evento\",\n\t\tnl: \"Bron van de laatste gebeurtenis\",\n\t\tfr: \"Source du dernier \u00E9v\u00E9nement\",\n\t\tit: \"Origine dell'ultimo evento\",\n\t\tes: \"Origen del \u00FAltimo evento\",\n\t\tpl: \"\u0179r\u00F3d\u0142o ostatniego zdarzenia\",\n\t\tuk: \"\u0414\u0436\u0435\u0440\u0435\u043B\u043E \u043E\u0441\u0442\u0430\u043D\u043D\u044C\u043E\u0457 \u043F\u043E\u0434\u0456\u0457\",\n\t\t\"zh-cn\": \"\u6700\u540E\u4E8B\u4EF6\u7684\u6765\u6E90\",\n\t},\n} satisfies Record<string, StateName>;\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -32,6 +32,7 @@ __export(states_exports, {
|
|
|
32
32
|
readUserSnapshot: () => readUserSnapshot
|
|
33
33
|
});
|
|
34
34
|
module.exports = __toCommonJS(states_exports);
|
|
35
|
+
var import_stateNames = require("./stateNames");
|
|
35
36
|
var import_time = require("../util/time");
|
|
36
37
|
const COMMAND_IDS = {
|
|
37
38
|
/** Employee the commands apply to */
|
|
@@ -64,6 +65,11 @@ function stateObject(name, type, role, options = {}) {
|
|
|
64
65
|
function channelObject(name) {
|
|
65
66
|
return { type: "channel", common: { name }, native: {} };
|
|
66
67
|
}
|
|
68
|
+
async function ensureObject(port, id, object) {
|
|
69
|
+
var _a;
|
|
70
|
+
await port.setObjectNotExists(id, object);
|
|
71
|
+
await port.extendObject(id, { common: { name: (_a = object.common) == null ? void 0 : _a.name } });
|
|
72
|
+
}
|
|
67
73
|
function readUserSnapshot(args) {
|
|
68
74
|
var _a, _b, _c;
|
|
69
75
|
const user = args.users.findById(args.userId);
|
|
@@ -125,143 +131,108 @@ async function publishAllUserStates(args) {
|
|
|
125
131
|
}
|
|
126
132
|
async function createUserChannel(port, userId) {
|
|
127
133
|
const id = `users.${userId}`;
|
|
128
|
-
await port
|
|
129
|
-
await port
|
|
130
|
-
await port
|
|
131
|
-
await
|
|
134
|
+
await ensureObject(port, "users", channelObject(import_stateNames.STATE_NAMES.usersChannel));
|
|
135
|
+
await ensureObject(port, id, channelObject(import_stateNames.STATE_NAMES.employeeChannel));
|
|
136
|
+
await ensureObject(port, `${id}.displayName`, stateObject(import_stateNames.STATE_NAMES.displayName, "string", "info.name"));
|
|
137
|
+
await ensureObject(
|
|
138
|
+
port,
|
|
132
139
|
`${id}.present`,
|
|
133
|
-
stateObject(
|
|
134
|
-
{ en: "Present (working time is running)", de: "Anwesenheit (Arbeitszeit l\xE4uft)" },
|
|
135
|
-
"boolean",
|
|
136
|
-
"switch",
|
|
137
|
-
{ write: true }
|
|
138
|
-
)
|
|
140
|
+
stateObject(import_stateNames.STATE_NAMES.userPresent, "boolean", "switch", { write: true })
|
|
139
141
|
);
|
|
140
|
-
await
|
|
142
|
+
await ensureObject(
|
|
143
|
+
port,
|
|
141
144
|
`${id}.hasOpenEntry`,
|
|
142
|
-
stateObject(
|
|
145
|
+
stateObject(import_stateNames.STATE_NAMES.hasOpenEntry, "boolean", "indicator.working")
|
|
143
146
|
);
|
|
144
|
-
await port.
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
);
|
|
148
|
-
await port.setObjectNotExists(
|
|
147
|
+
await ensureObject(port, `${id}.lastPunch`, stateObject(import_stateNames.STATE_NAMES.lastPunch, "number", "value.time"));
|
|
148
|
+
await ensureObject(
|
|
149
|
+
port,
|
|
149
150
|
`${id}.todayWorkedMinutes`,
|
|
150
|
-
stateObject(
|
|
151
|
+
stateObject(import_stateNames.STATE_NAMES.todayWorkedMinutes, "number", "value", { unit: "min" })
|
|
151
152
|
);
|
|
152
|
-
await
|
|
153
|
+
await ensureObject(
|
|
154
|
+
port,
|
|
153
155
|
`${id}.todayBalanceMinutes`,
|
|
154
|
-
stateObject(
|
|
156
|
+
stateObject(import_stateNames.STATE_NAMES.todayBalanceMinutes, "number", "value", { unit: "min" })
|
|
155
157
|
);
|
|
156
|
-
await
|
|
158
|
+
await ensureObject(
|
|
159
|
+
port,
|
|
157
160
|
`${id}.monthWorkedMinutes`,
|
|
158
|
-
stateObject(
|
|
161
|
+
stateObject(import_stateNames.STATE_NAMES.monthWorkedMinutes, "number", "value", { unit: "min" })
|
|
159
162
|
);
|
|
160
|
-
await
|
|
163
|
+
await ensureObject(
|
|
164
|
+
port,
|
|
161
165
|
`${id}.monthBalanceMinutes`,
|
|
162
|
-
stateObject(
|
|
166
|
+
stateObject(import_stateNames.STATE_NAMES.monthBalanceMinutes, "number", "value", { unit: "min" })
|
|
163
167
|
);
|
|
164
|
-
await
|
|
168
|
+
await ensureObject(
|
|
169
|
+
port,
|
|
165
170
|
`${id}.yearBalanceMinutes`,
|
|
166
|
-
stateObject(
|
|
167
|
-
);
|
|
168
|
-
await port.setObjectNotExists(
|
|
169
|
-
`${id}.openConflicts`,
|
|
170
|
-
stateObject({ en: "Open conflicts", de: "Offene Konflikte" }, "number", "value")
|
|
171
|
+
stateObject(import_stateNames.STATE_NAMES.yearBalanceMinutes, "number", "value", { unit: "min" })
|
|
171
172
|
);
|
|
173
|
+
await ensureObject(port, `${id}.openConflicts`, stateObject(import_stateNames.STATE_NAMES.openConflicts, "number", "value"));
|
|
172
174
|
return id;
|
|
173
175
|
}
|
|
174
176
|
async function createCommandStates(port) {
|
|
175
|
-
await port
|
|
176
|
-
await
|
|
177
|
+
await ensureObject(port, "commands", channelObject(import_stateNames.STATE_NAMES.commandsChannel));
|
|
178
|
+
await ensureObject(
|
|
179
|
+
port,
|
|
177
180
|
COMMAND_IDS.punchUserId,
|
|
178
|
-
stateObject(
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
"value",
|
|
182
|
-
{
|
|
183
|
-
write: true
|
|
184
|
-
}
|
|
185
|
-
)
|
|
181
|
+
stateObject(import_stateNames.STATE_NAMES.punchUserId, "number", "level", {
|
|
182
|
+
write: true
|
|
183
|
+
})
|
|
186
184
|
);
|
|
187
|
-
await
|
|
185
|
+
await ensureObject(
|
|
186
|
+
port,
|
|
188
187
|
COMMAND_IDS.punch,
|
|
189
|
-
stateObject(
|
|
188
|
+
stateObject(import_stateNames.STATE_NAMES.punch, "boolean", "button", {
|
|
190
189
|
read: false,
|
|
191
190
|
write: true
|
|
192
191
|
})
|
|
193
192
|
);
|
|
194
|
-
await
|
|
193
|
+
await ensureObject(
|
|
194
|
+
port,
|
|
195
195
|
COMMAND_IDS.quickPunch,
|
|
196
|
-
stateObject(
|
|
196
|
+
stateObject(import_stateNames.STATE_NAMES.quickPunch, "boolean", "button", {
|
|
197
197
|
read: false,
|
|
198
198
|
write: true
|
|
199
199
|
})
|
|
200
200
|
);
|
|
201
|
-
await
|
|
201
|
+
await ensureObject(
|
|
202
|
+
port,
|
|
202
203
|
COMMAND_IDS.closeMonth,
|
|
203
|
-
stateObject(
|
|
204
|
+
stateObject(import_stateNames.STATE_NAMES.closeMonth, "string", "text", {
|
|
204
205
|
write: true
|
|
205
206
|
})
|
|
206
207
|
);
|
|
207
|
-
await port.
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
{ en: "Recalculate period (YYYY-MM or YYYY)", de: "Zeitraum neu berechnen (JJJJ-MM oder JJJJ)" },
|
|
211
|
-
"string",
|
|
212
|
-
"text",
|
|
213
|
-
{ write: true }
|
|
214
|
-
)
|
|
215
|
-
);
|
|
216
|
-
await port.setObjectNotExists(
|
|
208
|
+
await ensureObject(port, COMMAND_IDS.recalc, stateObject(import_stateNames.STATE_NAMES.recalc, "string", "text", { write: true }));
|
|
209
|
+
await ensureObject(
|
|
210
|
+
port,
|
|
217
211
|
COMMAND_IDS.backup,
|
|
218
|
-
stateObject(
|
|
212
|
+
stateObject(import_stateNames.STATE_NAMES.backupCommand, "boolean", "button", {
|
|
219
213
|
read: false,
|
|
220
214
|
write: true
|
|
221
215
|
})
|
|
222
216
|
);
|
|
223
217
|
}
|
|
224
218
|
async function createInfoStates(port) {
|
|
225
|
-
await port
|
|
226
|
-
await port.
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
await port.setObjectNotExists(
|
|
231
|
-
"info.schemaVersion",
|
|
232
|
-
stateObject({ en: "Database schema version", de: "Datenbank-Schemaversion" }, "string", "text")
|
|
233
|
-
);
|
|
234
|
-
await port.setObjectNotExists(
|
|
219
|
+
await ensureObject(port, "info", channelObject(import_stateNames.STATE_NAMES.infoChannel));
|
|
220
|
+
await ensureObject(port, "info.version", stateObject(import_stateNames.STATE_NAMES.version, "string", "text"));
|
|
221
|
+
await ensureObject(port, "info.schemaVersion", stateObject(import_stateNames.STATE_NAMES.schemaVersion, "string", "text"));
|
|
222
|
+
await ensureObject(
|
|
223
|
+
port,
|
|
235
224
|
"info.dbSizeBytes",
|
|
236
|
-
stateObject(
|
|
237
|
-
);
|
|
238
|
-
await port.setObjectNotExists(
|
|
239
|
-
"info.lastError",
|
|
240
|
-
stateObject({ en: "Last error", de: "Letzter Fehler" }, "string", "text")
|
|
241
|
-
);
|
|
242
|
-
await port.setObjectNotExists(
|
|
243
|
-
"info.lastBackup",
|
|
244
|
-
stateObject({ en: "Last backup", de: "Letzte Sicherung" }, "number", "value.time")
|
|
225
|
+
stateObject(import_stateNames.STATE_NAMES.dbSizeBytes, "number", "value", { unit: "bytes" })
|
|
245
226
|
);
|
|
227
|
+
await ensureObject(port, "info.lastError", stateObject(import_stateNames.STATE_NAMES.lastError, "string", "text"));
|
|
228
|
+
await ensureObject(port, "info.lastBackup", stateObject(import_stateNames.STATE_NAMES.lastBackup, "number", "value.time"));
|
|
246
229
|
}
|
|
247
230
|
async function createCompanyStates(port) {
|
|
248
|
-
await port
|
|
249
|
-
await port.
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
);
|
|
253
|
-
await port.setObjectNotExists(
|
|
254
|
-
"company.present",
|
|
255
|
-
stateObject({ en: "Who is present", de: "Wer ist anwesend" }, "string", "text")
|
|
256
|
-
);
|
|
257
|
-
await port.setObjectNotExists(
|
|
258
|
-
"company.openConflicts",
|
|
259
|
-
stateObject({ en: "Open conflicts", de: "Offene Konflikte" }, "number", "value")
|
|
260
|
-
);
|
|
261
|
-
await port.setObjectNotExists(
|
|
262
|
-
"company.lastPunch",
|
|
263
|
-
stateObject({ en: "Last punch", de: "Letzte Buchung" }, "number", "value.time")
|
|
264
|
-
);
|
|
231
|
+
await ensureObject(port, "company", channelObject(import_stateNames.STATE_NAMES.companyChannel));
|
|
232
|
+
await ensureObject(port, "company.presentCount", stateObject(import_stateNames.STATE_NAMES.companyPresentCount, "number", "value"));
|
|
233
|
+
await ensureObject(port, "company.present", stateObject(import_stateNames.STATE_NAMES.companyPresent, "string", "text"));
|
|
234
|
+
await ensureObject(port, "company.openConflicts", stateObject(import_stateNames.STATE_NAMES.openConflicts, "number", "value"));
|
|
235
|
+
await ensureObject(port, "company.lastPunch", stateObject(import_stateNames.STATE_NAMES.companyLastPunch, "number", "value.time"));
|
|
265
236
|
}
|
|
266
237
|
function readCompanySnapshot(snapshots) {
|
|
267
238
|
const present = snapshots.filter((snapshot) => snapshot.hasOpenEntry);
|
|
@@ -283,27 +254,12 @@ async function publishCompanySnapshot(port, snapshot) {
|
|
|
283
254
|
await port.setState("company.lastPunch", (_a = snapshot.lastPunchUtc) != null ? _a : 0, true);
|
|
284
255
|
}
|
|
285
256
|
async function createEventStates(port) {
|
|
286
|
-
await port
|
|
287
|
-
await port.
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
);
|
|
291
|
-
await port.
|
|
292
|
-
"events.lastType",
|
|
293
|
-
stateObject({ en: "Kind of the last event", de: "Art des letzten Ereignisses" }, "string", "text")
|
|
294
|
-
);
|
|
295
|
-
await port.setObjectNotExists(
|
|
296
|
-
"events.lastUser",
|
|
297
|
-
stateObject({ en: "Employee of the last event", de: "Mitarbeiter des letzten Ereignisses" }, "string", "text")
|
|
298
|
-
);
|
|
299
|
-
await port.setObjectNotExists(
|
|
300
|
-
"events.lastDirection",
|
|
301
|
-
stateObject({ en: "Direction of the last punch", de: "Richtung der letzten Buchung" }, "string", "text")
|
|
302
|
-
);
|
|
303
|
-
await port.setObjectNotExists(
|
|
304
|
-
"events.lastSource",
|
|
305
|
-
stateObject({ en: "Source of the last event", de: "Quelle des letzten Ereignisses" }, "string", "text")
|
|
306
|
-
);
|
|
257
|
+
await ensureObject(port, "events", channelObject(import_stateNames.STATE_NAMES.eventsChannel));
|
|
258
|
+
await ensureObject(port, "events.lastAt", stateObject(import_stateNames.STATE_NAMES.lastAt, "number", "value.time"));
|
|
259
|
+
await ensureObject(port, "events.lastType", stateObject(import_stateNames.STATE_NAMES.lastType, "string", "text"));
|
|
260
|
+
await ensureObject(port, "events.lastUser", stateObject(import_stateNames.STATE_NAMES.lastUser, "string", "text"));
|
|
261
|
+
await ensureObject(port, "events.lastDirection", stateObject(import_stateNames.STATE_NAMES.lastDirection, "string", "text"));
|
|
262
|
+
await ensureObject(port, "events.lastSource", stateObject(import_stateNames.STATE_NAMES.lastSource, "string", "text"));
|
|
307
263
|
}
|
|
308
264
|
async function publishEventSnapshot(port, snapshot) {
|
|
309
265
|
await port.setState("events.lastAt", snapshot.atUtc, true);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/lib/adapter/states.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * States published by the adapter.\n *\n * The adapter exposes a small, stable state tree so that other adapters (and the user's dashboards) can show\n * and trigger time tracking without speaking to the REST API:\n *\n * ```\n * users.<userId>.displayName / present / hasOpenEntry / lastPunch / todayWorkedMinutes / todayBalanceMinutes\n * users.<userId>.openConflicts\n * commands.punchUserId / punch / quickPunch / closeMonth / recalc\n * ```\n *\n * All objects are created with `setObjectNotExists`, so existing instances keep their settings. The logic works\n * on a tiny port interface (`StatePort`) \u2014 the adapter instance in production, a recorder in the tests.\n */\n\nimport type { UsersRepository } from \"../db/repositories/users\";\nimport type { AggregationService } from \"../services/aggregation\";\nimport type { SyncService } from \"../services/sync\";\nimport { localDate as resolveLocalDate } from \"../util/time\";\n\n/** Subset of the adapter API the state layer needs. */\nexport interface StatePort {\n\t/**\n\t * Creates an object when it does not exist yet.\n\t *\n\t * @param id - full state id (including the instance prefix)\n\t * @param object - object definition\n\t */\n\tsetObjectNotExists(id: string, object: ioBroker.SettableObject): Promise<unknown> | void;\n\t/**\n\t * Writes a state value.\n\t *\n\t * @param id - full state id (including the instance prefix)\n\t * @param value - value to write\n\t * @param ack - true for confirmed values\n\t */\n\tsetState(id: string, value: ioBroker.StateValue, ack?: boolean): Promise<unknown> | void;\n}\n\n/** Figures of one employee shown in the state tree. */\nexport interface UserSnapshot {\n\t/** Database id of the employee */\n\tuserId: number;\n\t/** Shown name */\n\tdisplayName: string;\n\t/** True when the last punch of today has no counterpart */\n\thasOpenEntry: boolean;\n\t/** Instant of the last punch of the day, `null` when there is none */\n\tlastPunchUtc: number | null;\n\t/** Net working time of today in minutes */\n\tworkedMinutes: number;\n\t/** Balance of today in minutes */\n\tbalanceMinutes: number;\n\t/** Punches waiting for a decision */\n\topenConflicts: number;\n\t/** Net working time of the current month in minutes */\n\tmonthWorkedMinutes: number;\n\t/** Balance of the current month in minutes */\n\tmonthBalanceMinutes: number;\n\t/** Balance of the current year in minutes */\n\tyearBalanceMinutes: number;\n}\n\n/** Figures of the whole company, published next to the employees. */\nexport interface CompanySnapshot {\n\t/** Employees that are clocked in right now */\n\tpresentCount: number;\n\t/** Names of those employees, separated by a comma (empty when nobody is present) */\n\tpresent: string;\n\t/** Punches of all employees waiting for a decision */\n\topenConflicts: number;\n\t/** Instant of the newest punch of today, `null` when nobody punched */\n\tlastPunchUtc: number | null;\n}\n\n/** Newest event of the instance, mirrored into the state tree. */\nexport interface EventSnapshot {\n\t/** Kind of the event, e.g. `punch` */\n\ttype: string;\n\t/** Instant the event belongs to */\n\tatUtc: number;\n\t/** Name of the employee the event belongs to, empty for instance wide events */\n\tuserName: string;\n\t/** Direction of a punch (`in`/`out`), empty for other events */\n\tdirection: string;\n\t/** Where the change came from, e.g. `web` or `terminal`, empty when unknown */\n\tsource: string;\n}\n\n/** Names of the writable command states. */\nexport const COMMAND_IDS = {\n\t/** Employee the commands apply to */\n\tpunchUserId: \"commands.punchUserId\",\n\t/** Punch in or out for `punchUserId` */\n\tpunch: \"commands.punch\",\n\t/** Punch in or out with the configured quick rounding */\n\tquickPunch: \"commands.quickPunch\",\n\t/** Close a month, value `YYYY-MM` */\n\tcloseMonth: \"commands.closeMonth\",\n\t/** Recalculate a period, value `YYYY-MM` or `YYYY` */\n\trecalc: \"commands.recalc\",\n\t/** Write a backup of the database */\n\tbackup: \"commands.backup\",\n} as const;\n\n/**\n * Builds a state object definition.\n *\n * @param name - name in English and German\n * @param name.en - English name\n * @param name.de - German name\n * @param type - state type\n * @param role - state role\n * @param options - additional flags\n * @param options.read - value can be read (default true)\n * @param options.write - value can be written (default false)\n * @param options.unit - unit of the value\n * @returns object definition\n */\nfunction stateObject(\n\tname: { en: string; de: string },\n\ttype: ioBroker.CommonType,\n\trole: string,\n\toptions: { read?: boolean; write?: boolean; unit?: string } = {},\n): ioBroker.SettableObject {\n\treturn {\n\t\ttype: \"state\",\n\t\tcommon: {\n\t\t\tname,\n\t\t\ttype,\n\t\t\trole,\n\t\t\tread: options.read !== false,\n\t\t\twrite: options.write === true,\n\t\t\t...(options.unit ? { unit: options.unit } : {}),\n\t\t},\n\t\tnative: {},\n\t};\n}\n\n/**\n * Builds a channel object definition.\n *\n * @param name - name in English and German\n * @param name.en - English name\n * @param name.de - German name\n * @returns object definition\n */\nfunction channelObject(name: { en: string; de: string }): ioBroker.SettableObject {\n\treturn { type: \"channel\", common: { name }, native: {} };\n}\n\n/**\n * Reads the figures of an employee for the state tree.\n *\n * @param args - data sources and employee\n * @param args.aggregation - aggregation service\n * @param args.users - user storage\n * @param args.sync - synchronisation service (open conflicts)\n * @param args.userId - database id of the employee\n * @param args.now - instant of the snapshot\n * @returns snapshot of the figures\n */\nexport function readUserSnapshot(args: {\n\taggregation: AggregationService;\n\tusers: UsersRepository;\n\tsync: SyncService;\n\tuserId: number;\n\tnow?: number;\n}): UserSnapshot | null {\n\tconst user = args.users.findById(args.userId);\n\tif (!user) {\n\t\treturn null;\n\t}\n\n\tconst timestamp = args.now ?? Math.floor(Date.now() / 1000);\n\tconst today = resolveLocalDate(timestamp, user.timezone);\n\tconst day = args.aggregation.recalculateDay(user.id, today, { now: timestamp });\n\t// the month is recalculated like the month view does it; the year is read, so the publishing stays cheap\n\tconst year = Number(today.slice(0, 4));\n\tconst month = Number(today.slice(5, 7));\n\tconst monthAggregate = args.aggregation.recalculateMonth(user.id, year, month, { now: timestamp });\n\tconst yearAggregate = args.aggregation.year(user.id, year);\n\n\treturn {\n\t\tuserId: user.id,\n\t\tdisplayName: user.displayName,\n\t\thasOpenEntry: day.hasOpenEntry,\n\t\tlastPunchUtc: Math.max(day.firstInUtc ?? 0, day.lastOutUtc ?? 0) || null,\n\t\tworkedMinutes: day.workedMin,\n\t\tbalanceMinutes: day.balanceMin,\n\t\topenConflicts: args.sync.conflicts(user.id).length,\n\t\tmonthWorkedMinutes: monthAggregate.workedMin,\n\t\tmonthBalanceMinutes: monthAggregate.balanceMin,\n\t\tyearBalanceMinutes: yearAggregate ? yearAggregate.workedMin - yearAggregate.targetMin : 0,\n\t};\n}\n\n/**\n * Publishes the figures of one employee.\n *\n * @param port - state port\n * @param snapshot - figures to publish\n */\nexport async function publishUserSnapshot(port: StatePort, snapshot: UserSnapshot): Promise<void> {\n\tconst id = `users.${snapshot.userId}`;\n\tawait port.setState(`${id}.displayName`, snapshot.displayName, true);\n\tawait port.setState(`${id}.present`, snapshot.hasOpenEntry, true);\n\tawait port.setState(`${id}.hasOpenEntry`, snapshot.hasOpenEntry, true);\n\tawait port.setState(`${id}.lastPunch`, snapshot.lastPunchUtc ?? 0, true);\n\tawait port.setState(`${id}.todayWorkedMinutes`, snapshot.workedMinutes, true);\n\tawait port.setState(`${id}.todayBalanceMinutes`, snapshot.balanceMinutes, true);\n\tawait port.setState(`${id}.monthWorkedMinutes`, snapshot.monthWorkedMinutes, true);\n\tawait port.setState(`${id}.monthBalanceMinutes`, snapshot.monthBalanceMinutes, true);\n\tawait port.setState(`${id}.yearBalanceMinutes`, snapshot.yearBalanceMinutes, true);\n\tawait port.setState(`${id}.openConflicts`, snapshot.openConflicts, true);\n}\n\n/**\n * Creates the channels of all employees and publishes their current figures.\n *\n * @param args - state port and data sources\n * @param args.port - state port\n * @param args.aggregation - aggregation service\n * @param args.users - user storage\n * @param args.sync - synchronisation service\n * @param args.now - instant of the snapshot\n * @returns the published snapshots\n */\nexport async function publishAllUserStates(args: {\n\tport: StatePort;\n\taggregation: AggregationService;\n\tusers: UsersRepository;\n\tsync: SyncService;\n\tnow?: number;\n}): Promise<UserSnapshot[]> {\n\tconst snapshots: UserSnapshot[] = [];\n\tfor (const user of args.users.list({ includeInactive: true })) {\n\t\tawait createUserChannel(args.port, user.id);\n\t\tconst snapshot = readUserSnapshot({\n\t\t\taggregation: args.aggregation,\n\t\t\tusers: args.users,\n\t\t\tsync: args.sync,\n\t\t\tuserId: user.id,\n\t\t\tnow: args.now,\n\t\t});\n\t\tif (!snapshot) {\n\t\t\tcontinue;\n\t\t}\n\t\tawait publishUserSnapshot(args.port, snapshot);\n\t\tsnapshots.push(snapshot);\n\t}\n\treturn snapshots;\n}\n\n/**\n * Creates the channel of one employee, including the shared parent channel `users`.\n *\n * The parent channel matters: the ioBroker object structure check (`E3009`) requires every state to have its\n * parents, so `users.<userId>.*` below a missing `users` produced 126 findings in the repository check\n * (PR #6697). `setObjectNotExists` keeps the call idempotent.\n *\n * @param port - state port\n * @param userId - database id of the employee\n * @returns the channel id\n */\nexport async function createUserChannel(port: StatePort, userId: number): Promise<string> {\n\tconst id = `users.${userId}`;\n\tawait port.setObjectNotExists(\"users\", channelObject({ en: \"Employees\", de: \"Mitarbeiter\" }));\n\tawait port.setObjectNotExists(id, channelObject({ en: \"Employee\", de: \"Mitarbeiter\" }));\n\tawait port.setObjectNotExists(`${id}.displayName`, stateObject({ en: \"Name\", de: \"Name\" }, \"string\", \"info.name\"));\n\t// the writable twin of `hasOpenEntry`: a script, a fingerprint reader or a dashboard writes it to say that\n\t// somebody arrived (`true`) or left (`false`) \u2014 see `presence.ts` for what the adapter does with it\n\tawait port.setObjectNotExists(\n\t\t`${id}.present`,\n\t\tstateObject(\n\t\t\t{ en: \"Present (working time is running)\", de: \"Anwesenheit (Arbeitszeit l\u00E4uft)\" },\n\t\t\t\"boolean\",\n\t\t\t\"switch\",\n\t\t\t{ write: true },\n\t\t),\n\t);\n\tawait port.setObjectNotExists(\n\t\t`${id}.hasOpenEntry`,\n\t\tstateObject({ en: \"Punched in\", de: \"Eingestempelt\" }, \"boolean\", \"indicator.working\"),\n\t);\n\tawait port.setObjectNotExists(\n\t\t`${id}.lastPunch`,\n\t\tstateObject({ en: \"Last punch\", de: \"Letzte Buchung\" }, \"number\", \"value.time\"),\n\t);\n\tawait port.setObjectNotExists(\n\t\t`${id}.todayWorkedMinutes`,\n\t\tstateObject({ en: \"Worked today\", de: \"Heute gearbeitet\" }, \"number\", \"value\", { unit: \"min\" }),\n\t);\n\tawait port.setObjectNotExists(\n\t\t`${id}.todayBalanceMinutes`,\n\t\tstateObject({ en: \"Balance today\", de: \"Saldo heute\" }, \"number\", \"value\", { unit: \"min\" }),\n\t);\n\tawait port.setObjectNotExists(\n\t\t`${id}.monthWorkedMinutes`,\n\t\tstateObject({ en: \"Worked this month\", de: \"Diesen Monat gearbeitet\" }, \"number\", \"value\", { unit: \"min\" }),\n\t);\n\tawait port.setObjectNotExists(\n\t\t`${id}.monthBalanceMinutes`,\n\t\tstateObject({ en: \"Balance this month\", de: \"Saldo diesen Monat\" }, \"number\", \"value\", { unit: \"min\" }),\n\t);\n\tawait port.setObjectNotExists(\n\t\t`${id}.yearBalanceMinutes`,\n\t\tstateObject({ en: \"Balance this year\", de: \"Saldo dieses Jahr\" }, \"number\", \"value\", { unit: \"min\" }),\n\t);\n\tawait port.setObjectNotExists(\n\t\t`${id}.openConflicts`,\n\t\tstateObject({ en: \"Open conflicts\", de: \"Offene Konflikte\" }, \"number\", \"value\"),\n\t);\n\treturn id;\n}\n\n/**\n * Creates the writable command states.\n *\n * @param port - state port\n */\nexport async function createCommandStates(port: StatePort): Promise<void> {\n\tawait port.setObjectNotExists(\"commands\", channelObject({ en: \"Commands\", de: \"Befehle\" }));\n\tawait port.setObjectNotExists(\n\t\tCOMMAND_IDS.punchUserId,\n\t\tstateObject(\n\t\t\t{ en: \"Employee id for punch commands\", de: \"Mitarbeiter-Id f\u00FCr Stempelbefehle\" },\n\t\t\t\"number\",\n\t\t\t\"value\",\n\t\t\t{\n\t\t\t\twrite: true,\n\t\t\t},\n\t\t),\n\t);\n\tawait port.setObjectNotExists(\n\t\tCOMMAND_IDS.punch,\n\t\tstateObject({ en: \"Punch in or out\", de: \"Ein- oder ausstempeln\" }, \"boolean\", \"button\", {\n\t\t\tread: false,\n\t\t\twrite: true,\n\t\t}),\n\t);\n\tawait port.setObjectNotExists(\n\t\tCOMMAND_IDS.quickPunch,\n\t\tstateObject({ en: \"Punch with quick rounding\", de: \"Stempeln mit Schnellrundung\" }, \"boolean\", \"button\", {\n\t\t\tread: false,\n\t\t\twrite: true,\n\t\t}),\n\t);\n\tawait port.setObjectNotExists(\n\t\tCOMMAND_IDS.closeMonth,\n\t\tstateObject({ en: \"Close month (YYYY-MM)\", de: \"Monat abschlie\u00DFen (JJJJ-MM)\" }, \"string\", \"text\", {\n\t\t\twrite: true,\n\t\t}),\n\t);\n\tawait port.setObjectNotExists(\n\t\tCOMMAND_IDS.recalc,\n\t\tstateObject(\n\t\t\t{ en: \"Recalculate period (YYYY-MM or YYYY)\", de: \"Zeitraum neu berechnen (JJJJ-MM oder JJJJ)\" },\n\t\t\t\"string\",\n\t\t\t\"text\",\n\t\t\t{ write: true },\n\t\t),\n\t);\n\tawait port.setObjectNotExists(\n\t\tCOMMAND_IDS.backup,\n\t\tstateObject({ en: \"Write a database backup\", de: \"Datenbank-Sicherung schreiben\" }, \"boolean\", \"button\", {\n\t\t\tread: false,\n\t\t\twrite: true,\n\t\t}),\n\t);\n}\n\n/**\n * Creates the informational states of the instance.\n *\n * @param port - state port\n */\nexport async function createInfoStates(port: StatePort): Promise<void> {\n\tawait port.setObjectNotExists(\"info\", channelObject({ en: \"Information\", de: \"Information\" }));\n\tawait port.setObjectNotExists(\n\t\t\"info.version\",\n\t\tstateObject({ en: \"Adapter version\", de: \"Adapter-Version\" }, \"string\", \"text\"),\n\t);\n\tawait port.setObjectNotExists(\n\t\t\"info.schemaVersion\",\n\t\tstateObject({ en: \"Database schema version\", de: \"Datenbank-Schemaversion\" }, \"string\", \"text\"),\n\t);\n\tawait port.setObjectNotExists(\n\t\t\"info.dbSizeBytes\",\n\t\tstateObject({ en: \"Database size\", de: \"Datenbank-Gr\u00F6\u00DFe\" }, \"number\", \"value\", { unit: \"bytes\" }),\n\t);\n\tawait port.setObjectNotExists(\n\t\t\"info.lastError\",\n\t\tstateObject({ en: \"Last error\", de: \"Letzter Fehler\" }, \"string\", \"text\"),\n\t);\n\tawait port.setObjectNotExists(\n\t\t\"info.lastBackup\",\n\t\tstateObject({ en: \"Last backup\", de: \"Letzte Sicherung\" }, \"number\", \"value.time\"),\n\t);\n}\n\n/**\n * Creates the states of the company.\n *\n * @param port - state port\n */\nexport async function createCompanyStates(port: StatePort): Promise<void> {\n\tawait port.setObjectNotExists(\"company\", channelObject({ en: \"Company\", de: \"Firma\" }));\n\tawait port.setObjectNotExists(\n\t\t\"company.presentCount\",\n\t\tstateObject({ en: \"Present employees\", de: \"Anwesende Mitarbeiter\" }, \"number\", \"value\"),\n\t);\n\tawait port.setObjectNotExists(\n\t\t\"company.present\",\n\t\tstateObject({ en: \"Who is present\", de: \"Wer ist anwesend\" }, \"string\", \"text\"),\n\t);\n\tawait port.setObjectNotExists(\n\t\t\"company.openConflicts\",\n\t\tstateObject({ en: \"Open conflicts\", de: \"Offene Konflikte\" }, \"number\", \"value\"),\n\t);\n\tawait port.setObjectNotExists(\n\t\t\"company.lastPunch\",\n\t\tstateObject({ en: \"Last punch\", de: \"Letzte Buchung\" }, \"number\", \"value.time\"),\n\t);\n}\n\n/**\n * Reads the company figures out of the figures of the employees.\n *\n * @param snapshots - figures of all employees\n * @returns the company figures\n */\nexport function readCompanySnapshot(snapshots: UserSnapshot[]): CompanySnapshot {\n\tconst present = snapshots.filter(snapshot => snapshot.hasOpenEntry);\n\treturn {\n\t\tpresentCount: present.length,\n\t\tpresent: present.map(snapshot => snapshot.displayName).join(\", \"),\n\t\topenConflicts: snapshots.reduce((sum, snapshot) => sum + snapshot.openConflicts, 0),\n\t\tlastPunchUtc: snapshots.reduce<number | null>(\n\t\t\t(newest, snapshot) =>\n\t\t\t\tsnapshot.lastPunchUtc !== null && (newest === null || snapshot.lastPunchUtc > newest)\n\t\t\t\t\t? snapshot.lastPunchUtc\n\t\t\t\t\t: newest,\n\t\t\tnull,\n\t\t),\n\t};\n}\n\n/**\n * Publishes the company figures.\n *\n * @param port - state port\n * @param snapshot - figures to publish\n */\nexport async function publishCompanySnapshot(port: StatePort, snapshot: CompanySnapshot): Promise<void> {\n\tawait port.setState(\"company.presentCount\", snapshot.presentCount, true);\n\tawait port.setState(\"company.present\", snapshot.present, true);\n\tawait port.setState(\"company.openConflicts\", snapshot.openConflicts, true);\n\tawait port.setState(\"company.lastPunch\", snapshot.lastPunchUtc ?? 0, true);\n}\n\n/**\n * Creates the event states.\n *\n * @param port - state port\n */\nexport async function createEventStates(port: StatePort): Promise<void> {\n\tawait port.setObjectNotExists(\"events\", channelObject({ en: \"Events\", de: \"Ereignisse\" }));\n\tawait port.setObjectNotExists(\n\t\t\"events.lastAt\",\n\t\tstateObject({ en: \"Last event at\", de: \"Letztes Ereignis um\" }, \"number\", \"value.time\"),\n\t);\n\tawait port.setObjectNotExists(\n\t\t\"events.lastType\",\n\t\tstateObject({ en: \"Kind of the last event\", de: \"Art des letzten Ereignisses\" }, \"string\", \"text\"),\n\t);\n\tawait port.setObjectNotExists(\n\t\t\"events.lastUser\",\n\t\tstateObject({ en: \"Employee of the last event\", de: \"Mitarbeiter des letzten Ereignisses\" }, \"string\", \"text\"),\n\t);\n\tawait port.setObjectNotExists(\n\t\t\"events.lastDirection\",\n\t\tstateObject({ en: \"Direction of the last punch\", de: \"Richtung der letzten Buchung\" }, \"string\", \"text\"),\n\t);\n\tawait port.setObjectNotExists(\n\t\t\"events.lastSource\",\n\t\tstateObject({ en: \"Source of the last event\", de: \"Quelle des letzten Ereignisses\" }, \"string\", \"text\"),\n\t);\n}\n\n/**\n * Publishes the newest event.\n *\n * @param port - state port\n * @param snapshot - event to publish\n */\nexport async function publishEventSnapshot(port: StatePort, snapshot: EventSnapshot): Promise<void> {\n\tawait port.setState(\"events.lastAt\", snapshot.atUtc, true);\n\tawait port.setState(\"events.lastType\", snapshot.type, true);\n\tawait port.setState(\"events.lastUser\", snapshot.userName, true);\n\tawait port.setState(\"events.lastDirection\", snapshot.direction, true);\n\tawait port.setState(\"events.lastSource\", snapshot.source, true);\n}\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAmBA,kBAA8C;
|
|
4
|
+
"sourcesContent": ["/**\n * States published by the adapter.\n *\n * The adapter exposes a small, stable state tree so that other adapters (and the user's dashboards) can show\n * and trigger time tracking without speaking to the REST API:\n *\n * ```\n * users.<userId>.displayName / present / hasOpenEntry / lastPunch / todayWorkedMinutes / todayBalanceMinutes\n * users.<userId>.openConflicts\n * commands.punchUserId / punch / quickPunch / closeMonth / recalc\n * ```\n *\n * All objects are created with `setObjectNotExists`, so existing instances keep their settings. The logic works\n * on a tiny port interface (`StatePort`) \u2014 the adapter instance in production, a recorder in the tests.\n */\n\nimport type { UsersRepository } from \"../db/repositories/users\";\nimport type { AggregationService } from \"../services/aggregation\";\nimport type { SyncService } from \"../services/sync\";\nimport { STATE_NAMES, type StateName } from \"./stateNames\";\nimport { localDate as resolveLocalDate } from \"../util/time\";\n\n/** Subset of the adapter API the state layer needs. */\nexport interface StatePort {\n\t/**\n\t * Creates an object when it does not exist yet.\n\t *\n\t * @param id - full state id (including the instance prefix)\n\t * @param object - object definition\n\t */\n\tsetObjectNotExists(id: string, object: ioBroker.SettableObject): Promise<unknown> | void;\n\t/**\n\t * Merges fields into an object that already exists.\n\t *\n\t * @param id - full state id (including the instance prefix)\n\t * @param object - fields to merge\n\t */\n\textendObject(id: string, object: ioBroker.PartialObject): Promise<unknown> | void;\n\t/**\n\t * Writes a state value.\n\t *\n\t * @param id - full state id (including the instance prefix)\n\t * @param value - value to write\n\t * @param ack - true for confirmed values\n\t */\n\tsetState(id: string, value: ioBroker.StateValue, ack?: boolean): Promise<unknown> | void;\n}\n\n/** Figures of one employee shown in the state tree. */\nexport interface UserSnapshot {\n\t/** Database id of the employee */\n\tuserId: number;\n\t/** Shown name */\n\tdisplayName: string;\n\t/** True when the last punch of today has no counterpart */\n\thasOpenEntry: boolean;\n\t/** Instant of the last punch of the day, `null` when there is none */\n\tlastPunchUtc: number | null;\n\t/** Net working time of today in minutes */\n\tworkedMinutes: number;\n\t/** Balance of today in minutes */\n\tbalanceMinutes: number;\n\t/** Punches waiting for a decision */\n\topenConflicts: number;\n\t/** Net working time of the current month in minutes */\n\tmonthWorkedMinutes: number;\n\t/** Balance of the current month in minutes */\n\tmonthBalanceMinutes: number;\n\t/** Balance of the current year in minutes */\n\tyearBalanceMinutes: number;\n}\n\n/** Figures of the whole company, published next to the employees. */\nexport interface CompanySnapshot {\n\t/** Employees that are clocked in right now */\n\tpresentCount: number;\n\t/** Names of those employees, separated by a comma (empty when nobody is present) */\n\tpresent: string;\n\t/** Punches of all employees waiting for a decision */\n\topenConflicts: number;\n\t/** Instant of the newest punch of today, `null` when nobody punched */\n\tlastPunchUtc: number | null;\n}\n\n/** Newest event of the instance, mirrored into the state tree. */\nexport interface EventSnapshot {\n\t/** Kind of the event, e.g. `punch` */\n\ttype: string;\n\t/** Instant the event belongs to */\n\tatUtc: number;\n\t/** Name of the employee the event belongs to, empty for instance wide events */\n\tuserName: string;\n\t/** Direction of a punch (`in`/`out`), empty for other events */\n\tdirection: string;\n\t/** Where the change came from, e.g. `web` or `terminal`, empty when unknown */\n\tsource: string;\n}\n\n/** Names of the writable command states. */\nexport const COMMAND_IDS = {\n\t/** Employee the commands apply to */\n\tpunchUserId: \"commands.punchUserId\",\n\t/** Punch in or out for `punchUserId` */\n\tpunch: \"commands.punch\",\n\t/** Punch in or out with the configured quick rounding */\n\tquickPunch: \"commands.quickPunch\",\n\t/** Close a month, value `YYYY-MM` */\n\tcloseMonth: \"commands.closeMonth\",\n\t/** Recalculate a period, value `YYYY-MM` or `YYYY` */\n\trecalc: \"commands.recalc\",\n\t/** Write a backup of the database */\n\tbackup: \"commands.backup\",\n} as const;\n\n/**\n * Builds a state object definition.\n *\n * @param name - name in English and German\n * @param name.en - English name\n * @param name.de - German name\n * @param type - state type\n * @param role - state role\n * @param options - additional flags\n * @param options.read - value can be read (default true)\n * @param options.write - value can be written (default false)\n * @param options.unit - unit of the value\n * @returns object definition\n */\nfunction stateObject(\n\tname: StateName,\n\ttype: ioBroker.CommonType,\n\trole: string,\n\toptions: { read?: boolean; write?: boolean; unit?: string } = {},\n): ioBroker.SettableObject {\n\treturn {\n\t\ttype: \"state\",\n\t\tcommon: {\n\t\t\tname,\n\t\t\ttype,\n\t\t\trole,\n\t\t\tread: options.read !== false,\n\t\t\twrite: options.write === true,\n\t\t\t...(options.unit ? { unit: options.unit } : {}),\n\t\t},\n\t\tnative: {},\n\t};\n}\n\n/**\n * Builds a channel object definition.\n *\n * @param name - name in English and German\n * @param name.en - English name\n * @param name.de - German name\n * @returns object definition\n */\nfunction channelObject(name: StateName): ioBroker.SettableObject {\n\treturn { type: \"channel\", common: { name }, native: {} };\n}\n\n/**\n * Creates an object when it is missing and keeps its name current.\n *\n * `setObjectNotExists` alone would leave the names of existing installations untouched \u2014 the ioBroker object\n * structure check (`E6001`) reads them from the running instance, so the name is refreshed on every start. The\n * merge only touches `common.name`, existing links (for example in `vis`) stay as they are.\n *\n * @param port - state port\n * @param id - full state id (including the instance prefix)\n * @param object - object definition\n */\nasync function ensureObject(port: StatePort, id: string, object: ioBroker.SettableObject): Promise<void> {\n\tawait port.setObjectNotExists(id, object);\n\tawait port.extendObject(id, { common: { name: object.common?.name } });\n}\n\n/**\n * Reads the figures of an employee for the state tree.\n *\n * @param args - data sources and employee\n * @param args.aggregation - aggregation service\n * @param args.users - user storage\n * @param args.sync - synchronisation service (open conflicts)\n * @param args.userId - database id of the employee\n * @param args.now - instant of the snapshot\n * @returns snapshot of the figures\n */\nexport function readUserSnapshot(args: {\n\taggregation: AggregationService;\n\tusers: UsersRepository;\n\tsync: SyncService;\n\tuserId: number;\n\tnow?: number;\n}): UserSnapshot | null {\n\tconst user = args.users.findById(args.userId);\n\tif (!user) {\n\t\treturn null;\n\t}\n\n\tconst timestamp = args.now ?? Math.floor(Date.now() / 1000);\n\tconst today = resolveLocalDate(timestamp, user.timezone);\n\tconst day = args.aggregation.recalculateDay(user.id, today, { now: timestamp });\n\t// the month is recalculated like the month view does it; the year is read, so the publishing stays cheap\n\tconst year = Number(today.slice(0, 4));\n\tconst month = Number(today.slice(5, 7));\n\tconst monthAggregate = args.aggregation.recalculateMonth(user.id, year, month, { now: timestamp });\n\tconst yearAggregate = args.aggregation.year(user.id, year);\n\n\treturn {\n\t\tuserId: user.id,\n\t\tdisplayName: user.displayName,\n\t\thasOpenEntry: day.hasOpenEntry,\n\t\tlastPunchUtc: Math.max(day.firstInUtc ?? 0, day.lastOutUtc ?? 0) || null,\n\t\tworkedMinutes: day.workedMin,\n\t\tbalanceMinutes: day.balanceMin,\n\t\topenConflicts: args.sync.conflicts(user.id).length,\n\t\tmonthWorkedMinutes: monthAggregate.workedMin,\n\t\tmonthBalanceMinutes: monthAggregate.balanceMin,\n\t\tyearBalanceMinutes: yearAggregate ? yearAggregate.workedMin - yearAggregate.targetMin : 0,\n\t};\n}\n\n/**\n * Publishes the figures of one employee.\n *\n * @param port - state port\n * @param snapshot - figures to publish\n */\nexport async function publishUserSnapshot(port: StatePort, snapshot: UserSnapshot): Promise<void> {\n\tconst id = `users.${snapshot.userId}`;\n\tawait port.setState(`${id}.displayName`, snapshot.displayName, true);\n\tawait port.setState(`${id}.present`, snapshot.hasOpenEntry, true);\n\tawait port.setState(`${id}.hasOpenEntry`, snapshot.hasOpenEntry, true);\n\tawait port.setState(`${id}.lastPunch`, snapshot.lastPunchUtc ?? 0, true);\n\tawait port.setState(`${id}.todayWorkedMinutes`, snapshot.workedMinutes, true);\n\tawait port.setState(`${id}.todayBalanceMinutes`, snapshot.balanceMinutes, true);\n\tawait port.setState(`${id}.monthWorkedMinutes`, snapshot.monthWorkedMinutes, true);\n\tawait port.setState(`${id}.monthBalanceMinutes`, snapshot.monthBalanceMinutes, true);\n\tawait port.setState(`${id}.yearBalanceMinutes`, snapshot.yearBalanceMinutes, true);\n\tawait port.setState(`${id}.openConflicts`, snapshot.openConflicts, true);\n}\n\n/**\n * Creates the channels of all employees and publishes their current figures.\n *\n * @param args - state port and data sources\n * @param args.port - state port\n * @param args.aggregation - aggregation service\n * @param args.users - user storage\n * @param args.sync - synchronisation service\n * @param args.now - instant of the snapshot\n * @returns the published snapshots\n */\nexport async function publishAllUserStates(args: {\n\tport: StatePort;\n\taggregation: AggregationService;\n\tusers: UsersRepository;\n\tsync: SyncService;\n\tnow?: number;\n}): Promise<UserSnapshot[]> {\n\tconst snapshots: UserSnapshot[] = [];\n\tfor (const user of args.users.list({ includeInactive: true })) {\n\t\tawait createUserChannel(args.port, user.id);\n\t\tconst snapshot = readUserSnapshot({\n\t\t\taggregation: args.aggregation,\n\t\t\tusers: args.users,\n\t\t\tsync: args.sync,\n\t\t\tuserId: user.id,\n\t\t\tnow: args.now,\n\t\t});\n\t\tif (!snapshot) {\n\t\t\tcontinue;\n\t\t}\n\t\tawait publishUserSnapshot(args.port, snapshot);\n\t\tsnapshots.push(snapshot);\n\t}\n\treturn snapshots;\n}\n\n/**\n * Creates the channel of one employee, including the shared parent channel `users`.\n *\n * The parent channel matters: the ioBroker object structure check (`E3009`) requires every state to have its\n * parents, so `users.<userId>.*` below a missing `users` produced 126 findings in the repository check\n * (PR #6697). `setObjectNotExists` keeps the call idempotent.\n *\n * @param port - state port\n * @param userId - database id of the employee\n * @returns the channel id\n */\nexport async function createUserChannel(port: StatePort, userId: number): Promise<string> {\n\tconst id = `users.${userId}`;\n\tawait ensureObject(port, \"users\", channelObject(STATE_NAMES.usersChannel));\n\tawait ensureObject(port, id, channelObject(STATE_NAMES.employeeChannel));\n\tawait ensureObject(port, `${id}.displayName`, stateObject(STATE_NAMES.displayName, \"string\", \"info.name\"));\n\t// the writable twin of `hasOpenEntry`: a script, a fingerprint reader or a dashboard writes it to say that\n\t// somebody arrived (`true`) or left (`false`) \u2014 see `presence.ts` for what the adapter does with it\n\tawait ensureObject(\n\t\tport,\n\t\t`${id}.present`,\n\t\tstateObject(STATE_NAMES.userPresent, \"boolean\", \"switch\", { write: true }),\n\t);\n\tawait ensureObject(\n\t\tport,\n\t\t`${id}.hasOpenEntry`,\n\t\tstateObject(STATE_NAMES.hasOpenEntry, \"boolean\", \"indicator.working\"),\n\t);\n\tawait ensureObject(port, `${id}.lastPunch`, stateObject(STATE_NAMES.lastPunch, \"number\", \"value.time\"));\n\tawait ensureObject(\n\t\tport,\n\t\t`${id}.todayWorkedMinutes`,\n\t\tstateObject(STATE_NAMES.todayWorkedMinutes, \"number\", \"value\", { unit: \"min\" }),\n\t);\n\tawait ensureObject(\n\t\tport,\n\t\t`${id}.todayBalanceMinutes`,\n\t\tstateObject(STATE_NAMES.todayBalanceMinutes, \"number\", \"value\", { unit: \"min\" }),\n\t);\n\tawait ensureObject(\n\t\tport,\n\t\t`${id}.monthWorkedMinutes`,\n\t\tstateObject(STATE_NAMES.monthWorkedMinutes, \"number\", \"value\", { unit: \"min\" }),\n\t);\n\tawait ensureObject(\n\t\tport,\n\t\t`${id}.monthBalanceMinutes`,\n\t\tstateObject(STATE_NAMES.monthBalanceMinutes, \"number\", \"value\", { unit: \"min\" }),\n\t);\n\tawait ensureObject(\n\t\tport,\n\t\t`${id}.yearBalanceMinutes`,\n\t\tstateObject(STATE_NAMES.yearBalanceMinutes, \"number\", \"value\", { unit: \"min\" }),\n\t);\n\tawait ensureObject(port, `${id}.openConflicts`, stateObject(STATE_NAMES.openConflicts, \"number\", \"value\"));\n\treturn id;\n}\n\n/**\n * Creates the writable command states.\n *\n * @param port - state port\n */\nexport async function createCommandStates(port: StatePort): Promise<void> {\n\tawait ensureObject(port, \"commands\", channelObject(STATE_NAMES.commandsChannel));\n\tawait ensureObject(\n\t\tport,\n\t\tCOMMAND_IDS.punchUserId,\n\t\tstateObject(STATE_NAMES.punchUserId, \"number\", \"level\", {\n\t\t\twrite: true,\n\t\t}),\n\t);\n\tawait ensureObject(\n\t\tport,\n\t\tCOMMAND_IDS.punch,\n\t\tstateObject(STATE_NAMES.punch, \"boolean\", \"button\", {\n\t\t\tread: false,\n\t\t\twrite: true,\n\t\t}),\n\t);\n\tawait ensureObject(\n\t\tport,\n\t\tCOMMAND_IDS.quickPunch,\n\t\tstateObject(STATE_NAMES.quickPunch, \"boolean\", \"button\", {\n\t\t\tread: false,\n\t\t\twrite: true,\n\t\t}),\n\t);\n\tawait ensureObject(\n\t\tport,\n\t\tCOMMAND_IDS.closeMonth,\n\t\tstateObject(STATE_NAMES.closeMonth, \"string\", \"text\", {\n\t\t\twrite: true,\n\t\t}),\n\t);\n\tawait ensureObject(port, COMMAND_IDS.recalc, stateObject(STATE_NAMES.recalc, \"string\", \"text\", { write: true }));\n\tawait ensureObject(\n\t\tport,\n\t\tCOMMAND_IDS.backup,\n\t\tstateObject(STATE_NAMES.backupCommand, \"boolean\", \"button\", {\n\t\t\tread: false,\n\t\t\twrite: true,\n\t\t}),\n\t);\n}\n\n/**\n * Creates the informational states of the instance.\n *\n * @param port - state port\n */\nexport async function createInfoStates(port: StatePort): Promise<void> {\n\tawait ensureObject(port, \"info\", channelObject(STATE_NAMES.infoChannel));\n\tawait ensureObject(port, \"info.version\", stateObject(STATE_NAMES.version, \"string\", \"text\"));\n\tawait ensureObject(port, \"info.schemaVersion\", stateObject(STATE_NAMES.schemaVersion, \"string\", \"text\"));\n\tawait ensureObject(\n\t\tport,\n\t\t\"info.dbSizeBytes\",\n\t\tstateObject(STATE_NAMES.dbSizeBytes, \"number\", \"value\", { unit: \"bytes\" }),\n\t);\n\tawait ensureObject(port, \"info.lastError\", stateObject(STATE_NAMES.lastError, \"string\", \"text\"));\n\tawait ensureObject(port, \"info.lastBackup\", stateObject(STATE_NAMES.lastBackup, \"number\", \"value.time\"));\n}\n\n/**\n * Creates the states of the company.\n *\n * @param port - state port\n */\nexport async function createCompanyStates(port: StatePort): Promise<void> {\n\tawait ensureObject(port, \"company\", channelObject(STATE_NAMES.companyChannel));\n\tawait ensureObject(port, \"company.presentCount\", stateObject(STATE_NAMES.companyPresentCount, \"number\", \"value\"));\n\tawait ensureObject(port, \"company.present\", stateObject(STATE_NAMES.companyPresent, \"string\", \"text\"));\n\tawait ensureObject(port, \"company.openConflicts\", stateObject(STATE_NAMES.openConflicts, \"number\", \"value\"));\n\tawait ensureObject(port, \"company.lastPunch\", stateObject(STATE_NAMES.companyLastPunch, \"number\", \"value.time\"));\n}\n\n/**\n * Reads the company figures out of the figures of the employees.\n *\n * @param snapshots - figures of all employees\n * @returns the company figures\n */\nexport function readCompanySnapshot(snapshots: UserSnapshot[]): CompanySnapshot {\n\tconst present = snapshots.filter(snapshot => snapshot.hasOpenEntry);\n\treturn {\n\t\tpresentCount: present.length,\n\t\tpresent: present.map(snapshot => snapshot.displayName).join(\", \"),\n\t\topenConflicts: snapshots.reduce((sum, snapshot) => sum + snapshot.openConflicts, 0),\n\t\tlastPunchUtc: snapshots.reduce<number | null>(\n\t\t\t(newest, snapshot) =>\n\t\t\t\tsnapshot.lastPunchUtc !== null && (newest === null || snapshot.lastPunchUtc > newest)\n\t\t\t\t\t? snapshot.lastPunchUtc\n\t\t\t\t\t: newest,\n\t\t\tnull,\n\t\t),\n\t};\n}\n\n/**\n * Publishes the company figures.\n *\n * @param port - state port\n * @param snapshot - figures to publish\n */\nexport async function publishCompanySnapshot(port: StatePort, snapshot: CompanySnapshot): Promise<void> {\n\tawait port.setState(\"company.presentCount\", snapshot.presentCount, true);\n\tawait port.setState(\"company.present\", snapshot.present, true);\n\tawait port.setState(\"company.openConflicts\", snapshot.openConflicts, true);\n\tawait port.setState(\"company.lastPunch\", snapshot.lastPunchUtc ?? 0, true);\n}\n\n/**\n * Creates the event states.\n *\n * @param port - state port\n */\nexport async function createEventStates(port: StatePort): Promise<void> {\n\tawait ensureObject(port, \"events\", channelObject(STATE_NAMES.eventsChannel));\n\tawait ensureObject(port, \"events.lastAt\", stateObject(STATE_NAMES.lastAt, \"number\", \"value.time\"));\n\tawait ensureObject(port, \"events.lastType\", stateObject(STATE_NAMES.lastType, \"string\", \"text\"));\n\tawait ensureObject(port, \"events.lastUser\", stateObject(STATE_NAMES.lastUser, \"string\", \"text\"));\n\tawait ensureObject(port, \"events.lastDirection\", stateObject(STATE_NAMES.lastDirection, \"string\", \"text\"));\n\tawait ensureObject(port, \"events.lastSource\", stateObject(STATE_NAMES.lastSource, \"string\", \"text\"));\n}\n\n/**\n * Publishes the newest event.\n *\n * @param port - state port\n * @param snapshot - event to publish\n */\nexport async function publishEventSnapshot(port: StatePort, snapshot: EventSnapshot): Promise<void> {\n\tawait port.setState(\"events.lastAt\", snapshot.atUtc, true);\n\tawait port.setState(\"events.lastType\", snapshot.type, true);\n\tawait port.setState(\"events.lastUser\", snapshot.userName, true);\n\tawait port.setState(\"events.lastDirection\", snapshot.direction, true);\n\tawait port.setState(\"events.lastSource\", snapshot.source, true);\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["resolveLocalDate"]
|
|
7
7
|
}
|
package/io-package.json
CHANGED
|
@@ -1,9 +1,22 @@
|
|
|
1
1
|
{
|
|
2
2
|
"common": {
|
|
3
3
|
"name": "time-tracker",
|
|
4
|
-
"version": "0.2.
|
|
4
|
+
"version": "0.2.2",
|
|
5
5
|
"nogit": true,
|
|
6
6
|
"news": {
|
|
7
|
+
"0.2.2": {
|
|
8
|
+
"en": "the object structure check is satisfied: every object name carries all eleven languages (`E6001`) and the employee-id command uses the role `level` instead of `value` (`E1011`). The names live in one place and existing installations receive them on the next start",
|
|
9
|
+
"de": "die Objektstruktur-Prüfung ist erfüllt: jeder Objektname trägt jetzt alle elf Sprachen (`E6001`) und der Mitarbeiter-Id-Befehl nutzt die Rolle `level` statt `value` (`E1011`). Die Namen liegen an einer Stelle, bestehende Installationen erhalten sie beim nächsten Start",
|
|
10
|
+
"ru": "проверка структуры объектов пройдена: каждое имя объекта теперь содержит все одиннадцать языков (`E6001`), а команда с идентификатором сотрудника использует роль `level` вместо `value` (`E1011`). Имена хранятся в одном месте, существующие установки получат их при следующем запуске",
|
|
11
|
+
"pt": "a verificação da estrutura dos objetos está satisfeita: cada nome de objeto passa a ter os onze idiomas (`E6001`) e o comando do ID do funcionário usa a função `level` em vez de `value` (`E1011`). Os nomes ficam num único lugar e as instalações existentes recebem-nos no próximo arranque",
|
|
12
|
+
"nl": "de objectstructuurcontrole is voldaan: elke objectnaam heeft nu alle elf talen (`E6001`) en de opdracht met het medewerker-id gebruikt de rol `level` in plaats van `value` (`E1011`). De namen staan op één plek en bestaande installaties krijgen ze bij de volgende start",
|
|
13
|
+
"fr": "le contrôle de la structure des objets est satisfait : chaque nom d'objet porte désormais les onze langues (`E6001`) et la commande d'identifiant d'employé utilise le rôle `level` au lieu de `value` (`E1011`). Les noms sont au même endroit et les installations existantes les reçoivent au prochain démarrage",
|
|
14
|
+
"it": "il controllo della struttura degli oggetti è soddisfatto: ogni nome di oggetto ora porta tutte e undici le lingue (`E6001`) e il comando con l'ID del dipendente usa il ruolo `level` invece di `value` (`E1011`). I nomi stanno in un unico posto e le installazioni esistenti li ricevono al prossimo avvio",
|
|
15
|
+
"es": "la comprobación de la estructura de objetos está satisfecha: cada nombre de objeto lleva ahora los once idiomas (`E6001`) y el comando del ID del empleado usa el rol `level` en lugar de `value` (`E1011`). Los nombres están en un solo lugar y las instalaciones existentes los reciben en el próximo arranque",
|
|
16
|
+
"pl": "kontrola struktury obiektów jest spełniona: każda nazwa obiektu ma teraz wszystkie jedenaście języków (`E6001`), a polecenie z identyfikatorem pracownika używa roli `level` zamiast `value` (`E1011`). Nazwy są w jednym miejscu, a istniejące instalacje otrzymają je przy następnym starcie",
|
|
17
|
+
"uk": "перевірку структури об'єктів пройдено: кожна назва об'єкта тепер містить усі одинадцять мов (`E6001`), а команда з ідентифікатором співробітника використовує роль `level` замість `value` (`E1011`). Назви лежать в одному місці, наявні установки отримають їх під час наступного запуску",
|
|
18
|
+
"zh-cn": "对象结构检查已满足:每个对象名称现在都包含全部十一种语言(`E6001`),员工 ID 命令使用角色 `level` 而不是 `value`(`E1011`)。名称集中在一个地方,现有安装会在下次启动时获得它们"
|
|
19
|
+
},
|
|
7
20
|
"0.2.1": {
|
|
8
21
|
"en": "`common.news` starts fresh after the rename: the new npm package `iobroker.time-tracker` only carries 0.2.0, so the entries of 0.1.3 to 0.1.9 are removed again — the repository checker reported them as `E2004` (“do not exist at NPM”). The release notes of those versions stay in the changelog",
|
|
9
22
|
"de": "`common.news` beginnt nach der Umbenennung neu: das neue npm-Paket `iobroker.time-tracker` führt nur die 0.2.0, deshalb sind die Einträge 0.1.3 bis 0.1.9 wieder entfernt — der Repository-Checker meldete sie als `E2004` („do not exist at NPM“). Die Release-Notizen dieser Versionen bleiben im Changelog",
|
package/package.json
CHANGED
package/www/sw.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sw.js","sources":["../../../../../../tmp/
|
|
1
|
+
{"version":3,"file":"sw.js","sources":["../../../../../../tmp/fa11d11c8a67d5cf3c5508c32b17fc8f/sw.js"],"sourcesContent":["import {clientsClaim as workbox_core_clientsClaim} from '/home/runner/work/ioBroker.time-tracker/ioBroker.time-tracker/src-pwa/node_modules/workbox-core/clientsClaim.mjs';\nimport {precacheAndRoute as workbox_precaching_precacheAndRoute} from '/home/runner/work/ioBroker.time-tracker/ioBroker.time-tracker/src-pwa/node_modules/workbox-precaching/precacheAndRoute.mjs';\nimport {cleanupOutdatedCaches as workbox_precaching_cleanupOutdatedCaches} from '/home/runner/work/ioBroker.time-tracker/ioBroker.time-tracker/src-pwa/node_modules/workbox-precaching/cleanupOutdatedCaches.mjs';\nimport {registerRoute as workbox_routing_registerRoute} from '/home/runner/work/ioBroker.time-tracker/ioBroker.time-tracker/src-pwa/node_modules/workbox-routing/registerRoute.mjs';\nimport {NavigationRoute as workbox_routing_NavigationRoute} from '/home/runner/work/ioBroker.time-tracker/ioBroker.time-tracker/src-pwa/node_modules/workbox-routing/NavigationRoute.mjs';\nimport {createHandlerBoundToURL as workbox_precaching_createHandlerBoundToURL} from '/home/runner/work/ioBroker.time-tracker/ioBroker.time-tracker/src-pwa/node_modules/workbox-precaching/createHandlerBoundToURL.mjs';/**\n * Welcome to your Workbox-powered service worker!\n *\n * You'll need to register this file in your web app.\n * See https://goo.gl/nhQhGp\n *\n * The rest of the code is auto-generated. Please don't update this file\n * directly; instead, make changes to your Workbox build configuration\n * and re-run your build process.\n * See https://goo.gl/2aRDsh\n */\n\n\n\n\nself.skipWaiting();\nworkbox_core_clientsClaim();\n/**\n * The precacheAndRoute() method efficiently caches and responds to\n * requests for URLs in the manifest.\n * See https://goo.gl/S9QRab\n */\nworkbox_precaching_precacheAndRoute([\n {\n \"url\": \"person.png\",\n \"revision\": \"771d3283ece4739e203e02aac535855e\"\n },\n {\n \"url\": \"index.html\",\n \"revision\": \"45c88f7faf80a0e4c5539908dc6b94f2\"\n },\n {\n \"url\": \"icon-512.png\",\n \"revision\": \"d8e3715779f4cd7e67e1f82f215a2f22\"\n },\n {\n \"url\": \"icon-192.png\",\n \"revision\": \"940ef37caef09c52272ddab844b9ea9b\"\n },\n {\n \"url\": \"favicon.svg\",\n \"revision\": \"309e9efece69d60920618512ab9d57bf\"\n },\n {\n \"url\": \"assets/workbox-window.prod.es5-Bd17z0YL.js\",\n \"revision\": null\n },\n {\n \"url\": \"assets/index-QI3wrEvW.js\",\n \"revision\": null\n },\n {\n \"url\": \"icon-192.png\",\n \"revision\": \"940ef37caef09c52272ddab844b9ea9b\"\n },\n {\n \"url\": \"icon-512.png\",\n \"revision\": \"d8e3715779f4cd7e67e1f82f215a2f22\"\n },\n {\n \"url\": \"manifest.webmanifest\",\n \"revision\": \"6f40f1ce0ce138d5af307fb0dbb1e6f9\"\n }\n], {});\nworkbox_precaching_cleanupOutdatedCaches();workbox_routing_registerRoute(new workbox_routing_NavigationRoute(workbox_precaching_createHandlerBoundToURL(\"index.html\"), {\n allowlist: [/^\\/$/], denylist: [/^\\/api\\//],}));\n\n\n"],"names":["self","skipWaiting","workbox_core_clientsClaim","workbox_precaching_precacheAndRoute","url","revision","workbox_precaching_cleanupOutdatedCaches","workbox_routing_registerRoute","workbox_routing_NavigationRoute","workbox_precaching_createHandlerBoundToURL","allowlist","denylist"],"mappings":"inBAoBAA,KAAKC,cACLC,EAAAA,eAMAC,EAAAA,iBAAoC,CAClC,CACEC,IAAO,aACPC,SAAY,oCAEd,CACED,IAAO,aACPC,SAAY,oCAEd,CACED,IAAO,eACPC,SAAY,oCAEd,CACED,IAAO,eACPC,SAAY,oCAEd,CACED,IAAO,cACPC,SAAY,oCAEd,CACED,IAAO,6CACPC,SAAY,MAEd,CACED,IAAO,2BACPC,SAAY,MAEd,CACED,IAAO,eACPC,SAAY,oCAEd,CACED,IAAO,eACPC,SAAY,oCAEd,CACED,IAAO,uBACPC,SAAY,qCAEb,CAAA,GACHC,EAAAA,wBAA2CC,EAAAA,cAA8B,IAAIC,EAAAA,gBAAgCC,0BAA2C,cAAe,CACrKC,UAAW,CAAC,QAAUC,SAAU,CAAC"}
|