@serhii.olishevskyi/docs 1.0.4 → 1.0.6

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/dist/index.js CHANGED
@@ -30,2288 +30,6 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
30
30
  ));
31
31
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
32
32
 
33
- // node_modules/i18next/dist/esm/i18next.js
34
- function createProxy() {
35
- const state = [];
36
- const handler = /* @__PURE__ */ Object.create(null);
37
- let proxy;
38
- handler.get = (target, key) => {
39
- proxy?.revoke?.();
40
- if (key === PATH_KEY) return state;
41
- state.push(key);
42
- proxy = Proxy.revocable(target, handler);
43
- return proxy.proxy;
44
- };
45
- return Proxy.revocable(/* @__PURE__ */ Object.create(null), handler).proxy;
46
- }
47
- function keysFromSelector(selector, opts) {
48
- const {
49
- [PATH_KEY]: path
50
- } = selector(createProxy());
51
- const keySeparator = opts?.keySeparator ?? ".";
52
- const nsSeparator = opts?.nsSeparator ?? ":";
53
- const strict = opts?.enableSelector === "strict";
54
- if (path.length > 1 && nsSeparator) {
55
- const ns = opts?.ns;
56
- const nsList = strict ? Array.isArray(ns) ? ns : ns ? [ns] : null : Array.isArray(ns) ? ns : null;
57
- if (nsList) {
58
- const candidates = strict ? nsList : nsList.length > 1 ? nsList.slice(1) : [];
59
- if (candidates.includes(path[0])) {
60
- return `${path[0]}${nsSeparator}${path.slice(1).join(keySeparator)}`;
61
- }
62
- }
63
- }
64
- return path.join(keySeparator);
65
- }
66
- var isString, defer, makeString, copy, lastOfPathSeparatorRegExp, cleanKey, canNotTraverseDeeper, getLastOfPath, setPath, pushPath, getPath, getPathWithDefaults, deepExtend, regexEscape, _entityMap, escape, RegExpCache, chars, looksLikeObjectPathRegExpCache, looksLikeObjectPath, deepFind, getCleanedCode, consoleLogger, Logger, baseLogger, EventEmitter, ResourceStore, postProcessor, PATH_KEY, shouldHandleAsObject, Translator, LanguageUtil, suffixesOrder, dummyRule, PluralResolver, deepFindWithDefaults, regexSafe, Interpolator, parseFormatStr, createCachedFormatter, createNonCachedFormatter, Formatter, removePending, Connector, get, transformOptions, noop, bindMemberFunctions, I18n, instance, createInstance, dir, init, loadResources, reloadResources, use, changeLanguage, getFixedT, t, exists, setDefaultNamespace, hasLoadedNamespace, loadNamespaces, loadLanguages;
67
- var init_i18next = __esm({
68
- "node_modules/i18next/dist/esm/i18next.js"() {
69
- "use strict";
70
- isString = (obj) => typeof obj === "string";
71
- defer = () => {
72
- let res;
73
- let rej;
74
- const promise = new Promise((resolve, reject) => {
75
- res = resolve;
76
- rej = reject;
77
- });
78
- promise.resolve = res;
79
- promise.reject = rej;
80
- return promise;
81
- };
82
- makeString = (object) => {
83
- if (object == null) return "";
84
- return String(object);
85
- };
86
- copy = (a, s, t2) => {
87
- a.forEach((m) => {
88
- if (s[m]) t2[m] = s[m];
89
- });
90
- };
91
- lastOfPathSeparatorRegExp = /###/g;
92
- cleanKey = (key) => key && key.includes("###") ? key.replace(lastOfPathSeparatorRegExp, ".") : key;
93
- canNotTraverseDeeper = (object) => !object || isString(object);
94
- getLastOfPath = (object, path, Empty) => {
95
- const stack = !isString(path) ? path : path.split(".");
96
- let stackIndex = 0;
97
- while (stackIndex < stack.length - 1) {
98
- if (canNotTraverseDeeper(object)) return {};
99
- const key = cleanKey(stack[stackIndex]);
100
- if (!object[key] && Empty) object[key] = new Empty();
101
- if (Object.prototype.hasOwnProperty.call(object, key)) {
102
- object = object[key];
103
- } else {
104
- object = {};
105
- }
106
- ++stackIndex;
107
- }
108
- if (canNotTraverseDeeper(object)) return {};
109
- return {
110
- obj: object,
111
- k: cleanKey(stack[stackIndex])
112
- };
113
- };
114
- setPath = (object, path, newValue) => {
115
- const {
116
- obj,
117
- k
118
- } = getLastOfPath(object, path, Object);
119
- if (obj !== void 0 || path.length === 1) {
120
- obj[k] = newValue;
121
- return;
122
- }
123
- let e = path[path.length - 1];
124
- let p = path.slice(0, path.length - 1);
125
- let last = getLastOfPath(object, p, Object);
126
- while (last.obj === void 0 && p.length) {
127
- e = `${p[p.length - 1]}.${e}`;
128
- p = p.slice(0, p.length - 1);
129
- last = getLastOfPath(object, p, Object);
130
- if (last?.obj && typeof last.obj[`${last.k}.${e}`] !== "undefined") {
131
- last.obj = void 0;
132
- }
133
- }
134
- last.obj[`${last.k}.${e}`] = newValue;
135
- };
136
- pushPath = (object, path, newValue, concat) => {
137
- const {
138
- obj,
139
- k
140
- } = getLastOfPath(object, path, Object);
141
- obj[k] = obj[k] || [];
142
- obj[k].push(newValue);
143
- };
144
- getPath = (object, path) => {
145
- const {
146
- obj,
147
- k
148
- } = getLastOfPath(object, path);
149
- if (!obj) return void 0;
150
- if (!Object.prototype.hasOwnProperty.call(obj, k)) return void 0;
151
- return obj[k];
152
- };
153
- getPathWithDefaults = (data, defaultData, key) => {
154
- const value = getPath(data, key);
155
- if (value !== void 0) {
156
- return value;
157
- }
158
- return getPath(defaultData, key);
159
- };
160
- deepExtend = (target, source, overwrite) => {
161
- for (const prop in source) {
162
- if (prop !== "__proto__" && prop !== "constructor") {
163
- if (Object.prototype.hasOwnProperty.call(target, prop)) {
164
- if (isString(target[prop]) || target[prop] instanceof String || isString(source[prop]) || source[prop] instanceof String) {
165
- if (overwrite) target[prop] = source[prop];
166
- } else {
167
- deepExtend(target[prop], source[prop], overwrite);
168
- }
169
- } else {
170
- target[prop] = source[prop];
171
- }
172
- }
173
- }
174
- return target;
175
- };
176
- regexEscape = (str) => str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
177
- _entityMap = {
178
- "&": "&amp;",
179
- "<": "&lt;",
180
- ">": "&gt;",
181
- '"': "&quot;",
182
- "'": "&#39;",
183
- "/": "&#x2F;"
184
- };
185
- escape = (data) => {
186
- if (isString(data)) {
187
- return data.replace(/[&<>"'\/]/g, (s) => _entityMap[s]);
188
- }
189
- return data;
190
- };
191
- RegExpCache = class {
192
- constructor(capacity) {
193
- this.capacity = capacity;
194
- this.regExpMap = /* @__PURE__ */ new Map();
195
- this.regExpQueue = [];
196
- }
197
- getRegExp(pattern) {
198
- const regExpFromCache = this.regExpMap.get(pattern);
199
- if (regExpFromCache !== void 0) {
200
- return regExpFromCache;
201
- }
202
- const regExpNew = new RegExp(pattern);
203
- if (this.regExpQueue.length === this.capacity) {
204
- this.regExpMap.delete(this.regExpQueue.shift());
205
- }
206
- this.regExpMap.set(pattern, regExpNew);
207
- this.regExpQueue.push(pattern);
208
- return regExpNew;
209
- }
210
- };
211
- chars = [" ", ",", "?", "!", ";"];
212
- looksLikeObjectPathRegExpCache = new RegExpCache(20);
213
- looksLikeObjectPath = (key, nsSeparator, keySeparator) => {
214
- nsSeparator = nsSeparator || "";
215
- keySeparator = keySeparator || "";
216
- const possibleChars = chars.filter((c) => !nsSeparator.includes(c) && !keySeparator.includes(c));
217
- if (possibleChars.length === 0) return true;
218
- const r = looksLikeObjectPathRegExpCache.getRegExp(`(${possibleChars.map((c) => c === "?" ? "\\?" : c).join("|")})`);
219
- let matched = !r.test(key);
220
- if (!matched) {
221
- const ki = key.indexOf(keySeparator);
222
- if (ki > 0 && !r.test(key.substring(0, ki))) {
223
- matched = true;
224
- }
225
- }
226
- return matched;
227
- };
228
- deepFind = (obj, path, keySeparator = ".") => {
229
- if (!obj) return void 0;
230
- if (obj[path]) {
231
- if (!Object.prototype.hasOwnProperty.call(obj, path)) return void 0;
232
- return obj[path];
233
- }
234
- const tokens = path.split(keySeparator);
235
- let current = obj;
236
- for (let i = 0; i < tokens.length; ) {
237
- if (!current || typeof current !== "object") {
238
- return void 0;
239
- }
240
- let next;
241
- let nextPath = "";
242
- for (let j = i; j < tokens.length; ++j) {
243
- if (j !== i) {
244
- nextPath += keySeparator;
245
- }
246
- nextPath += tokens[j];
247
- next = current[nextPath];
248
- if (next !== void 0) {
249
- if (["string", "number", "boolean"].includes(typeof next) && j < tokens.length - 1) {
250
- continue;
251
- }
252
- i += j - i + 1;
253
- break;
254
- }
255
- }
256
- current = next;
257
- }
258
- return current;
259
- };
260
- getCleanedCode = (code) => code?.replace(/_/g, "-");
261
- consoleLogger = {
262
- type: "logger",
263
- log(args) {
264
- this.output("log", args);
265
- },
266
- warn(args) {
267
- this.output("warn", args);
268
- },
269
- error(args) {
270
- this.output("error", args);
271
- },
272
- output(type, args) {
273
- console?.[type]?.apply?.(console, args);
274
- }
275
- };
276
- Logger = class _Logger {
277
- constructor(concreteLogger, options = {}) {
278
- this.init(concreteLogger, options);
279
- }
280
- init(concreteLogger, options = {}) {
281
- this.prefix = options.prefix || "i18next:";
282
- this.logger = concreteLogger || consoleLogger;
283
- this.options = options;
284
- this.debug = options.debug;
285
- }
286
- log(...args) {
287
- return this.forward(args, "log", "", true);
288
- }
289
- warn(...args) {
290
- return this.forward(args, "warn", "", true);
291
- }
292
- error(...args) {
293
- return this.forward(args, "error", "");
294
- }
295
- deprecate(...args) {
296
- return this.forward(args, "warn", "WARNING DEPRECATED: ", true);
297
- }
298
- forward(args, lvl, prefix, debugOnly) {
299
- if (debugOnly && !this.debug) return null;
300
- args = args.map((a) => isString(a) ? a.replace(/[\r\n\x00-\x1F\x7F]/g, " ") : a);
301
- if (isString(args[0])) args[0] = `${prefix}${this.prefix} ${args[0]}`;
302
- return this.logger[lvl](args);
303
- }
304
- create(moduleName) {
305
- return new _Logger(this.logger, {
306
- ...{
307
- prefix: `${this.prefix}:${moduleName}:`
308
- },
309
- ...this.options
310
- });
311
- }
312
- clone(options) {
313
- options = options || this.options;
314
- options.prefix = options.prefix || this.prefix;
315
- return new _Logger(this.logger, options);
316
- }
317
- };
318
- baseLogger = new Logger();
319
- EventEmitter = class {
320
- constructor() {
321
- this.observers = {};
322
- }
323
- on(events, listener) {
324
- events.split(" ").forEach((event) => {
325
- if (!this.observers[event]) this.observers[event] = /* @__PURE__ */ new Map();
326
- const numListeners = this.observers[event].get(listener) || 0;
327
- this.observers[event].set(listener, numListeners + 1);
328
- });
329
- return this;
330
- }
331
- off(event, listener) {
332
- if (!this.observers[event]) return;
333
- if (!listener) {
334
- delete this.observers[event];
335
- return;
336
- }
337
- this.observers[event].delete(listener);
338
- }
339
- once(event, listener) {
340
- const wrapper = (...args) => {
341
- listener(...args);
342
- this.off(event, wrapper);
343
- };
344
- this.on(event, wrapper);
345
- return this;
346
- }
347
- emit(event, ...args) {
348
- if (this.observers[event]) {
349
- const cloned = Array.from(this.observers[event].entries());
350
- cloned.forEach(([observer, numTimesAdded]) => {
351
- for (let i = 0; i < numTimesAdded; i++) {
352
- observer(...args);
353
- }
354
- });
355
- }
356
- if (this.observers["*"]) {
357
- const cloned = Array.from(this.observers["*"].entries());
358
- cloned.forEach(([observer, numTimesAdded]) => {
359
- for (let i = 0; i < numTimesAdded; i++) {
360
- observer(event, ...args);
361
- }
362
- });
363
- }
364
- }
365
- };
366
- ResourceStore = class extends EventEmitter {
367
- constructor(data, options = {
368
- ns: ["translation"],
369
- defaultNS: "translation"
370
- }) {
371
- super();
372
- this.data = data || {};
373
- this.options = options;
374
- if (this.options.keySeparator === void 0) {
375
- this.options.keySeparator = ".";
376
- }
377
- if (this.options.ignoreJSONStructure === void 0) {
378
- this.options.ignoreJSONStructure = true;
379
- }
380
- }
381
- addNamespaces(ns) {
382
- if (!this.options.ns.includes(ns)) {
383
- this.options.ns.push(ns);
384
- }
385
- }
386
- removeNamespaces(ns) {
387
- const index = this.options.ns.indexOf(ns);
388
- if (index > -1) {
389
- this.options.ns.splice(index, 1);
390
- }
391
- }
392
- getResource(lng, ns, key, options = {}) {
393
- const keySeparator = options.keySeparator !== void 0 ? options.keySeparator : this.options.keySeparator;
394
- const ignoreJSONStructure = options.ignoreJSONStructure !== void 0 ? options.ignoreJSONStructure : this.options.ignoreJSONStructure;
395
- let path;
396
- if (lng.includes(".")) {
397
- path = lng.split(".");
398
- } else {
399
- path = [lng, ns];
400
- if (key) {
401
- if (Array.isArray(key)) {
402
- path.push(...key);
403
- } else if (isString(key) && keySeparator) {
404
- path.push(...key.split(keySeparator));
405
- } else {
406
- path.push(key);
407
- }
408
- }
409
- }
410
- const result = getPath(this.data, path);
411
- if (!result && !ns && !key && lng.includes(".")) {
412
- lng = path[0];
413
- ns = path[1];
414
- key = path.slice(2).join(".");
415
- }
416
- if (result || !ignoreJSONStructure || !isString(key)) return result;
417
- return deepFind(this.data?.[lng]?.[ns], key, keySeparator);
418
- }
419
- addResource(lng, ns, key, value, options = {
420
- silent: false
421
- }) {
422
- const keySeparator = options.keySeparator !== void 0 ? options.keySeparator : this.options.keySeparator;
423
- let path = [lng, ns];
424
- if (key) path = path.concat(keySeparator ? key.split(keySeparator) : key);
425
- if (lng.includes(".")) {
426
- path = lng.split(".");
427
- value = ns;
428
- ns = path[1];
429
- }
430
- this.addNamespaces(ns);
431
- setPath(this.data, path, value);
432
- if (!options.silent) this.emit("added", lng, ns, key, value);
433
- }
434
- addResources(lng, ns, resources, options = {
435
- silent: false
436
- }) {
437
- for (const m in resources) {
438
- if (isString(resources[m]) || Array.isArray(resources[m])) this.addResource(lng, ns, m, resources[m], {
439
- silent: true
440
- });
441
- }
442
- if (!options.silent) this.emit("added", lng, ns, resources);
443
- }
444
- addResourceBundle(lng, ns, resources, deep, overwrite, options = {
445
- silent: false,
446
- skipCopy: false
447
- }) {
448
- let path = [lng, ns];
449
- if (lng.includes(".")) {
450
- path = lng.split(".");
451
- deep = resources;
452
- resources = ns;
453
- ns = path[1];
454
- }
455
- this.addNamespaces(ns);
456
- let pack = getPath(this.data, path) || {};
457
- if (!options.skipCopy) resources = JSON.parse(JSON.stringify(resources));
458
- if (deep) {
459
- deepExtend(pack, resources, overwrite);
460
- } else {
461
- pack = {
462
- ...pack,
463
- ...resources
464
- };
465
- }
466
- setPath(this.data, path, pack);
467
- if (!options.silent) this.emit("added", lng, ns, resources);
468
- }
469
- removeResourceBundle(lng, ns) {
470
- if (this.hasResourceBundle(lng, ns)) {
471
- delete this.data[lng][ns];
472
- }
473
- this.removeNamespaces(ns);
474
- this.emit("removed", lng, ns);
475
- }
476
- hasResourceBundle(lng, ns) {
477
- return this.getResource(lng, ns) !== void 0;
478
- }
479
- getResourceBundle(lng, ns) {
480
- if (!ns) ns = this.options.defaultNS;
481
- return this.getResource(lng, ns);
482
- }
483
- getDataByLanguage(lng) {
484
- return this.data[lng];
485
- }
486
- hasLanguageSomeTranslations(lng) {
487
- const data = this.getDataByLanguage(lng);
488
- const n = data && Object.keys(data) || [];
489
- return !!n.find((v) => data[v] && Object.keys(data[v]).length > 0);
490
- }
491
- toJSON() {
492
- return this.data;
493
- }
494
- };
495
- postProcessor = {
496
- processors: {},
497
- addPostProcessor(module2) {
498
- this.processors[module2.name] = module2;
499
- },
500
- handle(processors, value, key, options, translator) {
501
- processors.forEach((processor) => {
502
- value = this.processors[processor]?.process(value, key, options, translator) ?? value;
503
- });
504
- return value;
505
- }
506
- };
507
- PATH_KEY = /* @__PURE__ */ Symbol("i18next/PATH_KEY");
508
- shouldHandleAsObject = (res) => !isString(res) && typeof res !== "boolean" && typeof res !== "number";
509
- Translator = class _Translator extends EventEmitter {
510
- constructor(services, options = {}) {
511
- super();
512
- copy(["resourceStore", "languageUtils", "pluralResolver", "interpolator", "backendConnector", "i18nFormat", "utils"], services, this);
513
- this.options = options;
514
- if (this.options.keySeparator === void 0) {
515
- this.options.keySeparator = ".";
516
- }
517
- this.logger = baseLogger.create("translator");
518
- this.checkedLoadedFor = {};
519
- }
520
- changeLanguage(lng) {
521
- if (lng) this.language = lng;
522
- }
523
- exists(key, o = {
524
- interpolation: {}
525
- }) {
526
- const opt = {
527
- ...o
528
- };
529
- if (key == null) return false;
530
- const resolved = this.resolve(key, opt);
531
- if (resolved?.res === void 0) return false;
532
- const isObject = shouldHandleAsObject(resolved.res);
533
- if (opt.returnObjects === false && isObject) {
534
- return false;
535
- }
536
- return true;
537
- }
538
- extractFromKey(key, opt) {
539
- let nsSeparator = opt.nsSeparator !== void 0 ? opt.nsSeparator : this.options.nsSeparator;
540
- if (nsSeparator === void 0) nsSeparator = ":";
541
- const keySeparator = opt.keySeparator !== void 0 ? opt.keySeparator : this.options.keySeparator;
542
- let namespaces = opt.ns || this.options.defaultNS || [];
543
- const wouldCheckForNsInKey = nsSeparator && key.includes(nsSeparator);
544
- const seemsNaturalLanguage = !this.options.userDefinedKeySeparator && !opt.keySeparator && !this.options.userDefinedNsSeparator && !opt.nsSeparator && !looksLikeObjectPath(key, nsSeparator, keySeparator);
545
- if (wouldCheckForNsInKey && !seemsNaturalLanguage) {
546
- const m = key.match(this.interpolator.nestingRegexp);
547
- if (m && m.length > 0) {
548
- return {
549
- key,
550
- namespaces: isString(namespaces) ? [namespaces] : namespaces
551
- };
552
- }
553
- const parts = key.split(nsSeparator);
554
- if (nsSeparator !== keySeparator || nsSeparator === keySeparator && this.options.ns.includes(parts[0])) namespaces = parts.shift();
555
- key = parts.join(keySeparator);
556
- }
557
- return {
558
- key,
559
- namespaces: isString(namespaces) ? [namespaces] : namespaces
560
- };
561
- }
562
- translate(keys, o, lastKey) {
563
- let opt = typeof o === "object" ? {
564
- ...o
565
- } : o;
566
- if (typeof opt !== "object" && this.options.overloadTranslationOptionHandler) {
567
- opt = this.options.overloadTranslationOptionHandler(arguments);
568
- }
569
- if (typeof opt === "object") opt = {
570
- ...opt
571
- };
572
- if (!opt) opt = {};
573
- if (keys == null) return "";
574
- if (typeof keys === "function") keys = keysFromSelector(keys, {
575
- ...this.options,
576
- ...opt
577
- });
578
- if (!Array.isArray(keys)) keys = [String(keys)];
579
- keys = keys.map((k) => typeof k === "function" ? keysFromSelector(k, {
580
- ...this.options,
581
- ...opt
582
- }) : String(k));
583
- const returnDetails = opt.returnDetails !== void 0 ? opt.returnDetails : this.options.returnDetails;
584
- const keySeparator = opt.keySeparator !== void 0 ? opt.keySeparator : this.options.keySeparator;
585
- const {
586
- key,
587
- namespaces
588
- } = this.extractFromKey(keys[keys.length - 1], opt);
589
- const namespace = namespaces[namespaces.length - 1];
590
- let nsSeparator = opt.nsSeparator !== void 0 ? opt.nsSeparator : this.options.nsSeparator;
591
- if (nsSeparator === void 0) nsSeparator = ":";
592
- const lng = opt.lng || this.language;
593
- const appendNamespaceToCIMode = opt.appendNamespaceToCIMode || this.options.appendNamespaceToCIMode;
594
- if (lng?.toLowerCase() === "cimode") {
595
- if (appendNamespaceToCIMode) {
596
- if (returnDetails) {
597
- return {
598
- res: `${namespace}${nsSeparator}${key}`,
599
- usedKey: key,
600
- exactUsedKey: key,
601
- usedLng: lng,
602
- usedNS: namespace,
603
- usedParams: this.getUsedParamsDetails(opt)
604
- };
605
- }
606
- return `${namespace}${nsSeparator}${key}`;
607
- }
608
- if (returnDetails) {
609
- return {
610
- res: key,
611
- usedKey: key,
612
- exactUsedKey: key,
613
- usedLng: lng,
614
- usedNS: namespace,
615
- usedParams: this.getUsedParamsDetails(opt)
616
- };
617
- }
618
- return key;
619
- }
620
- const resolved = this.resolve(keys, opt);
621
- let res = resolved?.res;
622
- const resUsedKey = resolved?.usedKey || key;
623
- const resExactUsedKey = resolved?.exactUsedKey || key;
624
- const noObject = ["[object Number]", "[object Function]", "[object RegExp]"];
625
- const joinArrays = opt.joinArrays !== void 0 ? opt.joinArrays : this.options.joinArrays;
626
- const handleAsObjectInI18nFormat = !this.i18nFormat || this.i18nFormat.handleAsObject;
627
- const needsPluralHandling = opt.count !== void 0 && !isString(opt.count);
628
- const hasDefaultValue = _Translator.hasDefaultValue(opt);
629
- const defaultValueSuffix = needsPluralHandling ? this.pluralResolver.getSuffix(lng, opt.count, opt) : "";
630
- const defaultValueSuffixOrdinalFallback = opt.ordinal && needsPluralHandling ? this.pluralResolver.getSuffix(lng, opt.count, {
631
- ordinal: false
632
- }) : "";
633
- const needsZeroSuffixLookup = needsPluralHandling && !opt.ordinal && opt.count === 0;
634
- const defaultValue = needsZeroSuffixLookup && opt[`defaultValue${this.options.pluralSeparator}zero`] || opt[`defaultValue${defaultValueSuffix}`] || opt[`defaultValue${defaultValueSuffixOrdinalFallback}`] || opt.defaultValue;
635
- let resForObjHndl = res;
636
- if (handleAsObjectInI18nFormat && !res && hasDefaultValue) {
637
- resForObjHndl = defaultValue;
638
- }
639
- const handleAsObject = shouldHandleAsObject(resForObjHndl);
640
- const resType = Object.prototype.toString.apply(resForObjHndl);
641
- if (handleAsObjectInI18nFormat && resForObjHndl && handleAsObject && !noObject.includes(resType) && !(isString(joinArrays) && Array.isArray(resForObjHndl))) {
642
- if (!opt.returnObjects && !this.options.returnObjects) {
643
- if (!this.options.returnedObjectHandler) {
644
- this.logger.warn("accessing an object - but returnObjects options is not enabled!");
645
- }
646
- const r = this.options.returnedObjectHandler ? this.options.returnedObjectHandler(resUsedKey, resForObjHndl, {
647
- ...opt,
648
- ns: namespaces
649
- }) : `key '${key} (${this.language})' returned an object instead of string.`;
650
- if (returnDetails) {
651
- resolved.res = r;
652
- resolved.usedParams = this.getUsedParamsDetails(opt);
653
- return resolved;
654
- }
655
- return r;
656
- }
657
- if (keySeparator) {
658
- const resTypeIsArray = Array.isArray(resForObjHndl);
659
- const copy2 = resTypeIsArray ? [] : {};
660
- const newKeyToUse = resTypeIsArray ? resExactUsedKey : resUsedKey;
661
- for (const m in resForObjHndl) {
662
- if (Object.prototype.hasOwnProperty.call(resForObjHndl, m)) {
663
- const deepKey = `${newKeyToUse}${keySeparator}${m}`;
664
- if (hasDefaultValue && !res) {
665
- copy2[m] = this.translate(deepKey, {
666
- ...opt,
667
- defaultValue: shouldHandleAsObject(defaultValue) ? defaultValue[m] : void 0,
668
- ...{
669
- joinArrays: false,
670
- ns: namespaces
671
- }
672
- });
673
- } else {
674
- copy2[m] = this.translate(deepKey, {
675
- ...opt,
676
- ...{
677
- joinArrays: false,
678
- ns: namespaces
679
- }
680
- });
681
- }
682
- if (copy2[m] === deepKey) copy2[m] = resForObjHndl[m];
683
- }
684
- }
685
- res = copy2;
686
- }
687
- } else if (handleAsObjectInI18nFormat && isString(joinArrays) && Array.isArray(res)) {
688
- res = res.join(joinArrays);
689
- if (res) res = this.extendTranslation(res, keys, opt, lastKey);
690
- } else {
691
- let usedDefault = false;
692
- let usedKey = false;
693
- if (!this.isValidLookup(res) && hasDefaultValue) {
694
- usedDefault = true;
695
- res = defaultValue;
696
- }
697
- if (!this.isValidLookup(res)) {
698
- usedKey = true;
699
- res = key;
700
- }
701
- const missingKeyNoValueFallbackToKey = opt.missingKeyNoValueFallbackToKey || this.options.missingKeyNoValueFallbackToKey;
702
- const resForMissing = missingKeyNoValueFallbackToKey && usedKey ? void 0 : res;
703
- const updateMissing = hasDefaultValue && defaultValue !== res && this.options.updateMissing;
704
- if (usedKey || usedDefault || updateMissing) {
705
- this.logger.log(updateMissing ? "updateKey" : "missingKey", lng, namespace, needsPluralHandling && !updateMissing ? `${key}${this.pluralResolver.getSuffix(lng, opt.count, opt)}` : key, updateMissing ? defaultValue : res);
706
- if (keySeparator) {
707
- const fk = this.resolve(key, {
708
- ...opt,
709
- keySeparator: false
710
- });
711
- if (fk && fk.res) this.logger.warn("Seems the loaded translations were in flat JSON format instead of nested. Either set keySeparator: false on init or make sure your translations are published in nested format.");
712
- }
713
- let lngs = [];
714
- const fallbackLngs = this.languageUtils.getFallbackCodes(this.options.fallbackLng, opt.lng || this.language);
715
- if (this.options.saveMissingTo === "fallback" && fallbackLngs && fallbackLngs[0]) {
716
- for (let i = 0; i < fallbackLngs.length; i++) {
717
- lngs.push(fallbackLngs[i]);
718
- }
719
- } else if (this.options.saveMissingTo === "all") {
720
- lngs = this.languageUtils.toResolveHierarchy(opt.lng || this.language);
721
- } else {
722
- lngs.push(opt.lng || this.language);
723
- }
724
- const send = (l, k, specificDefaultValue) => {
725
- const defaultForMissing = hasDefaultValue && specificDefaultValue !== res ? specificDefaultValue : resForMissing;
726
- if (this.options.missingKeyHandler) {
727
- this.options.missingKeyHandler(l, namespace, k, defaultForMissing, updateMissing, opt);
728
- } else if (this.backendConnector?.saveMissing) {
729
- this.backendConnector.saveMissing(l, namespace, k, defaultForMissing, updateMissing, opt);
730
- }
731
- this.emit("missingKey", l, namespace, k, res);
732
- };
733
- if (this.options.saveMissing) {
734
- if (this.options.saveMissingPlurals && needsPluralHandling) {
735
- lngs.forEach((language) => {
736
- const suffixes = this.pluralResolver.getSuffixes(language, opt);
737
- if (needsZeroSuffixLookup && opt[`defaultValue${this.options.pluralSeparator}zero`] && !suffixes.includes(`${this.options.pluralSeparator}zero`)) {
738
- suffixes.push(`${this.options.pluralSeparator}zero`);
739
- }
740
- suffixes.forEach((suffix) => {
741
- send([language], key + suffix, opt[`defaultValue${suffix}`] || defaultValue);
742
- });
743
- });
744
- } else {
745
- send(lngs, key, defaultValue);
746
- }
747
- }
748
- }
749
- res = this.extendTranslation(res, keys, opt, resolved, lastKey);
750
- if (usedKey && res === key && this.options.appendNamespaceToMissingKey) {
751
- res = `${namespace}${nsSeparator}${key}`;
752
- }
753
- if ((usedKey || usedDefault) && this.options.parseMissingKeyHandler) {
754
- res = this.options.parseMissingKeyHandler(this.options.appendNamespaceToMissingKey ? `${namespace}${nsSeparator}${key}` : key, usedDefault ? res : void 0, opt);
755
- }
756
- }
757
- if (returnDetails) {
758
- resolved.res = res;
759
- resolved.usedParams = this.getUsedParamsDetails(opt);
760
- return resolved;
761
- }
762
- return res;
763
- }
764
- extendTranslation(res, key, opt, resolved, lastKey) {
765
- if (this.i18nFormat?.parse) {
766
- res = this.i18nFormat.parse(res, {
767
- ...this.options.interpolation.defaultVariables,
768
- ...opt
769
- }, opt.lng || this.language || resolved.usedLng, resolved.usedNS, resolved.usedKey, {
770
- resolved
771
- });
772
- } else if (!opt.skipInterpolation) {
773
- if (opt.interpolation) this.interpolator.init({
774
- ...opt,
775
- ...{
776
- interpolation: {
777
- ...this.options.interpolation,
778
- ...opt.interpolation
779
- }
780
- }
781
- });
782
- const skipOnVariables = isString(res) && (opt?.interpolation?.skipOnVariables !== void 0 ? opt.interpolation.skipOnVariables : this.options.interpolation.skipOnVariables);
783
- let nestBef;
784
- if (skipOnVariables) {
785
- const nb = res.match(this.interpolator.nestingRegexp);
786
- nestBef = nb && nb.length;
787
- }
788
- let data = opt.replace && !isString(opt.replace) ? opt.replace : opt;
789
- if (this.options.interpolation.defaultVariables) data = {
790
- ...this.options.interpolation.defaultVariables,
791
- ...data
792
- };
793
- res = this.interpolator.interpolate(res, data, opt.lng || this.language || resolved.usedLng, opt);
794
- if (skipOnVariables) {
795
- const na = res.match(this.interpolator.nestingRegexp);
796
- const nestAft = na && na.length;
797
- if (nestBef < nestAft) opt.nest = false;
798
- }
799
- if (!opt.lng && resolved && resolved.res) opt.lng = this.language || resolved.usedLng;
800
- if (opt.nest !== false) res = this.interpolator.nest(res, (...args) => {
801
- if (lastKey?.[0] === args[0] && !opt.context) {
802
- this.logger.warn(`It seems you are nesting recursively key: ${args[0]} in key: ${key[0]}`);
803
- return null;
804
- }
805
- return this.translate(...args, key);
806
- }, opt);
807
- if (opt.interpolation) this.interpolator.reset();
808
- }
809
- const postProcess = opt.postProcess || this.options.postProcess;
810
- const postProcessorNames = isString(postProcess) ? [postProcess] : postProcess;
811
- if (res != null && postProcessorNames?.length && opt.applyPostProcessor !== false) {
812
- res = postProcessor.handle(postProcessorNames, res, key, this.options && this.options.postProcessPassResolved ? {
813
- i18nResolved: {
814
- ...resolved,
815
- usedParams: this.getUsedParamsDetails(opt)
816
- },
817
- ...opt
818
- } : opt, this);
819
- }
820
- return res;
821
- }
822
- resolve(keys, opt = {}) {
823
- let found;
824
- let usedKey;
825
- let exactUsedKey;
826
- let usedLng;
827
- let usedNS;
828
- if (isString(keys)) keys = [keys];
829
- if (Array.isArray(keys)) keys = keys.map((k) => typeof k === "function" ? keysFromSelector(k, {
830
- ...this.options,
831
- ...opt
832
- }) : k);
833
- keys.forEach((k) => {
834
- if (this.isValidLookup(found)) return;
835
- const extracted = this.extractFromKey(k, opt);
836
- const key = extracted.key;
837
- usedKey = key;
838
- let namespaces = extracted.namespaces;
839
- if (this.options.fallbackNS) namespaces = namespaces.concat(this.options.fallbackNS);
840
- const needsPluralHandling = opt.count !== void 0 && !isString(opt.count);
841
- const needsZeroSuffixLookup = needsPluralHandling && !opt.ordinal && opt.count === 0;
842
- const needsContextHandling = opt.context !== void 0 && (isString(opt.context) || typeof opt.context === "number") && opt.context !== "";
843
- const codes = opt.lngs ? opt.lngs : this.languageUtils.toResolveHierarchy(opt.lng || this.language, opt.fallbackLng);
844
- namespaces.forEach((ns) => {
845
- if (this.isValidLookup(found)) return;
846
- usedNS = ns;
847
- if (!this.checkedLoadedFor[`${codes[0]}-${ns}`] && this.utils?.hasLoadedNamespace && !this.utils?.hasLoadedNamespace(usedNS)) {
848
- this.checkedLoadedFor[`${codes[0]}-${ns}`] = true;
849
- this.logger.warn(`key "${usedKey}" for languages "${codes.join(", ")}" won't get resolved as namespace "${usedNS}" was not yet loaded`, "This means something IS WRONG in your setup. You access the t function before i18next.init / i18next.loadNamespace / i18next.changeLanguage was done. Wait for the callback or Promise to resolve before accessing it!!!");
850
- }
851
- codes.forEach((code) => {
852
- if (this.isValidLookup(found)) return;
853
- usedLng = code;
854
- const finalKeys = [key];
855
- if (this.i18nFormat?.addLookupKeys) {
856
- this.i18nFormat.addLookupKeys(finalKeys, key, code, ns, opt);
857
- } else {
858
- let pluralSuffix;
859
- if (needsPluralHandling) pluralSuffix = this.pluralResolver.getSuffix(code, opt.count, opt);
860
- const zeroSuffix = `${this.options.pluralSeparator}zero`;
861
- const ordinalPrefix = `${this.options.pluralSeparator}ordinal${this.options.pluralSeparator}`;
862
- if (needsPluralHandling) {
863
- if (opt.ordinal && pluralSuffix.startsWith(ordinalPrefix)) {
864
- finalKeys.push(key + pluralSuffix.replace(ordinalPrefix, this.options.pluralSeparator));
865
- }
866
- finalKeys.push(key + pluralSuffix);
867
- if (needsZeroSuffixLookup) {
868
- finalKeys.push(key + zeroSuffix);
869
- }
870
- }
871
- if (needsContextHandling) {
872
- const contextKey = `${key}${this.options.contextSeparator || "_"}${opt.context}`;
873
- finalKeys.push(contextKey);
874
- if (needsPluralHandling) {
875
- if (opt.ordinal && pluralSuffix.startsWith(ordinalPrefix)) {
876
- finalKeys.push(contextKey + pluralSuffix.replace(ordinalPrefix, this.options.pluralSeparator));
877
- }
878
- finalKeys.push(contextKey + pluralSuffix);
879
- if (needsZeroSuffixLookup) {
880
- finalKeys.push(contextKey + zeroSuffix);
881
- }
882
- }
883
- }
884
- }
885
- let possibleKey;
886
- while (possibleKey = finalKeys.pop()) {
887
- if (!this.isValidLookup(found)) {
888
- exactUsedKey = possibleKey;
889
- found = this.getResource(code, ns, possibleKey, opt);
890
- }
891
- }
892
- });
893
- });
894
- });
895
- return {
896
- res: found,
897
- usedKey,
898
- exactUsedKey,
899
- usedLng,
900
- usedNS
901
- };
902
- }
903
- isValidLookup(res) {
904
- return res !== void 0 && !(!this.options.returnNull && res === null) && !(!this.options.returnEmptyString && res === "");
905
- }
906
- getResource(code, ns, key, options = {}) {
907
- if (this.i18nFormat?.getResource) return this.i18nFormat.getResource(code, ns, key, options);
908
- return this.resourceStore.getResource(code, ns, key, options);
909
- }
910
- getUsedParamsDetails(options = {}) {
911
- const optionsKeys = ["defaultValue", "ordinal", "context", "replace", "lng", "lngs", "fallbackLng", "ns", "keySeparator", "nsSeparator", "returnObjects", "returnDetails", "joinArrays", "postProcess", "interpolation"];
912
- const useOptionsReplaceForData = options.replace && !isString(options.replace);
913
- let data = useOptionsReplaceForData ? options.replace : options;
914
- if (useOptionsReplaceForData && typeof options.count !== "undefined") {
915
- data = {
916
- ...data,
917
- count: options.count
918
- };
919
- }
920
- if (this.options.interpolation.defaultVariables) {
921
- data = {
922
- ...this.options.interpolation.defaultVariables,
923
- ...data
924
- };
925
- }
926
- if (!useOptionsReplaceForData) {
927
- data = {
928
- ...data
929
- };
930
- for (const key of optionsKeys) {
931
- delete data[key];
932
- }
933
- }
934
- return data;
935
- }
936
- static hasDefaultValue(options) {
937
- const prefix = "defaultValue";
938
- for (const option in options) {
939
- if (Object.prototype.hasOwnProperty.call(options, option) && option.startsWith(prefix) && void 0 !== options[option]) {
940
- return true;
941
- }
942
- }
943
- return false;
944
- }
945
- };
946
- LanguageUtil = class {
947
- constructor(options) {
948
- this.options = options;
949
- this.supportedLngs = this.options.supportedLngs || false;
950
- this.logger = baseLogger.create("languageUtils");
951
- this.resolveHierarchyCache = {};
952
- }
953
- clearCache() {
954
- this.resolveHierarchyCache = {};
955
- }
956
- getScriptPartFromCode(code) {
957
- code = getCleanedCode(code);
958
- if (!code || !code.includes("-")) return null;
959
- const p = code.split("-");
960
- if (p.length === 2) return null;
961
- p.pop();
962
- if (p[p.length - 1].toLowerCase() === "x") return null;
963
- return this.formatLanguageCode(p.join("-"));
964
- }
965
- getLanguagePartFromCode(code) {
966
- code = getCleanedCode(code);
967
- if (!code || !code.includes("-")) return code;
968
- const p = code.split("-");
969
- return this.formatLanguageCode(p[0]);
970
- }
971
- formatLanguageCode(code) {
972
- if (isString(code) && code.includes("-")) {
973
- let formattedCode;
974
- try {
975
- formattedCode = Intl.getCanonicalLocales(code)[0];
976
- } catch (e) {
977
- }
978
- if (formattedCode && this.options.lowerCaseLng) {
979
- formattedCode = formattedCode.toLowerCase();
980
- }
981
- if (formattedCode) return formattedCode;
982
- if (this.options.lowerCaseLng) {
983
- return code.toLowerCase();
984
- }
985
- return code;
986
- }
987
- return this.options.cleanCode || this.options.lowerCaseLng ? code.toLowerCase() : code;
988
- }
989
- isSupportedCode(code) {
990
- if (this.options.load === "languageOnly" || this.options.nonExplicitSupportedLngs) {
991
- code = this.getLanguagePartFromCode(code);
992
- }
993
- return !this.supportedLngs || !this.supportedLngs.length || this.supportedLngs.includes(code);
994
- }
995
- getBestMatchFromCodes(codes) {
996
- if (!codes) return null;
997
- let found;
998
- codes.forEach((code) => {
999
- if (found) return;
1000
- const cleanedLng = this.formatLanguageCode(code);
1001
- if (!this.options.supportedLngs || this.isSupportedCode(cleanedLng)) found = cleanedLng;
1002
- });
1003
- if (!found && this.options.supportedLngs) {
1004
- codes.forEach((code) => {
1005
- if (found) return;
1006
- const lngScOnly = this.getScriptPartFromCode(code);
1007
- if (this.isSupportedCode(lngScOnly)) return found = lngScOnly;
1008
- const lngOnly = this.getLanguagePartFromCode(code);
1009
- if (this.isSupportedCode(lngOnly)) return found = lngOnly;
1010
- found = this.options.supportedLngs.find((supportedLng) => {
1011
- if (supportedLng === lngOnly) return true;
1012
- if (!supportedLng.includes("-") && !lngOnly.includes("-")) return false;
1013
- if (supportedLng.includes("-") && !lngOnly.includes("-") && supportedLng.slice(0, supportedLng.indexOf("-")) === lngOnly) return true;
1014
- if (supportedLng.startsWith(lngOnly) && lngOnly.length > 1) return true;
1015
- return false;
1016
- });
1017
- });
1018
- }
1019
- if (!found) found = this.getFallbackCodes(this.options.fallbackLng)[0];
1020
- return found;
1021
- }
1022
- getFallbackCodes(fallbacks, code) {
1023
- if (!fallbacks) return [];
1024
- if (typeof fallbacks === "function") fallbacks = fallbacks(code);
1025
- if (isString(fallbacks)) fallbacks = [fallbacks];
1026
- if (Array.isArray(fallbacks)) return fallbacks;
1027
- if (!code) return fallbacks.default || [];
1028
- let found = fallbacks[code];
1029
- if (!found) found = fallbacks[this.getScriptPartFromCode(code)];
1030
- if (!found) found = fallbacks[this.formatLanguageCode(code)];
1031
- if (!found) found = fallbacks[this.getLanguagePartFromCode(code)];
1032
- if (!found) found = fallbacks.default;
1033
- return found || [];
1034
- }
1035
- toResolveHierarchy(code, fallbackCode) {
1036
- const fallbackLng = this.options.fallbackLng;
1037
- const fallbackLngKey = Array.isArray(fallbackLng) ? fallbackLng.join("|") : fallbackLng;
1038
- if (fallbackLngKey !== this._cachedFallbackLng) {
1039
- this.resolveHierarchyCache = {};
1040
- this._cachedFallbackLng = fallbackLngKey;
1041
- }
1042
- const hasCacheableFallback = fallbackCode === void 0 || fallbackCode === false || isString(fallbackCode);
1043
- const usesUncacheableOptionsFallback = fallbackCode === void 0 && typeof this.options.fallbackLng === "function";
1044
- const cacheable = isString(code) && hasCacheableFallback && !usesUncacheableOptionsFallback;
1045
- let cacheKey = null;
1046
- if (cacheable) {
1047
- let fallbackCacheKey;
1048
- if (fallbackCode === void 0) fallbackCacheKey = "undefined";
1049
- else if (fallbackCode === false) fallbackCacheKey = "boolean:false";
1050
- else fallbackCacheKey = `string:${fallbackCode}`;
1051
- cacheKey = `${code.length}:${code}|${fallbackCacheKey}`;
1052
- }
1053
- if (cacheKey !== null) {
1054
- const cached = this.resolveHierarchyCache[cacheKey];
1055
- if (cached !== void 0) return cached.slice();
1056
- }
1057
- const fallbackCodes = this.getFallbackCodes((fallbackCode === false ? [] : fallbackCode) || this.options.fallbackLng || [], code);
1058
- const codes = [];
1059
- const addCode = (c) => {
1060
- if (!c) return;
1061
- if (this.isSupportedCode(c)) {
1062
- codes.push(c);
1063
- } else {
1064
- this.logger.warn(`rejecting language code not found in supportedLngs: ${c}`);
1065
- }
1066
- };
1067
- if (isString(code) && (code.includes("-") || code.includes("_"))) {
1068
- if (this.options.load !== "languageOnly") addCode(this.formatLanguageCode(code));
1069
- if (this.options.load !== "languageOnly" && this.options.load !== "currentOnly") addCode(this.getScriptPartFromCode(code));
1070
- if (this.options.load !== "currentOnly") addCode(this.getLanguagePartFromCode(code));
1071
- } else if (isString(code)) {
1072
- addCode(this.formatLanguageCode(code));
1073
- }
1074
- fallbackCodes.forEach((fc) => {
1075
- if (!codes.includes(fc)) addCode(this.formatLanguageCode(fc));
1076
- });
1077
- if (cacheKey !== null) {
1078
- this.resolveHierarchyCache[cacheKey] = codes;
1079
- return codes.slice();
1080
- }
1081
- return codes;
1082
- }
1083
- };
1084
- suffixesOrder = {
1085
- zero: 0,
1086
- one: 1,
1087
- two: 2,
1088
- few: 3,
1089
- many: 4,
1090
- other: 5
1091
- };
1092
- dummyRule = {
1093
- select: (count) => count === 1 ? "one" : "other",
1094
- resolvedOptions: () => ({
1095
- pluralCategories: ["one", "other"]
1096
- })
1097
- };
1098
- PluralResolver = class {
1099
- constructor(languageUtils, options = {}) {
1100
- this.languageUtils = languageUtils;
1101
- this.options = options;
1102
- this.logger = baseLogger.create("pluralResolver");
1103
- this.pluralRulesCache = {};
1104
- }
1105
- clearCache() {
1106
- this.pluralRulesCache = {};
1107
- }
1108
- getRule(code, options = {}) {
1109
- const cleanedCode = getCleanedCode(code === "dev" ? "en" : code);
1110
- const type = options.ordinal ? "ordinal" : "cardinal";
1111
- const cacheKey = JSON.stringify({
1112
- cleanedCode,
1113
- type
1114
- });
1115
- if (cacheKey in this.pluralRulesCache) {
1116
- return this.pluralRulesCache[cacheKey];
1117
- }
1118
- let rule;
1119
- try {
1120
- rule = new Intl.PluralRules(cleanedCode, {
1121
- type
1122
- });
1123
- } catch (err) {
1124
- if (typeof Intl === "undefined") {
1125
- this.logger.error("No Intl support, please use an Intl polyfill!");
1126
- return dummyRule;
1127
- }
1128
- if (!code.match(/-|_/)) return dummyRule;
1129
- const lngPart = this.languageUtils.getLanguagePartFromCode(code);
1130
- rule = this.getRule(lngPart, options);
1131
- }
1132
- this.pluralRulesCache[cacheKey] = rule;
1133
- return rule;
1134
- }
1135
- needsPlural(code, options = {}) {
1136
- let rule = this.getRule(code, options);
1137
- if (!rule) rule = this.getRule("dev", options);
1138
- return rule?.resolvedOptions().pluralCategories.length > 1;
1139
- }
1140
- getPluralFormsOfKey(code, key, options = {}) {
1141
- return this.getSuffixes(code, options).map((suffix) => `${key}${suffix}`);
1142
- }
1143
- getSuffixes(code, options = {}) {
1144
- let rule = this.getRule(code, options);
1145
- if (!rule) rule = this.getRule("dev", options);
1146
- if (!rule) return [];
1147
- return rule.resolvedOptions().pluralCategories.sort((pluralCategory1, pluralCategory2) => suffixesOrder[pluralCategory1] - suffixesOrder[pluralCategory2]).map((pluralCategory) => `${this.options.prepend}${options.ordinal ? `ordinal${this.options.prepend}` : ""}${pluralCategory}`);
1148
- }
1149
- getSuffix(code, count, options = {}) {
1150
- const rule = this.getRule(code, options);
1151
- if (rule) {
1152
- return `${this.options.prepend}${options.ordinal ? `ordinal${this.options.prepend}` : ""}${rule.select(count)}`;
1153
- }
1154
- this.logger.warn(`no plural rule found for: ${code}`);
1155
- return this.getSuffix("dev", count, options);
1156
- }
1157
- };
1158
- deepFindWithDefaults = (data, defaultData, key, keySeparator = ".", ignoreJSONStructure = true) => {
1159
- let path = getPathWithDefaults(data, defaultData, key);
1160
- if (!path && ignoreJSONStructure && isString(key)) {
1161
- path = deepFind(data, key, keySeparator);
1162
- if (path === void 0) path = deepFind(defaultData, key, keySeparator);
1163
- }
1164
- return path;
1165
- };
1166
- regexSafe = (val) => val.replace(/\$/g, "$$$$");
1167
- Interpolator = class {
1168
- constructor(options = {}) {
1169
- this.logger = baseLogger.create("interpolator");
1170
- this.options = options;
1171
- this.format = options?.interpolation?.format || ((value) => value);
1172
- this.init(options);
1173
- }
1174
- init(options = {}) {
1175
- if (!options.interpolation) options.interpolation = {
1176
- escapeValue: true
1177
- };
1178
- const {
1179
- escape: escape$1,
1180
- escapeValue,
1181
- useRawValueToEscape,
1182
- prefix,
1183
- prefixEscaped,
1184
- suffix,
1185
- suffixEscaped,
1186
- formatSeparator,
1187
- unescapeSuffix,
1188
- unescapePrefix,
1189
- nestingPrefix,
1190
- nestingPrefixEscaped,
1191
- nestingSuffix,
1192
- nestingSuffixEscaped,
1193
- nestingOptionsSeparator,
1194
- maxReplaces,
1195
- alwaysFormat
1196
- } = options.interpolation;
1197
- this.escape = escape$1 !== void 0 ? escape$1 : escape;
1198
- this.escapeValue = escapeValue !== void 0 ? escapeValue : true;
1199
- this.useRawValueToEscape = useRawValueToEscape !== void 0 ? useRawValueToEscape : false;
1200
- this.prefix = prefix ? regexEscape(prefix) : prefixEscaped || "{{";
1201
- this.suffix = suffix ? regexEscape(suffix) : suffixEscaped || "}}";
1202
- this.formatSeparator = formatSeparator || ",";
1203
- this.unescapePrefix = unescapeSuffix ? "" : unescapePrefix ? regexEscape(unescapePrefix) : "-";
1204
- this.unescapeSuffix = this.unescapePrefix ? "" : unescapeSuffix ? regexEscape(unescapeSuffix) : "";
1205
- this.nestingPrefix = nestingPrefix ? regexEscape(nestingPrefix) : nestingPrefixEscaped || regexEscape("$t(");
1206
- this.nestingSuffix = nestingSuffix ? regexEscape(nestingSuffix) : nestingSuffixEscaped || regexEscape(")");
1207
- this.nestingOptionsSeparator = nestingOptionsSeparator || ",";
1208
- this.maxReplaces = maxReplaces || 1e3;
1209
- this.alwaysFormat = alwaysFormat !== void 0 ? alwaysFormat : false;
1210
- this.resetRegExp();
1211
- }
1212
- reset() {
1213
- if (this.options) this.init(this.options);
1214
- }
1215
- resetRegExp() {
1216
- const getOrResetRegExp = (existingRegExp, pattern) => {
1217
- if (existingRegExp?.source === pattern) {
1218
- existingRegExp.lastIndex = 0;
1219
- return existingRegExp;
1220
- }
1221
- return new RegExp(pattern, "g");
1222
- };
1223
- this.regexp = getOrResetRegExp(this.regexp, `${this.prefix}(.+?)${this.suffix}`);
1224
- this.regexpUnescape = getOrResetRegExp(this.regexpUnescape, `${this.prefix}${this.unescapePrefix}(.+?)${this.unescapeSuffix}${this.suffix}`);
1225
- this.nestingRegexp = getOrResetRegExp(this.nestingRegexp, `${this.nestingPrefix}((?:[^()"']+|"[^"]*"|'[^']*'|\\((?:[^()]|"[^"]*"|'[^']*')*\\))*?)${this.nestingSuffix}`);
1226
- }
1227
- interpolate(str, data, lng, options) {
1228
- let match;
1229
- let value;
1230
- let replaces;
1231
- const defaultData = this.options && this.options.interpolation && this.options.interpolation.defaultVariables || {};
1232
- const handleFormat = (key) => {
1233
- if (!key.includes(this.formatSeparator)) {
1234
- const path = deepFindWithDefaults(data, defaultData, key, this.options.keySeparator, this.options.ignoreJSONStructure);
1235
- return this.alwaysFormat ? this.format(path, void 0, lng, {
1236
- ...options,
1237
- ...data,
1238
- interpolationkey: key
1239
- }) : path;
1240
- }
1241
- const p = key.split(this.formatSeparator);
1242
- const k = p.shift().trim();
1243
- const f = p.join(this.formatSeparator).trim();
1244
- return this.format(deepFindWithDefaults(data, defaultData, k, this.options.keySeparator, this.options.ignoreJSONStructure), f, lng, {
1245
- ...options,
1246
- ...data,
1247
- interpolationkey: k
1248
- });
1249
- };
1250
- this.resetRegExp();
1251
- if (!this.escapeValue && typeof str === "string" && /\$t\([^)]*\{[^}]*\{\{/.test(str)) {
1252
- this.logger.warn("nesting options string contains interpolated variables with escapeValue: false \u2014 if any of those values are attacker-controlled they can inject additional nesting options (e.g. redirect lng/ns). Sanitise untrusted input before passing it to t(), or keep escapeValue: true.");
1253
- }
1254
- const missingInterpolationHandler = options?.missingInterpolationHandler || this.options.missingInterpolationHandler;
1255
- const skipOnVariables = options?.interpolation?.skipOnVariables !== void 0 ? options.interpolation.skipOnVariables : this.options.interpolation.skipOnVariables;
1256
- const todos = [{
1257
- regex: this.regexpUnescape,
1258
- safeValue: (val) => val
1259
- }, {
1260
- regex: this.regexp,
1261
- safeValue: (val) => this.escapeValue ? this.escape(val) : val
1262
- }];
1263
- todos.forEach((todo) => {
1264
- replaces = 0;
1265
- while (match = todo.regex.exec(str)) {
1266
- const matchedVar = match[1].trim();
1267
- value = handleFormat(matchedVar);
1268
- if (value === void 0) {
1269
- if (typeof missingInterpolationHandler === "function") {
1270
- const temp = missingInterpolationHandler(str, match, options);
1271
- value = isString(temp) ? temp : "";
1272
- } else if (options && Object.prototype.hasOwnProperty.call(options, matchedVar)) {
1273
- value = "";
1274
- } else if (skipOnVariables) {
1275
- value = match[0];
1276
- continue;
1277
- } else {
1278
- this.logger.warn(`missed to pass in variable ${matchedVar} for interpolating ${str}`);
1279
- value = "";
1280
- }
1281
- } else if (!isString(value) && !this.useRawValueToEscape) {
1282
- value = makeString(value);
1283
- }
1284
- const safeValue = todo.safeValue(value);
1285
- str = str.replace(match[0], regexSafe(safeValue));
1286
- if (skipOnVariables) {
1287
- todo.regex.lastIndex += safeValue.length;
1288
- todo.regex.lastIndex -= match[0].length;
1289
- } else {
1290
- todo.regex.lastIndex = 0;
1291
- }
1292
- replaces++;
1293
- if (replaces >= this.maxReplaces) {
1294
- break;
1295
- }
1296
- }
1297
- });
1298
- return str;
1299
- }
1300
- nest(str, fc, options = {}) {
1301
- let match;
1302
- let value;
1303
- let clonedOptions;
1304
- const handleHasOptions = (key, inheritedOptions) => {
1305
- const sep = this.nestingOptionsSeparator;
1306
- if (!key.includes(sep)) return key;
1307
- const c = key.split(new RegExp(`${regexEscape(sep)}[ ]*{`));
1308
- let optionsString = `{${c[1]}`;
1309
- key = c[0];
1310
- optionsString = this.interpolate(optionsString, clonedOptions);
1311
- const matchedSingleQuotes = optionsString.match(/'/g);
1312
- const matchedDoubleQuotes = optionsString.match(/"/g);
1313
- if ((matchedSingleQuotes?.length ?? 0) % 2 === 0 && !matchedDoubleQuotes || (matchedDoubleQuotes?.length ?? 0) % 2 !== 0) {
1314
- optionsString = optionsString.replace(/'/g, '"');
1315
- }
1316
- try {
1317
- clonedOptions = JSON.parse(optionsString);
1318
- if (inheritedOptions) clonedOptions = {
1319
- ...inheritedOptions,
1320
- ...clonedOptions
1321
- };
1322
- } catch (e) {
1323
- this.logger.warn(`failed parsing options string in nesting for key ${key}`, e);
1324
- return `${key}${sep}${optionsString}`;
1325
- }
1326
- if (clonedOptions.defaultValue && clonedOptions.defaultValue.includes(this.prefix)) delete clonedOptions.defaultValue;
1327
- return key;
1328
- };
1329
- while (match = this.nestingRegexp.exec(str)) {
1330
- let formatters = [];
1331
- clonedOptions = {
1332
- ...options
1333
- };
1334
- clonedOptions = clonedOptions.replace && !isString(clonedOptions.replace) ? clonedOptions.replace : clonedOptions;
1335
- clonedOptions.applyPostProcessor = false;
1336
- delete clonedOptions.defaultValue;
1337
- const keyEndIndex = /{.*}/s.test(match[1]) ? match[1].lastIndexOf("}") + 1 : match[1].indexOf(this.formatSeparator);
1338
- if (keyEndIndex !== -1) {
1339
- formatters = match[1].slice(keyEndIndex).split(this.formatSeparator).map((elem) => elem.trim()).filter(Boolean);
1340
- match[1] = match[1].slice(0, keyEndIndex);
1341
- }
1342
- value = fc(handleHasOptions.call(this, match[1].trim(), clonedOptions), clonedOptions);
1343
- if (value && match[0] === str && !isString(value)) return value;
1344
- if (!isString(value)) value = makeString(value);
1345
- if (!value) {
1346
- this.logger.warn(`missed to resolve ${match[1]} for nesting ${str}`);
1347
- value = "";
1348
- }
1349
- if (formatters.length) {
1350
- value = formatters.reduce((v, f) => this.format(v, f, options.lng, {
1351
- ...options,
1352
- interpolationkey: match[1].trim()
1353
- }), value.trim());
1354
- }
1355
- str = str.replace(match[0], regexSafe(makeString(value)));
1356
- this.regexp.lastIndex = 0;
1357
- }
1358
- return str;
1359
- }
1360
- };
1361
- parseFormatStr = (formatStr) => {
1362
- let formatName = formatStr.toLowerCase().trim();
1363
- const formatOptions = {};
1364
- if (formatStr.includes("(")) {
1365
- const p = formatStr.split("(");
1366
- formatName = p[0].toLowerCase().trim();
1367
- const optStr = p[1].slice(0, -1);
1368
- if (formatName === "currency" && !optStr.includes(":")) {
1369
- if (!formatOptions.currency) formatOptions.currency = optStr.trim();
1370
- } else if (formatName === "relativetime" && !optStr.includes(":")) {
1371
- if (!formatOptions.range) formatOptions.range = optStr.trim();
1372
- } else {
1373
- const opts = optStr.split(";");
1374
- opts.forEach((opt) => {
1375
- if (opt) {
1376
- const [key, ...rest] = opt.split(":");
1377
- const val = rest.join(":").trim().replace(/^'+|'+$/g, "");
1378
- const trimmedKey = key.trim();
1379
- if (!formatOptions[trimmedKey]) formatOptions[trimmedKey] = val;
1380
- if (val === "false") formatOptions[trimmedKey] = false;
1381
- if (val === "true") formatOptions[trimmedKey] = true;
1382
- if (!isNaN(val)) formatOptions[trimmedKey] = parseInt(val, 10);
1383
- }
1384
- });
1385
- }
1386
- }
1387
- return {
1388
- formatName,
1389
- formatOptions
1390
- };
1391
- };
1392
- createCachedFormatter = (fn) => {
1393
- const cache = {};
1394
- return (v, l, o) => {
1395
- let optForCache = o;
1396
- if (o && o.interpolationkey && o.formatParams && o.formatParams[o.interpolationkey] && o[o.interpolationkey]) {
1397
- optForCache = {
1398
- ...optForCache,
1399
- [o.interpolationkey]: void 0
1400
- };
1401
- }
1402
- const key = l + JSON.stringify(optForCache);
1403
- let frm = cache[key];
1404
- if (!frm) {
1405
- frm = fn(getCleanedCode(l), o);
1406
- cache[key] = frm;
1407
- }
1408
- return frm(v);
1409
- };
1410
- };
1411
- createNonCachedFormatter = (fn) => (v, l, o) => fn(getCleanedCode(l), o)(v);
1412
- Formatter = class {
1413
- constructor(options = {}) {
1414
- this.logger = baseLogger.create("formatter");
1415
- this.options = options;
1416
- this.init(options);
1417
- }
1418
- init(services, options = {
1419
- interpolation: {}
1420
- }) {
1421
- this.formatSeparator = options.interpolation.formatSeparator || ",";
1422
- const cf = options.cacheInBuiltFormats ? createCachedFormatter : createNonCachedFormatter;
1423
- this.formats = {
1424
- number: cf((lng, opt) => {
1425
- const formatter = new Intl.NumberFormat(lng, {
1426
- ...opt
1427
- });
1428
- return (val) => formatter.format(val);
1429
- }),
1430
- currency: cf((lng, opt) => {
1431
- const formatter = new Intl.NumberFormat(lng, {
1432
- ...opt,
1433
- style: "currency"
1434
- });
1435
- return (val) => formatter.format(val);
1436
- }),
1437
- datetime: cf((lng, opt) => {
1438
- const formatter = new Intl.DateTimeFormat(lng, {
1439
- ...opt
1440
- });
1441
- return (val) => formatter.format(val);
1442
- }),
1443
- relativetime: cf((lng, opt) => {
1444
- const formatter = new Intl.RelativeTimeFormat(lng, {
1445
- ...opt
1446
- });
1447
- return (val) => formatter.format(val, opt.range || "day");
1448
- }),
1449
- list: cf((lng, opt) => {
1450
- const formatter = new Intl.ListFormat(lng, {
1451
- ...opt
1452
- });
1453
- return (val) => formatter.format(val);
1454
- })
1455
- };
1456
- }
1457
- add(name, fc) {
1458
- this.formats[name.toLowerCase().trim()] = fc;
1459
- }
1460
- addCached(name, fc) {
1461
- this.formats[name.toLowerCase().trim()] = createCachedFormatter(fc);
1462
- }
1463
- format(value, format, lng, options = {}) {
1464
- if (!format) return value;
1465
- if (value == null) return value;
1466
- const rawFormats = format.split(this.formatSeparator);
1467
- const formats = [];
1468
- for (let i = 0; i < rawFormats.length; i++) {
1469
- let f = rawFormats[i];
1470
- while (f.indexOf("(") > -1 && !f.includes(")") && i + 1 < rawFormats.length) {
1471
- f = `${f}${this.formatSeparator}${rawFormats[++i]}`;
1472
- }
1473
- formats.push(f);
1474
- }
1475
- const result = formats.reduce((mem, f) => {
1476
- const {
1477
- formatName,
1478
- formatOptions
1479
- } = parseFormatStr(f);
1480
- if (this.formats[formatName]) {
1481
- let formatted = mem;
1482
- try {
1483
- const valOptions = options?.formatParams?.[options.interpolationkey] || {};
1484
- const l = valOptions.locale || valOptions.lng || options.locale || options.lng || lng;
1485
- formatted = this.formats[formatName](mem, l, {
1486
- ...formatOptions,
1487
- ...options,
1488
- ...valOptions
1489
- });
1490
- } catch (error) {
1491
- this.logger.warn(error);
1492
- }
1493
- return formatted;
1494
- } else {
1495
- this.logger.warn(`there was no format function for ${formatName}`);
1496
- }
1497
- return mem;
1498
- }, value);
1499
- return result;
1500
- }
1501
- };
1502
- removePending = (q, name) => {
1503
- if (q.pending[name] !== void 0) {
1504
- delete q.pending[name];
1505
- q.pendingCount--;
1506
- }
1507
- };
1508
- Connector = class extends EventEmitter {
1509
- constructor(backend, store, services, options = {}) {
1510
- super();
1511
- this.backend = backend;
1512
- this.store = store;
1513
- this.services = services;
1514
- this.languageUtils = services.languageUtils;
1515
- this.options = options;
1516
- this.logger = baseLogger.create("backendConnector");
1517
- this.waitingReads = [];
1518
- this.maxParallelReads = options.maxParallelReads || 10;
1519
- this.readingCalls = 0;
1520
- this.maxRetries = options.maxRetries >= 0 ? options.maxRetries : 5;
1521
- this.retryTimeout = options.retryTimeout >= 1 ? options.retryTimeout : 350;
1522
- this.state = {};
1523
- this.queue = [];
1524
- this.backend?.init?.(services, options.backend, options);
1525
- }
1526
- queueLoad(languages, namespaces, options, callback) {
1527
- const toLoad = {};
1528
- const pending = {};
1529
- const toLoadLanguages = {};
1530
- const toLoadNamespaces = {};
1531
- languages.forEach((lng) => {
1532
- let hasAllNamespaces = true;
1533
- namespaces.forEach((ns) => {
1534
- const name = `${lng}|${ns}`;
1535
- if (!options.reload && this.store.hasResourceBundle(lng, ns)) {
1536
- this.state[name] = 2;
1537
- } else if (this.state[name] < 0) ;
1538
- else if (this.state[name] === 1) {
1539
- if (pending[name] === void 0) pending[name] = true;
1540
- } else {
1541
- this.state[name] = 1;
1542
- hasAllNamespaces = false;
1543
- if (pending[name] === void 0) pending[name] = true;
1544
- if (toLoad[name] === void 0) toLoad[name] = true;
1545
- if (toLoadNamespaces[ns] === void 0) toLoadNamespaces[ns] = true;
1546
- }
1547
- });
1548
- if (!hasAllNamespaces) toLoadLanguages[lng] = true;
1549
- });
1550
- if (Object.keys(toLoad).length || Object.keys(pending).length) {
1551
- this.queue.push({
1552
- pending,
1553
- pendingCount: Object.keys(pending).length,
1554
- loaded: {},
1555
- errors: [],
1556
- callback
1557
- });
1558
- }
1559
- return {
1560
- toLoad: Object.keys(toLoad),
1561
- pending: Object.keys(pending),
1562
- toLoadLanguages: Object.keys(toLoadLanguages),
1563
- toLoadNamespaces: Object.keys(toLoadNamespaces)
1564
- };
1565
- }
1566
- loaded(name, err, data) {
1567
- const s = name.split("|");
1568
- const lng = s[0];
1569
- const ns = s[1];
1570
- if (err) this.emit("failedLoading", lng, ns, err);
1571
- if (!err && data) {
1572
- this.store.addResourceBundle(lng, ns, data, void 0, void 0, {
1573
- skipCopy: true
1574
- });
1575
- }
1576
- this.state[name] = err ? -1 : 2;
1577
- if (err && data) this.state[name] = 0;
1578
- const loaded = {};
1579
- this.queue.forEach((q) => {
1580
- pushPath(q.loaded, [lng], ns);
1581
- removePending(q, name);
1582
- if (err) q.errors.push(err);
1583
- if (q.pendingCount === 0 && !q.done) {
1584
- Object.keys(q.loaded).forEach((l) => {
1585
- if (!loaded[l]) loaded[l] = {};
1586
- const loadedKeys = q.loaded[l];
1587
- if (loadedKeys.length) {
1588
- loadedKeys.forEach((n) => {
1589
- if (loaded[l][n] === void 0) loaded[l][n] = true;
1590
- });
1591
- }
1592
- });
1593
- q.done = true;
1594
- if (q.errors.length) {
1595
- q.callback(q.errors);
1596
- } else {
1597
- q.callback();
1598
- }
1599
- }
1600
- });
1601
- this.emit("loaded", loaded);
1602
- this.queue = this.queue.filter((q) => !q.done);
1603
- }
1604
- read(lng, ns, fcName, tried = 0, wait = this.retryTimeout, callback) {
1605
- if (!lng.length) return callback(null, {});
1606
- if (this.readingCalls >= this.maxParallelReads) {
1607
- this.waitingReads.push({
1608
- lng,
1609
- ns,
1610
- fcName,
1611
- tried,
1612
- wait,
1613
- callback
1614
- });
1615
- return;
1616
- }
1617
- this.readingCalls++;
1618
- const resolver = (err, data) => {
1619
- this.readingCalls--;
1620
- if (this.waitingReads.length > 0) {
1621
- const next = this.waitingReads.shift();
1622
- this.read(next.lng, next.ns, next.fcName, next.tried, next.wait, next.callback);
1623
- }
1624
- if (err && data && tried < this.maxRetries) {
1625
- setTimeout(() => {
1626
- this.read(lng, ns, fcName, tried + 1, wait * 2, callback);
1627
- }, wait);
1628
- return;
1629
- }
1630
- callback(err, data);
1631
- };
1632
- const fc = this.backend[fcName].bind(this.backend);
1633
- if (fc.length === 2) {
1634
- try {
1635
- const r = fc(lng, ns);
1636
- if (r && typeof r.then === "function") {
1637
- r.then((data) => resolver(null, data)).catch(resolver);
1638
- } else {
1639
- resolver(null, r);
1640
- }
1641
- } catch (err) {
1642
- resolver(err);
1643
- }
1644
- return;
1645
- }
1646
- return fc(lng, ns, resolver);
1647
- }
1648
- prepareLoading(languages, namespaces, options = {}, callback) {
1649
- if (!this.backend) {
1650
- this.logger.warn("No backend was added via i18next.use. Will not load resources.");
1651
- return callback && callback();
1652
- }
1653
- if (isString(languages)) languages = this.languageUtils.toResolveHierarchy(languages);
1654
- if (isString(namespaces)) namespaces = [namespaces];
1655
- const toLoad = this.queueLoad(languages, namespaces, options, callback);
1656
- if (!toLoad.toLoad.length) {
1657
- if (!toLoad.pending.length) callback();
1658
- return null;
1659
- }
1660
- toLoad.toLoad.forEach((name) => {
1661
- this.loadOne(name);
1662
- });
1663
- }
1664
- load(languages, namespaces, callback) {
1665
- this.prepareLoading(languages, namespaces, {}, callback);
1666
- }
1667
- reload(languages, namespaces, callback) {
1668
- this.prepareLoading(languages, namespaces, {
1669
- reload: true
1670
- }, callback);
1671
- }
1672
- loadOne(name, prefix = "") {
1673
- const s = name.split("|");
1674
- const lng = s[0];
1675
- const ns = s[1];
1676
- this.read(lng, ns, "read", void 0, void 0, (err, data) => {
1677
- if (err) this.logger.warn(`${prefix}loading namespace ${ns} for language ${lng} failed`, err);
1678
- if (!err && data) this.logger.log(`${prefix}loaded namespace ${ns} for language ${lng}`, data);
1679
- this.loaded(name, err, data);
1680
- });
1681
- }
1682
- saveMissing(languages, namespace, key, fallbackValue, isUpdate, options = {}, clb = () => {
1683
- }) {
1684
- if (this.services?.utils?.hasLoadedNamespace && !this.services?.utils?.hasLoadedNamespace(namespace)) {
1685
- this.logger.warn(`did not save key "${key}" as the namespace "${namespace}" was not yet loaded`, "This means something IS WRONG in your setup. You access the t function before i18next.init / i18next.loadNamespace / i18next.changeLanguage was done. Wait for the callback or Promise to resolve before accessing it!!!");
1686
- return;
1687
- }
1688
- if (key === void 0 || key === null || key === "") return;
1689
- if (this.backend?.create) {
1690
- const opts = {
1691
- ...options,
1692
- isUpdate
1693
- };
1694
- const fc = this.backend.create.bind(this.backend);
1695
- if (fc.length < 6) {
1696
- try {
1697
- let r;
1698
- if (fc.length === 5) {
1699
- r = fc(languages, namespace, key, fallbackValue, opts);
1700
- } else {
1701
- r = fc(languages, namespace, key, fallbackValue);
1702
- }
1703
- if (r && typeof r.then === "function") {
1704
- r.then((data) => clb(null, data)).catch(clb);
1705
- } else {
1706
- clb(null, r);
1707
- }
1708
- } catch (err) {
1709
- clb(err);
1710
- }
1711
- } else {
1712
- fc(languages, namespace, key, fallbackValue, clb, opts);
1713
- }
1714
- }
1715
- if (!languages || !languages[0]) return;
1716
- this.store.addResource(languages[0], namespace, key, fallbackValue);
1717
- }
1718
- };
1719
- get = () => ({
1720
- debug: false,
1721
- initAsync: true,
1722
- ns: ["translation"],
1723
- defaultNS: ["translation"],
1724
- fallbackLng: ["dev"],
1725
- fallbackNS: false,
1726
- supportedLngs: false,
1727
- nonExplicitSupportedLngs: false,
1728
- load: "all",
1729
- preload: false,
1730
- keySeparator: ".",
1731
- nsSeparator: ":",
1732
- pluralSeparator: "_",
1733
- contextSeparator: "_",
1734
- enableSelector: false,
1735
- partialBundledLanguages: false,
1736
- saveMissing: false,
1737
- updateMissing: false,
1738
- saveMissingTo: "fallback",
1739
- saveMissingPlurals: true,
1740
- missingKeyHandler: false,
1741
- missingInterpolationHandler: false,
1742
- postProcess: false,
1743
- postProcessPassResolved: false,
1744
- returnNull: false,
1745
- returnEmptyString: true,
1746
- returnObjects: false,
1747
- joinArrays: false,
1748
- returnedObjectHandler: false,
1749
- parseMissingKeyHandler: false,
1750
- appendNamespaceToMissingKey: false,
1751
- appendNamespaceToCIMode: false,
1752
- overloadTranslationOptionHandler: (args) => {
1753
- let ret = {};
1754
- if (typeof args[1] === "object") ret = args[1];
1755
- if (isString(args[1])) ret.defaultValue = args[1];
1756
- if (isString(args[2])) ret.tDescription = args[2];
1757
- if (typeof args[2] === "object" || typeof args[3] === "object") {
1758
- const options = args[3] || args[2];
1759
- Object.keys(options).forEach((key) => {
1760
- ret[key] = options[key];
1761
- });
1762
- }
1763
- return ret;
1764
- },
1765
- interpolation: {
1766
- escapeValue: true,
1767
- prefix: "{{",
1768
- suffix: "}}",
1769
- formatSeparator: ",",
1770
- unescapePrefix: "-",
1771
- nestingPrefix: "$t(",
1772
- nestingSuffix: ")",
1773
- nestingOptionsSeparator: ",",
1774
- maxReplaces: 1e3,
1775
- skipOnVariables: true
1776
- },
1777
- cacheInBuiltFormats: true
1778
- });
1779
- transformOptions = (options) => {
1780
- if (isString(options.ns)) options.ns = [options.ns];
1781
- if (isString(options.fallbackLng)) options.fallbackLng = [options.fallbackLng];
1782
- if (isString(options.fallbackNS)) options.fallbackNS = [options.fallbackNS];
1783
- if (options.supportedLngs && !options.supportedLngs.includes("cimode")) {
1784
- options.supportedLngs = options.supportedLngs.concat(["cimode"]);
1785
- }
1786
- return options;
1787
- };
1788
- noop = () => {
1789
- };
1790
- bindMemberFunctions = (inst) => {
1791
- const mems = Object.getOwnPropertyNames(Object.getPrototypeOf(inst));
1792
- mems.forEach((mem) => {
1793
- if (typeof inst[mem] === "function") {
1794
- inst[mem] = inst[mem].bind(inst);
1795
- }
1796
- });
1797
- };
1798
- I18n = class _I18n extends EventEmitter {
1799
- constructor(options = {}, callback) {
1800
- super();
1801
- this.options = transformOptions(options);
1802
- this.services = {};
1803
- this.logger = baseLogger;
1804
- this.modules = {
1805
- external: []
1806
- };
1807
- bindMemberFunctions(this);
1808
- if (callback && !this.isInitialized && !options.isClone) {
1809
- if (!this.options.initAsync) {
1810
- this.init(options, callback);
1811
- return this;
1812
- }
1813
- setTimeout(() => {
1814
- this.init(options, callback);
1815
- }, 0);
1816
- }
1817
- }
1818
- init(options = {}, callback) {
1819
- this.isInitializing = true;
1820
- if (typeof options === "function") {
1821
- callback = options;
1822
- options = {};
1823
- }
1824
- if (options.defaultNS == null && options.ns) {
1825
- if (isString(options.ns)) {
1826
- options.defaultNS = options.ns;
1827
- } else if (!options.ns.includes("translation")) {
1828
- options.defaultNS = options.ns[0];
1829
- }
1830
- }
1831
- const defOpts = get();
1832
- this.options = {
1833
- ...defOpts,
1834
- ...this.options,
1835
- ...transformOptions(options)
1836
- };
1837
- this.options.interpolation = {
1838
- ...defOpts.interpolation,
1839
- ...this.options.interpolation
1840
- };
1841
- if (options.keySeparator !== void 0) {
1842
- this.options.userDefinedKeySeparator = options.keySeparator;
1843
- }
1844
- if (options.nsSeparator !== void 0) {
1845
- this.options.userDefinedNsSeparator = options.nsSeparator;
1846
- }
1847
- if (typeof this.options.overloadTranslationOptionHandler !== "function") {
1848
- this.options.overloadTranslationOptionHandler = defOpts.overloadTranslationOptionHandler;
1849
- }
1850
- const createClassOnDemand = (ClassOrObject) => {
1851
- if (!ClassOrObject) return null;
1852
- if (typeof ClassOrObject === "function") return new ClassOrObject();
1853
- return ClassOrObject;
1854
- };
1855
- if (!this.options.isClone) {
1856
- if (this.modules.logger) {
1857
- baseLogger.init(createClassOnDemand(this.modules.logger), this.options);
1858
- } else {
1859
- baseLogger.init(null, this.options);
1860
- }
1861
- let formatter;
1862
- if (this.modules.formatter) {
1863
- formatter = this.modules.formatter;
1864
- } else {
1865
- formatter = Formatter;
1866
- }
1867
- const lu = new LanguageUtil(this.options);
1868
- this.store = new ResourceStore(this.options.resources, this.options);
1869
- const s = this.services;
1870
- s.logger = baseLogger;
1871
- s.resourceStore = this.store;
1872
- s.languageUtils = lu;
1873
- s.pluralResolver = new PluralResolver(lu, {
1874
- prepend: this.options.pluralSeparator
1875
- });
1876
- if (formatter) {
1877
- s.formatter = createClassOnDemand(formatter);
1878
- if (s.formatter.init) s.formatter.init(s, this.options);
1879
- this.options.interpolation.format = s.formatter.format.bind(s.formatter);
1880
- }
1881
- s.interpolator = new Interpolator(this.options);
1882
- s.utils = {
1883
- hasLoadedNamespace: this.hasLoadedNamespace.bind(this)
1884
- };
1885
- s.backendConnector = new Connector(createClassOnDemand(this.modules.backend), s.resourceStore, s, this.options);
1886
- s.backendConnector.on("*", (event, ...args) => {
1887
- this.emit(event, ...args);
1888
- });
1889
- if (this.modules.languageDetector) {
1890
- s.languageDetector = createClassOnDemand(this.modules.languageDetector);
1891
- if (s.languageDetector.init) s.languageDetector.init(s, this.options.detection, this.options);
1892
- }
1893
- if (this.modules.i18nFormat) {
1894
- s.i18nFormat = createClassOnDemand(this.modules.i18nFormat);
1895
- if (s.i18nFormat.init) s.i18nFormat.init(this);
1896
- }
1897
- this.translator = new Translator(this.services, this.options);
1898
- this.translator.on("*", (event, ...args) => {
1899
- this.emit(event, ...args);
1900
- });
1901
- this.modules.external.forEach((m) => {
1902
- if (m.init) m.init(this);
1903
- });
1904
- }
1905
- this.format = this.options.interpolation.format;
1906
- if (!callback) callback = noop;
1907
- if (this.options.fallbackLng && !this.services.languageDetector && !this.options.lng) {
1908
- const codes = this.services.languageUtils.getFallbackCodes(this.options.fallbackLng);
1909
- if (codes.length > 0 && codes[0] !== "dev") this.options.lng = codes[0];
1910
- }
1911
- if (!this.services.languageDetector && !this.options.lng) {
1912
- this.logger.warn("init: no languageDetector is used and no lng is defined");
1913
- }
1914
- const storeApi = ["getResource", "hasResourceBundle", "getResourceBundle", "getDataByLanguage"];
1915
- storeApi.forEach((fcName) => {
1916
- this[fcName] = (...args) => this.store[fcName](...args);
1917
- });
1918
- const storeApiChained = ["addResource", "addResources", "addResourceBundle", "removeResourceBundle"];
1919
- storeApiChained.forEach((fcName) => {
1920
- this[fcName] = (...args) => {
1921
- this.store[fcName](...args);
1922
- return this;
1923
- };
1924
- });
1925
- const deferred = defer();
1926
- const load = () => {
1927
- const finish = (err, t2) => {
1928
- this.isInitializing = false;
1929
- if (this.isInitialized && !this.initializedStoreOnce) this.logger.warn("init: i18next is already initialized. You should call init just once!");
1930
- this.isInitialized = true;
1931
- if (!this.options.isClone) this.logger.log("initialized", this.options);
1932
- this.emit("initialized", this.options);
1933
- deferred.resolve(t2);
1934
- callback(err, t2);
1935
- };
1936
- if ((this.languages || this.isLanguageChangingTo) && !this.isInitialized) return finish(null, this.t.bind(this));
1937
- this.changeLanguage(this.options.lng, finish);
1938
- };
1939
- if (this.options.resources || !this.options.initAsync) {
1940
- load();
1941
- } else {
1942
- setTimeout(load, 0);
1943
- }
1944
- return deferred;
1945
- }
1946
- loadResources(language, callback = noop) {
1947
- let usedCallback = callback;
1948
- const usedLng = isString(language) ? language : this.language;
1949
- if (typeof language === "function") usedCallback = language;
1950
- if (!this.options.resources || this.options.partialBundledLanguages) {
1951
- if (usedLng?.toLowerCase() === "cimode" && (!this.options.preload || this.options.preload.length === 0)) return usedCallback();
1952
- const toLoad = [];
1953
- const append = (lng) => {
1954
- if (!lng) return;
1955
- if (lng === "cimode") return;
1956
- const lngs = this.services.languageUtils.toResolveHierarchy(lng);
1957
- lngs.forEach((l) => {
1958
- if (l === "cimode") return;
1959
- if (!toLoad.includes(l)) toLoad.push(l);
1960
- });
1961
- };
1962
- if (!usedLng) {
1963
- const fallbacks = this.services.languageUtils.getFallbackCodes(this.options.fallbackLng);
1964
- fallbacks.forEach((l) => append(l));
1965
- } else {
1966
- append(usedLng);
1967
- }
1968
- this.options.preload?.forEach?.((l) => append(l));
1969
- this.services.backendConnector.load(toLoad, this.options.ns, (e) => {
1970
- if (!e && !this.resolvedLanguage && this.language) this.setResolvedLanguage(this.language);
1971
- usedCallback(e);
1972
- });
1973
- } else {
1974
- usedCallback(null);
1975
- }
1976
- }
1977
- reloadResources(lngs, ns, callback) {
1978
- const deferred = defer();
1979
- if (typeof lngs === "function") {
1980
- callback = lngs;
1981
- lngs = void 0;
1982
- }
1983
- if (typeof ns === "function") {
1984
- callback = ns;
1985
- ns = void 0;
1986
- }
1987
- if (!lngs) lngs = this.languages;
1988
- if (!ns) ns = this.options.ns;
1989
- if (!callback) callback = noop;
1990
- this.services.backendConnector.reload(lngs, ns, (err) => {
1991
- deferred.resolve();
1992
- callback(err);
1993
- });
1994
- return deferred;
1995
- }
1996
- use(module2) {
1997
- if (!module2) throw new Error("You are passing an undefined module! Please check the object you are passing to i18next.use()");
1998
- if (!module2.type) throw new Error("You are passing a wrong module! Please check the object you are passing to i18next.use()");
1999
- if (module2.type === "backend") {
2000
- this.modules.backend = module2;
2001
- }
2002
- if (module2.type === "logger" || module2.log && module2.warn && module2.error) {
2003
- this.modules.logger = module2;
2004
- }
2005
- if (module2.type === "languageDetector") {
2006
- this.modules.languageDetector = module2;
2007
- }
2008
- if (module2.type === "i18nFormat") {
2009
- this.modules.i18nFormat = module2;
2010
- }
2011
- if (module2.type === "postProcessor") {
2012
- postProcessor.addPostProcessor(module2);
2013
- }
2014
- if (module2.type === "formatter") {
2015
- this.modules.formatter = module2;
2016
- }
2017
- if (module2.type === "3rdParty") {
2018
- this.modules.external.push(module2);
2019
- }
2020
- return this;
2021
- }
2022
- setResolvedLanguage(l) {
2023
- if (!l || !this.languages) return;
2024
- if (["cimode", "dev"].includes(l)) return;
2025
- for (let li = 0; li < this.languages.length; li++) {
2026
- const lngInLngs = this.languages[li];
2027
- if (["cimode", "dev"].includes(lngInLngs)) continue;
2028
- if (this.store.hasLanguageSomeTranslations(lngInLngs)) {
2029
- this.resolvedLanguage = lngInLngs;
2030
- break;
2031
- }
2032
- }
2033
- if (!this.resolvedLanguage && !this.languages.includes(l) && this.store.hasLanguageSomeTranslations(l)) {
2034
- this.resolvedLanguage = l;
2035
- this.languages.unshift(l);
2036
- }
2037
- }
2038
- changeLanguage(lng, callback) {
2039
- this.isLanguageChangingTo = lng;
2040
- const deferred = defer();
2041
- this.emit("languageChanging", lng);
2042
- const setLngProps = (l) => {
2043
- this.language = l;
2044
- this.languages = this.services.languageUtils.toResolveHierarchy(l);
2045
- this.resolvedLanguage = void 0;
2046
- this.setResolvedLanguage(l);
2047
- };
2048
- const done = (err, l) => {
2049
- if (l) {
2050
- if (this.isLanguageChangingTo === lng) {
2051
- setLngProps(l);
2052
- this.translator.changeLanguage(l);
2053
- this.isLanguageChangingTo = void 0;
2054
- this.emit("languageChanged", l);
2055
- this.logger.log("languageChanged", l);
2056
- }
2057
- } else {
2058
- this.isLanguageChangingTo = void 0;
2059
- }
2060
- deferred.resolve((...args) => this.t(...args));
2061
- if (callback) callback(err, (...args) => this.t(...args));
2062
- };
2063
- const setLng = (lngs) => {
2064
- if (!lng && !lngs && this.services.languageDetector) lngs = [];
2065
- const fl = isString(lngs) ? lngs : lngs && lngs[0];
2066
- const l = this.store.hasLanguageSomeTranslations(fl) ? fl : this.services.languageUtils.getBestMatchFromCodes(isString(lngs) ? [lngs] : lngs);
2067
- if (l) {
2068
- if (!this.language) {
2069
- setLngProps(l);
2070
- }
2071
- if (!this.translator.language) this.translator.changeLanguage(l);
2072
- this.services.languageDetector?.cacheUserLanguage?.(l);
2073
- }
2074
- this.loadResources(l, (err) => {
2075
- done(err, l);
2076
- });
2077
- };
2078
- if (!lng && this.services.languageDetector && !this.services.languageDetector.async) {
2079
- setLng(this.services.languageDetector.detect());
2080
- } else if (!lng && this.services.languageDetector && this.services.languageDetector.async) {
2081
- if (this.services.languageDetector.detect.length === 0) {
2082
- this.services.languageDetector.detect().then(setLng);
2083
- } else {
2084
- this.services.languageDetector.detect(setLng);
2085
- }
2086
- } else {
2087
- setLng(lng);
2088
- }
2089
- return deferred;
2090
- }
2091
- getFixedT(lng, ns, keyPrefix, fixedOpts) {
2092
- const scopeNs = fixedOpts?.scopeNs;
2093
- const fixedT = (key, opts, ...rest) => {
2094
- let o;
2095
- if (typeof opts !== "object") {
2096
- o = this.options.overloadTranslationOptionHandler([key, opts].concat(rest));
2097
- } else {
2098
- o = {
2099
- ...opts
2100
- };
2101
- }
2102
- o.lng = o.lng || fixedT.lng;
2103
- o.lngs = o.lngs || fixedT.lngs;
2104
- const explicitCallNs = o.ns !== void 0 && o.ns !== null;
2105
- o.ns = o.ns || fixedT.ns;
2106
- if (o.keyPrefix !== "") o.keyPrefix = o.keyPrefix || keyPrefix || fixedT.keyPrefix;
2107
- const selectorOpts = {
2108
- ...this.options,
2109
- ...o
2110
- };
2111
- if (Array.isArray(scopeNs) && !explicitCallNs) selectorOpts.ns = scopeNs;
2112
- if (typeof o.keyPrefix === "function") o.keyPrefix = keysFromSelector(o.keyPrefix, selectorOpts);
2113
- const keySeparator = this.options.keySeparator || ".";
2114
- let resultKey;
2115
- if (o.keyPrefix && Array.isArray(key)) {
2116
- resultKey = key.map((k) => {
2117
- if (typeof k === "function") k = keysFromSelector(k, selectorOpts);
2118
- return `${o.keyPrefix}${keySeparator}${k}`;
2119
- });
2120
- } else {
2121
- if (typeof key === "function") key = keysFromSelector(key, selectorOpts);
2122
- resultKey = o.keyPrefix ? `${o.keyPrefix}${keySeparator}${key}` : key;
2123
- }
2124
- return this.t(resultKey, o);
2125
- };
2126
- if (isString(lng)) {
2127
- fixedT.lng = lng;
2128
- } else {
2129
- fixedT.lngs = lng;
2130
- }
2131
- fixedT.ns = ns;
2132
- fixedT.keyPrefix = keyPrefix;
2133
- return fixedT;
2134
- }
2135
- t(...args) {
2136
- return this.translator?.translate(...args);
2137
- }
2138
- exists(...args) {
2139
- return this.translator?.exists(...args);
2140
- }
2141
- setDefaultNamespace(ns) {
2142
- this.options.defaultNS = ns;
2143
- }
2144
- hasLoadedNamespace(ns, options = {}) {
2145
- if (!this.isInitialized) {
2146
- this.logger.warn("hasLoadedNamespace: i18next was not initialized", this.languages);
2147
- return false;
2148
- }
2149
- if (!this.languages || !this.languages.length) {
2150
- this.logger.warn("hasLoadedNamespace: i18n.languages were undefined or empty", this.languages);
2151
- return false;
2152
- }
2153
- const lng = options.lng || this.resolvedLanguage || this.languages[0];
2154
- const fallbackLng = this.options ? this.options.fallbackLng : false;
2155
- const lastLng = this.languages[this.languages.length - 1];
2156
- if (lng.toLowerCase() === "cimode") return true;
2157
- const loadNotPending = (l, n) => {
2158
- const loadState = this.services.backendConnector.state[`${l}|${n}`];
2159
- return loadState === -1 || loadState === 0 || loadState === 2;
2160
- };
2161
- if (options.precheck) {
2162
- const preResult = options.precheck(this, loadNotPending);
2163
- if (preResult !== void 0) return preResult;
2164
- }
2165
- if (this.hasResourceBundle(lng, ns)) return true;
2166
- if (!this.services.backendConnector.backend || this.options.resources && !this.options.partialBundledLanguages) return true;
2167
- if (loadNotPending(lng, ns) && (!fallbackLng || loadNotPending(lastLng, ns))) return true;
2168
- return false;
2169
- }
2170
- loadNamespaces(ns, callback) {
2171
- const deferred = defer();
2172
- if (!this.options.ns) {
2173
- if (callback) callback();
2174
- return Promise.resolve();
2175
- }
2176
- if (isString(ns)) ns = [ns];
2177
- ns.forEach((n) => {
2178
- if (!this.options.ns.includes(n)) this.options.ns.push(n);
2179
- });
2180
- this.loadResources((err) => {
2181
- deferred.resolve();
2182
- if (callback) callback(err);
2183
- });
2184
- return deferred;
2185
- }
2186
- loadLanguages(lngs, callback) {
2187
- const deferred = defer();
2188
- if (isString(lngs)) lngs = [lngs];
2189
- const preloaded = this.options.preload || [];
2190
- const newLngs = lngs.filter((lng) => !preloaded.includes(lng) && this.services.languageUtils.isSupportedCode(lng));
2191
- if (!newLngs.length) {
2192
- if (callback) callback();
2193
- return Promise.resolve();
2194
- }
2195
- this.options.preload = preloaded.concat(newLngs);
2196
- this.loadResources((err) => {
2197
- deferred.resolve();
2198
- if (callback) callback(err);
2199
- });
2200
- return deferred;
2201
- }
2202
- dir(lng) {
2203
- if (!lng) lng = this.resolvedLanguage || (this.languages?.length > 0 ? this.languages[0] : this.language);
2204
- if (!lng) return "rtl";
2205
- try {
2206
- const l = new Intl.Locale(lng);
2207
- if (l && l.getTextInfo) {
2208
- const ti = l.getTextInfo();
2209
- if (ti && ti.direction) return ti.direction;
2210
- }
2211
- } catch (e) {
2212
- }
2213
- const rtlLngs = ["ar", "shu", "sqr", "ssh", "xaa", "yhd", "yud", "aao", "abh", "abv", "acm", "acq", "acw", "acx", "acy", "adf", "ads", "aeb", "aec", "afb", "ajp", "apc", "apd", "arb", "arq", "ars", "ary", "arz", "auz", "avl", "ayh", "ayl", "ayn", "ayp", "bbz", "pga", "he", "iw", "ps", "pbt", "pbu", "pst", "prp", "prd", "ug", "ur", "ydd", "yds", "yih", "ji", "yi", "hbo", "men", "xmn", "fa", "jpr", "peo", "pes", "prs", "dv", "sam", "ckb"];
2214
- const languageUtils = this.services?.languageUtils || new LanguageUtil(get());
2215
- if (lng.toLowerCase().indexOf("-latn") > 1) return "ltr";
2216
- return rtlLngs.includes(languageUtils.getLanguagePartFromCode(lng)) || lng.toLowerCase().indexOf("-arab") > 1 ? "rtl" : "ltr";
2217
- }
2218
- static createInstance(options = {}, callback) {
2219
- const instance2 = new _I18n(options, callback);
2220
- instance2.createInstance = _I18n.createInstance;
2221
- return instance2;
2222
- }
2223
- cloneInstance(options = {}, callback = noop) {
2224
- const forkResourceStore = options.forkResourceStore;
2225
- if (forkResourceStore) delete options.forkResourceStore;
2226
- const mergedOptions = {
2227
- ...this.options,
2228
- ...options,
2229
- ...{
2230
- isClone: true
2231
- }
2232
- };
2233
- const clone = new _I18n(mergedOptions);
2234
- if (options.debug !== void 0 || options.prefix !== void 0) {
2235
- clone.logger = clone.logger.clone(options);
2236
- }
2237
- const membersToCopy = ["store", "services", "language"];
2238
- membersToCopy.forEach((m) => {
2239
- clone[m] = this[m];
2240
- });
2241
- clone.services = {
2242
- ...this.services
2243
- };
2244
- clone.services.utils = {
2245
- hasLoadedNamespace: clone.hasLoadedNamespace.bind(clone)
2246
- };
2247
- if (forkResourceStore) {
2248
- const clonedData = Object.keys(this.store.data).reduce((prev, l) => {
2249
- prev[l] = {
2250
- ...this.store.data[l]
2251
- };
2252
- prev[l] = Object.keys(prev[l]).reduce((acc, n) => {
2253
- acc[n] = {
2254
- ...prev[l][n]
2255
- };
2256
- return acc;
2257
- }, prev[l]);
2258
- return prev;
2259
- }, {});
2260
- clone.store = new ResourceStore(clonedData, mergedOptions);
2261
- clone.services.resourceStore = clone.store;
2262
- }
2263
- if (options.interpolation) {
2264
- const defOpts = get();
2265
- const mergedInterpolation = {
2266
- ...defOpts.interpolation,
2267
- ...this.options.interpolation,
2268
- ...options.interpolation
2269
- };
2270
- const mergedForInterpolator = {
2271
- ...mergedOptions,
2272
- interpolation: mergedInterpolation
2273
- };
2274
- clone.services.interpolator = new Interpolator(mergedForInterpolator);
2275
- }
2276
- clone.translator = new Translator(clone.services, mergedOptions);
2277
- clone.translator.on("*", (event, ...args) => {
2278
- clone.emit(event, ...args);
2279
- });
2280
- clone.init(mergedOptions, callback);
2281
- clone.translator.options = mergedOptions;
2282
- clone.translator.backendConnector.services.utils = {
2283
- hasLoadedNamespace: clone.hasLoadedNamespace.bind(clone)
2284
- };
2285
- return clone;
2286
- }
2287
- toJSON() {
2288
- return {
2289
- options: this.options,
2290
- store: this.store,
2291
- language: this.language,
2292
- languages: this.languages,
2293
- resolvedLanguage: this.resolvedLanguage
2294
- };
2295
- }
2296
- };
2297
- instance = I18n.createInstance();
2298
- createInstance = instance.createInstance;
2299
- dir = instance.dir;
2300
- init = instance.init;
2301
- loadResources = instance.loadResources;
2302
- reloadResources = instance.reloadResources;
2303
- use = instance.use;
2304
- changeLanguage = instance.changeLanguage;
2305
- getFixedT = instance.getFixedT;
2306
- t = instance.t;
2307
- exists = instance.exists;
2308
- setDefaultNamespace = instance.setDefaultNamespace;
2309
- hasLoadedNamespace = instance.hasLoadedNamespace;
2310
- loadNamespaces = instance.loadNamespaces;
2311
- loadLanguages = instance.loadLanguages;
2312
- }
2313
- });
2314
-
2315
33
  // src/i18n/customCacheBackend.ts
2316
34
  var _SupabaseCacheBackend, SupabaseCacheBackend;
2317
35
  var init_customCacheBackend = __esm({
@@ -2423,14 +141,14 @@ var init_customCacheBackend = __esm({
2423
141
  });
2424
142
 
2425
143
  // src/i18n/config.ts
2426
- var import_react_i18next, config_default;
144
+ var import_i18next, import_react_i18next, config_default;
2427
145
  var init_config = __esm({
2428
146
  "src/i18n/config.ts"() {
2429
147
  "use strict";
2430
- init_i18next();
148
+ import_i18next = __toESM(require("i18next"));
2431
149
  import_react_i18next = require("react-i18next");
2432
150
  init_customCacheBackend();
2433
- config_default = instance;
151
+ config_default = import_i18next.default;
2434
152
  }
2435
153
  });
2436
154
 
@@ -2811,7 +529,7 @@ var init_TranslationDialog = __esm({
2811
529
  const initialValues = {};
2812
530
  let existingHint = "";
2813
531
  langs?.forEach((l) => {
2814
- const found = trans?.find((t2) => t2.lang_code === l.code);
532
+ const found = trans?.find((t) => t.lang_code === l.code);
2815
533
  initialValues[l.code] = found ? found.value : "";
2816
534
  if (found?.context_hint) {
2817
535
  existingHint = found.context_hint;
@@ -3057,13 +775,13 @@ var init_TranslateText = __esm({
3057
775
  values
3058
776
  }) => {
3059
777
  const namespace = useTranslationNamespace(overrideNamespace);
3060
- const { t: t2, i18n } = (0, import_react_i18next2.useTranslation)(namespace);
778
+ const { t, i18n: i18n2 } = (0, import_react_i18next2.useTranslation)(namespace);
3061
779
  const { isTranslationMode, canEdit } = useTranslationEdit();
3062
780
  const supabase = useSupabase();
3063
781
  const [anchorEl, setAnchorEl] = (0, import_react7.useState)(null);
3064
782
  const [isDialogOpen, setIsDialogOpen] = (0, import_react7.useState)(false);
3065
783
  const timeoutRef = (0, import_react7.useRef)(null);
3066
- const translatedValue = t2(children, values);
784
+ const translatedValue = t(children, values);
3067
785
  (0, import_react7.useEffect)(() => {
3068
786
  return () => {
3069
787
  if (timeoutRef.current) clearTimeout(timeoutRef.current);
@@ -3087,7 +805,7 @@ var init_TranslateText = __esm({
3087
805
  }
3088
806
  await translationService.incrementVersion(supabase, namespace, Object.keys(newValues));
3089
807
  Object.entries(newValues).forEach(([langCode, text]) => {
3090
- i18n.addResource(langCode, namespace, children, text);
808
+ i18n2.addResource(langCode, namespace, children, text);
3091
809
  });
3092
810
  };
3093
811
  const handleMouseEnter = (event) => {
@@ -3300,7 +1018,7 @@ var init_LocalizationProvider = __esm({
3300
1018
  LocalizationContext = (0, import_react12.createContext)(void 0);
3301
1019
  LocalizationProvider = ({ children }) => {
3302
1020
  const supabase = useSupabase();
3303
- const { i18n } = (0, import_react_i18next4.useTranslation)();
1021
+ const { i18n: i18n2 } = (0, import_react_i18next4.useTranslation)();
3304
1022
  const [languages, setLanguages] = (0, import_react12.useState)([]);
3305
1023
  const [isLoadingLangs, setIsLoadingLangs] = (0, import_react12.useState)(true);
3306
1024
  const [languagesError, setLanguagesError] = (0, import_react12.useState)(null);
@@ -3333,7 +1051,7 @@ var init_LocalizationProvider = __esm({
3333
1051
  isMounted = false;
3334
1052
  };
3335
1053
  }, [supabase]);
3336
- const rawLang = i18n.language || "uk";
1054
+ const rawLang = i18n2.language || "uk";
3337
1055
  const currentLang = rawLang.split("-")[0].toLowerCase();
3338
1056
  const getDateFormat = () => {
3339
1057
  return DEFAULT_DATE_FORMATS[currentLang] || "DD.MM.YYYY";
@@ -3363,8 +1081,8 @@ var init_LocalizationProvider = __esm({
3363
1081
  if (!date) return "\u2014";
3364
1082
  return (0, import_moment_with_locales.default)(date).locale(currentLang).fromNow(withoutSuffix);
3365
1083
  };
3366
- const changeLanguage2 = async (lang) => {
3367
- await i18n.changeLanguage(lang);
1084
+ const changeLanguage = async (lang) => {
1085
+ await i18n2.changeLanguage(lang);
3368
1086
  };
3369
1087
  const value = (0, import_react12.useMemo)(
3370
1088
  () => ({
@@ -3372,7 +1090,7 @@ var init_LocalizationProvider = __esm({
3372
1090
  languages,
3373
1091
  isLoadingLangs,
3374
1092
  languagesError,
3375
- changeLanguage: changeLanguage2,
1093
+ changeLanguage,
3376
1094
  getDateFormat,
3377
1095
  getTimeFormat,
3378
1096
  getDateTimeFormat,
@@ -3797,6 +1515,76 @@ var init_ConfirmationProvider = __esm({
3797
1515
  }
3798
1516
  });
3799
1517
 
1518
+ // src/context/AppSettingsProvider.tsx
1519
+ var import_react17, import_jsx_runtime18, DEFAULT_SETTINGS, AppSettingsContext, AppSettingsProvider, useAppSettings;
1520
+ var init_AppSettingsProvider = __esm({
1521
+ "src/context/AppSettingsProvider.tsx"() {
1522
+ "use strict";
1523
+ import_react17 = require("react");
1524
+ init_SupabaseProvider();
1525
+ import_jsx_runtime18 = require("react/jsx-runtime");
1526
+ DEFAULT_SETTINGS = {
1527
+ max_group_members: 100
1528
+ };
1529
+ AppSettingsContext = (0, import_react17.createContext)(void 0);
1530
+ AppSettingsProvider = ({ children }) => {
1531
+ const supabase = useSupabase();
1532
+ const [settings, setSettings] = (0, import_react17.useState)(DEFAULT_SETTINGS);
1533
+ const [loading, setLoading] = (0, import_react17.useState)(true);
1534
+ const [error, setError] = (0, import_react17.useState)(null);
1535
+ const fetchSettings = (0, import_react17.useCallback)(async () => {
1536
+ try {
1537
+ setLoading(true);
1538
+ setError(null);
1539
+ const { data, error: supabaseError } = await supabase.from("app_settings").select("key, value");
1540
+ if (supabaseError) throw supabaseError;
1541
+ if (data) {
1542
+ const parsedSettings = data.reduce((acc, item) => {
1543
+ acc[item.key] = item.value;
1544
+ return acc;
1545
+ }, { ...DEFAULT_SETTINGS });
1546
+ setSettings(parsedSettings);
1547
+ }
1548
+ } catch (err) {
1549
+ console.error("\u041E\u0448\u0438\u0431\u043A\u0430 \u0437\u0430\u0433\u0440\u0443\u0437\u043A\u0438 \u0441\u0438\u0441\u0442\u0435\u043C\u043D\u044B\u0445 \u043D\u0430\u0441\u0442\u0440\u043E\u0435\u043A:", err.message || err);
1550
+ setError(err.message || "\u041D\u0435 \u0443\u0434\u0430\u043B\u043E\u0441\u044C \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044C \u043D\u0430\u0441\u0442\u0440\u043E\u0439\u043A\u0438 \u043F\u0440\u0438\u043B\u043E\u0436\u0435\u043D\u0438\u044F");
1551
+ } finally {
1552
+ setLoading(false);
1553
+ }
1554
+ }, []);
1555
+ (0, import_react17.useEffect)(() => {
1556
+ fetchSettings();
1557
+ }, [fetchSettings]);
1558
+ const getSetting = (0, import_react17.useCallback)((key, defaultValue) => {
1559
+ if (key in settings && settings[key] !== null && settings[key] !== void 0) {
1560
+ return settings[key];
1561
+ }
1562
+ return defaultValue;
1563
+ }, [settings]);
1564
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
1565
+ AppSettingsContext.Provider,
1566
+ {
1567
+ value: {
1568
+ settings,
1569
+ loading,
1570
+ error,
1571
+ getSetting,
1572
+ refetchSettings: fetchSettings
1573
+ },
1574
+ children
1575
+ }
1576
+ );
1577
+ };
1578
+ useAppSettings = () => {
1579
+ const context = (0, import_react17.useContext)(AppSettingsContext);
1580
+ if (!context) {
1581
+ throw new Error("useAppSettings should be used within the AppSettingsProvider");
1582
+ }
1583
+ return context;
1584
+ };
1585
+ }
1586
+ });
1587
+
3800
1588
  // src/context/index.ts
3801
1589
  var Providers;
3802
1590
  var init_context = __esm({
@@ -3811,7 +1599,9 @@ var init_context = __esm({
3811
1599
  init_ToastProvider();
3812
1600
  init_ConfirmationProvider();
3813
1601
  init_AIProvider();
1602
+ init_AppSettingsProvider();
3814
1603
  init_SupabaseProvider();
1604
+ init_AppSettingsProvider();
3815
1605
  init_TranslateProvider();
3816
1606
  init_TranslateText();
3817
1607
  init_TranslationEditProvider();
@@ -3823,6 +1613,7 @@ var init_context = __esm({
3823
1613
  init_AIProvider();
3824
1614
  Providers = {
3825
1615
  Supabase: SupabaseProvider,
1616
+ AppSettings: AppSettingsProvider,
3826
1617
  Translate: TranslateProvider,
3827
1618
  TranslationEdit: TranslationEditProvider,
3828
1619
  Localization: LocalizationProvider,
@@ -3836,33 +1627,33 @@ var init_context = __esm({
3836
1627
  });
3837
1628
 
3838
1629
  // src/UI/components/data.display/UserStatusChipComponent.tsx
3839
- var import_material10, import_InfoOutlined, import_jsx_runtime18, UserStatusChipComponent;
1630
+ var import_material10, import_InfoOutlined, import_jsx_runtime19, UserStatusChipComponent;
3840
1631
  var init_UserStatusChipComponent = __esm({
3841
1632
  "src/UI/components/data.display/UserStatusChipComponent.tsx"() {
3842
1633
  "use strict";
3843
1634
  import_material10 = require("@mui/material");
3844
1635
  import_InfoOutlined = __toESM(require("@mui/icons-material/InfoOutlined"));
3845
1636
  init_context();
3846
- import_jsx_runtime18 = require("react/jsx-runtime");
1637
+ import_jsx_runtime19 = require("react/jsx-runtime");
3847
1638
  UserStatusChipComponent = ({ overrideNamespace, state }) => {
3848
1639
  const confirm = useConfirmation();
3849
1640
  const handleShowReason = async (e) => {
3850
1641
  e.stopPropagation();
3851
1642
  if (!state.locked_reason) return;
3852
1643
  await confirm({
3853
- title: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(TranslateText, { overrideNamespace: overrideNamespace || "system_widgets", children: "Lock Reason" }),
1644
+ title: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(TranslateText, { overrideNamespace: overrideNamespace || "system_widgets", children: "Lock Reason" }),
3854
1645
  message: state.locked_reason,
3855
1646
  type: "info",
3856
- confirmText: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(TranslateText, { overrideNamespace: overrideNamespace || "system_widgets", children: "OK" }),
1647
+ confirmText: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(TranslateText, { overrideNamespace: overrideNamespace || "system_widgets", children: "OK" }),
3857
1648
  showNoButton: false,
3858
1649
  showCancelButton: false
3859
1650
  });
3860
1651
  };
3861
1652
  if (state.profile_archived) {
3862
- return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
1653
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
3863
1654
  import_material10.Chip,
3864
1655
  {
3865
- label: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(TranslateText, { overrideNamespace: overrideNamespace || "system_widgets", children: "Archived" }),
1656
+ label: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(TranslateText, { overrideNamespace: overrideNamespace || "system_widgets", children: "Archived" }),
3866
1657
  color: "default",
3867
1658
  size: "small",
3868
1659
  variant: "filled"
@@ -3870,10 +1661,10 @@ var init_UserStatusChipComponent = __esm({
3870
1661
  );
3871
1662
  }
3872
1663
  if (state.profile_locked) {
3873
- return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
1664
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
3874
1665
  import_material10.Chip,
3875
1666
  {
3876
- label: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(TranslateText, { overrideNamespace: overrideNamespace || "system_widgets", children: "System Locked" }),
1667
+ label: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(TranslateText, { overrideNamespace: overrideNamespace || "system_widgets", children: "System Locked" }),
3877
1668
  color: "error",
3878
1669
  size: "small",
3879
1670
  variant: "filled"
@@ -3881,30 +1672,30 @@ var init_UserStatusChipComponent = __esm({
3881
1672
  );
3882
1673
  }
3883
1674
  if (state.excluded) {
3884
- return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
1675
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
3885
1676
  import_material10.Chip,
3886
1677
  {
3887
- label: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(TranslateText, { overrideNamespace: overrideNamespace || "system_widgets", children: "Excluded" }),
1678
+ label: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(TranslateText, { overrideNamespace: overrideNamespace || "system_widgets", children: "Excluded" }),
3888
1679
  size: "small"
3889
1680
  }
3890
1681
  );
3891
1682
  }
3892
1683
  if (state.locked) {
3893
- return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
1684
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
3894
1685
  import_material10.Chip,
3895
1686
  {
3896
- label: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(TranslateText, { overrideNamespace: overrideNamespace || "system_widgets", children: "Locked" }),
1687
+ label: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(TranslateText, { overrideNamespace: overrideNamespace || "system_widgets", children: "Locked" }),
3897
1688
  color: "error",
3898
1689
  size: "small",
3899
1690
  onDelete: state.locked_reason ? handleShowReason : void 0,
3900
- deleteIcon: state.locked_reason ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_material10.IconButton, { size: "small", component: "span", sx: { p: 0.2 }, children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_InfoOutlined.default, { fontSize: "small" }) }) : void 0
1691
+ deleteIcon: state.locked_reason ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_material10.IconButton, { size: "small", component: "span", sx: { p: 0.2 }, children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_InfoOutlined.default, { fontSize: "small" }) }) : void 0
3901
1692
  }
3902
1693
  );
3903
1694
  }
3904
- return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
1695
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
3905
1696
  import_material10.Chip,
3906
1697
  {
3907
- label: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(TranslateText, { overrideNamespace: overrideNamespace || "system_widgets", children: "Active" }),
1698
+ label: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(TranslateText, { overrideNamespace: overrideNamespace || "system_widgets", children: "Active" }),
3908
1699
  color: "success",
3909
1700
  size: "small",
3910
1701
  variant: "outlined"
@@ -3915,38 +1706,38 @@ var init_UserStatusChipComponent = __esm({
3915
1706
  });
3916
1707
 
3917
1708
  // src/UI/components/data.display/UserRoleChipComponent.tsx
3918
- var import_material11, import_jsx_runtime19, UserRoleChipComponent;
1709
+ var import_material11, import_jsx_runtime20, UserRoleChipComponent;
3919
1710
  var init_UserRoleChipComponent = __esm({
3920
1711
  "src/UI/components/data.display/UserRoleChipComponent.tsx"() {
3921
1712
  "use strict";
3922
1713
  import_material11 = require("@mui/material");
3923
1714
  init_context();
3924
- import_jsx_runtime19 = require("react/jsx-runtime");
1715
+ import_jsx_runtime20 = require("react/jsx-runtime");
3925
1716
  UserRoleChipComponent = ({ overrideNamespace, role }) => {
3926
1717
  switch (role) {
3927
1718
  case "superadmin":
3928
- return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
1719
+ return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
3929
1720
  import_material11.Chip,
3930
1721
  {
3931
- label: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(TranslateText, { overrideNamespace: overrideNamespace || "system_widgets", children: "Superadministrator" }),
1722
+ label: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(TranslateText, { overrideNamespace: overrideNamespace || "system_widgets", children: "Superadministrator" }),
3932
1723
  color: "error",
3933
1724
  size: "small"
3934
1725
  }
3935
1726
  );
3936
1727
  case "admin":
3937
- return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
1728
+ return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
3938
1729
  import_material11.Chip,
3939
1730
  {
3940
- label: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(TranslateText, { overrideNamespace: overrideNamespace || "system_widgets", children: "Administrator" }),
1731
+ label: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(TranslateText, { overrideNamespace: overrideNamespace || "system_widgets", children: "Administrator" }),
3941
1732
  color: "primary",
3942
1733
  size: "small"
3943
1734
  }
3944
1735
  );
3945
1736
  default:
3946
- return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
1737
+ return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
3947
1738
  import_material11.Chip,
3948
1739
  {
3949
- label: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(TranslateText, { overrideNamespace: overrideNamespace || "system_widgets", children: "User" }),
1740
+ label: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(TranslateText, { overrideNamespace: overrideNamespace || "system_widgets", children: "User" }),
3950
1741
  variant: "outlined",
3951
1742
  size: "small"
3952
1743
  }
@@ -3957,16 +1748,16 @@ var init_UserRoleChipComponent = __esm({
3957
1748
  });
3958
1749
 
3959
1750
  // src/UI/components/buttons/CopyClipboardButtonComponent.tsx
3960
- var import_react17, import_material12, import_Check3, import_ContentCopy3, import_jsx_runtime20, CopyClipboardButtonComponent;
1751
+ var import_react18, import_material12, import_Check3, import_ContentCopy3, import_jsx_runtime21, CopyClipboardButtonComponent;
3961
1752
  var init_CopyClipboardButtonComponent = __esm({
3962
1753
  "src/UI/components/buttons/CopyClipboardButtonComponent.tsx"() {
3963
1754
  "use strict";
3964
- import_react17 = require("react");
1755
+ import_react18 = require("react");
3965
1756
  import_material12 = require("@mui/material");
3966
1757
  import_Check3 = __toESM(require("@mui/icons-material/Check"));
3967
1758
  import_ContentCopy3 = __toESM(require("@mui/icons-material/ContentCopy"));
3968
1759
  init_TranslatableTooltipComponent();
3969
- import_jsx_runtime20 = require("react/jsx-runtime");
1760
+ import_jsx_runtime21 = require("react/jsx-runtime");
3970
1761
  CopyClipboardButtonComponent = ({
3971
1762
  overrideNamespace,
3972
1763
  textToCopy,
@@ -3979,7 +1770,7 @@ var init_CopyClipboardButtonComponent = __esm({
3979
1770
  sx,
3980
1771
  ...iconButtonProps
3981
1772
  }) => {
3982
- const [copied, setCopied] = (0, import_react17.useState)(false);
1773
+ const [copied, setCopied] = (0, import_react18.useState)(false);
3983
1774
  const handleCopy = async (e) => {
3984
1775
  e.stopPropagation();
3985
1776
  if (!textToCopy) return;
@@ -3996,7 +1787,7 @@ var init_CopyClipboardButtonComponent = __esm({
3996
1787
  console.error("Failed to copy text to clipboard:", error);
3997
1788
  }
3998
1789
  };
3999
- return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(TranslatableTooltipComponent, { title: copied ? copiedTooltipText : copyTooltipText, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
1790
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(TranslatableTooltipComponent, { title: copied ? copiedTooltipText : copyTooltipText, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
4000
1791
  import_material12.IconButton,
4001
1792
  {
4002
1793
  size,
@@ -4004,7 +1795,7 @@ var init_CopyClipboardButtonComponent = __esm({
4004
1795
  disabled: !textToCopy || iconButtonProps.disabled,
4005
1796
  sx: { p: 0.25, ...sx },
4006
1797
  ...iconButtonProps,
4007
- children: copied ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_Check3.default, { fontSize: size === "large" ? "medium" : "small", color: "success" }) : /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_ContentCopy3.default, { fontSize: size === "large" ? "medium" : "small" })
1798
+ children: copied ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_Check3.default, { fontSize: size === "large" ? "medium" : "small", color: "success" }) : /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_ContentCopy3.default, { fontSize: size === "large" ? "medium" : "small" })
4008
1799
  }
4009
1800
  ) }) });
4010
1801
  };
@@ -4019,19 +1810,19 @@ var init_user_types = __esm({
4019
1810
  });
4020
1811
 
4021
1812
  // src/context/UserSettingsProvider.tsx
4022
- var import_react18, import_jsx_runtime21, UserSettingsContext, useUserSettings;
1813
+ var import_react19, import_jsx_runtime22, UserSettingsContext, useUserSettings;
4023
1814
  var init_UserSettingsProvider = __esm({
4024
1815
  "src/context/UserSettingsProvider.tsx"() {
4025
1816
  "use strict";
4026
- import_react18 = require("react");
1817
+ import_react19 = require("react");
4027
1818
  init_user_types();
4028
1819
  init_ThemeProvider();
4029
1820
  init_AuthProvider();
4030
1821
  init_SupabaseProvider();
4031
- import_jsx_runtime21 = require("react/jsx-runtime");
4032
- UserSettingsContext = (0, import_react18.createContext)(void 0);
1822
+ import_jsx_runtime22 = require("react/jsx-runtime");
1823
+ UserSettingsContext = (0, import_react19.createContext)(void 0);
4033
1824
  useUserSettings = () => {
4034
- const context = (0, import_react18.useContext)(UserSettingsContext);
1825
+ const context = (0, import_react19.useContext)(UserSettingsContext);
4035
1826
  if (!context) {
4036
1827
  throw new Error("useUserSettings should be used within the UserSettingsProvider");
4037
1828
  }
@@ -4046,11 +1837,11 @@ __export(UserPopoverComponent_exports, {
4046
1837
  UserPopoverComponent: () => UserPopoverComponent,
4047
1838
  default: () => UserPopoverComponent_default
4048
1839
  });
4049
- var import_react19, import_material13, import_icons_material2, import_jsx_runtime22, useUserStatus, UserPopoverComponent, UserPopoverComponent_default;
1840
+ var import_react20, import_material13, import_icons_material2, import_jsx_runtime23, useUserStatus, UserPopoverComponent, UserPopoverComponent_default;
4050
1841
  var init_UserPopoverComponent = __esm({
4051
1842
  "src/UI/components/data.display/UserPopoverComponent.tsx"() {
4052
1843
  "use strict";
4053
- import_react19 = require("react");
1844
+ import_react20 = require("react");
4054
1845
  import_material13 = require("@mui/material");
4055
1846
  import_icons_material2 = require("@mui/icons-material");
4056
1847
  init_UserStatusChipComponent();
@@ -4061,11 +1852,11 @@ var init_UserPopoverComponent = __esm({
4061
1852
  init_UserSettingsProvider();
4062
1853
  init_TranslatableTooltipComponent();
4063
1854
  init_session_service();
4064
- import_jsx_runtime22 = require("react/jsx-runtime");
1855
+ import_jsx_runtime23 = require("react/jsx-runtime");
4065
1856
  useUserStatus = (supabase, userId, open) => {
4066
- const [lastSeenAt, setLastSeenAt] = (0, import_react19.useState)(null);
4067
- const [loading, setLoading] = (0, import_react19.useState)(true);
4068
- (0, import_react19.useEffect)(() => {
1857
+ const [lastSeenAt, setLastSeenAt] = (0, import_react20.useState)(null);
1858
+ const [loading, setLoading] = (0, import_react20.useState)(true);
1859
+ (0, import_react20.useEffect)(() => {
4069
1860
  if (!userId || !open) {
4070
1861
  setLastSeenAt(null);
4071
1862
  setLoading(false);
@@ -4114,13 +1905,13 @@ var init_UserPopoverComponent = __esm({
4114
1905
  const { activeCompanyId, membership: currentMembership } = useAuth();
4115
1906
  const { openChatWithUser } = useUserSettings();
4116
1907
  const { formatDate, formatRelativeTime } = useLocalization();
4117
- const [profileData, setProfileData] = (0, import_react19.useState)(null);
4118
- const [membershipData, setMembershipData] = (0, import_react19.useState)(null);
4119
- const [avatarUrl, setAvatarUrl] = (0, import_react19.useState)(null);
4120
- const [coverUrl, setCoverUrl] = (0, import_react19.useState)(null);
4121
- const [loading, setLoading] = (0, import_react19.useState)(true);
1908
+ const [profileData, setProfileData] = (0, import_react20.useState)(null);
1909
+ const [membershipData, setMembershipData] = (0, import_react20.useState)(null);
1910
+ const [avatarUrl, setAvatarUrl] = (0, import_react20.useState)(null);
1911
+ const [coverUrl, setCoverUrl] = (0, import_react20.useState)(null);
1912
+ const [loading, setLoading] = (0, import_react20.useState)(true);
4122
1913
  const { lastSeenAt, isOnline } = useUserStatus(supabase, userId, open);
4123
- (0, import_react19.useEffect)(() => {
1914
+ (0, import_react20.useEffect)(() => {
4124
1915
  if (!open || !userId || !activeCompanyId) return;
4125
1916
  let isMounted = true;
4126
1917
  setLoading(true);
@@ -4166,7 +1957,7 @@ var init_UserPopoverComponent = __esm({
4166
1957
  }, [open, userId, currentMembership?.id, activeCompanyId]);
4167
1958
  const getStatusChip = () => {
4168
1959
  if (!profileData) return null;
4169
- return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(UserStatusChipComponent, { state: { profile_archived: profileData.archived, profile_locked: profileData.locked, excluded: membershipData?.excluded || false, locked: membershipData?.locked || false, locked_reason: membershipData?.locked_reason || "" } });
1960
+ return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(UserStatusChipComponent, { state: { profile_archived: profileData.archived, profile_locked: profileData.locked, excluded: membershipData?.excluded || false, locked: membershipData?.locked || false, locked_reason: membershipData?.locked_reason || "" } });
4170
1961
  };
4171
1962
  const getStatusTypographyColor = (isOnline2, lastSeenAt2) => {
4172
1963
  if (isOnline2) return "success";
@@ -4187,7 +1978,7 @@ var init_UserPopoverComponent = __esm({
4187
1978
  return "inherit";
4188
1979
  };
4189
1980
  const canChat = currentMembership && membershipData && currentMembership.id !== membershipData.id;
4190
- return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
1981
+ return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
4191
1982
  import_material13.Popover,
4192
1983
  {
4193
1984
  open,
@@ -4206,8 +1997,8 @@ var init_UserPopoverComponent = __esm({
4206
1997
  }
4207
1998
  }
4208
1999
  },
4209
- children: loading ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_material13.Box, { sx: { display: "flex", justifyContent: "center", py: 4 }, children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_material13.CircularProgress, { size: 28 }) }) : profileData ? /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_material13.Box, { sx: { display: "flex", flexDirection: "column" }, children: [
4210
- /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
2000
+ children: loading ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_material13.Box, { sx: { display: "flex", justifyContent: "center", py: 4 }, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_material13.CircularProgress, { size: 28 }) }) : profileData ? /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_material13.Box, { sx: { display: "flex", flexDirection: "column" }, children: [
2001
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
4211
2002
  import_material13.Box,
4212
2003
  {
4213
2004
  sx: {
@@ -4217,7 +2008,7 @@ var init_UserPopoverComponent = __esm({
4217
2008
  bgcolor: "action.selected"
4218
2009
  },
4219
2010
  children: [
4220
- coverUrl && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
2011
+ coverUrl && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
4221
2012
  import_material13.Box,
4222
2013
  {
4223
2014
  component: "img",
@@ -4233,7 +2024,7 @@ var init_UserPopoverComponent = __esm({
4233
2024
  }
4234
2025
  }
4235
2026
  ),
4236
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
2027
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
4237
2028
  import_material13.IconButton,
4238
2029
  {
4239
2030
  size: "small",
@@ -4251,15 +2042,15 @@ var init_UserPopoverComponent = __esm({
4251
2042
  transform: "scale(1.1)"
4252
2043
  }
4253
2044
  },
4254
- children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_icons_material2.Close, { fontSize: "small" })
2045
+ children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_icons_material2.Close, { fontSize: "small" })
4255
2046
  }
4256
2047
  )
4257
2048
  ]
4258
2049
  }
4259
2050
  ),
4260
- /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_material13.Box, { sx: { p: 2, pt: 0 }, children: [
4261
- /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_material13.Stack, { direction: "row", spacing: 1.5, sx: { alignItems: "flex-end", mt: "-18px", mb: 1 }, children: [
4262
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
2051
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_material13.Box, { sx: { p: 2, pt: 0 }, children: [
2052
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_material13.Stack, { direction: "row", spacing: 1.5, sx: { alignItems: "flex-end", mt: "-18px", mb: 1 }, children: [
2053
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
4263
2054
  import_material13.Badge,
4264
2055
  {
4265
2056
  overlap: "circular",
@@ -4296,7 +2087,7 @@ var init_UserPopoverComponent = __esm({
4296
2087
  }
4297
2088
  }
4298
2089
  },
4299
- children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
2090
+ children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
4300
2091
  import_material13.Avatar,
4301
2092
  {
4302
2093
  src: avatarUrl || coverUrl || void 0,
@@ -4315,53 +2106,53 @@ var init_UserPopoverComponent = __esm({
4315
2106
  )
4316
2107
  }
4317
2108
  ),
4318
- /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_material13.Box, { sx: { overflow: "hidden", pb: 0.5 }, children: [
4319
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_material13.Typography, { variant: "subtitle1", sx: { fontWeight: 600, lineHeight: 1.2 }, noWrap: true, children: profileData.display_name || `${profileData.first_name || ""} ${profileData.last_name || ""}` }),
4320
- membershipData?.employee_post && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_material13.Typography, { variant: "body2", color: "text.secondary", noWrap: true, children: membershipData.employee_post })
2109
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_material13.Box, { sx: { overflow: "hidden", pb: 0.5 }, children: [
2110
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_material13.Typography, { variant: "subtitle1", sx: { fontWeight: 600, lineHeight: 1.2 }, noWrap: true, children: profileData.display_name || `${profileData.first_name || ""} ${profileData.last_name || ""}` }),
2111
+ membershipData?.employee_post && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_material13.Typography, { variant: "body2", color: "text.secondary", noWrap: true, children: membershipData.employee_post })
4321
2112
  ] })
4322
2113
  ] }),
4323
- /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_material13.Stack, { direction: "row", spacing: 1, sx: { my: 1, flexWrap: "wrap", gap: 0.5 }, children: [
2114
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_material13.Stack, { direction: "row", spacing: 1, sx: { my: 1, flexWrap: "wrap", gap: 0.5 }, children: [
4324
2115
  getStatusChip(),
4325
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(UserRoleChipComponent, { role: membershipData?.role || "user" })
2116
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(UserRoleChipComponent, { role: membershipData?.role || "user" })
4326
2117
  ] }),
4327
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_material13.Divider, { sx: { my: 1.5 } }),
4328
- /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_material13.Stack, { spacing: 1, sx: { fontSize: "0.875rem", mb: 1.5 }, children: [
4329
- /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_material13.Stack, { direction: "row", spacing: 1, sx: { alignItems: "center" }, color: "text.secondary", children: [
4330
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_icons_material2.AccessTime, { fontSize: "small", color: getStatusIconColor(isOnline, lastSeenAt) }),
4331
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_material13.Typography, { variant: "body2", color: getStatusTypographyColor(isOnline, lastSeenAt), children: isOnline ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(TranslateText, { overrideNamespace: overrideNamespace || "form_components", children: "Online" }) : lastSeenAt ? /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_jsx_runtime22.Fragment, { children: [
4332
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(TranslateText, { overrideNamespace: overrideNamespace || "form_components", children: "Last seen" }),
2118
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_material13.Divider, { sx: { my: 1.5 } }),
2119
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_material13.Stack, { spacing: 1, sx: { fontSize: "0.875rem", mb: 1.5 }, children: [
2120
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_material13.Stack, { direction: "row", spacing: 1, sx: { alignItems: "center" }, color: "text.secondary", children: [
2121
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_icons_material2.AccessTime, { fontSize: "small", color: getStatusIconColor(isOnline, lastSeenAt) }),
2122
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_material13.Typography, { variant: "body2", color: getStatusTypographyColor(isOnline, lastSeenAt), children: isOnline ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(TranslateText, { overrideNamespace: overrideNamespace || "form_components", children: "Online" }) : lastSeenAt ? /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_jsx_runtime23.Fragment, { children: [
2123
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(TranslateText, { overrideNamespace: overrideNamespace || "form_components", children: "Last seen" }),
4333
2124
  ":",
4334
2125
  " ",
4335
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("strong", { children: formatRelativeTime(lastSeenAt) })
4336
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(TranslateText, { overrideNamespace: overrideNamespace || "form_components", children: "Offline" }) })
2126
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("strong", { children: formatRelativeTime(lastSeenAt) })
2127
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(TranslateText, { overrideNamespace: overrideNamespace || "form_components", children: "Offline" }) })
4337
2128
  ] }),
4338
- profileData.email && /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_material13.Stack, { direction: "row", spacing: 1, sx: { alignItems: "center" }, color: "text.secondary", children: [
4339
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_icons_material2.Email, { fontSize: "small" }),
4340
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_material13.Typography, { variant: "body2", color: "text.primary", noWrap: true, sx: { flexGrow: 1 }, children: profileData.email }),
4341
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(CopyClipboardButtonComponent, { textToCopy: profileData.email })
2129
+ profileData.email && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_material13.Stack, { direction: "row", spacing: 1, sx: { alignItems: "center" }, color: "text.secondary", children: [
2130
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_icons_material2.Email, { fontSize: "small" }),
2131
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_material13.Typography, { variant: "body2", color: "text.primary", noWrap: true, sx: { flexGrow: 1 }, children: profileData.email }),
2132
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(CopyClipboardButtonComponent, { textToCopy: profileData.email })
4342
2133
  ] }),
4343
- membershipData?.employee_post && /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_material13.Stack, { direction: "row", spacing: 1, sx: { alignItems: "center" }, color: "text.secondary", children: [
4344
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_icons_material2.Work, { fontSize: "small" }),
4345
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_material13.Typography, { variant: "body2", color: "text.primary", noWrap: true, sx: { flexGrow: 1 }, children: membershipData.employee_post }),
4346
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(CopyClipboardButtonComponent, { textToCopy: membershipData.employee_post })
2134
+ membershipData?.employee_post && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_material13.Stack, { direction: "row", spacing: 1, sx: { alignItems: "center" }, color: "text.secondary", children: [
2135
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_icons_material2.Work, { fontSize: "small" }),
2136
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_material13.Typography, { variant: "body2", color: "text.primary", noWrap: true, sx: { flexGrow: 1 }, children: membershipData.employee_post }),
2137
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(CopyClipboardButtonComponent, { textToCopy: membershipData.employee_post })
4347
2138
  ] }),
4348
- profileData.phone && /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_material13.Stack, { direction: "row", spacing: 1, sx: { alignItems: "center" }, color: "text.secondary", children: [
4349
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_icons_material2.Phone, { fontSize: "small" }),
4350
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_material13.Typography, { variant: "body2", color: "text.primary", children: profileData.phone })
2139
+ profileData.phone && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_material13.Stack, { direction: "row", spacing: 1, sx: { alignItems: "center" }, color: "text.secondary", children: [
2140
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_icons_material2.Phone, { fontSize: "small" }),
2141
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_material13.Typography, { variant: "body2", color: "text.primary", children: profileData.phone })
4351
2142
  ] }),
4352
- profileData.birthday && /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_material13.Stack, { direction: "row", spacing: 1, sx: { alignItems: "center" }, color: "text.secondary", children: [
4353
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_icons_material2.Cake, { fontSize: "small" }),
4354
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_material13.Typography, { variant: "body2", color: "text.primary", children: formatDate(profileData.birthday) })
2143
+ profileData.birthday && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_material13.Stack, { direction: "row", spacing: 1, sx: { alignItems: "center" }, color: "text.secondary", children: [
2144
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_icons_material2.Cake, { fontSize: "small" }),
2145
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_material13.Typography, { variant: "body2", color: "text.primary", children: formatDate(profileData.birthday) })
4355
2146
  ] }),
4356
- membershipData?.created_at && /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_material13.Stack, { direction: "row", spacing: 1, sx: { alignItems: "center" }, color: "text.secondary", children: [
4357
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_icons_material2.CalendarToday, { fontSize: "small" }),
4358
- /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_material13.Typography, { variant: "body2", color: "text.primary", children: [
4359
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(TranslateText, { overrideNamespace: overrideNamespace || "form_components", children: "In company from" }),
2147
+ membershipData?.created_at && /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_material13.Stack, { direction: "row", spacing: 1, sx: { alignItems: "center" }, color: "text.secondary", children: [
2148
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_icons_material2.CalendarToday, { fontSize: "small" }),
2149
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_material13.Typography, { variant: "body2", color: "text.primary", children: [
2150
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(TranslateText, { overrideNamespace: overrideNamespace || "form_components", children: "In company from" }),
4360
2151
  ": ",
4361
2152
  formatDate(membershipData.created_at)
4362
2153
  ] })
4363
2154
  ] }),
4364
- profileData.description && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
2155
+ profileData.description && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
4365
2156
  import_material13.Typography,
4366
2157
  {
4367
2158
  variant: "caption",
@@ -4377,28 +2168,28 @@ var init_UserPopoverComponent = __esm({
4377
2168
  }
4378
2169
  )
4379
2170
  ] }),
4380
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_material13.Divider, { sx: { my: 1 } }),
4381
- /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_material13.Stack, { direction: "row", spacing: 1, sx: { justifyContent: "space-around", pt: 0.5 }, children: [
4382
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(TranslatableTooltipComponent, { title: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(TranslateText, { overrideNamespace: overrideNamespace || "form_components", children: "Send a notification" }), children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_material13.IconButton, { size: "small", color: "primary", children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_icons_material2.NotificationsNone, { fontSize: "small" }) }) }),
4383
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(TranslatableTooltipComponent, { title: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(TranslateText, { overrideNamespace: overrideNamespace || "form_components", children: "Set a task" }), children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_material13.IconButton, { size: "small", color: "primary", children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_icons_material2.AssignmentOutlined, { fontSize: "small" }) }) }),
4384
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(TranslatableTooltipComponent, { title: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(TranslateText, { overrideNamespace: overrideNamespace || "form_components", children: "Start a chat" }), children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
2171
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_material13.Divider, { sx: { my: 1 } }),
2172
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_material13.Stack, { direction: "row", spacing: 1, sx: { justifyContent: "space-around", pt: 0.5 }, children: [
2173
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(TranslatableTooltipComponent, { title: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(TranslateText, { overrideNamespace: overrideNamespace || "form_components", children: "Send a notification" }), children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_material13.IconButton, { size: "small", color: "primary", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_icons_material2.NotificationsNone, { fontSize: "small" }) }) }),
2174
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(TranslatableTooltipComponent, { title: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(TranslateText, { overrideNamespace: overrideNamespace || "form_components", children: "Set a task" }), children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_material13.IconButton, { size: "small", color: "primary", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_icons_material2.AssignmentOutlined, { fontSize: "small" }) }) }),
2175
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(TranslatableTooltipComponent, { title: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(TranslateText, { overrideNamespace: overrideNamespace || "form_components", children: "Start a chat" }), children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
4385
2176
  import_material13.IconButton,
4386
2177
  {
4387
2178
  size: "small",
4388
2179
  color: "primary",
4389
2180
  disabled: !canChat,
4390
2181
  onClick: () => membershipData && openChatWithUser(membershipData.id),
4391
- children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_icons_material2.ChatBubble, { fontSize: "small" })
2182
+ children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_icons_material2.ChatBubble, { fontSize: "small" })
4392
2183
  }
4393
2184
  ) })
4394
2185
  ] })
4395
2186
  ] })
4396
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_material13.Box, { sx: { p: 2 }, children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
2187
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_material13.Box, { sx: { p: 2 }, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
4397
2188
  import_material13.Typography,
4398
2189
  {
4399
2190
  color: "error",
4400
2191
  variant: "body2",
4401
- children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(TranslateText, { overrideNamespace: overrideNamespace || "form_components", children: "Failed to load user data" })
2192
+ children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(TranslateText, { overrideNamespace: overrideNamespace || "form_components", children: "Failed to load user data" })
4402
2193
  }
4403
2194
  ) })
4404
2195
  }
@@ -4412,6 +2203,7 @@ var init_UserPopoverComponent = __esm({
4412
2203
  var index_exports = {};
4413
2204
  __export(index_exports, {
4414
2205
  AIProvider: () => AIProvider,
2206
+ AppSettingsProvider: () => AppSettingsProvider,
4415
2207
  BreadcrumbProvider: () => BreadcrumbProvider,
4416
2208
  ConfirmationProvider: () => ConfirmationProvider,
4417
2209
  LocalizationProvider: () => LocalizationProvider,
@@ -4424,6 +2216,7 @@ __export(index_exports, {
4424
2216
  TranslationEditProvider: () => TranslationEditProvider,
4425
2217
  UI: () => UI,
4426
2218
  useAI: () => useAI,
2219
+ useAppSettings: () => useAppSettings,
4427
2220
  useAppTheme: () => useAppTheme,
4428
2221
  useBreadcrumb: () => useBreadcrumb,
4429
2222
  useConfirmation: () => useConfirmation,
@@ -4470,7 +2263,7 @@ var TextFieldComponent = ({
4470
2263
  }) => {
4471
2264
  const supabase = useSupabase();
4472
2265
  const namespace = useTranslationNamespace();
4473
- const { t: t2, i18n } = (0, import_react_i18next3.useTranslation)(namespace);
2266
+ const { t, i18n: i18n2 } = (0, import_react_i18next3.useTranslation)(namespace);
4474
2267
  const { isTranslationMode } = useTranslationEdit();
4475
2268
  const [copied, setCopied] = (0, import_react8.useState)(false);
4476
2269
  const [isDialogOpen, setIsDialogOpen] = (0, import_react8.useState)(false);
@@ -4478,7 +2271,7 @@ var TextFieldComponent = ({
4478
2271
  const isLocked = disabled || isReadOnly;
4479
2272
  const stringValue = String(value ?? "");
4480
2273
  const hasValue = stringValue.length > 0;
4481
- const translatedPlaceholder = placeholderKey ? t2(placeholderKey) : void 0;
2274
+ const translatedPlaceholder = placeholderKey ? t(placeholderKey) : void 0;
4482
2275
  const handleClear = (e) => {
4483
2276
  e.stopPropagation();
4484
2277
  if (onChange) {
@@ -4517,7 +2310,7 @@ var TextFieldComponent = ({
4517
2310
  }
4518
2311
  await translationService.incrementVersion(supabase, namespace, Object.keys(newValues));
4519
2312
  Object.entries(newValues).forEach(([langCode, text]) => {
4520
- i18n.addResource(langCode, namespace, placeholderKey, text);
2313
+ i18n2.addResource(langCode, namespace, placeholderKey, text);
4521
2314
  });
4522
2315
  };
4523
2316
  return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_jsx_runtime9.Fragment, { children: [
@@ -5124,11 +2917,11 @@ var EmailInputComponent = ({
5124
2917
  };
5125
2918
 
5126
2919
  // src/UI/components/data.display/UserAvatarComponent.tsx
5127
- var import_react20 = require("react");
2920
+ var import_react21 = require("react");
5128
2921
  var import_material14 = require("@mui/material");
5129
2922
  init_context();
5130
- var import_jsx_runtime23 = require("react/jsx-runtime");
5131
- var LazyUserPopover = (0, import_react20.lazy)(() => Promise.resolve().then(() => (init_UserPopoverComponent(), UserPopoverComponent_exports)));
2923
+ var import_jsx_runtime24 = require("react/jsx-runtime");
2924
+ var LazyUserPopover = (0, import_react21.lazy)(() => Promise.resolve().then(() => (init_UserPopoverComponent(), UserPopoverComponent_exports)));
5132
2925
  var getInitials = (name) => {
5133
2926
  if (!name) return "?";
5134
2927
  const parts = name.trim().split(" ");
@@ -5150,11 +2943,11 @@ var UserAvatarComponent = ({
5150
2943
  sx = {}
5151
2944
  }) => {
5152
2945
  const supabase = useSupabase();
5153
- const [anchorEl, setAnchorEl] = (0, import_react20.useState)(null);
5154
- const [hasInteracted, setHasInteracted] = (0, import_react20.useState)(false);
5155
- const [resolvedAvatarUrl, setResolvedAvatarUrl] = (0, import_react20.useState)(null);
2946
+ const [anchorEl, setAnchorEl] = (0, import_react21.useState)(null);
2947
+ const [hasInteracted, setHasInteracted] = (0, import_react21.useState)(false);
2948
+ const [resolvedAvatarUrl, setResolvedAvatarUrl] = (0, import_react21.useState)(null);
5156
2949
  const canShowPopover = !disablePopover && Boolean(userId);
5157
- (0, import_react20.useEffect)(() => {
2950
+ (0, import_react21.useEffect)(() => {
5158
2951
  let isMounted = true;
5159
2952
  const resolveAvatar = async () => {
5160
2953
  if (!avatarUrl) {
@@ -5199,12 +2992,12 @@ var UserAvatarComponent = ({
5199
2992
  };
5200
2993
  const isPopoverOpen = Boolean(anchorEl);
5201
2994
  const initials = getInitials(displayName || "");
5202
- const getTooltip = /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_jsx_runtime23.Fragment, { children: [
5203
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_material14.Typography, { component: "div", variant: "caption", children: displayName }),
5204
- displayName && employeePost && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_material14.Typography, { component: "div", variant: "caption", children: employeePost })
2995
+ const getTooltip = /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(import_jsx_runtime24.Fragment, { children: [
2996
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_material14.Typography, { component: "div", variant: "caption", children: displayName }),
2997
+ displayName && employeePost && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_material14.Typography, { component: "div", variant: "caption", children: employeePost })
5205
2998
  ] });
5206
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_jsx_runtime23.Fragment, { children: [
5207
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_material14.Tooltip, { title: disableTooltip || isPopoverOpen ? "" : getTooltip, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
2999
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(import_jsx_runtime24.Fragment, { children: [
3000
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_material14.Tooltip, { title: disableTooltip || isPopoverOpen ? "" : getTooltip, children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
5208
3001
  import_material14.Avatar,
5209
3002
  {
5210
3003
  src: resolvedAvatarUrl || void 0,
@@ -5230,7 +3023,7 @@ var UserAvatarComponent = ({
5230
3023
  children: !resolvedAvatarUrl && initials
5231
3024
  }
5232
3025
  ) }),
5233
- canShowPopover && hasInteracted && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_react20.Suspense, { fallback: null, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
3026
+ canShowPopover && hasInteracted && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_react21.Suspense, { fallback: null, children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
5234
3027
  LazyUserPopover,
5235
3028
  {
5236
3029
  userId,
@@ -5275,6 +3068,7 @@ init_context();
5275
3068
  // Annotate the CommonJS export names for ESM import in node:
5276
3069
  0 && (module.exports = {
5277
3070
  AIProvider,
3071
+ AppSettingsProvider,
5278
3072
  BreadcrumbProvider,
5279
3073
  ConfirmationProvider,
5280
3074
  LocalizationProvider,
@@ -5287,6 +3081,7 @@ init_context();
5287
3081
  TranslationEditProvider,
5288
3082
  UI,
5289
3083
  useAI,
3084
+ useAppSettings,
5290
3085
  useAppTheme,
5291
3086
  useBreadcrumb,
5292
3087
  useConfirmation,