iobroker.parcelapp 0.3.2 → 0.4.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  # ioBroker.parcelapp
2
2
 
3
3
  [![npm version](https://img.shields.io/npm/v/iobroker.parcelapp)](https://www.npmjs.com/package/iobroker.parcelapp)
4
- ![Node](https://img.shields.io/badge/node-%3E%3D20-brightgreen)
4
+ ![Node](https://img.shields.io/badge/node-%3E%3D22-brightgreen)
5
5
  ![TypeScript](https://img.shields.io/badge/TypeScript-strict-blue)
6
6
  [![License](https://img.shields.io/badge/license-MIT-green)](LICENSE)
7
7
  [![npm downloads](https://img.shields.io/npm/dt/iobroker.parcelapp)](https://www.npmjs.com/package/iobroker.parcelapp)
@@ -11,7 +11,7 @@
11
11
 
12
12
  <img src="https://raw.githubusercontent.com/krobipd/ioBroker.parcelapp/main/admin/parcelapp.svg" width="100" />
13
13
 
14
- ioBroker adapter that connects to the [parcel.app](https://parcelapp.net) API and exposes package tracking data as ioBroker states — including delivery status, time windows, and tracking events. Supports all carriers that parcel.app tracks.
14
+ ioBroker adapter for the [parcel.app](https://parcelapp.net) API. Supports all carriers that parcel.app tracks.
15
15
 
16
16
  ---
17
17
 
@@ -21,19 +21,18 @@ ioBroker adapter that connects to the [parcel.app](https://parcelapp.net) API an
21
21
  - **Per-package ioBroker states** — carrier, status, tracking number, delivery window, last event, last location
22
22
  - **Summary states** — active count, today count, combined delivery window
23
23
  - **Delivery time estimates** — today, tomorrow, in X days with combined time window
24
- - **Automatic polling** with configurable interval (5–60 minutes)
24
+ - **Configurable poll interval** (5–60 minutes)
25
25
  - **Configurable cleanup** — auto-remove delivered packages or keep them until deleted in parcel.app
26
26
  - **Add deliveries** via sendTo message from scripts or other adapters
27
27
  - **Admin UI** with connection test and polling settings
28
- - **Status labels follow the ioBroker system language** — all 11 supported languages (de, en, ru, pt, nl, fr, it, es, pl, uk, zh-cn), English fallback for unknown codes
29
28
 
30
29
  ---
31
30
 
32
31
  ## Requirements
33
32
 
34
- - **Node.js >= 20**
33
+ - **Node.js >= 22**
35
34
  - **ioBroker js-controller >= 7.0.7**
36
- - **ioBroker Admin >= 7.7.22**
35
+ - **ioBroker Admin >= 7.8.23**
37
36
  - **parcel.app Premium subscription** — required for API access
38
37
 
39
38
  ---
@@ -119,6 +118,11 @@ The delivery is added to your parcel.app account and immediately appears in ioBr
119
118
  ---
120
119
 
121
120
  ## Changelog
121
+ ### 0.4.0 (2026-05-06)
122
+
123
+ - State names now follow your ioBroker system language (11 languages). User-visible info/warn/error logs are localized too.
124
+ - Minimum requirements: Node.js 22 and ioBroker Admin 7.8.23.
125
+
122
126
  ### 0.3.2 (2026-05-01)
123
127
  - Documentation: rewrote release notes for v0.2.14–v0.3.1 in user-friendly style across all languages.
124
128
 
@@ -131,12 +135,7 @@ The delivery is added to your parcel.app account and immediately appears in ioBr
131
135
  ### 0.2.18 (2026-04-28)
132
136
  - Internal cleanup. No user-facing changes.
133
137
 
134
- ### 0.2.17 (2026-04-28)
135
- - Internal cleanup. No user-facing changes.
136
-
137
- Older entries are in [CHANGELOG_OLD.md](CHANGELOG_OLD.md).
138
-
139
- ## Support
138
+ Older entries are in [CHANGELOG_OLD.md](CHANGELOG_OLD.md).## Support
140
139
 
141
140
  - [ioBroker Forum](https://forum.iobroker.net/)
142
141
  - [GitHub Issues](https://github.com/krobipd/ioBroker.parcelapp/issues)
@@ -0,0 +1,99 @@
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 coerce_exports = {};
20
+ __export(coerce_exports, {
21
+ coerceBoolean: () => coerceBoolean,
22
+ coerceFiniteNumber: () => coerceFiniteNumber,
23
+ coerceString: () => coerceString,
24
+ errText: () => errText,
25
+ isPlainObject: () => isPlainObject,
26
+ isTrueish: () => isTrueish
27
+ });
28
+ module.exports = __toCommonJS(coerce_exports);
29
+ const DECIMAL_NUMBER_RE = /^-?\d+(\.\d+)?$/;
30
+ function coerceFiniteNumber(value) {
31
+ if (typeof value === "number") {
32
+ return Number.isFinite(value) ? value : null;
33
+ }
34
+ if (typeof value === "string" && DECIMAL_NUMBER_RE.test(value)) {
35
+ const n = Number(value);
36
+ return Number.isFinite(n) ? n : null;
37
+ }
38
+ return null;
39
+ }
40
+ function coerceString(value) {
41
+ if (typeof value === "string" && value.length > 0) {
42
+ return value;
43
+ }
44
+ return null;
45
+ }
46
+ function coerceBoolean(value) {
47
+ if (typeof value === "boolean") {
48
+ return value;
49
+ }
50
+ return null;
51
+ }
52
+ function isPlainObject(value) {
53
+ return typeof value === "object" && value !== null && !Array.isArray(value);
54
+ }
55
+ function isTrueish(v) {
56
+ if (typeof v === "boolean") {
57
+ return v;
58
+ }
59
+ if (typeof v === "number") {
60
+ return v === 1;
61
+ }
62
+ if (typeof v === "string") {
63
+ const s = v.toLowerCase();
64
+ return s === "true" || s === "1";
65
+ }
66
+ return false;
67
+ }
68
+ function errText(err) {
69
+ if (err instanceof Error) {
70
+ return err.message;
71
+ }
72
+ if (err === null) {
73
+ return "null";
74
+ }
75
+ if (err === void 0) {
76
+ return "undefined";
77
+ }
78
+ if (typeof err === "string") {
79
+ return err;
80
+ }
81
+ if (typeof err === "number" || typeof err === "boolean" || typeof err === "bigint") {
82
+ return String(err);
83
+ }
84
+ try {
85
+ return JSON.stringify(err);
86
+ } catch {
87
+ return Object.prototype.toString.call(err);
88
+ }
89
+ }
90
+ // Annotate the CommonJS export names for ESM import in node:
91
+ 0 && (module.exports = {
92
+ coerceBoolean,
93
+ coerceFiniteNumber,
94
+ coerceString,
95
+ errText,
96
+ isPlainObject,
97
+ isTrueish
98
+ });
99
+ //# sourceMappingURL=coerce.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/lib/coerce.ts"],
4
+ "sourcesContent": ["/**\n * Boundary coercion helpers for external API data.\n *\n * The parcel.app API is documented but field types still drift in practice\n * (rare success-flag returned as `\"true\"` string, occasional null where a\n * number is expected). These helpers guard against NaN/Infinity/non-string\n * values reaching ioBroker states.\n */\n\n// Strict decimal regex \u2014 only optional minus sign + digits + optional fractional part.\n// Rejects HEX (`0x...`), exponential (`1e3`), Infinity, NaN, leading/trailing whitespace.\n// Hassemu (E8 in v1.9.0) hardened the same coerce-helper this way; homewizard\n// adopted it in v0.7.2 (D8). Consistent with both adapters.\nconst DECIMAL_NUMBER_RE = /^-?\\d+(\\.\\d+)?$/;\n\n/**\n * Coerce to a finite number or null.\n * Accepts numbers directly; parses strict decimal strings; rejects NaN, Infinity,\n * HEX (`0x...`) and exponential notation (`1e3`).\n *\n * @param value Unknown external value\n */\nexport function coerceFiniteNumber(value: unknown): number | null {\n if (typeof value === \"number\") {\n return Number.isFinite(value) ? value : null;\n }\n if (typeof value === \"string\" && DECIMAL_NUMBER_RE.test(value)) {\n const n = Number(value);\n return Number.isFinite(n) ? n : null;\n }\n return null;\n}\n\n/**\n * Coerce to a non-empty string, or null.\n *\n * @param value Unknown external value\n */\nexport function coerceString(value: unknown): string | null {\n if (typeof value === \"string\" && value.length > 0) {\n return value;\n }\n return null;\n}\n\n/**\n * Coerce to a boolean (only `true`/`false` accepted \u2014 no truthy/falsy JS rules).\n *\n * @param value Unknown external value\n */\nexport function coerceBoolean(value: unknown): boolean | null {\n if (typeof value === \"boolean\") {\n return value;\n }\n return null;\n}\n\n/**\n * Guard for plain objects (not arrays, not null).\n *\n * @param value Unknown external value\n */\nexport function isPlainObject(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\n/**\n * Coerce a parcel.app `success` flag. The API returns a real boolean in normal\n * operation, but the guard accepts common string/number encodings (`1`, `\"true\"`,\n * `\"1\"`) so a one-off drift doesn't break the entire poll cycle.\n *\n * @param v Value to interpret as a success flag\n */\nexport function isTrueish(v: unknown): boolean {\n if (typeof v === \"boolean\") {\n return v;\n }\n if (typeof v === \"number\") {\n return v === 1;\n }\n if (typeof v === \"string\") {\n const s = v.toLowerCase();\n return s === \"true\" || s === \"1\";\n }\n return false;\n}\n\n/**\n * Extract a log-friendly message from a thrown / rejected value. Centralizes the\n * `err instanceof Error ? err.message : String(err)` pattern that otherwise\n * gets repeated at every catch-site. Plain objects are JSON-stringified so a\n * `[object Object]` log is avoided when callers throw bag-of-fields.\n *\n * @param err Caught value of unknown shape (Error, string, undefined, ...).\n */\nexport function errText(err: unknown): string {\n if (err instanceof Error) {\n return err.message;\n }\n if (err === null) {\n return \"null\";\n }\n if (err === undefined) {\n return \"undefined\";\n }\n if (typeof err === \"string\") {\n return err;\n }\n if (typeof err === \"number\" || typeof err === \"boolean\" || typeof err === \"bigint\") {\n return String(err);\n }\n // Plain objects + symbols would otherwise stringify to \"[object Object]\" / fail.\n // Prefer JSON for the common case so the log is at least diagnosable.\n try {\n return JSON.stringify(err);\n } catch {\n return Object.prototype.toString.call(err);\n }\n}\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAaA,MAAM,oBAAoB;AASnB,SAAS,mBAAmB,OAA+B;AAChE,MAAI,OAAO,UAAU,UAAU;AAC7B,WAAO,OAAO,SAAS,KAAK,IAAI,QAAQ;AAAA,EAC1C;AACA,MAAI,OAAO,UAAU,YAAY,kBAAkB,KAAK,KAAK,GAAG;AAC9D,UAAM,IAAI,OAAO,KAAK;AACtB,WAAO,OAAO,SAAS,CAAC,IAAI,IAAI;AAAA,EAClC;AACA,SAAO;AACT;AAOO,SAAS,aAAa,OAA+B;AAC1D,MAAI,OAAO,UAAU,YAAY,MAAM,SAAS,GAAG;AACjD,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAOO,SAAS,cAAc,OAAgC;AAC5D,MAAI,OAAO,UAAU,WAAW;AAC9B,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAOO,SAAS,cAAc,OAAkD;AAC9E,SAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAC5E;AASO,SAAS,UAAU,GAAqB;AAC7C,MAAI,OAAO,MAAM,WAAW;AAC1B,WAAO;AAAA,EACT;AACA,MAAI,OAAO,MAAM,UAAU;AACzB,WAAO,MAAM;AAAA,EACf;AACA,MAAI,OAAO,MAAM,UAAU;AACzB,UAAM,IAAI,EAAE,YAAY;AACxB,WAAO,MAAM,UAAU,MAAM;AAAA,EAC/B;AACA,SAAO;AACT;AAUO,SAAS,QAAQ,KAAsB;AAC5C,MAAI,eAAe,OAAO;AACxB,WAAO,IAAI;AAAA,EACb;AACA,MAAI,QAAQ,MAAM;AAChB,WAAO;AAAA,EACT;AACA,MAAI,QAAQ,QAAW;AACrB,WAAO;AAAA,EACT;AACA,MAAI,OAAO,QAAQ,UAAU;AAC3B,WAAO;AAAA,EACT;AACA,MAAI,OAAO,QAAQ,YAAY,OAAO,QAAQ,aAAa,OAAO,QAAQ,UAAU;AAClF,WAAO,OAAO,GAAG;AAAA,EACnB;AAGA,MAAI;AACF,WAAO,KAAK,UAAU,GAAG;AAAA,EAC3B,QAAQ;AACN,WAAO,OAAO,UAAU,SAAS,KAAK,GAAG;AAAA,EAC3C;AACF;",
6
+ "names": []
7
+ }
@@ -0,0 +1,229 @@
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 i18n_logs_exports = {};
20
+ __export(i18n_logs_exports, {
21
+ LOG_STRINGS: () => LOG_STRINGS,
22
+ tLog: () => tLog
23
+ });
24
+ module.exports = __toCommonJS(i18n_logs_exports);
25
+ const SUPPORTED_LANGS = ["en", "de", "ru", "pt", "nl", "fr", "it", "es", "pl", "uk", "zh-cn"];
26
+ function fmt(template, params) {
27
+ if (!params) {
28
+ return template;
29
+ }
30
+ return template.replace(/\{(\w+)\}/g, (_, key) => {
31
+ const v = params[key];
32
+ if (v === null) {
33
+ return "(none)";
34
+ }
35
+ if (v === void 0) {
36
+ return `{${key}}`;
37
+ }
38
+ return String(v);
39
+ });
40
+ }
41
+ const LOG_STRINGS = {
42
+ // ──────── Adapter lifecycle / crash defense ────────
43
+ onReadyFailed: {
44
+ en: "onReady failed: {error}",
45
+ de: "onReady fehlgeschlagen: {error}",
46
+ ru: "onReady \u0437\u0430\u0432\u0435\u0440\u0448\u0438\u043B\u0441\u044F \u0441 \u043E\u0448\u0438\u0431\u043A\u043E\u0439: {error}",
47
+ pt: "onReady falhou: {error}",
48
+ nl: "onReady is mislukt: {error}",
49
+ fr: "onReady a \xE9chou\xE9 : {error}",
50
+ it: "onReady non riuscito: {error}",
51
+ es: "onReady fall\xF3: {error}",
52
+ pl: "onReady nie powi\xF3d\u0142 si\u0119: {error}",
53
+ uk: "onReady \u0437\u0430\u0432\u0435\u0440\u0448\u0438\u0432\u0441\u044F \u0437 \u043F\u043E\u043C\u0438\u043B\u043A\u043E\u044E: {error}",
54
+ "zh-cn": "onReady \u5931\u8D25\uFF1A{error}"
55
+ },
56
+ onMessageFailed: {
57
+ en: "onMessage failed: {error}",
58
+ de: "onMessage fehlgeschlagen: {error}",
59
+ ru: "onMessage \u0437\u0430\u0432\u0435\u0440\u0448\u0438\u043B\u0441\u044F \u0441 \u043E\u0448\u0438\u0431\u043A\u043E\u0439: {error}",
60
+ pt: "onMessage falhou: {error}",
61
+ nl: "onMessage is mislukt: {error}",
62
+ fr: "onMessage a \xE9chou\xE9 : {error}",
63
+ it: "onMessage non riuscito: {error}",
64
+ es: "onMessage fall\xF3: {error}",
65
+ pl: "onMessage nie powi\xF3d\u0142 si\u0119: {error}",
66
+ uk: "onMessage \u0437\u0430\u0432\u0435\u0440\u0448\u0438\u0432\u0441\u044F \u0437 \u043F\u043E\u043C\u0438\u043B\u043A\u043E\u044E: {error}",
67
+ "zh-cn": "onMessage \u5931\u8D25\uFF1A{error}"
68
+ },
69
+ unhandledRejection: {
70
+ en: "Unhandled rejection: {error}",
71
+ de: "Unbehandelte Promise-Rejection: {error}",
72
+ ru: "\u041D\u0435\u043E\u0431\u0440\u0430\u0431\u043E\u0442\u0430\u043D\u043D\u044B\u0439 rejection: {error}",
73
+ pt: "Rejei\xE7\xE3o n\xE3o tratada: {error}",
74
+ nl: "Onafgehandelde rejection: {error}",
75
+ fr: "Rejet non g\xE9r\xE9 : {error}",
76
+ it: "Rejection non gestita: {error}",
77
+ es: "Rechazo no manejado: {error}",
78
+ pl: "Nieobs\u0142u\u017Cone odrzucenie: {error}",
79
+ uk: "\u041D\u0435\u043E\u0431\u0440\u043E\u0431\u043B\u0435\u043D\u0438\u0439 rejection: {error}",
80
+ "zh-cn": "\u672A\u5904\u7406\u7684 rejection\uFF1A{error}"
81
+ },
82
+ uncaughtException: {
83
+ en: "Uncaught exception: {error}",
84
+ de: "Nicht abgefangene Exception: {error}",
85
+ ru: "\u041D\u0435\u043E\u0431\u0440\u0430\u0431\u043E\u0442\u0430\u043D\u043D\u043E\u0435 \u0438\u0441\u043A\u043B\u044E\u0447\u0435\u043D\u0438\u0435: {error}",
86
+ pt: "Exce\xE7\xE3o n\xE3o capturada: {error}",
87
+ nl: "Niet-opgevangen exception: {error}",
88
+ fr: "Exception non captur\xE9e : {error}",
89
+ it: "Eccezione non catturata: {error}",
90
+ es: "Excepci\xF3n no capturada: {error}",
91
+ pl: "Nieprzechwycony wyj\u0105tek: {error}",
92
+ uk: "\u041D\u0435\u043F\u0435\u0440\u0435\u0445\u043E\u043F\u043B\u0435\u043D\u0435 \u0432\u0438\u043A\u043B\u044E\u0447\u0435\u043D\u043D\u044F: {error}",
93
+ "zh-cn": "\u672A\u6355\u83B7\u7684\u5F02\u5E38\uFF1A{error}"
94
+ },
95
+ // ──────── Configuration / startup ────────
96
+ noApiKey: {
97
+ en: "No valid API key configured \u2014 please enter your parcel.app API key in the adapter settings",
98
+ de: "Kein g\xFCltiger API-Key konfiguriert \u2014 bitte trage deinen parcel.app API-Key in den Adapter-Einstellungen ein",
99
+ ru: "API-\u043A\u043B\u044E\u0447 \u043D\u0435 \u043D\u0430\u0441\u0442\u0440\u043E\u0435\u043D \u2014 \u0432\u0432\u0435\u0434\u0438\u0442\u0435 \u0432\u0430\u0448 parcel.app API-\u043A\u043B\u044E\u0447 \u0432 \u043D\u0430\u0441\u0442\u0440\u043E\u0439\u043A\u0430\u0445 \u0430\u0434\u0430\u043F\u0442\u0435\u0440\u0430",
100
+ pt: "Nenhuma chave de API v\xE1lida configurada \u2014 insira a sua chave parcel.app nas configura\xE7\xF5es do adaptador",
101
+ nl: "Geen geldige API-sleutel geconfigureerd \u2014 voer je parcel.app API-sleutel in de adapter-instellingen in",
102
+ fr: "Aucune cl\xE9 API valide configur\xE9e \u2014 saisissez votre cl\xE9 parcel.app dans les param\xE8tres de l'adaptateur",
103
+ it: "Nessuna chiave API valida configurata \u2014 inserisci la tua chiave parcel.app nelle impostazioni dell'adattatore",
104
+ es: "Ninguna clave API v\xE1lida configurada \u2014 introduce tu clave parcel.app en los ajustes del adaptador",
105
+ pl: "Nie skonfigurowano poprawnego klucza API \u2014 wprowad\u017A sw\xF3j klucz parcel.app w ustawieniach adaptera",
106
+ uk: "\u041D\u0435\u043C\u0430\u0454 \u043D\u0430\u043B\u0430\u0448\u0442\u043E\u0432\u0430\u043D\u043E\u0433\u043E API-\u043A\u043B\u044E\u0447\u0430 \u2014 \u0432\u0432\u0435\u0434\u0456\u0442\u044C \u0432\u0430\u0448 parcel.app API-\u043A\u043B\u044E\u0447 \u0443 \u043D\u0430\u043B\u0430\u0448\u0442\u0443\u0432\u0430\u043D\u043D\u044F\u0445 \u0430\u0434\u0430\u043F\u0442\u0435\u0440\u0430",
107
+ "zh-cn": "\u672A\u914D\u7F6E\u6709\u6548\u7684 API \u5BC6\u94A5 \u2014 \u8BF7\u5728\u9002\u914D\u5668\u8BBE\u7F6E\u4E2D\u8F93\u5165\u60A8\u7684 parcel.app API \u5BC6\u94A5"
108
+ },
109
+ trackingStarted: {
110
+ en: "Parcel tracking started \u2014 polling every {minutes} minutes",
111
+ de: "Paketverfolgung gestartet \u2014 Abfrage alle {minutes} Minuten",
112
+ ru: "\u041E\u0442\u0441\u043B\u0435\u0436\u0438\u0432\u0430\u043D\u0438\u0435 \u043F\u043E\u0441\u044B\u043B\u043E\u043A \u0437\u0430\u043F\u0443\u0449\u0435\u043D\u043E \u2014 \u043E\u043F\u0440\u043E\u0441 \u043A\u0430\u0436\u0434\u044B\u0435 {minutes} \u043C\u0438\u043D",
113
+ pt: "Monitoriza\xE7\xE3o de encomendas iniciada \u2014 sondagem a cada {minutes} minutos",
114
+ nl: "Pakketvolg-systeem gestart \u2014 pollen elke {minutes} minuten",
115
+ fr: "Suivi des colis d\xE9marr\xE9 \u2014 interrogation toutes les {minutes} minutes",
116
+ it: "Tracciamento pacchi avviato \u2014 interrogazione ogni {minutes} minuti",
117
+ es: "Seguimiento de paquetes iniciado \u2014 consulta cada {minutes} minutos",
118
+ pl: "\u015Aledzenie paczek uruchomione \u2014 odpytywanie co {minutes} minut",
119
+ uk: "\u0412\u0456\u0434\u0441\u0442\u0435\u0436\u0435\u043D\u043D\u044F \u043F\u043E\u0441\u0438\u043B\u043E\u043A \u0437\u0430\u043F\u0443\u0449\u0435\u043D\u043E \u2014 \u043E\u043F\u0438\u0442\u0443\u0432\u0430\u043D\u043D\u044F \u043A\u043E\u0436\u043D\u0456 {minutes} \u0445\u0432",
120
+ "zh-cn": "\u5305\u88F9\u8DDF\u8E2A\u5DF2\u542F\u52A8 \u2014 \u6BCF {minutes} \u5206\u949F\u8F6E\u8BE2\u4E00\u6B21"
121
+ },
122
+ // ──────── Connection / poll ────────
123
+ connectionRestored: {
124
+ en: "Connection restored",
125
+ de: "Verbindung wiederhergestellt",
126
+ ru: "\u0421\u043E\u0435\u0434\u0438\u043D\u0435\u043D\u0438\u0435 \u0432\u043E\u0441\u0441\u0442\u0430\u043D\u043E\u0432\u043B\u0435\u043D\u043E",
127
+ pt: "Conex\xE3o restabelecida",
128
+ nl: "Verbinding hersteld",
129
+ fr: "Connexion r\xE9tablie",
130
+ it: "Connessione ripristinata",
131
+ es: "Conexi\xF3n restablecida",
132
+ pl: "Po\u0142\u0105czenie przywr\xF3cone",
133
+ uk: "\u0417'\u0454\u0434\u043D\u0430\u043D\u043D\u044F \u0432\u0456\u0434\u043D\u043E\u0432\u043B\u0435\u043D\u043E",
134
+ "zh-cn": "\u8FDE\u63A5\u5DF2\u6062\u590D"
135
+ },
136
+ cannotReach: {
137
+ en: "Cannot reach parcel.app API \u2014 will keep retrying",
138
+ de: "parcel.app-API nicht erreichbar \u2014 Versuche werden fortgesetzt",
139
+ ru: "parcel.app API \u043D\u0435\u0434\u043E\u0441\u0442\u0443\u043F\u0435\u043D \u2014 \u043F\u043E\u043F\u044B\u0442\u043A\u0438 \u043F\u0440\u043E\u0434\u043E\u043B\u0436\u0430\u044E\u0442\u0441\u044F",
140
+ pt: "N\xE3o foi poss\xEDvel contactar a API parcel.app \u2014 tentativas continuar\xE3o",
141
+ nl: "parcel.app-API onbereikbaar \u2014 pogingen worden voortgezet",
142
+ fr: "API parcel.app injoignable \u2014 les tentatives continuent",
143
+ it: "API parcel.app non raggiungibile \u2014 i tentativi continueranno",
144
+ es: "API parcel.app inaccesible \u2014 se seguir\xE1n intentando",
145
+ pl: "API parcel.app niedost\u0119pne \u2014 pr\xF3by b\u0119d\u0105 kontynuowane",
146
+ uk: "API parcel.app \u043D\u0435\u0434\u043E\u0441\u0442\u0443\u043F\u043D\u0438\u0439 \u2014 \u0441\u043F\u0440\u043E\u0431\u0438 \u0442\u0440\u0438\u0432\u0430\u0442\u0438\u043C\u0443\u0442\u044C",
147
+ "zh-cn": "\u65E0\u6CD5\u8BBF\u95EE parcel.app API \u2014 \u5C06\u7EE7\u7EED\u91CD\u8BD5"
148
+ },
149
+ apiTimeout: {
150
+ en: "API request timeout \u2014 will retry next cycle",
151
+ de: "API-Anfrage-Timeout \u2014 Wiederholung im n\xE4chsten Zyklus",
152
+ ru: "\u0422\u0430\u0439\u043C-\u0430\u0443\u0442 API-\u0437\u0430\u043F\u0440\u043E\u0441\u0430 \u2014 \u043F\u043E\u0432\u0442\u043E\u0440 \u0432 \u0441\u043B\u0435\u0434\u0443\u044E\u0449\u0435\u043C \u0446\u0438\u043A\u043B\u0435",
153
+ pt: "Tempo limite da API \u2014 tentar de novo no pr\xF3ximo ciclo",
154
+ nl: "API-verzoek-time-out \u2014 opnieuw proberen volgende cyclus",
155
+ fr: "D\xE9lai d'API d\xE9pass\xE9 \u2014 nouvelle tentative au prochain cycle",
156
+ it: "Timeout della richiesta API \u2014 riprovo al prossimo ciclo",
157
+ es: "Tiempo de espera de la API agotado \u2014 se reintentar\xE1 en el pr\xF3ximo ciclo",
158
+ pl: "Przekroczono limit czasu API \u2014 ponowa pr\xF3ba w nast\u0119pnym cyklu",
159
+ uk: "\u0422\u0430\u0439\u043C-\u0430\u0443\u0442 API-\u0437\u0430\u043F\u0438\u0442\u0443 \u2014 \u043F\u043E\u0432\u0442\u043E\u0440 \u0443 \u043D\u0430\u0441\u0442\u0443\u043F\u043D\u043E\u043C\u0443 \u0446\u0438\u043A\u043B\u0456",
160
+ "zh-cn": "API \u8BF7\u6C42\u8D85\u65F6 \u2014 \u5C06\u5728\u4E0B\u4E00\u4E2A\u5468\u671F\u91CD\u8BD5"
161
+ },
162
+ pollFailed: {
163
+ en: "Poll failed: {error}",
164
+ de: "Abfrage fehlgeschlagen: {error}",
165
+ ru: "\u041E\u043F\u0440\u043E\u0441 \u0437\u0430\u0432\u0435\u0440\u0448\u0438\u043B\u0441\u044F \u0441 \u043E\u0448\u0438\u0431\u043A\u043E\u0439: {error}",
166
+ pt: "Sondagem falhou: {error}",
167
+ nl: "Poll is mislukt: {error}",
168
+ fr: "\xC9chec de l'interrogation : {error}",
169
+ it: "Interrogazione non riuscita: {error}",
170
+ es: "Consulta fall\xF3: {error}",
171
+ pl: "Odpytywanie nie powiod\u0142o si\u0119: {error}",
172
+ uk: "\u041E\u043F\u0438\u0442\u0443\u0432\u0430\u043D\u043D\u044F \u0437\u0430\u0432\u0435\u0440\u0448\u0438\u043B\u043E\u0441\u044C \u0437 \u043F\u043E\u043C\u0438\u043B\u043A\u043E\u044E: {error}",
173
+ "zh-cn": "\u8F6E\u8BE2\u5931\u8D25\uFF1A{error}"
174
+ },
175
+ // ──────── Rate limit / auth ────────
176
+ rateLimitHit: {
177
+ en: "Rate limit hit \u2014 pausing API requests for {minutes} minute(s)",
178
+ de: "Rate-Limit erreicht \u2014 API-Anfragen pausieren f\xFCr {minutes} Minute(n)",
179
+ ru: "\u0414\u043E\u0441\u0442\u0438\u0433\u043D\u0443\u0442 \u043B\u0438\u043C\u0438\u0442 \u0437\u0430\u043F\u0440\u043E\u0441\u043E\u0432 \u2014 \u043F\u0430\u0443\u0437\u0430 API \u043D\u0430 {minutes} \u043C\u0438\u043D",
180
+ pt: "Limite de taxa atingido \u2014 pausa nos pedidos \xE0 API por {minutes} minuto(s)",
181
+ nl: "Rate limit bereikt \u2014 API-verzoeken pauzeren voor {minutes} minuut/minuten",
182
+ fr: "Limite de d\xE9bit atteinte \u2014 pause des requ\xEAtes API pendant {minutes} minute(s)",
183
+ it: "Limite di frequenza raggiunto \u2014 pausa delle richieste API per {minutes} minuto/i",
184
+ es: "L\xEDmite de solicitudes alcanzado \u2014 pausando peticiones API durante {minutes} minuto(s)",
185
+ pl: "Osi\u0105gni\u0119to limit zapyta\u0144 \u2014 pauza w \u017C\u0105daniach API przez {minutes} minut",
186
+ uk: "\u0414\u043E\u0441\u044F\u0433\u043D\u0443\u0442\u043E \u043B\u0456\u043C\u0456\u0442 \u0437\u0430\u043F\u0438\u0442\u0456\u0432 \u2014 \u043F\u0430\u0443\u0437\u0430 API \u043D\u0430 {minutes} \u0445\u0432",
187
+ "zh-cn": "\u8FBE\u5230\u901F\u7387\u9650\u5236 \u2014 API \u8BF7\u6C42\u6682\u505C {minutes} \u5206\u949F"
188
+ },
189
+ invalidApiKey: {
190
+ en: "Invalid API key \u2014 please check your parcel.app API key",
191
+ de: "Ung\xFCltiger API-Key \u2014 bitte pr\xFCfe deinen parcel.app API-Key",
192
+ ru: "\u041D\u0435\u0432\u0435\u0440\u043D\u044B\u0439 API-\u043A\u043B\u044E\u0447 \u2014 \u043F\u0440\u043E\u0432\u0435\u0440\u044C\u0442\u0435 \u0432\u0430\u0448 parcel.app API-\u043A\u043B\u044E\u0447",
193
+ pt: "Chave de API inv\xE1lida \u2014 verifique a sua chave parcel.app",
194
+ nl: "Ongeldige API-sleutel \u2014 controleer je parcel.app API-sleutel",
195
+ fr: "Cl\xE9 API invalide \u2014 v\xE9rifiez votre cl\xE9 parcel.app",
196
+ it: "Chiave API non valida \u2014 verifica la tua chiave parcel.app",
197
+ es: "Clave API inv\xE1lida \u2014 comprueba tu clave parcel.app",
198
+ pl: "Nieprawid\u0142owy klucz API \u2014 sprawd\u017A sw\xF3j klucz parcel.app",
199
+ uk: "\u041D\u0435\u0432\u0456\u0440\u043D\u0438\u0439 API-\u043A\u043B\u044E\u0447 \u2014 \u043F\u0435\u0440\u0435\u0432\u0456\u0440\u0442\u0435 \u0432\u0430\u0448 parcel.app API-\u043A\u043B\u044E\u0447",
200
+ "zh-cn": "API \u5BC6\u94A5\u65E0\u6548 \u2014 \u8BF7\u68C0\u67E5\u60A8\u7684 parcel.app API \u5BC6\u94A5"
201
+ },
202
+ // ──────── Per-package update failure ────────
203
+ updateFailed: {
204
+ en: "Failed to update '{tracking}': {error}",
205
+ de: "Aktualisierung von '{tracking}' fehlgeschlagen: {error}",
206
+ ru: "\u041D\u0435 \u0443\u0434\u0430\u043B\u043E\u0441\u044C \u043E\u0431\u043D\u043E\u0432\u0438\u0442\u044C '{tracking}': {error}",
207
+ pt: "Falha ao atualizar '{tracking}': {error}",
208
+ nl: "Bijwerken van '{tracking}' is mislukt: {error}",
209
+ fr: "\xC9chec de la mise \xE0 jour de '{tracking}' : {error}",
210
+ it: "Impossibile aggiornare '{tracking}': {error}",
211
+ es: "Error al actualizar '{tracking}': {error}",
212
+ pl: "Nie uda\u0142o si\u0119 zaktualizowa\u0107 '{tracking}': {error}",
213
+ uk: "\u041D\u0435 \u0432\u0434\u0430\u043B\u043E\u0441\u044F \u043E\u043D\u043E\u0432\u0438\u0442\u0438 '{tracking}': {error}",
214
+ "zh-cn": "\u66F4\u65B0 '{tracking}' \u5931\u8D25\uFF1A{error}"
215
+ }
216
+ };
217
+ function tLog(lang, key, params) {
218
+ var _a;
219
+ const langKey = SUPPORTED_LANGS.includes(lang) ? lang : "en";
220
+ const bundle = LOG_STRINGS[key];
221
+ const template = (_a = bundle[langKey]) != null ? _a : bundle.en;
222
+ return fmt(template, params);
223
+ }
224
+ // Annotate the CommonJS export names for ESM import in node:
225
+ 0 && (module.exports = {
226
+ LOG_STRINGS,
227
+ tLog
228
+ });
229
+ //# sourceMappingURL=i18n-logs.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/lib/i18n-logs.ts"],
4
+ "sourcesContent": ["/**\n * Localized log strings \u2014 info/warn/error end up in the ioBroker admin log,\n * which is user-facing. Translations cover all 11 ioBroker system languages\n * (en/de/ru/pt/nl/fr/it/es/pl/uk/zh-cn).\n *\n * The active language is read once in `main.onReady` from\n * `system.config.language` and stored on the adapter instance. A language\n * change in admin requires an adapter restart \u2014 acceptable, users don't\n * switch languages on the fly.\n *\n * Debug logs stay English (maintainer diagnostics, not user-visible at\n * default loglevel).\n */\n\nconst SUPPORTED_LANGS = [\"en\", \"de\", \"ru\", \"pt\", \"nl\", \"fr\", \"it\", \"es\", \"pl\", \"uk\", \"zh-cn\"] as const;\ntype Lang = (typeof SUPPORTED_LANGS)[number];\n\n/**\n * Token substitution: `{name}` in the template is replaced with `params.name`.\n * `null` values render as `(none)`, missing tokens are kept as `{key}` so a\n * caller bug surfaces in the log instead of silently emitting an empty string.\n *\n * @param template Localized log string with `{key}` placeholders.\n * @param params Token values; `null` \u2192 `(none)`, `undefined` \u2192 token kept.\n */\nfunction fmt(template: string, params?: Record<string, string | number | null | undefined>): string {\n if (!params) {\n return template;\n }\n return template.replace(/\\{(\\w+)\\}/g, (_, key: string) => {\n const v = params[key];\n if (v === null) {\n return \"(none)\";\n }\n if (v === undefined) {\n return `{${key}}`;\n }\n return String(v);\n });\n}\n\n/**\n * All user-facing info/warn/error strings. Keys are descriptive identifiers,\n * values are bundles for the 11 supported ioBroker system languages.\n */\nexport const LOG_STRINGS = {\n // \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 Adapter lifecycle / crash defense \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n onReadyFailed: {\n en: \"onReady failed: {error}\",\n de: \"onReady fehlgeschlagen: {error}\",\n ru: \"onReady \u0437\u0430\u0432\u0435\u0440\u0448\u0438\u043B\u0441\u044F \u0441 \u043E\u0448\u0438\u0431\u043A\u043E\u0439: {error}\",\n pt: \"onReady falhou: {error}\",\n nl: \"onReady is mislukt: {error}\",\n fr: \"onReady a \u00E9chou\u00E9 : {error}\",\n it: \"onReady non riuscito: {error}\",\n es: \"onReady fall\u00F3: {error}\",\n pl: \"onReady nie powi\u00F3d\u0142 si\u0119: {error}\",\n uk: \"onReady \u0437\u0430\u0432\u0435\u0440\u0448\u0438\u0432\u0441\u044F \u0437 \u043F\u043E\u043C\u0438\u043B\u043A\u043E\u044E: {error}\",\n \"zh-cn\": \"onReady \u5931\u8D25\uFF1A{error}\",\n },\n onMessageFailed: {\n en: \"onMessage failed: {error}\",\n de: \"onMessage fehlgeschlagen: {error}\",\n ru: \"onMessage \u0437\u0430\u0432\u0435\u0440\u0448\u0438\u043B\u0441\u044F \u0441 \u043E\u0448\u0438\u0431\u043A\u043E\u0439: {error}\",\n pt: \"onMessage falhou: {error}\",\n nl: \"onMessage is mislukt: {error}\",\n fr: \"onMessage a \u00E9chou\u00E9 : {error}\",\n it: \"onMessage non riuscito: {error}\",\n es: \"onMessage fall\u00F3: {error}\",\n pl: \"onMessage nie powi\u00F3d\u0142 si\u0119: {error}\",\n uk: \"onMessage \u0437\u0430\u0432\u0435\u0440\u0448\u0438\u0432\u0441\u044F \u0437 \u043F\u043E\u043C\u0438\u043B\u043A\u043E\u044E: {error}\",\n \"zh-cn\": \"onMessage \u5931\u8D25\uFF1A{error}\",\n },\n unhandledRejection: {\n en: \"Unhandled rejection: {error}\",\n de: \"Unbehandelte Promise-Rejection: {error}\",\n ru: \"\u041D\u0435\u043E\u0431\u0440\u0430\u0431\u043E\u0442\u0430\u043D\u043D\u044B\u0439 rejection: {error}\",\n pt: \"Rejei\u00E7\u00E3o n\u00E3o tratada: {error}\",\n nl: \"Onafgehandelde rejection: {error}\",\n fr: \"Rejet non g\u00E9r\u00E9 : {error}\",\n it: \"Rejection non gestita: {error}\",\n es: \"Rechazo no manejado: {error}\",\n pl: \"Nieobs\u0142u\u017Cone odrzucenie: {error}\",\n uk: \"\u041D\u0435\u043E\u0431\u0440\u043E\u0431\u043B\u0435\u043D\u0438\u0439 rejection: {error}\",\n \"zh-cn\": \"\u672A\u5904\u7406\u7684 rejection\uFF1A{error}\",\n },\n uncaughtException: {\n en: \"Uncaught exception: {error}\",\n de: \"Nicht abgefangene Exception: {error}\",\n ru: \"\u041D\u0435\u043E\u0431\u0440\u0430\u0431\u043E\u0442\u0430\u043D\u043D\u043E\u0435 \u0438\u0441\u043A\u043B\u044E\u0447\u0435\u043D\u0438\u0435: {error}\",\n pt: \"Exce\u00E7\u00E3o n\u00E3o capturada: {error}\",\n nl: \"Niet-opgevangen exception: {error}\",\n fr: \"Exception non captur\u00E9e : {error}\",\n it: \"Eccezione non catturata: {error}\",\n es: \"Excepci\u00F3n no capturada: {error}\",\n pl: \"Nieprzechwycony wyj\u0105tek: {error}\",\n uk: \"\u041D\u0435\u043F\u0435\u0440\u0435\u0445\u043E\u043F\u043B\u0435\u043D\u0435 \u0432\u0438\u043A\u043B\u044E\u0447\u0435\u043D\u043D\u044F: {error}\",\n \"zh-cn\": \"\u672A\u6355\u83B7\u7684\u5F02\u5E38\uFF1A{error}\",\n },\n\n // \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 Configuration / startup \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n noApiKey: {\n en: \"No valid API key configured \u2014 please enter your parcel.app API key in the adapter settings\",\n de: \"Kein g\u00FCltiger API-Key konfiguriert \u2014 bitte trage deinen parcel.app API-Key in den Adapter-Einstellungen ein\",\n ru: \"API-\u043A\u043B\u044E\u0447 \u043D\u0435 \u043D\u0430\u0441\u0442\u0440\u043E\u0435\u043D \u2014 \u0432\u0432\u0435\u0434\u0438\u0442\u0435 \u0432\u0430\u0448 parcel.app API-\u043A\u043B\u044E\u0447 \u0432 \u043D\u0430\u0441\u0442\u0440\u043E\u0439\u043A\u0430\u0445 \u0430\u0434\u0430\u043F\u0442\u0435\u0440\u0430\",\n pt: \"Nenhuma chave de API v\u00E1lida configurada \u2014 insira a sua chave parcel.app nas configura\u00E7\u00F5es do adaptador\",\n nl: \"Geen geldige API-sleutel geconfigureerd \u2014 voer je parcel.app API-sleutel in de adapter-instellingen in\",\n fr: \"Aucune cl\u00E9 API valide configur\u00E9e \u2014 saisissez votre cl\u00E9 parcel.app dans les param\u00E8tres de l'adaptateur\",\n it: \"Nessuna chiave API valida configurata \u2014 inserisci la tua chiave parcel.app nelle impostazioni dell'adattatore\",\n es: \"Ninguna clave API v\u00E1lida configurada \u2014 introduce tu clave parcel.app en los ajustes del adaptador\",\n pl: \"Nie skonfigurowano poprawnego klucza API \u2014 wprowad\u017A sw\u00F3j klucz parcel.app w ustawieniach adaptera\",\n uk: \"\u041D\u0435\u043C\u0430\u0454 \u043D\u0430\u043B\u0430\u0448\u0442\u043E\u0432\u0430\u043D\u043E\u0433\u043E API-\u043A\u043B\u044E\u0447\u0430 \u2014 \u0432\u0432\u0435\u0434\u0456\u0442\u044C \u0432\u0430\u0448 parcel.app API-\u043A\u043B\u044E\u0447 \u0443 \u043D\u0430\u043B\u0430\u0448\u0442\u0443\u0432\u0430\u043D\u043D\u044F\u0445 \u0430\u0434\u0430\u043F\u0442\u0435\u0440\u0430\",\n \"zh-cn\": \"\u672A\u914D\u7F6E\u6709\u6548\u7684 API \u5BC6\u94A5 \u2014 \u8BF7\u5728\u9002\u914D\u5668\u8BBE\u7F6E\u4E2D\u8F93\u5165\u60A8\u7684 parcel.app API \u5BC6\u94A5\",\n },\n trackingStarted: {\n en: \"Parcel tracking started \u2014 polling every {minutes} minutes\",\n de: \"Paketverfolgung gestartet \u2014 Abfrage alle {minutes} Minuten\",\n ru: \"\u041E\u0442\u0441\u043B\u0435\u0436\u0438\u0432\u0430\u043D\u0438\u0435 \u043F\u043E\u0441\u044B\u043B\u043E\u043A \u0437\u0430\u043F\u0443\u0449\u0435\u043D\u043E \u2014 \u043E\u043F\u0440\u043E\u0441 \u043A\u0430\u0436\u0434\u044B\u0435 {minutes} \u043C\u0438\u043D\",\n pt: \"Monitoriza\u00E7\u00E3o de encomendas iniciada \u2014 sondagem a cada {minutes} minutos\",\n nl: \"Pakketvolg-systeem gestart \u2014 pollen elke {minutes} minuten\",\n fr: \"Suivi des colis d\u00E9marr\u00E9 \u2014 interrogation toutes les {minutes} minutes\",\n it: \"Tracciamento pacchi avviato \u2014 interrogazione ogni {minutes} minuti\",\n es: \"Seguimiento de paquetes iniciado \u2014 consulta cada {minutes} minutos\",\n pl: \"\u015Aledzenie paczek uruchomione \u2014 odpytywanie co {minutes} minut\",\n uk: \"\u0412\u0456\u0434\u0441\u0442\u0435\u0436\u0435\u043D\u043D\u044F \u043F\u043E\u0441\u0438\u043B\u043E\u043A \u0437\u0430\u043F\u0443\u0449\u0435\u043D\u043E \u2014 \u043E\u043F\u0438\u0442\u0443\u0432\u0430\u043D\u043D\u044F \u043A\u043E\u0436\u043D\u0456 {minutes} \u0445\u0432\",\n \"zh-cn\": \"\u5305\u88F9\u8DDF\u8E2A\u5DF2\u542F\u52A8 \u2014 \u6BCF {minutes} \u5206\u949F\u8F6E\u8BE2\u4E00\u6B21\",\n },\n\n // \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 Connection / poll \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n connectionRestored: {\n en: \"Connection restored\",\n de: \"Verbindung wiederhergestellt\",\n ru: \"\u0421\u043E\u0435\u0434\u0438\u043D\u0435\u043D\u0438\u0435 \u0432\u043E\u0441\u0441\u0442\u0430\u043D\u043E\u0432\u043B\u0435\u043D\u043E\",\n pt: \"Conex\u00E3o restabelecida\",\n nl: \"Verbinding hersteld\",\n fr: \"Connexion r\u00E9tablie\",\n it: \"Connessione ripristinata\",\n es: \"Conexi\u00F3n restablecida\",\n pl: \"Po\u0142\u0105czenie przywr\u00F3cone\",\n uk: \"\u0417'\u0454\u0434\u043D\u0430\u043D\u043D\u044F \u0432\u0456\u0434\u043D\u043E\u0432\u043B\u0435\u043D\u043E\",\n \"zh-cn\": \"\u8FDE\u63A5\u5DF2\u6062\u590D\",\n },\n cannotReach: {\n en: \"Cannot reach parcel.app API \u2014 will keep retrying\",\n de: \"parcel.app-API nicht erreichbar \u2014 Versuche werden fortgesetzt\",\n ru: \"parcel.app API \u043D\u0435\u0434\u043E\u0441\u0442\u0443\u043F\u0435\u043D \u2014 \u043F\u043E\u043F\u044B\u0442\u043A\u0438 \u043F\u0440\u043E\u0434\u043E\u043B\u0436\u0430\u044E\u0442\u0441\u044F\",\n pt: \"N\u00E3o foi poss\u00EDvel contactar a API parcel.app \u2014 tentativas continuar\u00E3o\",\n nl: \"parcel.app-API onbereikbaar \u2014 pogingen worden voortgezet\",\n fr: \"API parcel.app injoignable \u2014 les tentatives continuent\",\n it: \"API parcel.app non raggiungibile \u2014 i tentativi continueranno\",\n es: \"API parcel.app inaccesible \u2014 se seguir\u00E1n intentando\",\n pl: \"API parcel.app niedost\u0119pne \u2014 pr\u00F3by b\u0119d\u0105 kontynuowane\",\n uk: \"API parcel.app \u043D\u0435\u0434\u043E\u0441\u0442\u0443\u043F\u043D\u0438\u0439 \u2014 \u0441\u043F\u0440\u043E\u0431\u0438 \u0442\u0440\u0438\u0432\u0430\u0442\u0438\u043C\u0443\u0442\u044C\",\n \"zh-cn\": \"\u65E0\u6CD5\u8BBF\u95EE parcel.app API \u2014 \u5C06\u7EE7\u7EED\u91CD\u8BD5\",\n },\n apiTimeout: {\n en: \"API request timeout \u2014 will retry next cycle\",\n de: \"API-Anfrage-Timeout \u2014 Wiederholung im n\u00E4chsten Zyklus\",\n ru: \"\u0422\u0430\u0439\u043C-\u0430\u0443\u0442 API-\u0437\u0430\u043F\u0440\u043E\u0441\u0430 \u2014 \u043F\u043E\u0432\u0442\u043E\u0440 \u0432 \u0441\u043B\u0435\u0434\u0443\u044E\u0449\u0435\u043C \u0446\u0438\u043A\u043B\u0435\",\n pt: \"Tempo limite da API \u2014 tentar de novo no pr\u00F3ximo ciclo\",\n nl: \"API-verzoek-time-out \u2014 opnieuw proberen volgende cyclus\",\n fr: \"D\u00E9lai d'API d\u00E9pass\u00E9 \u2014 nouvelle tentative au prochain cycle\",\n it: \"Timeout della richiesta API \u2014 riprovo al prossimo ciclo\",\n es: \"Tiempo de espera de la API agotado \u2014 se reintentar\u00E1 en el pr\u00F3ximo ciclo\",\n pl: \"Przekroczono limit czasu API \u2014 ponowa pr\u00F3ba w nast\u0119pnym cyklu\",\n uk: \"\u0422\u0430\u0439\u043C-\u0430\u0443\u0442 API-\u0437\u0430\u043F\u0438\u0442\u0443 \u2014 \u043F\u043E\u0432\u0442\u043E\u0440 \u0443 \u043D\u0430\u0441\u0442\u0443\u043F\u043D\u043E\u043C\u0443 \u0446\u0438\u043A\u043B\u0456\",\n \"zh-cn\": \"API \u8BF7\u6C42\u8D85\u65F6 \u2014 \u5C06\u5728\u4E0B\u4E00\u4E2A\u5468\u671F\u91CD\u8BD5\",\n },\n pollFailed: {\n en: \"Poll failed: {error}\",\n de: \"Abfrage fehlgeschlagen: {error}\",\n ru: \"\u041E\u043F\u0440\u043E\u0441 \u0437\u0430\u0432\u0435\u0440\u0448\u0438\u043B\u0441\u044F \u0441 \u043E\u0448\u0438\u0431\u043A\u043E\u0439: {error}\",\n pt: \"Sondagem falhou: {error}\",\n nl: \"Poll is mislukt: {error}\",\n fr: \"\u00C9chec de l'interrogation : {error}\",\n it: \"Interrogazione non riuscita: {error}\",\n es: \"Consulta fall\u00F3: {error}\",\n pl: \"Odpytywanie nie powiod\u0142o si\u0119: {error}\",\n uk: \"\u041E\u043F\u0438\u0442\u0443\u0432\u0430\u043D\u043D\u044F \u0437\u0430\u0432\u0435\u0440\u0448\u0438\u043B\u043E\u0441\u044C \u0437 \u043F\u043E\u043C\u0438\u043B\u043A\u043E\u044E: {error}\",\n \"zh-cn\": \"\u8F6E\u8BE2\u5931\u8D25\uFF1A{error}\",\n },\n\n // \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 Rate limit / auth \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n rateLimitHit: {\n en: \"Rate limit hit \u2014 pausing API requests for {minutes} minute(s)\",\n de: \"Rate-Limit erreicht \u2014 API-Anfragen pausieren f\u00FCr {minutes} Minute(n)\",\n ru: \"\u0414\u043E\u0441\u0442\u0438\u0433\u043D\u0443\u0442 \u043B\u0438\u043C\u0438\u0442 \u0437\u0430\u043F\u0440\u043E\u0441\u043E\u0432 \u2014 \u043F\u0430\u0443\u0437\u0430 API \u043D\u0430 {minutes} \u043C\u0438\u043D\",\n pt: \"Limite de taxa atingido \u2014 pausa nos pedidos \u00E0 API por {minutes} minuto(s)\",\n nl: \"Rate limit bereikt \u2014 API-verzoeken pauzeren voor {minutes} minuut/minuten\",\n fr: \"Limite de d\u00E9bit atteinte \u2014 pause des requ\u00EAtes API pendant {minutes} minute(s)\",\n it: \"Limite di frequenza raggiunto \u2014 pausa delle richieste API per {minutes} minuto/i\",\n es: \"L\u00EDmite de solicitudes alcanzado \u2014 pausando peticiones API durante {minutes} minuto(s)\",\n pl: \"Osi\u0105gni\u0119to limit zapyta\u0144 \u2014 pauza w \u017C\u0105daniach API przez {minutes} minut\",\n uk: \"\u0414\u043E\u0441\u044F\u0433\u043D\u0443\u0442\u043E \u043B\u0456\u043C\u0456\u0442 \u0437\u0430\u043F\u0438\u0442\u0456\u0432 \u2014 \u043F\u0430\u0443\u0437\u0430 API \u043D\u0430 {minutes} \u0445\u0432\",\n \"zh-cn\": \"\u8FBE\u5230\u901F\u7387\u9650\u5236 \u2014 API \u8BF7\u6C42\u6682\u505C {minutes} \u5206\u949F\",\n },\n invalidApiKey: {\n en: \"Invalid API key \u2014 please check your parcel.app API key\",\n de: \"Ung\u00FCltiger API-Key \u2014 bitte pr\u00FCfe deinen parcel.app API-Key\",\n ru: \"\u041D\u0435\u0432\u0435\u0440\u043D\u044B\u0439 API-\u043A\u043B\u044E\u0447 \u2014 \u043F\u0440\u043E\u0432\u0435\u0440\u044C\u0442\u0435 \u0432\u0430\u0448 parcel.app API-\u043A\u043B\u044E\u0447\",\n pt: \"Chave de API inv\u00E1lida \u2014 verifique a sua chave parcel.app\",\n nl: \"Ongeldige API-sleutel \u2014 controleer je parcel.app API-sleutel\",\n fr: \"Cl\u00E9 API invalide \u2014 v\u00E9rifiez votre cl\u00E9 parcel.app\",\n it: \"Chiave API non valida \u2014 verifica la tua chiave parcel.app\",\n es: \"Clave API inv\u00E1lida \u2014 comprueba tu clave parcel.app\",\n pl: \"Nieprawid\u0142owy klucz API \u2014 sprawd\u017A sw\u00F3j klucz parcel.app\",\n uk: \"\u041D\u0435\u0432\u0456\u0440\u043D\u0438\u0439 API-\u043A\u043B\u044E\u0447 \u2014 \u043F\u0435\u0440\u0435\u0432\u0456\u0440\u0442\u0435 \u0432\u0430\u0448 parcel.app API-\u043A\u043B\u044E\u0447\",\n \"zh-cn\": \"API \u5BC6\u94A5\u65E0\u6548 \u2014 \u8BF7\u68C0\u67E5\u60A8\u7684 parcel.app API \u5BC6\u94A5\",\n },\n\n // \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 Per-package update failure \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n updateFailed: {\n en: \"Failed to update '{tracking}': {error}\",\n de: \"Aktualisierung von '{tracking}' fehlgeschlagen: {error}\",\n ru: \"\u041D\u0435 \u0443\u0434\u0430\u043B\u043E\u0441\u044C \u043E\u0431\u043D\u043E\u0432\u0438\u0442\u044C '{tracking}': {error}\",\n pt: \"Falha ao atualizar '{tracking}': {error}\",\n nl: \"Bijwerken van '{tracking}' is mislukt: {error}\",\n fr: \"\u00C9chec de la mise \u00E0 jour de '{tracking}' : {error}\",\n it: \"Impossibile aggiornare '{tracking}': {error}\",\n es: \"Error al actualizar '{tracking}': {error}\",\n pl: \"Nie uda\u0142o si\u0119 zaktualizowa\u0107 '{tracking}': {error}\",\n uk: \"\u041D\u0435 \u0432\u0434\u0430\u043B\u043E\u0441\u044F \u043E\u043D\u043E\u0432\u0438\u0442\u0438 '{tracking}': {error}\",\n \"zh-cn\": \"\u66F4\u65B0 '{tracking}' \u5931\u8D25\uFF1A{error}\",\n },\n} as const;\n\n/**\n * Look up a log string in the requested language with EN fallback.\n *\n * @param lang ioBroker system language (`'en'`, `'de'`, \u2026) \u2014 any string\n * accepted, falls back to `en` for unknown values.\n * @param key Translation key from {@link LOG_STRINGS}.\n * @param params Token values for `{name}` placeholders.\n */\nexport function tLog(\n lang: string,\n key: keyof typeof LOG_STRINGS,\n params?: Record<string, string | number | null | undefined>,\n): string {\n const langKey = (SUPPORTED_LANGS as readonly string[]).includes(lang) ? (lang as Lang) : \"en\";\n const bundle = LOG_STRINGS[key];\n const template = bundle[langKey] ?? bundle.en;\n return fmt(template, params);\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }