@gears-frontx/i18n 0.1.0 → 0.2.0-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CLAUDE.md +1 -1
- package/dist/index.cjs +51 -39
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +51 -39
- package/dist/index.js.map +1 -1
- package/dist/types.cjs.map +1 -1
- package/dist/types.d.cts +1 -1
- package/dist/types.d.ts +1 -1
- package/dist/types.js.map +1 -1
- package/llms.txt +7 -7
- package/package.json +12 -6
package/CLAUDE.md
CHANGED
package/dist/index.cjs
CHANGED
|
@@ -149,7 +149,9 @@ var SUPPORTED_LANGUAGES = [
|
|
|
149
149
|
englishName: "Dutch",
|
|
150
150
|
direction: "ltr" /* LeftToRight */
|
|
151
151
|
},
|
|
152
|
+
// @cpt-end:cpt-frontx-dod-i18n-infrastructure-language-support:p1:inst-array-western
|
|
152
153
|
// Eastern European
|
|
154
|
+
// @cpt-begin:cpt-frontx-dod-i18n-infrastructure-language-support:p1:inst-array-eastern
|
|
153
155
|
{
|
|
154
156
|
code: "ru" /* Russian */,
|
|
155
157
|
name: "\u0420\u0443\u0441\u0441\u043A\u0438\u0439",
|
|
@@ -174,7 +176,9 @@ var SUPPORTED_LANGUAGES = [
|
|
|
174
176
|
englishName: "Czech",
|
|
175
177
|
direction: "ltr" /* LeftToRight */
|
|
176
178
|
},
|
|
179
|
+
// @cpt-end:cpt-frontx-dod-i18n-infrastructure-language-support:p1:inst-array-eastern
|
|
177
180
|
// Middle East & North Africa (RTL)
|
|
181
|
+
// @cpt-begin:cpt-frontx-dod-i18n-infrastructure-language-support:p1:inst-array-mena
|
|
178
182
|
{
|
|
179
183
|
code: "ar" /* Arabic */,
|
|
180
184
|
name: "\u0627\u0644\u0639\u0631\u0628\u064A\u0629",
|
|
@@ -205,7 +209,9 @@ var SUPPORTED_LANGUAGES = [
|
|
|
205
209
|
englishName: "Turkish",
|
|
206
210
|
direction: "ltr" /* LeftToRight */
|
|
207
211
|
},
|
|
212
|
+
// @cpt-end:cpt-frontx-dod-i18n-infrastructure-language-support:p1:inst-array-mena
|
|
208
213
|
// Asian
|
|
214
|
+
// @cpt-begin:cpt-frontx-dod-i18n-infrastructure-language-support:p1:inst-array-asian
|
|
209
215
|
{
|
|
210
216
|
code: "zh" /* ChineseSimplified */,
|
|
211
217
|
name: "\u7B80\u4F53\u4E2D\u6587",
|
|
@@ -261,7 +267,9 @@ var SUPPORTED_LANGUAGES = [
|
|
|
261
267
|
englishName: "Bengali",
|
|
262
268
|
direction: "ltr" /* LeftToRight */
|
|
263
269
|
},
|
|
270
|
+
// @cpt-end:cpt-frontx-dod-i18n-infrastructure-language-support:p1:inst-array-asian
|
|
264
271
|
// Nordic
|
|
272
|
+
// @cpt-begin:cpt-frontx-dod-i18n-infrastructure-language-support:p1:inst-array-nordic
|
|
265
273
|
{
|
|
266
274
|
code: "sv" /* Swedish */,
|
|
267
275
|
name: "Svenska",
|
|
@@ -286,7 +294,9 @@ var SUPPORTED_LANGUAGES = [
|
|
|
286
294
|
englishName: "Finnish",
|
|
287
295
|
direction: "ltr" /* LeftToRight */
|
|
288
296
|
},
|
|
297
|
+
// @cpt-end:cpt-frontx-dod-i18n-infrastructure-language-support:p1:inst-array-nordic
|
|
289
298
|
// Other
|
|
299
|
+
// @cpt-begin:cpt-frontx-dod-i18n-infrastructure-language-support:p1:inst-array-remaining
|
|
290
300
|
{
|
|
291
301
|
code: "el" /* Greek */,
|
|
292
302
|
name: "\u0395\u03BB\u03BB\u03B7\u03BD\u03B9\u03BA\u03AC",
|
|
@@ -355,7 +365,7 @@ var I18nRegistryImpl = class _I18nRegistryImpl {
|
|
|
355
365
|
subscribers = /* @__PURE__ */ new Set();
|
|
356
366
|
/** Version counter for React re-rendering */
|
|
357
367
|
version = 0;
|
|
358
|
-
// @cpt-begin:cpt-
|
|
368
|
+
// @cpt-begin:cpt-frontx-algo-i18n-infrastructure-language-file-map:p1:inst-1
|
|
359
369
|
/** Language file mapping */
|
|
360
370
|
static LANGUAGE_FILE_MAP = {
|
|
361
371
|
["en" /* English */]: "en.json",
|
|
@@ -395,14 +405,14 @@ var I18nRegistryImpl = class _I18nRegistryImpl {
|
|
|
395
405
|
["ta" /* Tamil */]: "ta.json",
|
|
396
406
|
["sw" /* Swahili */]: "sw.json"
|
|
397
407
|
};
|
|
398
|
-
// @cpt-end:cpt-
|
|
408
|
+
// @cpt-end:cpt-frontx-algo-i18n-infrastructure-language-file-map:p1:inst-1
|
|
399
409
|
constructor(config) {
|
|
400
410
|
this.config = config;
|
|
401
411
|
}
|
|
402
412
|
// ============================================================================
|
|
403
413
|
// Registration
|
|
404
414
|
// ============================================================================
|
|
405
|
-
// @cpt-begin:cpt-
|
|
415
|
+
// @cpt-begin:cpt-frontx-state-i18n-infrastructure-namespace-cache:p1:inst-1
|
|
406
416
|
/**
|
|
407
417
|
* Register translations for a namespace.
|
|
408
418
|
*/
|
|
@@ -413,7 +423,7 @@ var I18nRegistryImpl = class _I18nRegistryImpl {
|
|
|
413
423
|
this.dictionaries.get(namespace).set(language, translations);
|
|
414
424
|
this.notifySubscribers();
|
|
415
425
|
}
|
|
416
|
-
// @cpt-end:cpt-
|
|
426
|
+
// @cpt-end:cpt-frontx-state-i18n-infrastructure-namespace-cache:p1:inst-1
|
|
417
427
|
/**
|
|
418
428
|
* Subscribe to translation changes.
|
|
419
429
|
* Returns an unsubscribe function.
|
|
@@ -429,7 +439,9 @@ var I18nRegistryImpl = class _I18nRegistryImpl {
|
|
|
429
439
|
*/
|
|
430
440
|
notifySubscribers() {
|
|
431
441
|
this.version++;
|
|
432
|
-
this.subscribers.forEach((callback) =>
|
|
442
|
+
this.subscribers.forEach((callback) => {
|
|
443
|
+
callback();
|
|
444
|
+
});
|
|
433
445
|
}
|
|
434
446
|
/**
|
|
435
447
|
* Get the current version number.
|
|
@@ -438,16 +450,16 @@ var I18nRegistryImpl = class _I18nRegistryImpl {
|
|
|
438
450
|
getVersion() {
|
|
439
451
|
return this.version;
|
|
440
452
|
}
|
|
441
|
-
// @cpt-begin:cpt-
|
|
442
|
-
// @cpt-begin:cpt-
|
|
453
|
+
// @cpt-begin:cpt-frontx-flow-i18n-infrastructure-screenset-registration:p1:inst-1
|
|
454
|
+
// @cpt-begin:cpt-frontx-flow-i18n-infrastructure-screen-lazy-load:p1:inst-1
|
|
443
455
|
/**
|
|
444
456
|
* Register a translation loader for a namespace.
|
|
445
457
|
*/
|
|
446
458
|
registerLoader(namespace, loader) {
|
|
447
459
|
this.loaders.set(namespace, loader);
|
|
448
460
|
}
|
|
449
|
-
// @cpt-end:cpt-
|
|
450
|
-
// @cpt-end:cpt-
|
|
461
|
+
// @cpt-end:cpt-frontx-flow-i18n-infrastructure-screenset-registration:p1:inst-1
|
|
462
|
+
// @cpt-end:cpt-frontx-flow-i18n-infrastructure-screen-lazy-load:p1:inst-1
|
|
451
463
|
/**
|
|
452
464
|
* Check if namespace is registered.
|
|
453
465
|
*/
|
|
@@ -466,7 +478,7 @@ var I18nRegistryImpl = class _I18nRegistryImpl {
|
|
|
466
478
|
// ============================================================================
|
|
467
479
|
// Translation
|
|
468
480
|
// ============================================================================
|
|
469
|
-
// @cpt-begin:cpt-
|
|
481
|
+
// @cpt-begin:cpt-frontx-flow-i18n-infrastructure-key-resolution:p1:inst-1
|
|
470
482
|
/**
|
|
471
483
|
* Translate a key.
|
|
472
484
|
* Format: 'namespace:key.subkey' or just 'key' for default namespace
|
|
@@ -479,8 +491,8 @@ var I18nRegistryImpl = class _I18nRegistryImpl {
|
|
|
479
491
|
}
|
|
480
492
|
return this.interpolate(translation, params);
|
|
481
493
|
}
|
|
482
|
-
// @cpt-end:cpt-
|
|
483
|
-
// @cpt-begin:cpt-
|
|
494
|
+
// @cpt-end:cpt-frontx-flow-i18n-infrastructure-key-resolution:p1:inst-1
|
|
495
|
+
// @cpt-begin:cpt-frontx-flow-i18n-infrastructure-key-resolution:p1:inst-2
|
|
484
496
|
/**
|
|
485
497
|
* Parse a translation key into namespace and path.
|
|
486
498
|
*/
|
|
@@ -497,8 +509,8 @@ var I18nRegistryImpl = class _I18nRegistryImpl {
|
|
|
497
509
|
path: key.slice(separatorIndex + 1)
|
|
498
510
|
};
|
|
499
511
|
}
|
|
500
|
-
// @cpt-end:cpt-
|
|
501
|
-
// @cpt-begin:cpt-
|
|
512
|
+
// @cpt-end:cpt-frontx-flow-i18n-infrastructure-key-resolution:p1:inst-2
|
|
513
|
+
// @cpt-begin:cpt-frontx-flow-i18n-infrastructure-key-resolution:p1:inst-3
|
|
502
514
|
/**
|
|
503
515
|
* Get a translation from the dictionary.
|
|
504
516
|
*/
|
|
@@ -517,9 +529,9 @@ var I18nRegistryImpl = class _I18nRegistryImpl {
|
|
|
517
529
|
}
|
|
518
530
|
return void 0;
|
|
519
531
|
}
|
|
520
|
-
// @cpt-end:cpt-
|
|
521
|
-
// @cpt-begin:cpt-
|
|
522
|
-
// @cpt-begin:cpt-
|
|
532
|
+
// @cpt-end:cpt-frontx-flow-i18n-infrastructure-key-resolution:p1:inst-3
|
|
533
|
+
// @cpt-begin:cpt-frontx-flow-i18n-infrastructure-key-resolution:p1:inst-4
|
|
534
|
+
// @cpt-begin:cpt-frontx-algo-i18n-infrastructure-path-traversal:p1:inst-1
|
|
523
535
|
/**
|
|
524
536
|
* Find a translation in the dictionary.
|
|
525
537
|
*/
|
|
@@ -545,9 +557,9 @@ var I18nRegistryImpl = class _I18nRegistryImpl {
|
|
|
545
557
|
}
|
|
546
558
|
return typeof current === "string" ? current : void 0;
|
|
547
559
|
}
|
|
548
|
-
// @cpt-end:cpt-
|
|
549
|
-
// @cpt-end:cpt-
|
|
550
|
-
// @cpt-begin:cpt-
|
|
560
|
+
// @cpt-end:cpt-frontx-flow-i18n-infrastructure-key-resolution:p1:inst-4
|
|
561
|
+
// @cpt-end:cpt-frontx-algo-i18n-infrastructure-path-traversal:p1:inst-1
|
|
562
|
+
// @cpt-begin:cpt-frontx-flow-i18n-infrastructure-key-resolution:p1:inst-5
|
|
551
563
|
/**
|
|
552
564
|
* Interpolate parameters into a translation string.
|
|
553
565
|
*/
|
|
@@ -560,12 +572,12 @@ var I18nRegistryImpl = class _I18nRegistryImpl {
|
|
|
560
572
|
return value !== void 0 ? String(value) : match;
|
|
561
573
|
});
|
|
562
574
|
}
|
|
563
|
-
// @cpt-end:cpt-
|
|
575
|
+
// @cpt-end:cpt-frontx-flow-i18n-infrastructure-key-resolution:p1:inst-5
|
|
564
576
|
// ============================================================================
|
|
565
577
|
// Language Management
|
|
566
578
|
// ============================================================================
|
|
567
|
-
// @cpt-begin:cpt-
|
|
568
|
-
// @cpt-begin:cpt-
|
|
579
|
+
// @cpt-begin:cpt-frontx-flow-i18n-infrastructure-language-activation:p1:inst-1
|
|
580
|
+
// @cpt-begin:cpt-frontx-state-i18n-infrastructure-registry:p1:inst-1
|
|
569
581
|
/**
|
|
570
582
|
* Set current language and load translations.
|
|
571
583
|
*/
|
|
@@ -574,15 +586,15 @@ var I18nRegistryImpl = class _I18nRegistryImpl {
|
|
|
574
586
|
this.updateHtmlAttributes(language);
|
|
575
587
|
await this.loadLanguage(language);
|
|
576
588
|
}
|
|
577
|
-
// @cpt-end:cpt-
|
|
578
|
-
// @cpt-end:cpt-
|
|
589
|
+
// @cpt-end:cpt-frontx-flow-i18n-infrastructure-language-activation:p1:inst-1
|
|
590
|
+
// @cpt-end:cpt-frontx-state-i18n-infrastructure-registry:p1:inst-1
|
|
579
591
|
/**
|
|
580
592
|
* Get current language.
|
|
581
593
|
*/
|
|
582
594
|
getLanguage() {
|
|
583
595
|
return this.currentLanguage;
|
|
584
596
|
}
|
|
585
|
-
// @cpt-begin:cpt-
|
|
597
|
+
// @cpt-begin:cpt-frontx-algo-i18n-infrastructure-html-attrs:p1:inst-1
|
|
586
598
|
/**
|
|
587
599
|
* Update HTML lang and dir attributes.
|
|
588
600
|
*/
|
|
@@ -597,7 +609,7 @@ var I18nRegistryImpl = class _I18nRegistryImpl {
|
|
|
597
609
|
this.isRTL(language) ? "rtl" /* RightToLeft */ : "ltr" /* LeftToRight */
|
|
598
610
|
);
|
|
599
611
|
}
|
|
600
|
-
// @cpt-end:cpt-
|
|
612
|
+
// @cpt-end:cpt-frontx-algo-i18n-infrastructure-html-attrs:p1:inst-1
|
|
601
613
|
// ============================================================================
|
|
602
614
|
// Language Metadata
|
|
603
615
|
// ============================================================================
|
|
@@ -631,8 +643,8 @@ var I18nRegistryImpl = class _I18nRegistryImpl {
|
|
|
631
643
|
// ============================================================================
|
|
632
644
|
// Translation Loading
|
|
633
645
|
// ============================================================================
|
|
634
|
-
// @cpt-begin:cpt-
|
|
635
|
-
// @cpt-begin:cpt-
|
|
646
|
+
// @cpt-begin:cpt-frontx-algo-i18n-infrastructure-lazy-exclusion:p1:inst-1
|
|
647
|
+
// @cpt-begin:cpt-frontx-flow-i18n-infrastructure-language-activation:p1:inst-2
|
|
636
648
|
/**
|
|
637
649
|
* Load translations for a language.
|
|
638
650
|
* Excludes screen.* and screenset.* namespaces which are lazy-loaded:
|
|
@@ -649,9 +661,9 @@ var I18nRegistryImpl = class _I18nRegistryImpl {
|
|
|
649
661
|
});
|
|
650
662
|
await Promise.all(loadPromises);
|
|
651
663
|
}
|
|
652
|
-
// @cpt-end:cpt-
|
|
653
|
-
// @cpt-end:cpt-
|
|
654
|
-
// @cpt-begin:cpt-
|
|
664
|
+
// @cpt-end:cpt-frontx-algo-i18n-infrastructure-lazy-exclusion:p1:inst-1
|
|
665
|
+
// @cpt-end:cpt-frontx-flow-i18n-infrastructure-language-activation:p1:inst-2
|
|
666
|
+
// @cpt-begin:cpt-frontx-flow-i18n-infrastructure-screen-lazy-load:p1:inst-2
|
|
655
667
|
/**
|
|
656
668
|
* Load translations for a specific namespace.
|
|
657
669
|
*/
|
|
@@ -667,8 +679,8 @@ var I18nRegistryImpl = class _I18nRegistryImpl {
|
|
|
667
679
|
console.warn(`Failed to load translations for ${namespace}/${language}:`, error);
|
|
668
680
|
}
|
|
669
681
|
}
|
|
670
|
-
// @cpt-end:cpt-
|
|
671
|
-
// @cpt-begin:cpt-
|
|
682
|
+
// @cpt-end:cpt-frontx-flow-i18n-infrastructure-screen-lazy-load:p1:inst-2
|
|
683
|
+
// @cpt-begin:cpt-frontx-flow-i18n-infrastructure-screenset-registration:p1:inst-2
|
|
672
684
|
/**
|
|
673
685
|
* Load translations for a specific screenset.
|
|
674
686
|
*/
|
|
@@ -677,7 +689,7 @@ var I18nRegistryImpl = class _I18nRegistryImpl {
|
|
|
677
689
|
const namespace = `screenset.${screensetId}`;
|
|
678
690
|
await this.loadNamespace(namespace, targetLanguage);
|
|
679
691
|
}
|
|
680
|
-
// @cpt-end:cpt-
|
|
692
|
+
// @cpt-end:cpt-frontx-flow-i18n-infrastructure-screenset-registration:p1:inst-2
|
|
681
693
|
/**
|
|
682
694
|
* Preload translations for multiple languages.
|
|
683
695
|
*/
|
|
@@ -699,8 +711,8 @@ var I18nRegistryImpl = class _I18nRegistryImpl {
|
|
|
699
711
|
* });
|
|
700
712
|
* ```
|
|
701
713
|
*/
|
|
702
|
-
// @cpt-begin:cpt-
|
|
703
|
-
// @cpt-begin:cpt-
|
|
714
|
+
// @cpt-begin:cpt-frontx-algo-i18n-infrastructure-create-loader:p1:inst-1
|
|
715
|
+
// @cpt-begin:cpt-frontx-dod-i18n-infrastructure-lazy-chunks:p1:inst-1
|
|
704
716
|
static createLoader(translationMap) {
|
|
705
717
|
return async (language) => {
|
|
706
718
|
const importFn = translationMap[language];
|
|
@@ -711,8 +723,8 @@ var I18nRegistryImpl = class _I18nRegistryImpl {
|
|
|
711
723
|
return module2.default;
|
|
712
724
|
};
|
|
713
725
|
}
|
|
714
|
-
// @cpt-end:cpt-
|
|
715
|
-
// @cpt-end:cpt-
|
|
726
|
+
// @cpt-end:cpt-frontx-algo-i18n-infrastructure-create-loader:p1:inst-1
|
|
727
|
+
// @cpt-end:cpt-frontx-dod-i18n-infrastructure-lazy-chunks:p1:inst-1
|
|
716
728
|
/**
|
|
717
729
|
* Create a translation loader from a directory.
|
|
718
730
|
* Maps Language enum values to file names automatically.
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/types.ts","../src/languages.ts","../src/I18nRegistry.ts","../src/formatters/utils.ts","../src/formatters/dateFormatter.ts","../src/formatters/numberFormatter.ts","../src/formatters/currencyFormatter.ts","../src/formatters/sortUtils.ts"],"sourcesContent":["/**\n * @gears-frontx/i18n - Internationalization\n *\n * This package provides:\n * - Language enum with 36 supported languages\n * - Translation registry with namespace support\n * - RTL support for Arabic, Hebrew, Persian, Urdu\n * - Lazy loading with dynamic imports\n *\n * SDK Layer: L1 (Zero @gears-frontx dependencies)\n */\n\n// Re-export enums and constants\nexport {\n TextDirection,\n Language,\n LanguageDisplayMode,\n I18N_NAMESPACE_SEPARATOR,\n I18N_PATH_SEPARATOR,\n I18N_DEFAULT_NAMESPACE,\n HTML_LANG_ATTRIBUTE,\n HTML_DIR_ATTRIBUTE,\n} from './types';\n\n// Re-export types\nexport type {\n LanguageMetadata,\n LanguageCode,\n TranslationDictionary,\n TranslationLoader,\n TranslationMap,\n I18nConfig,\n TranslationParams,\n I18nRegistry,\n} from './types';\n\n// Export I18n Registry implementation and singleton\nexport {\n i18nRegistry,\n I18nRegistryImpl,\n createI18nRegistry,\n} from './I18nRegistry';\n\n// Export language utilities\nexport {\n SUPPORTED_LANGUAGES,\n getLanguageMetadata,\n getRTLLanguages,\n isValidLanguage,\n} from './languages';\n\n// Export formatters (locale from i18nRegistry.getLanguage())\nexport {\n formatDate,\n formatTime,\n formatDateTime,\n formatRelative,\n formatNumber,\n formatPercent,\n formatCompact,\n formatCurrency,\n compareStrings,\n createCollator,\n type DateFormatStyle,\n type TimeFormatStyle,\n type DateInput,\n type Formatters,\n} from './formatters';\n","/**\n * @gears-frontx/i18n - Type Definitions\n *\n * Core types for HAI3 internationalization.\n * Supports 36 languages with RTL support.\n */\n\n// ============================================================================\n// Text Direction\n// ============================================================================\n\n/**\n * Text Direction Enum\n * Defines text direction for RTL language support.\n */\nexport enum TextDirection {\n LeftToRight = 'ltr',\n RightToLeft = 'rtl',\n}\n\n// ============================================================================\n// Language Enum\n// ============================================================================\n\n/**\n * Language Enum\n * All 36 supported languages based on major platforms (Google, Facebook, Microsoft, Apple).\n */\nexport enum Language {\n // Western European\n English = 'en',\n Spanish = 'es',\n French = 'fr',\n German = 'de',\n Italian = 'it',\n Portuguese = 'pt',\n Dutch = 'nl',\n\n // Eastern European\n Russian = 'ru',\n Polish = 'pl',\n Ukrainian = 'uk',\n Czech = 'cs',\n\n // Middle East & North Africa (RTL)\n Arabic = 'ar',\n Hebrew = 'he',\n Persian = 'fa',\n Urdu = 'ur',\n Turkish = 'tr',\n\n // Asian\n ChineseSimplified = 'zh',\n ChineseTraditional = 'zh-TW',\n Japanese = 'ja',\n Korean = 'ko',\n Vietnamese = 'vi',\n Thai = 'th',\n Indonesian = 'id',\n Hindi = 'hi',\n Bengali = 'bn',\n\n // Nordic\n Swedish = 'sv',\n Danish = 'da',\n Norwegian = 'no',\n Finnish = 'fi',\n\n // Other\n Greek = 'el',\n Romanian = 'ro',\n Hungarian = 'hu',\n\n // Additional major languages\n Malay = 'ms',\n Tagalog = 'tl',\n Tamil = 'ta',\n Swahili = 'sw',\n}\n\n// ============================================================================\n// Language Metadata\n// ============================================================================\n\n/**\n * Language Metadata\n * Complete information about a supported language.\n */\nexport interface LanguageMetadata {\n /** Language code (from Language enum) */\n code: Language;\n /** Native name (e.g., 'English', 'العربية') */\n name: string;\n /** English name for settings UI */\n englishName: string;\n /** Text direction */\n direction: TextDirection;\n /** Optional region (e.g., 'US', 'GB', 'TW') */\n region?: string;\n}\n\n/**\n * Language Code Type\n * Type alias for language codes.\n */\nexport type LanguageCode = Language;\n\n// ============================================================================\n// Translation Types\n// ============================================================================\n\n/**\n * Translation Dictionary\n * Nested key-value structure for translations.\n *\n * @example\n * ```typescript\n * const translations: TranslationDictionary = {\n * button: {\n * submit: 'Submit',\n * cancel: 'Cancel',\n * },\n * messages: {\n * success: 'Operation completed successfully',\n * },\n * };\n * ```\n */\nexport interface TranslationDictionary {\n [key: string]: string | TranslationDictionary;\n}\n\n/**\n * Translation Loader Function\n * Returns translations for a given language using dynamic import.\n * Accepts both Language enum and string for compatibility with @gears-frontx/layout.\n *\n * @example\n * ```typescript\n * const loader: TranslationLoader = async (language) => {\n * const module = await import(`./i18n/${language}.json`);\n * return module.default;\n * };\n * ```\n */\nexport type TranslationLoader = (language: Language | string) => Promise<TranslationDictionary>;\n\n/**\n * Translation Map\n * Maps languages to their dynamic import functions.\n * Used by I18nRegistry.createLoader().\n *\n * @example\n * ```typescript\n * const translationMap: TranslationMap = {\n * [Language.English]: () => import('./i18n/en.json'),\n * [Language.Spanish]: () => import('./i18n/es.json'),\n * // ... all 36 languages\n * };\n * ```\n */\nexport type TranslationMap = Record<Language, () => Promise<{ default: TranslationDictionary }>>;\n\n// ============================================================================\n// I18n Configuration\n// ============================================================================\n\n/**\n * I18n Configuration\n * Configuration options for the i18n system.\n */\nexport interface I18nConfig {\n /** Default language to use */\n defaultLanguage: LanguageCode;\n /** Fallback language when translation is missing */\n fallbackLanguage: LanguageCode;\n}\n\n/**\n * Translation Parameters\n * Parameters for string interpolation.\n *\n * @example\n * ```typescript\n * // Translation: \"Hello, {name}!\"\n * t('greeting', { name: 'John' }); // \"Hello, John!\"\n * ```\n */\nexport type TranslationParams = Record<string, string | number | boolean>;\n\n// ============================================================================\n// I18n Registry Interface\n// ============================================================================\n\n/**\n * I18n Registry Interface\n * Central registry for translation management.\n *\n * @example\n * ```typescript\n * // Register translations\n * i18nRegistry.registerLoader('screenset.demo', demoLoader);\n *\n * // Set language\n * await i18nRegistry.setLanguage(Language.Spanish);\n *\n * // Translate\n * const text = i18nRegistry.t('screenset.demo:welcome.title');\n * ```\n */\nexport interface I18nRegistry {\n /**\n * Register translations for a namespace.\n *\n * @param namespace - Translation namespace (e.g., 'screenset.demo')\n * @param language - Language enum value\n * @param translations - Translation dictionary\n */\n register(namespace: string, language: Language, translations: TranslationDictionary): void;\n\n /**\n * Register a translation loader for a namespace.\n * Loader is called on-demand when language changes.\n *\n * @param namespace - Namespace identifier\n * @param loader - Function that loads translations\n */\n registerLoader(namespace: string, loader: TranslationLoader): void;\n\n /**\n * Translate a key.\n *\n * @param key - Format: 'namespace:key.subkey' or just 'key' for default namespace\n * @param params - Interpolation parameters\n * @returns Translated string\n */\n t(key: string, params?: TranslationParams): string;\n\n /**\n * Set current language and load translations.\n * Updates HTML lang and dir attributes.\n *\n * @param language - Language to set\n */\n setLanguage(language: Language): Promise<void>;\n\n /**\n * Get current language.\n *\n * @returns Current language or null if not set\n */\n getLanguage(): Language | null;\n\n /**\n * Get language metadata.\n *\n * @param code - Optional language code (defaults to current)\n * @returns Language metadata\n */\n getLanguageMetadata(code?: Language): LanguageMetadata | undefined;\n\n /**\n * Get all supported languages.\n *\n * @returns Array of language metadata\n */\n getSupportedLanguages(): LanguageMetadata[];\n\n /**\n * Check if current language is RTL.\n *\n * @param code - Optional language code (defaults to current)\n * @returns True if RTL\n */\n isRTL(code?: Language): boolean;\n\n /**\n * Check if namespace is registered.\n *\n * @param namespace - Namespace to check\n * @returns True if registered\n */\n hasNamespace(namespace: string): boolean;\n\n /**\n * Get all registered namespaces.\n *\n * @returns Array of namespace identifiers\n */\n getNamespaces(): string[];\n\n /**\n * Load translations for a specific language.\n *\n * @param language - Language to load\n */\n loadLanguage(language: Language): Promise<void>;\n\n /**\n * Load translations for a specific screenset.\n *\n * @param screensetId - Screenset ID\n * @param language - Optional language (defaults to current)\n */\n loadScreensetTranslations(screensetId: string, language?: Language): Promise<void>;\n\n /**\n * Preload translations for multiple languages.\n *\n * @param languages - Languages to preload\n */\n preloadLanguages(languages: Language[]): Promise<void>;\n\n /**\n * Subscribe to translation changes.\n * Called when new translations are registered.\n *\n * @param callback - Function to call on changes\n * @returns Unsubscribe function\n */\n subscribe(callback: () => void): () => void;\n\n /**\n * Get the current version number.\n * Increments when translations change. Used by React for re-rendering.\n *\n * @returns Current version number\n */\n getVersion(): number;\n}\n\n// ============================================================================\n// Display Mode\n// ============================================================================\n\n/**\n * Language Display Mode\n * How to display language names in the UI.\n */\nexport enum LanguageDisplayMode {\n /** Show native name (e.g., 'Español') */\n Native = 'native',\n /** Show English name (e.g., 'Spanish') */\n English = 'english',\n}\n\n// ============================================================================\n// Constants\n// ============================================================================\n\n/**\n * I18n namespace separator constant.\n * Used to separate namespace from key: 'namespace:key'\n */\nexport const I18N_NAMESPACE_SEPARATOR = ':';\n\n/**\n * I18n path separator constant.\n * Used to separate nested keys: 'key.subkey'\n */\nexport const I18N_PATH_SEPARATOR = '.';\n\n/**\n * Default namespace for translations without explicit namespace.\n */\nexport const I18N_DEFAULT_NAMESPACE = 'app';\n\n/**\n * HTML lang attribute name.\n */\nexport const HTML_LANG_ATTRIBUTE = 'lang';\n\n/**\n * HTML dir attribute name.\n */\nexport const HTML_DIR_ATTRIBUTE = 'dir';\n","/**\n * Supported Languages - All 36 HAI3 supported languages\n *\n * Based on major platforms (Google, Facebook, Microsoft, Apple).\n * Includes native names, English names, and text direction.\n */\n// @cpt-dod:cpt-hai3-dod-i18n-infrastructure-language-support:p1\n\nimport { Language, TextDirection } from './types';\nimport type { LanguageMetadata } from './types';\n\n// @cpt-begin:cpt-hai3-dod-i18n-infrastructure-language-support:p1:inst-1\n/**\n * All supported languages with metadata.\n * This list defines what languages the application can use.\n */\nexport const SUPPORTED_LANGUAGES: LanguageMetadata[] = [\n // Western European\n {\n code: Language.English,\n name: 'English',\n englishName: 'English',\n direction: TextDirection.LeftToRight,\n },\n {\n code: Language.Spanish,\n name: 'Español',\n englishName: 'Spanish',\n direction: TextDirection.LeftToRight,\n },\n {\n code: Language.French,\n name: 'Français',\n englishName: 'French',\n direction: TextDirection.LeftToRight,\n },\n {\n code: Language.German,\n name: 'Deutsch',\n englishName: 'German',\n direction: TextDirection.LeftToRight,\n },\n {\n code: Language.Italian,\n name: 'Italiano',\n englishName: 'Italian',\n direction: TextDirection.LeftToRight,\n },\n {\n code: Language.Portuguese,\n name: 'Português',\n englishName: 'Portuguese',\n direction: TextDirection.LeftToRight,\n },\n {\n code: Language.Dutch,\n name: 'Nederlands',\n englishName: 'Dutch',\n direction: TextDirection.LeftToRight,\n },\n\n // Eastern European\n {\n code: Language.Russian,\n name: 'Русский',\n englishName: 'Russian',\n direction: TextDirection.LeftToRight,\n },\n {\n code: Language.Polish,\n name: 'Polski',\n englishName: 'Polish',\n direction: TextDirection.LeftToRight,\n },\n {\n code: Language.Ukrainian,\n name: 'Українська',\n englishName: 'Ukrainian',\n direction: TextDirection.LeftToRight,\n },\n {\n code: Language.Czech,\n name: 'Čeština',\n englishName: 'Czech',\n direction: TextDirection.LeftToRight,\n },\n\n // Middle East & North Africa (RTL)\n {\n code: Language.Arabic,\n name: 'العربية',\n englishName: 'Arabic',\n direction: TextDirection.RightToLeft,\n },\n {\n code: Language.Hebrew,\n name: 'עברית',\n englishName: 'Hebrew',\n direction: TextDirection.RightToLeft,\n },\n {\n code: Language.Persian,\n name: 'فارسی',\n englishName: 'Persian',\n direction: TextDirection.RightToLeft,\n },\n {\n code: Language.Urdu,\n name: 'اردو',\n englishName: 'Urdu',\n direction: TextDirection.RightToLeft,\n },\n {\n code: Language.Turkish,\n name: 'Türkçe',\n englishName: 'Turkish',\n direction: TextDirection.LeftToRight,\n },\n\n // Asian\n {\n code: Language.ChineseSimplified,\n name: '简体中文',\n englishName: 'Chinese (Simplified)',\n direction: TextDirection.LeftToRight,\n },\n {\n code: Language.ChineseTraditional,\n name: '繁體中文',\n englishName: 'Chinese (Traditional)',\n direction: TextDirection.LeftToRight,\n region: 'TW',\n },\n {\n code: Language.Japanese,\n name: '日本語',\n englishName: 'Japanese',\n direction: TextDirection.LeftToRight,\n },\n {\n code: Language.Korean,\n name: '한국어',\n englishName: 'Korean',\n direction: TextDirection.LeftToRight,\n },\n {\n code: Language.Vietnamese,\n name: 'Tiếng Việt',\n englishName: 'Vietnamese',\n direction: TextDirection.LeftToRight,\n },\n {\n code: Language.Thai,\n name: 'ไทย',\n englishName: 'Thai',\n direction: TextDirection.LeftToRight,\n },\n {\n code: Language.Indonesian,\n name: 'Bahasa Indonesia',\n englishName: 'Indonesian',\n direction: TextDirection.LeftToRight,\n },\n {\n code: Language.Hindi,\n name: 'हिन्दी',\n englishName: 'Hindi',\n direction: TextDirection.LeftToRight,\n },\n {\n code: Language.Bengali,\n name: 'বাংলা',\n englishName: 'Bengali',\n direction: TextDirection.LeftToRight,\n },\n\n // Nordic\n {\n code: Language.Swedish,\n name: 'Svenska',\n englishName: 'Swedish',\n direction: TextDirection.LeftToRight,\n },\n {\n code: Language.Danish,\n name: 'Dansk',\n englishName: 'Danish',\n direction: TextDirection.LeftToRight,\n },\n {\n code: Language.Norwegian,\n name: 'Norsk',\n englishName: 'Norwegian',\n direction: TextDirection.LeftToRight,\n },\n {\n code: Language.Finnish,\n name: 'Suomi',\n englishName: 'Finnish',\n direction: TextDirection.LeftToRight,\n },\n\n // Other\n {\n code: Language.Greek,\n name: 'Ελληνικά',\n englishName: 'Greek',\n direction: TextDirection.LeftToRight,\n },\n {\n code: Language.Romanian,\n name: 'Română',\n englishName: 'Romanian',\n direction: TextDirection.LeftToRight,\n },\n {\n code: Language.Hungarian,\n name: 'Magyar',\n englishName: 'Hungarian',\n direction: TextDirection.LeftToRight,\n },\n\n // Additional major languages\n {\n code: Language.Malay,\n name: 'Bahasa Melayu',\n englishName: 'Malay',\n direction: TextDirection.LeftToRight,\n },\n {\n code: Language.Tagalog,\n name: 'Tagalog',\n englishName: 'Tagalog',\n direction: TextDirection.LeftToRight,\n },\n {\n code: Language.Tamil,\n name: 'தமிழ்',\n englishName: 'Tamil',\n direction: TextDirection.LeftToRight,\n },\n {\n code: Language.Swahili,\n name: 'Kiswahili',\n englishName: 'Swahili',\n direction: TextDirection.LeftToRight,\n },\n];\n// @cpt-end:cpt-hai3-dod-i18n-infrastructure-language-support:p1:inst-1\n\n/**\n * Get language metadata by code.\n *\n * @param code - Language code\n * @returns Language metadata or undefined\n */\nexport function getLanguageMetadata(code: Language): LanguageMetadata | undefined {\n return SUPPORTED_LANGUAGES.find((lang) => lang.code === code);\n}\n\n// @cpt-begin:cpt-hai3-dod-i18n-infrastructure-language-support:p1:inst-2\n/**\n * Get RTL language codes.\n *\n * @returns Array of RTL language codes\n */\nexport function getRTLLanguages(): Language[] {\n return SUPPORTED_LANGUAGES\n .filter((lang) => lang.direction === TextDirection.RightToLeft)\n .map((lang) => lang.code);\n}\n// @cpt-end:cpt-hai3-dod-i18n-infrastructure-language-support:p1:inst-2\n\n/**\n * Check if a language code is valid.\n *\n * @param code - Language code to check\n * @returns True if valid\n */\nexport function isValidLanguage(code: string): code is Language {\n return SUPPORTED_LANGUAGES.some((lang) => lang.code === code);\n}\n","/**\n * I18n Registry - Central translation management\n *\n * Implements namespace-based translation loading with:\n * - Lazy loading for screenset/screen translations\n * - RTL/LTR support\n * - Parameter interpolation\n *\n * SDK Layer: L1 (Zero @gears-frontx dependencies)\n */\n// @cpt-flow:cpt-hai3-flow-i18n-infrastructure-language-activation:p1\n// @cpt-flow:cpt-hai3-flow-i18n-infrastructure-screenset-registration:p1\n// @cpt-flow:cpt-hai3-flow-i18n-infrastructure-screen-lazy-load:p1\n// @cpt-flow:cpt-hai3-flow-i18n-infrastructure-key-resolution:p1\n// @cpt-algo:cpt-hai3-algo-i18n-infrastructure-language-file-map:p1\n// @cpt-algo:cpt-hai3-algo-i18n-infrastructure-create-loader:p1\n// @cpt-algo:cpt-hai3-algo-i18n-infrastructure-lazy-exclusion:p1\n// @cpt-algo:cpt-hai3-algo-i18n-infrastructure-html-attrs:p1\n// @cpt-algo:cpt-hai3-algo-i18n-infrastructure-path-traversal:p1\n// @cpt-state:cpt-hai3-state-i18n-infrastructure-registry:p1\n// @cpt-state:cpt-hai3-state-i18n-infrastructure-namespace-cache:p1\n// @cpt-dod:cpt-hai3-dod-i18n-infrastructure-hybrid-namespace:p1\n// @cpt-dod:cpt-hai3-dod-i18n-infrastructure-lazy-chunks:p1\n\nimport type {\n I18nRegistry as II18nRegistry,\n I18nConfig,\n TranslationDictionary,\n TranslationLoader,\n TranslationParams,\n TranslationMap,\n LanguageMetadata,\n} from './types';\n\nimport {\n Language,\n TextDirection,\n I18N_NAMESPACE_SEPARATOR,\n I18N_PATH_SEPARATOR,\n I18N_DEFAULT_NAMESPACE,\n HTML_LANG_ATTRIBUTE,\n HTML_DIR_ATTRIBUTE,\n} from './types';\n\nimport { SUPPORTED_LANGUAGES } from './languages';\n\n// ============================================================================\n// I18n Registry Implementation\n// ============================================================================\n\n/**\n * I18n Registry Implementation\n *\n * Central registry for managing translations across the application.\n * Supports lazy loading, namespace isolation, and RTL languages.\n */\nexport class I18nRegistryImpl implements II18nRegistry {\n /** Configuration */\n private config: I18nConfig;\n\n /** Current language */\n private currentLanguage: Language | null = null;\n\n /** Translation dictionaries: namespace -> language -> dictionary */\n private dictionaries: Map<string, Map<Language, TranslationDictionary>> = new Map();\n\n /** Translation loaders: namespace -> loader function */\n private loaders: Map<string, TranslationLoader> = new Map();\n\n /** Subscribers for translation changes */\n private subscribers: Set<() => void> = new Set();\n\n /** Version counter for React re-rendering */\n private version: number = 0;\n\n // @cpt-begin:cpt-hai3-algo-i18n-infrastructure-language-file-map:p1:inst-1\n /** Language file mapping */\n static readonly LANGUAGE_FILE_MAP: Record<Language, string> = {\n [Language.English]: 'en.json',\n [Language.Spanish]: 'es.json',\n [Language.French]: 'fr.json',\n [Language.German]: 'de.json',\n [Language.Italian]: 'it.json',\n [Language.Portuguese]: 'pt.json',\n [Language.Dutch]: 'nl.json',\n [Language.Russian]: 'ru.json',\n [Language.Polish]: 'pl.json',\n [Language.Ukrainian]: 'uk.json',\n [Language.Czech]: 'cs.json',\n [Language.Arabic]: 'ar.json',\n [Language.Hebrew]: 'he.json',\n [Language.Persian]: 'fa.json',\n [Language.Urdu]: 'ur.json',\n [Language.Turkish]: 'tr.json',\n [Language.ChineseSimplified]: 'zh.json',\n [Language.ChineseTraditional]: 'zh-TW.json',\n [Language.Japanese]: 'ja.json',\n [Language.Korean]: 'ko.json',\n [Language.Vietnamese]: 'vi.json',\n [Language.Thai]: 'th.json',\n [Language.Indonesian]: 'id.json',\n [Language.Hindi]: 'hi.json',\n [Language.Bengali]: 'bn.json',\n [Language.Swedish]: 'sv.json',\n [Language.Danish]: 'da.json',\n [Language.Norwegian]: 'no.json',\n [Language.Finnish]: 'fi.json',\n [Language.Greek]: 'el.json',\n [Language.Romanian]: 'ro.json',\n [Language.Hungarian]: 'hu.json',\n [Language.Malay]: 'ms.json',\n [Language.Tagalog]: 'tl.json',\n [Language.Tamil]: 'ta.json',\n [Language.Swahili]: 'sw.json',\n };\n // @cpt-end:cpt-hai3-algo-i18n-infrastructure-language-file-map:p1:inst-1\n\n constructor(config: I18nConfig) {\n this.config = config;\n }\n\n // ============================================================================\n // Registration\n // ============================================================================\n\n // @cpt-begin:cpt-hai3-state-i18n-infrastructure-namespace-cache:p1:inst-1\n /**\n * Register translations for a namespace.\n */\n register(namespace: string, language: Language, translations: TranslationDictionary): void {\n if (!this.dictionaries.has(namespace)) {\n this.dictionaries.set(namespace, new Map());\n }\n this.dictionaries.get(namespace)!.set(language, translations);\n this.notifySubscribers();\n }\n // @cpt-end:cpt-hai3-state-i18n-infrastructure-namespace-cache:p1:inst-1\n\n /**\n * Subscribe to translation changes.\n * Returns an unsubscribe function.\n */\n subscribe(callback: () => void): () => void {\n this.subscribers.add(callback);\n return () => {\n this.subscribers.delete(callback);\n };\n }\n\n /**\n * Notify all subscribers of a change.\n */\n private notifySubscribers(): void {\n this.version++;\n this.subscribers.forEach((callback) => callback());\n }\n\n /**\n * Get the current version number.\n * Used by React to detect changes.\n */\n getVersion(): number {\n return this.version;\n }\n\n // @cpt-begin:cpt-hai3-flow-i18n-infrastructure-screenset-registration:p1:inst-1\n // @cpt-begin:cpt-hai3-flow-i18n-infrastructure-screen-lazy-load:p1:inst-1\n /**\n * Register a translation loader for a namespace.\n */\n registerLoader(namespace: string, loader: TranslationLoader): void {\n this.loaders.set(namespace, loader);\n }\n // @cpt-end:cpt-hai3-flow-i18n-infrastructure-screenset-registration:p1:inst-1\n // @cpt-end:cpt-hai3-flow-i18n-infrastructure-screen-lazy-load:p1:inst-1\n\n /**\n * Check if namespace is registered.\n */\n hasNamespace(namespace: string): boolean {\n return this.dictionaries.has(namespace) || this.loaders.has(namespace);\n }\n\n /**\n * Get all registered namespaces.\n */\n getNamespaces(): string[] {\n const namespaces = new Set<string>();\n this.dictionaries.forEach((_, key) => namespaces.add(key));\n this.loaders.forEach((_, key) => namespaces.add(key));\n return Array.from(namespaces);\n }\n\n // ============================================================================\n // Translation\n // ============================================================================\n\n // @cpt-begin:cpt-hai3-flow-i18n-infrastructure-key-resolution:p1:inst-1\n /**\n * Translate a key.\n * Format: 'namespace:key.subkey' or just 'key' for default namespace\n */\n t(key: string, params?: TranslationParams): string {\n // Parse namespace and path\n const { namespace, path } = this.parseKey(key);\n\n // Get translation from dictionary\n const translation = this.getTranslation(namespace, path);\n\n // Return key if no translation found\n if (translation === undefined) {\n return key;\n }\n\n // Interpolate parameters\n return this.interpolate(translation, params);\n }\n // @cpt-end:cpt-hai3-flow-i18n-infrastructure-key-resolution:p1:inst-1\n\n // @cpt-begin:cpt-hai3-flow-i18n-infrastructure-key-resolution:p1:inst-2\n /**\n * Parse a translation key into namespace and path.\n */\n private parseKey(key: string): { namespace: string; path: string } {\n const separatorIndex = key.indexOf(I18N_NAMESPACE_SEPARATOR);\n\n if (separatorIndex === -1) {\n return {\n namespace: I18N_DEFAULT_NAMESPACE,\n path: key,\n };\n }\n\n return {\n namespace: key.slice(0, separatorIndex),\n path: key.slice(separatorIndex + 1),\n };\n }\n // @cpt-end:cpt-hai3-flow-i18n-infrastructure-key-resolution:p1:inst-2\n\n // @cpt-begin:cpt-hai3-flow-i18n-infrastructure-key-resolution:p1:inst-3\n /**\n * Get a translation from the dictionary.\n */\n private getTranslation(namespace: string, path: string): string | undefined {\n const language = this.currentLanguage ?? this.config.defaultLanguage;\n const fallback = this.config.fallbackLanguage;\n\n // Try current language first\n let translation = this.findTranslation(namespace, language, path);\n if (translation !== undefined) {\n return translation;\n }\n\n // Try fallback language\n if (language !== fallback) {\n translation = this.findTranslation(namespace, fallback, path);\n if (translation !== undefined) {\n return translation;\n }\n }\n\n return undefined;\n }\n // @cpt-end:cpt-hai3-flow-i18n-infrastructure-key-resolution:p1:inst-3\n\n // @cpt-begin:cpt-hai3-flow-i18n-infrastructure-key-resolution:p1:inst-4\n // @cpt-begin:cpt-hai3-algo-i18n-infrastructure-path-traversal:p1:inst-1\n /**\n * Find a translation in the dictionary.\n */\n private findTranslation(\n namespace: string,\n language: Language,\n path: string\n ): string | undefined {\n const namespaceDicts = this.dictionaries.get(namespace);\n if (!namespaceDicts) {\n return undefined;\n }\n\n const dict = namespaceDicts.get(language);\n if (!dict) {\n return undefined;\n }\n\n // Navigate nested path\n const parts = path.split(I18N_PATH_SEPARATOR);\n let current: TranslationDictionary | string = dict;\n\n for (const part of parts) {\n if (typeof current !== 'object' || current === null) {\n return undefined;\n }\n current = current[part] as TranslationDictionary | string;\n if (current === undefined) {\n return undefined;\n }\n }\n\n return typeof current === 'string' ? current : undefined;\n }\n // @cpt-end:cpt-hai3-flow-i18n-infrastructure-key-resolution:p1:inst-4\n // @cpt-end:cpt-hai3-algo-i18n-infrastructure-path-traversal:p1:inst-1\n\n // @cpt-begin:cpt-hai3-flow-i18n-infrastructure-key-resolution:p1:inst-5\n /**\n * Interpolate parameters into a translation string.\n */\n private interpolate(text: string, params?: TranslationParams): string {\n if (!params) {\n return text;\n }\n\n return text.replace(/\\{(\\w+)\\}/g, (match, key) => {\n const value = params[key];\n return value !== undefined ? String(value) : match;\n });\n }\n // @cpt-end:cpt-hai3-flow-i18n-infrastructure-key-resolution:p1:inst-5\n\n // ============================================================================\n // Language Management\n // ============================================================================\n\n // @cpt-begin:cpt-hai3-flow-i18n-infrastructure-language-activation:p1:inst-1\n // @cpt-begin:cpt-hai3-state-i18n-infrastructure-registry:p1:inst-1\n /**\n * Set current language and load translations.\n */\n async setLanguage(language: Language): Promise<void> {\n this.currentLanguage = language;\n\n // Update HTML attributes\n this.updateHtmlAttributes(language);\n\n // Load translations for the language\n await this.loadLanguage(language);\n }\n // @cpt-end:cpt-hai3-flow-i18n-infrastructure-language-activation:p1:inst-1\n // @cpt-end:cpt-hai3-state-i18n-infrastructure-registry:p1:inst-1\n\n /**\n * Get current language.\n */\n getLanguage(): Language | null {\n return this.currentLanguage;\n }\n\n // @cpt-begin:cpt-hai3-algo-i18n-infrastructure-html-attrs:p1:inst-1\n /**\n * Update HTML lang and dir attributes.\n */\n private updateHtmlAttributes(language: Language): void {\n if (typeof document === 'undefined') {\n return; // Skip in SSR/Node.js environment\n }\n\n const htmlElement = document.documentElement;\n htmlElement.setAttribute(HTML_LANG_ATTRIBUTE, language);\n htmlElement.setAttribute(\n HTML_DIR_ATTRIBUTE,\n this.isRTL(language) ? TextDirection.RightToLeft : TextDirection.LeftToRight\n );\n }\n // @cpt-end:cpt-hai3-algo-i18n-infrastructure-html-attrs:p1:inst-1\n\n // ============================================================================\n // Language Metadata\n // ============================================================================\n\n /**\n * Get language metadata.\n */\n getLanguageMetadata(code?: Language): LanguageMetadata | undefined {\n const targetCode = code ?? this.currentLanguage;\n if (!targetCode) {\n return undefined;\n }\n return SUPPORTED_LANGUAGES.find((lang) => lang.code === targetCode);\n }\n\n /**\n * Get all supported languages.\n */\n getSupportedLanguages(): LanguageMetadata[] {\n return [...SUPPORTED_LANGUAGES];\n }\n\n /**\n * Check if a language is RTL.\n */\n isRTL(code?: Language): boolean {\n const targetCode = code ?? this.currentLanguage;\n if (!targetCode) {\n return false;\n }\n const metadata = this.getLanguageMetadata(targetCode);\n return metadata?.direction === TextDirection.RightToLeft;\n }\n\n // ============================================================================\n // Translation Loading\n // ============================================================================\n\n // @cpt-begin:cpt-hai3-algo-i18n-infrastructure-lazy-exclusion:p1:inst-1\n // @cpt-begin:cpt-hai3-flow-i18n-infrastructure-language-activation:p1:inst-2\n /**\n * Load translations for a language.\n * Excludes screen.* and screenset.* namespaces which are lazy-loaded:\n * - screen.* namespaces: loaded when screen mounts\n * - screenset.* namespaces: loaded when screenset is activated\n */\n async loadLanguage(language: Language): Promise<void> {\n const loadPromises: Promise<void>[] = [];\n\n this.loaders.forEach((_loader, namespace) => {\n // Skip screen and screenset namespaces (lazy-loaded on demand)\n if (namespace.startsWith('screen.') || namespace.startsWith('screenset.')) {\n return;\n }\n loadPromises.push(this.loadNamespace(namespace, language));\n });\n\n await Promise.all(loadPromises);\n }\n // @cpt-end:cpt-hai3-algo-i18n-infrastructure-lazy-exclusion:p1:inst-1\n // @cpt-end:cpt-hai3-flow-i18n-infrastructure-language-activation:p1:inst-2\n\n // @cpt-begin:cpt-hai3-flow-i18n-infrastructure-screen-lazy-load:p1:inst-2\n /**\n * Load translations for a specific namespace.\n */\n private async loadNamespace(namespace: string, language: Language): Promise<void> {\n const loader = this.loaders.get(namespace);\n if (!loader) {\n return;\n }\n\n try {\n const translations = await loader(language);\n this.register(namespace, language, translations);\n } catch (error) {\n console.warn(`Failed to load translations for ${namespace}/${language}:`, error);\n }\n }\n // @cpt-end:cpt-hai3-flow-i18n-infrastructure-screen-lazy-load:p1:inst-2\n\n // @cpt-begin:cpt-hai3-flow-i18n-infrastructure-screenset-registration:p1:inst-2\n /**\n * Load translations for a specific screenset.\n */\n async loadScreensetTranslations(screensetId: string, language?: Language): Promise<void> {\n const targetLanguage = language ?? this.currentLanguage ?? this.config.defaultLanguage;\n const namespace = `screenset.${screensetId}`;\n\n await this.loadNamespace(namespace, targetLanguage);\n }\n // @cpt-end:cpt-hai3-flow-i18n-infrastructure-screenset-registration:p1:inst-2\n\n /**\n * Preload translations for multiple languages.\n */\n async preloadLanguages(languages: Language[]): Promise<void> {\n const loadPromises = languages.map((language) => this.loadLanguage(language));\n await Promise.all(loadPromises);\n }\n\n // ============================================================================\n // Static Helpers\n // ============================================================================\n\n /**\n * Create a translation loader from a translation map.\n *\n * @example\n * ```typescript\n * const loader = I18nRegistry.createLoader({\n * [Language.English]: () => import('./i18n/en.json'),\n * [Language.Spanish]: () => import('./i18n/es.json'),\n * });\n * ```\n */\n // @cpt-begin:cpt-hai3-algo-i18n-infrastructure-create-loader:p1:inst-1\n // @cpt-begin:cpt-hai3-dod-i18n-infrastructure-lazy-chunks:p1:inst-1\n static createLoader(translationMap: TranslationMap): TranslationLoader {\n return async (language: Language | string): Promise<TranslationDictionary> => {\n const importFn = translationMap[language as Language];\n if (!importFn) {\n throw new Error(`No translation found for language: ${language}`);\n }\n const module = await importFn();\n return module.default;\n };\n }\n // @cpt-end:cpt-hai3-algo-i18n-infrastructure-create-loader:p1:inst-1\n // @cpt-end:cpt-hai3-dod-i18n-infrastructure-lazy-chunks:p1:inst-1\n\n /**\n * Create a translation loader from a directory.\n * Maps Language enum values to file names automatically.\n *\n * @param basePath - Base path for translation files\n * @param importFn - Dynamic import function\n */\n static createLoaderFromDirectory(\n importFn: (filename: string) => Promise<{ default: TranslationDictionary }>\n ): TranslationLoader {\n return async (language: Language | string): Promise<TranslationDictionary> => {\n const filename = I18nRegistryImpl.LANGUAGE_FILE_MAP[language as Language];\n const module = await importFn(filename);\n return module.default;\n };\n }\n}\n\n// ============================================================================\n// Singleton Instance\n// ============================================================================\n\n// @cpt-begin:cpt-hai3-state-i18n-infrastructure-registry:p1:inst-2\n// @cpt-begin:cpt-hai3-dod-i18n-infrastructure-language-support:p1:inst-1\n/**\n * Default i18n registry instance.\n * Use this instance throughout the application.\n */\nexport const i18nRegistry = new I18nRegistryImpl({\n defaultLanguage: Language.English,\n fallbackLanguage: Language.English,\n});\n// @cpt-end:cpt-hai3-state-i18n-infrastructure-registry:p1:inst-2\n// @cpt-end:cpt-hai3-dod-i18n-infrastructure-language-support:p1:inst-1\n\n/**\n * Create a new i18n registry with custom configuration.\n *\n * @param config - I18n configuration\n * @returns New I18nRegistry instance\n */\nexport function createI18nRegistry(config: I18nConfig): I18nRegistryImpl {\n return new I18nRegistryImpl(config);\n}\n","/**\n * Shared formatter utilities - locale and value coercion used by formatters.\n */\n// @cpt-algo:cpt-hai3-algo-i18n-infrastructure-locale-resolution:p1\n// @cpt-algo:cpt-hai3-algo-i18n-infrastructure-formatter-input-guard:p2\n// @cpt-dod:cpt-hai3-dod-i18n-infrastructure-formatters:p1\n\nimport { i18nRegistry } from '../I18nRegistry';\nimport { Language } from '../types';\n\n// @cpt-begin:cpt-hai3-algo-i18n-infrastructure-locale-resolution:p1:inst-1\nexport function getLocale(): string {\n return i18nRegistry.getLanguage() ?? Language.English;\n}\n// @cpt-end:cpt-hai3-algo-i18n-infrastructure-locale-resolution:p1:inst-1\n\n// @cpt-begin:cpt-hai3-algo-i18n-infrastructure-formatter-input-guard:p2:inst-1\nexport function toNumber(value: number | null | undefined): number | null {\n if (value === null || value === undefined) return null;\n const n = Number(value);\n return Number.isNaN(n) ? null : n;\n}\n// @cpt-end:cpt-hai3-algo-i18n-infrastructure-formatter-input-guard:p2:inst-1\n","/**\n * Date formatter - Locale-aware date and time formatting\n *\n * Uses i18nRegistry.getLanguage() for locale; fallback to Language.English when null.\n * Invalid date inputs return ''.\n */\n// @cpt-flow:cpt-hai3-flow-i18n-infrastructure-formatter-usage:p1\n// @cpt-dod:cpt-hai3-dod-i18n-infrastructure-formatters:p1\n\nimport { getLocale } from './utils';\n\nexport type DateFormatStyle = 'short' | 'medium' | 'long' | 'full';\nexport type TimeFormatStyle = 'short' | 'medium';\n\nexport type DateInput = Date | number | string | null | undefined;\n\nfunction toDate(value: DateInput): Date | null {\n if (value === null || value === undefined) return null;\n const d = new Date(value);\n return Number.isNaN(d.getTime()) ? null : d;\n}\n\n// @cpt-begin:cpt-hai3-flow-i18n-infrastructure-formatter-usage:p1:inst-1\n// @cpt-begin:cpt-hai3-dod-i18n-infrastructure-formatters:p1:inst-1\n/**\n * Format a date according to the current locale.\n *\n * @param date - Date, timestamp, or ISO string\n * @param format - 'short' | 'medium' | 'long' | 'full'\n * @returns Formatted date string, or '' if input is invalid\n */\nexport function formatDate(date: DateInput, format: DateFormatStyle): string {\n const d = toDate(date);\n if (!d) return '';\n const locale = getLocale();\n return new Intl.DateTimeFormat(locale, { dateStyle: format }).format(d);\n}\n// @cpt-end:cpt-hai3-flow-i18n-infrastructure-formatter-usage:p1:inst-1\n// @cpt-end:cpt-hai3-dod-i18n-infrastructure-formatters:p1:inst-1\n\n// @cpt-begin:cpt-hai3-dod-i18n-infrastructure-formatters:p1:inst-2\n/**\n * Format the time portion of a date according to the current locale.\n *\n * @param date - Date, timestamp, or ISO string\n * @param format - 'short' | 'medium'\n * @returns Formatted time string, or '' if input is invalid\n */\nexport function formatTime(date: DateInput, format: TimeFormatStyle): string {\n const d = toDate(date);\n if (!d) return '';\n const locale = getLocale();\n return new Intl.DateTimeFormat(locale, { timeStyle: format }).format(d);\n}\n// @cpt-end:cpt-hai3-dod-i18n-infrastructure-formatters:p1:inst-2\n\n// @cpt-begin:cpt-hai3-dod-i18n-infrastructure-formatters:p1:inst-3\n/**\n * Format date and time according to the current locale.\n *\n * @param date - Date, timestamp, or ISO string\n * @param dateFormat - Date style: 'short' | 'medium' | 'long' | 'full'\n * @param timeFormat - Time style: 'short' | 'medium'\n * @returns Formatted date-time string, or '' if input is invalid\n */\nexport function formatDateTime(\n date: DateInput,\n dateFormat: DateFormatStyle,\n timeFormat: TimeFormatStyle\n): string {\n const d = toDate(date);\n if (!d) return '';\n const locale = getLocale();\n return new Intl.DateTimeFormat(locale, {\n dateStyle: dateFormat,\n timeStyle: timeFormat,\n }).format(d);\n}\n// @cpt-end:cpt-hai3-dod-i18n-infrastructure-formatters:p1:inst-3\n\nconst MS_PER_SECOND = 1000;\nconst MS_PER_MINUTE = 60 * MS_PER_SECOND;\nconst MS_PER_HOUR = 60 * MS_PER_MINUTE;\nconst MS_PER_DAY = 24 * MS_PER_HOUR;\n\n/**\n * Picks relative-time unit and value using calendar-aware boundaries for day/month/year\n * (no 30d/365d approximations), and exact second/minute/hour for sub-day deltas.\n */\nfunction getRelativeUnit(\n date: Date,\n base: Date\n): { value: number; unit: Intl.RelativeTimeFormatUnit } {\n const diffMs = date.getTime() - base.getTime();\n const absMs = Math.abs(diffMs);\n const sign = diffMs < 0 ? -1 : 1;\n\n if (absMs < 60 * MS_PER_SECOND) {\n const value = Math.round(diffMs / MS_PER_SECOND);\n return { value: value === 0 ? 0 : value, unit: 'second' };\n }\n if (absMs < 60 * MS_PER_MINUTE) {\n return { value: sign * Math.round(absMs / MS_PER_MINUTE), unit: 'minute' };\n }\n if (absMs < MS_PER_DAY) {\n return { value: sign * Math.round(absMs / MS_PER_HOUR), unit: 'hour' };\n }\n\n const baseY = base.getUTCFullYear();\n const baseM = base.getUTCMonth();\n const baseD = base.getUTCDate();\n const dateY = date.getUTCFullYear();\n const dateM = date.getUTCMonth();\n const dateD = date.getUTCDate();\n\n const totalMonths = (dateY - baseY) * 12 + (dateM - baseM);\n const baseUTC = Date.UTC(baseY, baseM, baseD);\n const dateUTC = Date.UTC(dateY, dateM, dateD);\n const diffDays = Math.round((dateUTC - baseUTC) / MS_PER_DAY);\n\n if (Math.abs(totalMonths) >= 12) {\n const value = Math.round(totalMonths / 12);\n return { value, unit: 'year' };\n }\n if (Math.abs(totalMonths) >= 1) {\n return { value: totalMonths, unit: 'month' };\n }\n return { value: diffDays === 0 ? sign * 1 : diffDays, unit: 'day' };\n}\n\n// @cpt-begin:cpt-hai3-dod-i18n-infrastructure-formatters:p1:inst-4\n/**\n * Format a date as relative time (e.g. \"2 hours ago\", \"in 3 days\").\n *\n * @param date - Date, timestamp, or ISO string\n * @param base - Reference date for \"now\"; defaults to new Date()\n * @returns Relative time string, or '' if input is invalid\n */\nexport function formatRelative(date: DateInput, base?: DateInput): string {\n const d = toDate(date);\n if (!d) return '';\n const baseDate = base !== undefined ? toDate(base) : new Date();\n if (!baseDate) return '';\n const locale = getLocale();\n const rtf = new Intl.RelativeTimeFormat(locale, { numeric: 'auto' });\n const { value, unit } = getRelativeUnit(d, baseDate);\n return rtf.format(value, unit);\n}\n// @cpt-end:cpt-hai3-dod-i18n-infrastructure-formatters:p1:inst-4\n","/**\n * Number formatter - Locale-aware number formatting\n *\n * Uses i18nRegistry.getLanguage() for locale; fallback to Language.English when null.\n * null, undefined, and NaN return ''.\n */\n// @cpt-dod:cpt-hai3-dod-i18n-infrastructure-formatters:p1\n\nimport { getLocale, toNumber } from './utils';\n\n// @cpt-begin:cpt-hai3-dod-i18n-infrastructure-formatters:p1:inst-5\n/**\n * Format a number according to the current locale.\n *\n * @param value - Number to format\n * @param options - Intl.NumberFormatOptions (e.g. minimumFractionDigits)\n * @returns Formatted number string, or '' if input is null, undefined, or NaN\n */\nexport function formatNumber(\n value: number | null | undefined,\n options?: Intl.NumberFormatOptions\n): string {\n const n = toNumber(value);\n if (n === null) return '';\n const locale = getLocale();\n return new Intl.NumberFormat(locale, options).format(n);\n}\n// @cpt-end:cpt-hai3-dod-i18n-infrastructure-formatters:p1:inst-5\n\n// @cpt-begin:cpt-hai3-dod-i18n-infrastructure-formatters:p1:inst-6\n/**\n * Format a value as a percentage (0.15 -> \"15%\").\n *\n * @param value - Decimal value (e.g. 0.15 for 15%)\n * @param decimals - Optional decimal places\n * @returns Formatted percent string, or '' if input is null, undefined, or NaN\n */\nexport function formatPercent(\n value: number | null | undefined,\n decimals?: number\n): string {\n const n = toNumber(value);\n if (n === null) return '';\n const locale = getLocale();\n const opts: Intl.NumberFormatOptions = {\n style: 'percent',\n ...(decimals !== undefined && { minimumFractionDigits: decimals, maximumFractionDigits: decimals }),\n };\n return new Intl.NumberFormat(locale, opts).format(n);\n}\n// @cpt-end:cpt-hai3-dod-i18n-infrastructure-formatters:p1:inst-6\n\n// @cpt-begin:cpt-hai3-dod-i18n-infrastructure-formatters:p1:inst-7\n/**\n * Format a number in compact notation (e.g. \"1.2K\", \"3.4M\").\n *\n * @param value - Number to format\n * @returns Compact formatted string, or '' if input is null, undefined, or NaN\n */\nexport function formatCompact(value: number | null | undefined): string {\n const n = toNumber(value);\n if (n === null) return '';\n const locale = getLocale();\n return new Intl.NumberFormat(locale, { notation: 'compact' }).format(n);\n}\n// @cpt-end:cpt-hai3-dod-i18n-infrastructure-formatters:p1:inst-7\n","/**\n * Currency formatter - Locale-aware currency formatting\n *\n * Uses i18nRegistry.getLanguage() for locale; fallback to Language.English when null.\n * null, undefined, and NaN return ''; invalid currencyCode also returns '' and does not throw.\n */\n// @cpt-dod:cpt-hai3-dod-i18n-infrastructure-formatters:p1\n\nimport { getLocale, toNumber } from './utils';\n\n// @cpt-begin:cpt-hai3-dod-i18n-infrastructure-formatters:p1:inst-8\n/**\n * Format a value as currency for the given currency code.\n *\n * @param value - Numeric amount\n * @param currencyCode - ISO 4217 currency code (e.g. 'USD', 'EUR')\n * @returns Formatted currency string, or '' if value is null, undefined, NaN, or currencyCode is invalid\n */\nexport function formatCurrency(\n value: number | null | undefined,\n currencyCode: string\n): string {\n const n = toNumber(value);\n if (n === null) return '';\n if (!currencyCode || typeof currencyCode !== 'string') return '';\n const locale = getLocale();\n try {\n return new Intl.NumberFormat(locale, {\n style: 'currency',\n currency: currencyCode,\n }).format(n);\n } catch {\n return '';\n }\n}\n// @cpt-end:cpt-hai3-dod-i18n-infrastructure-formatters:p1:inst-8\n","/**\n * Sort utilities - Locale-aware string comparison\n *\n * Uses i18nRegistry.getLanguage() for locale; fallback to Language.English when null.\n */\n// @cpt-dod:cpt-hai3-dod-i18n-infrastructure-formatters:p1\n\nimport { getLocale } from './utils';\n\n// @cpt-begin:cpt-hai3-dod-i18n-infrastructure-formatters:p1:inst-9\n/**\n * Compare two strings according to the current locale (for sorting).\n *\n * @param a - First string\n * @param b - Second string\n * @param options - Intl.Collator options (e.g. sensitivity, numeric)\n * @returns Negative if a < b, 0 if equal, positive if a > b\n */\nexport function compareStrings(\n a: string,\n b: string,\n options?: Intl.CollatorOptions\n): number {\n const locale = getLocale();\n return new Intl.Collator(locale, options).compare(a, b);\n}\n// @cpt-end:cpt-hai3-dod-i18n-infrastructure-formatters:p1:inst-9\n\n// @cpt-begin:cpt-hai3-dod-i18n-infrastructure-formatters:p1:inst-10\n/**\n * Create a Collator for the current locale (reuse for many comparisons, e.g. in tables).\n *\n * @param options - Intl.Collator options\n * @returns Intl.Collator instance\n */\nexport function createCollator(options?: Intl.CollatorOptions): Intl.Collator {\n const locale = getLocale();\n return new Intl.Collator(locale, options);\n}\n// @cpt-end:cpt-hai3-dod-i18n-infrastructure-formatters:p1:inst-10\n"],"mappings":"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","names":["TextDirection","Language","LanguageDisplayMode","module"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/types.ts","../src/languages.ts","../src/I18nRegistry.ts","../src/formatters/utils.ts","../src/formatters/dateFormatter.ts","../src/formatters/numberFormatter.ts","../src/formatters/currencyFormatter.ts","../src/formatters/sortUtils.ts"],"sourcesContent":["/**\n * @gears-frontx/i18n - Internationalization\n *\n * This package provides:\n * - Language enum with 36 supported languages\n * - Translation registry with namespace support\n * - RTL support for Arabic, Hebrew, Persian, Urdu\n * - Lazy loading with dynamic imports\n *\n * SDK Layer: L1 (Zero @gears-frontx dependencies)\n */\n\n// Re-export enums and constants\nexport {\n TextDirection,\n Language,\n LanguageDisplayMode,\n I18N_NAMESPACE_SEPARATOR,\n I18N_PATH_SEPARATOR,\n I18N_DEFAULT_NAMESPACE,\n HTML_LANG_ATTRIBUTE,\n HTML_DIR_ATTRIBUTE,\n} from './types';\n\n// Re-export types\nexport type {\n LanguageMetadata,\n LanguageCode,\n TranslationDictionary,\n TranslationLoader,\n TranslationMap,\n I18nConfig,\n TranslationParams,\n I18nRegistry,\n} from './types';\n\n// Export I18n Registry implementation and singleton\nexport {\n i18nRegistry,\n I18nRegistryImpl,\n createI18nRegistry,\n} from './I18nRegistry';\n\n// Export language utilities\nexport {\n SUPPORTED_LANGUAGES,\n getLanguageMetadata,\n getRTLLanguages,\n isValidLanguage,\n} from './languages';\n\n// Export formatters (locale from i18nRegistry.getLanguage())\nexport {\n formatDate,\n formatTime,\n formatDateTime,\n formatRelative,\n formatNumber,\n formatPercent,\n formatCompact,\n formatCurrency,\n compareStrings,\n createCollator,\n type DateFormatStyle,\n type TimeFormatStyle,\n type DateInput,\n type Formatters,\n} from './formatters';\n","/**\n * @gears-frontx/i18n - Type Definitions\n *\n * Core types for FrontX internationalization.\n * Supports 36 languages with RTL support.\n */\n\n// ============================================================================\n// Text Direction\n// ============================================================================\n\n/**\n * Text Direction Enum\n * Defines text direction for RTL language support.\n */\nexport enum TextDirection {\n LeftToRight = 'ltr',\n RightToLeft = 'rtl',\n}\n\n// ============================================================================\n// Language Enum\n// ============================================================================\n\n/**\n * Language Enum\n * All 36 supported languages based on major platforms (Google, Facebook, Microsoft, Apple).\n */\nexport enum Language {\n // Western European\n English = 'en',\n Spanish = 'es',\n French = 'fr',\n German = 'de',\n Italian = 'it',\n Portuguese = 'pt',\n Dutch = 'nl',\n\n // Eastern European\n Russian = 'ru',\n Polish = 'pl',\n Ukrainian = 'uk',\n Czech = 'cs',\n\n // Middle East & North Africa (RTL)\n Arabic = 'ar',\n Hebrew = 'he',\n Persian = 'fa',\n Urdu = 'ur',\n Turkish = 'tr',\n\n // Asian\n ChineseSimplified = 'zh',\n ChineseTraditional = 'zh-TW',\n Japanese = 'ja',\n Korean = 'ko',\n Vietnamese = 'vi',\n Thai = 'th',\n Indonesian = 'id',\n Hindi = 'hi',\n Bengali = 'bn',\n\n // Nordic\n Swedish = 'sv',\n Danish = 'da',\n Norwegian = 'no',\n Finnish = 'fi',\n\n // Other\n Greek = 'el',\n Romanian = 'ro',\n Hungarian = 'hu',\n\n // Additional major languages\n Malay = 'ms',\n Tagalog = 'tl',\n Tamil = 'ta',\n Swahili = 'sw',\n}\n\n// ============================================================================\n// Language Metadata\n// ============================================================================\n\n/**\n * Language Metadata\n * Complete information about a supported language.\n */\nexport interface LanguageMetadata {\n /** Language code (from Language enum) */\n code: Language;\n /** Native name (e.g., 'English', 'العربية') */\n name: string;\n /** English name for settings UI */\n englishName: string;\n /** Text direction */\n direction: TextDirection;\n /** Optional region (e.g., 'US', 'GB', 'TW') */\n region?: string;\n}\n\n/**\n * Language Code Type\n * Type alias for language codes.\n */\nexport type LanguageCode = Language;\n\n// ============================================================================\n// Translation Types\n// ============================================================================\n\n/**\n * Translation Dictionary\n * Nested key-value structure for translations.\n *\n * @example\n * ```typescript\n * const translations: TranslationDictionary = {\n * button: {\n * submit: 'Submit',\n * cancel: 'Cancel',\n * },\n * messages: {\n * success: 'Operation completed successfully',\n * },\n * };\n * ```\n */\nexport interface TranslationDictionary {\n [key: string]: string | TranslationDictionary;\n}\n\n/**\n * Translation Loader Function\n * Returns translations for a given language using dynamic import.\n * Accepts both Language enum and string for compatibility with @gears-frontx/layout.\n *\n * @example\n * ```typescript\n * const loader: TranslationLoader = async (language) => {\n * const module = await import(`./i18n/${language}.json`);\n * return module.default;\n * };\n * ```\n */\nexport type TranslationLoader = (language: Language | string) => Promise<TranslationDictionary>;\n\n/**\n * Translation Map\n * Maps languages to their dynamic import functions.\n * Used by I18nRegistry.createLoader().\n *\n * @example\n * ```typescript\n * const translationMap: TranslationMap = {\n * [Language.English]: () => import('./i18n/en.json'),\n * [Language.Spanish]: () => import('./i18n/es.json'),\n * // ... all 36 languages\n * };\n * ```\n */\nexport type TranslationMap = Record<Language, () => Promise<{ default: TranslationDictionary }>>;\n\n// ============================================================================\n// I18n Configuration\n// ============================================================================\n\n/**\n * I18n Configuration\n * Configuration options for the i18n system.\n */\nexport interface I18nConfig {\n /** Default language to use */\n defaultLanguage: LanguageCode;\n /** Fallback language when translation is missing */\n fallbackLanguage: LanguageCode;\n}\n\n/**\n * Translation Parameters\n * Parameters for string interpolation.\n *\n * @example\n * ```typescript\n * // Translation: \"Hello, {name}!\"\n * t('greeting', { name: 'John' }); // \"Hello, John!\"\n * ```\n */\nexport type TranslationParams = Record<string, string | number | boolean>;\n\n// ============================================================================\n// I18n Registry Interface\n// ============================================================================\n\n/**\n * I18n Registry Interface\n * Central registry for translation management.\n *\n * @example\n * ```typescript\n * // Register translations\n * i18nRegistry.registerLoader('screenset.demo', demoLoader);\n *\n * // Set language\n * await i18nRegistry.setLanguage(Language.Spanish);\n *\n * // Translate\n * const text = i18nRegistry.t('screenset.demo:welcome.title');\n * ```\n */\nexport interface I18nRegistry {\n /**\n * Register translations for a namespace.\n *\n * @param namespace - Translation namespace (e.g., 'screenset.demo')\n * @param language - Language enum value\n * @param translations - Translation dictionary\n */\n register(namespace: string, language: Language, translations: TranslationDictionary): void;\n\n /**\n * Register a translation loader for a namespace.\n * Loader is called on-demand when language changes.\n *\n * @param namespace - Namespace identifier\n * @param loader - Function that loads translations\n */\n registerLoader(namespace: string, loader: TranslationLoader): void;\n\n /**\n * Translate a key.\n *\n * @param key - Format: 'namespace:key.subkey' or just 'key' for default namespace\n * @param params - Interpolation parameters\n * @returns Translated string\n */\n t(key: string, params?: TranslationParams): string;\n\n /**\n * Set current language and load translations.\n * Updates HTML lang and dir attributes.\n *\n * @param language - Language to set\n */\n setLanguage(language: Language): Promise<void>;\n\n /**\n * Get current language.\n *\n * @returns Current language or null if not set\n */\n getLanguage(): Language | null;\n\n /**\n * Get language metadata.\n *\n * @param code - Optional language code (defaults to current)\n * @returns Language metadata\n */\n getLanguageMetadata(code?: Language): LanguageMetadata | undefined;\n\n /**\n * Get all supported languages.\n *\n * @returns Array of language metadata\n */\n getSupportedLanguages(): LanguageMetadata[];\n\n /**\n * Check if current language is RTL.\n *\n * @param code - Optional language code (defaults to current)\n * @returns True if RTL\n */\n isRTL(code?: Language): boolean;\n\n /**\n * Check if namespace is registered.\n *\n * @param namespace - Namespace to check\n * @returns True if registered\n */\n hasNamespace(namespace: string): boolean;\n\n /**\n * Get all registered namespaces.\n *\n * @returns Array of namespace identifiers\n */\n getNamespaces(): string[];\n\n /**\n * Load translations for a specific language.\n *\n * @param language - Language to load\n */\n loadLanguage(language: Language): Promise<void>;\n\n /**\n * Load translations for a specific screenset.\n *\n * @param screensetId - Screenset ID\n * @param language - Optional language (defaults to current)\n */\n loadScreensetTranslations(screensetId: string, language?: Language): Promise<void>;\n\n /**\n * Preload translations for multiple languages.\n *\n * @param languages - Languages to preload\n */\n preloadLanguages(languages: Language[]): Promise<void>;\n\n /**\n * Subscribe to translation changes.\n * Called when new translations are registered.\n *\n * @param callback - Function to call on changes\n * @returns Unsubscribe function\n */\n subscribe(callback: () => void): () => void;\n\n /**\n * Get the current version number.\n * Increments when translations change. Used by React for re-rendering.\n *\n * @returns Current version number\n */\n getVersion(): number;\n}\n\n// ============================================================================\n// Display Mode\n// ============================================================================\n\n/**\n * Language Display Mode\n * How to display language names in the UI.\n */\nexport enum LanguageDisplayMode {\n /** Show native name (e.g., 'Español') */\n Native = 'native',\n /** Show English name (e.g., 'Spanish') */\n English = 'english',\n}\n\n// ============================================================================\n// Constants\n// ============================================================================\n\n/**\n * I18n namespace separator constant.\n * Used to separate namespace from key: 'namespace:key'\n */\nexport const I18N_NAMESPACE_SEPARATOR = ':';\n\n/**\n * I18n path separator constant.\n * Used to separate nested keys: 'key.subkey'\n */\nexport const I18N_PATH_SEPARATOR = '.';\n\n/**\n * Default namespace for translations without explicit namespace.\n */\nexport const I18N_DEFAULT_NAMESPACE = 'app';\n\n/**\n * HTML lang attribute name.\n */\nexport const HTML_LANG_ATTRIBUTE = 'lang';\n\n/**\n * HTML dir attribute name.\n */\nexport const HTML_DIR_ATTRIBUTE = 'dir';\n","/**\n * Supported Languages - All 36 FrontX supported languages\n *\n * Based on major platforms (Google, Facebook, Microsoft, Apple).\n * Includes native names, English names, and text direction.\n */\n// @cpt-dod:cpt-frontx-dod-i18n-infrastructure-language-support:p1\n\nimport { Language, TextDirection } from './types';\nimport type { LanguageMetadata } from './types';\n\n/**\n * All supported languages with metadata.\n * This list defines what languages the application can use.\n */\n// @cpt-begin:cpt-frontx-dod-i18n-infrastructure-language-support:p1:inst-array-western\nexport const SUPPORTED_LANGUAGES: LanguageMetadata[] = [\n // Western European\n {\n code: Language.English,\n name: 'English',\n englishName: 'English',\n direction: TextDirection.LeftToRight,\n },\n {\n code: Language.Spanish,\n name: 'Español',\n englishName: 'Spanish',\n direction: TextDirection.LeftToRight,\n },\n {\n code: Language.French,\n name: 'Français',\n englishName: 'French',\n direction: TextDirection.LeftToRight,\n },\n {\n code: Language.German,\n name: 'Deutsch',\n englishName: 'German',\n direction: TextDirection.LeftToRight,\n },\n {\n code: Language.Italian,\n name: 'Italiano',\n englishName: 'Italian',\n direction: TextDirection.LeftToRight,\n },\n {\n code: Language.Portuguese,\n name: 'Português',\n englishName: 'Portuguese',\n direction: TextDirection.LeftToRight,\n },\n {\n code: Language.Dutch,\n name: 'Nederlands',\n englishName: 'Dutch',\n direction: TextDirection.LeftToRight,\n },\n// @cpt-end:cpt-frontx-dod-i18n-infrastructure-language-support:p1:inst-array-western\n\n // Eastern European\n// @cpt-begin:cpt-frontx-dod-i18n-infrastructure-language-support:p1:inst-array-eastern\n {\n code: Language.Russian,\n name: 'Русский',\n englishName: 'Russian',\n direction: TextDirection.LeftToRight,\n },\n {\n code: Language.Polish,\n name: 'Polski',\n englishName: 'Polish',\n direction: TextDirection.LeftToRight,\n },\n {\n code: Language.Ukrainian,\n name: 'Українська',\n englishName: 'Ukrainian',\n direction: TextDirection.LeftToRight,\n },\n {\n code: Language.Czech,\n name: 'Čeština',\n englishName: 'Czech',\n direction: TextDirection.LeftToRight,\n },\n// @cpt-end:cpt-frontx-dod-i18n-infrastructure-language-support:p1:inst-array-eastern\n\n // Middle East & North Africa (RTL)\n// @cpt-begin:cpt-frontx-dod-i18n-infrastructure-language-support:p1:inst-array-mena\n {\n code: Language.Arabic,\n name: 'العربية',\n englishName: 'Arabic',\n direction: TextDirection.RightToLeft,\n },\n {\n code: Language.Hebrew,\n name: 'עברית',\n englishName: 'Hebrew',\n direction: TextDirection.RightToLeft,\n },\n {\n code: Language.Persian,\n name: 'فارسی',\n englishName: 'Persian',\n direction: TextDirection.RightToLeft,\n },\n {\n code: Language.Urdu,\n name: 'اردو',\n englishName: 'Urdu',\n direction: TextDirection.RightToLeft,\n },\n {\n code: Language.Turkish,\n name: 'Türkçe',\n englishName: 'Turkish',\n direction: TextDirection.LeftToRight,\n },\n// @cpt-end:cpt-frontx-dod-i18n-infrastructure-language-support:p1:inst-array-mena\n\n // Asian\n// @cpt-begin:cpt-frontx-dod-i18n-infrastructure-language-support:p1:inst-array-asian\n {\n code: Language.ChineseSimplified,\n name: '简体中文',\n englishName: 'Chinese (Simplified)',\n direction: TextDirection.LeftToRight,\n },\n {\n code: Language.ChineseTraditional,\n name: '繁體中文',\n englishName: 'Chinese (Traditional)',\n direction: TextDirection.LeftToRight,\n region: 'TW',\n },\n {\n code: Language.Japanese,\n name: '日本語',\n englishName: 'Japanese',\n direction: TextDirection.LeftToRight,\n },\n {\n code: Language.Korean,\n name: '한국어',\n englishName: 'Korean',\n direction: TextDirection.LeftToRight,\n },\n {\n code: Language.Vietnamese,\n name: 'Tiếng Việt',\n englishName: 'Vietnamese',\n direction: TextDirection.LeftToRight,\n },\n {\n code: Language.Thai,\n name: 'ไทย',\n englishName: 'Thai',\n direction: TextDirection.LeftToRight,\n },\n {\n code: Language.Indonesian,\n name: 'Bahasa Indonesia',\n englishName: 'Indonesian',\n direction: TextDirection.LeftToRight,\n },\n {\n code: Language.Hindi,\n name: 'हिन्दी',\n englishName: 'Hindi',\n direction: TextDirection.LeftToRight,\n },\n {\n code: Language.Bengali,\n name: 'বাংলা',\n englishName: 'Bengali',\n direction: TextDirection.LeftToRight,\n },\n// @cpt-end:cpt-frontx-dod-i18n-infrastructure-language-support:p1:inst-array-asian\n\n // Nordic\n// @cpt-begin:cpt-frontx-dod-i18n-infrastructure-language-support:p1:inst-array-nordic\n {\n code: Language.Swedish,\n name: 'Svenska',\n englishName: 'Swedish',\n direction: TextDirection.LeftToRight,\n },\n {\n code: Language.Danish,\n name: 'Dansk',\n englishName: 'Danish',\n direction: TextDirection.LeftToRight,\n },\n {\n code: Language.Norwegian,\n name: 'Norsk',\n englishName: 'Norwegian',\n direction: TextDirection.LeftToRight,\n },\n {\n code: Language.Finnish,\n name: 'Suomi',\n englishName: 'Finnish',\n direction: TextDirection.LeftToRight,\n },\n// @cpt-end:cpt-frontx-dod-i18n-infrastructure-language-support:p1:inst-array-nordic\n\n // Other\n// @cpt-begin:cpt-frontx-dod-i18n-infrastructure-language-support:p1:inst-array-remaining\n {\n code: Language.Greek,\n name: 'Ελληνικά',\n englishName: 'Greek',\n direction: TextDirection.LeftToRight,\n },\n {\n code: Language.Romanian,\n name: 'Română',\n englishName: 'Romanian',\n direction: TextDirection.LeftToRight,\n },\n {\n code: Language.Hungarian,\n name: 'Magyar',\n englishName: 'Hungarian',\n direction: TextDirection.LeftToRight,\n },\n\n // Additional major languages\n {\n code: Language.Malay,\n name: 'Bahasa Melayu',\n englishName: 'Malay',\n direction: TextDirection.LeftToRight,\n },\n {\n code: Language.Tagalog,\n name: 'Tagalog',\n englishName: 'Tagalog',\n direction: TextDirection.LeftToRight,\n },\n {\n code: Language.Tamil,\n name: 'தமிழ்',\n englishName: 'Tamil',\n direction: TextDirection.LeftToRight,\n },\n {\n code: Language.Swahili,\n name: 'Kiswahili',\n englishName: 'Swahili',\n direction: TextDirection.LeftToRight,\n },\n];\n// @cpt-end:cpt-frontx-dod-i18n-infrastructure-language-support:p1:inst-array-remaining\n\n/**\n * Get language metadata by code.\n *\n * @param code - Language code\n * @returns Language metadata or undefined\n */\nexport function getLanguageMetadata(code: Language): LanguageMetadata | undefined {\n return SUPPORTED_LANGUAGES.find((lang) => lang.code === code);\n}\n\n// @cpt-begin:cpt-frontx-dod-i18n-infrastructure-language-support:p1:inst-2\n/**\n * Get RTL language codes.\n *\n * @returns Array of RTL language codes\n */\nexport function getRTLLanguages(): Language[] {\n return SUPPORTED_LANGUAGES\n .filter((lang) => lang.direction === TextDirection.RightToLeft)\n .map((lang) => lang.code);\n}\n// @cpt-end:cpt-frontx-dod-i18n-infrastructure-language-support:p1:inst-2\n\n/**\n * Check if a language code is valid.\n *\n * @param code - Language code to check\n * @returns True if valid\n */\nexport function isValidLanguage(code: string): code is Language {\n return SUPPORTED_LANGUAGES.some((lang) => lang.code === code);\n}\n","/**\n * I18n Registry - Central translation management\n *\n * Implements namespace-based translation loading with:\n * - Lazy loading for screenset/screen translations\n * - RTL/LTR support\n * - Parameter interpolation\n *\n * SDK Layer: L1 (Zero @gears-frontx dependencies)\n */\n// @cpt-flow:cpt-frontx-flow-i18n-infrastructure-language-activation:p1\n// @cpt-flow:cpt-frontx-flow-i18n-infrastructure-screenset-registration:p1\n// @cpt-flow:cpt-frontx-flow-i18n-infrastructure-screen-lazy-load:p1\n// @cpt-flow:cpt-frontx-flow-i18n-infrastructure-key-resolution:p1\n// @cpt-algo:cpt-frontx-algo-i18n-infrastructure-language-file-map:p1\n// @cpt-algo:cpt-frontx-algo-i18n-infrastructure-create-loader:p1\n// @cpt-algo:cpt-frontx-algo-i18n-infrastructure-lazy-exclusion:p1\n// @cpt-algo:cpt-frontx-algo-i18n-infrastructure-html-attrs:p1\n// @cpt-algo:cpt-frontx-algo-i18n-infrastructure-path-traversal:p1\n// @cpt-state:cpt-frontx-state-i18n-infrastructure-registry:p1\n// @cpt-state:cpt-frontx-state-i18n-infrastructure-namespace-cache:p1\n// @cpt-dod:cpt-frontx-dod-i18n-infrastructure-hybrid-namespace:p1\n// @cpt-dod:cpt-frontx-dod-i18n-infrastructure-lazy-chunks:p1\n\nimport type {\n I18nRegistry as II18nRegistry,\n I18nConfig,\n TranslationDictionary,\n TranslationLoader,\n TranslationParams,\n TranslationMap,\n LanguageMetadata,\n} from './types';\n\nimport {\n Language,\n TextDirection,\n I18N_NAMESPACE_SEPARATOR,\n I18N_PATH_SEPARATOR,\n I18N_DEFAULT_NAMESPACE,\n HTML_LANG_ATTRIBUTE,\n HTML_DIR_ATTRIBUTE,\n} from './types';\n\nimport { SUPPORTED_LANGUAGES } from './languages';\n\n// ============================================================================\n// I18n Registry Implementation\n// ============================================================================\n\n/**\n * I18n Registry Implementation\n *\n * Central registry for managing translations across the application.\n * Supports lazy loading, namespace isolation, and RTL languages.\n */\nexport class I18nRegistryImpl implements II18nRegistry {\n /** Configuration */\n private config: I18nConfig;\n\n /** Current language */\n private currentLanguage: Language | null = null;\n\n /** Translation dictionaries: namespace -> language -> dictionary */\n private dictionaries: Map<string, Map<Language, TranslationDictionary>> = new Map();\n\n /** Translation loaders: namespace -> loader function */\n private loaders: Map<string, TranslationLoader> = new Map();\n\n /** Subscribers for translation changes */\n private subscribers: Set<() => void> = new Set();\n\n /** Version counter for React re-rendering */\n private version: number = 0;\n\n // @cpt-begin:cpt-frontx-algo-i18n-infrastructure-language-file-map:p1:inst-1\n /** Language file mapping */\n static readonly LANGUAGE_FILE_MAP: Record<Language, string> = {\n [Language.English]: 'en.json',\n [Language.Spanish]: 'es.json',\n [Language.French]: 'fr.json',\n [Language.German]: 'de.json',\n [Language.Italian]: 'it.json',\n [Language.Portuguese]: 'pt.json',\n [Language.Dutch]: 'nl.json',\n [Language.Russian]: 'ru.json',\n [Language.Polish]: 'pl.json',\n [Language.Ukrainian]: 'uk.json',\n [Language.Czech]: 'cs.json',\n [Language.Arabic]: 'ar.json',\n [Language.Hebrew]: 'he.json',\n [Language.Persian]: 'fa.json',\n [Language.Urdu]: 'ur.json',\n [Language.Turkish]: 'tr.json',\n [Language.ChineseSimplified]: 'zh.json',\n [Language.ChineseTraditional]: 'zh-TW.json',\n [Language.Japanese]: 'ja.json',\n [Language.Korean]: 'ko.json',\n [Language.Vietnamese]: 'vi.json',\n [Language.Thai]: 'th.json',\n [Language.Indonesian]: 'id.json',\n [Language.Hindi]: 'hi.json',\n [Language.Bengali]: 'bn.json',\n [Language.Swedish]: 'sv.json',\n [Language.Danish]: 'da.json',\n [Language.Norwegian]: 'no.json',\n [Language.Finnish]: 'fi.json',\n [Language.Greek]: 'el.json',\n [Language.Romanian]: 'ro.json',\n [Language.Hungarian]: 'hu.json',\n [Language.Malay]: 'ms.json',\n [Language.Tagalog]: 'tl.json',\n [Language.Tamil]: 'ta.json',\n [Language.Swahili]: 'sw.json',\n };\n // @cpt-end:cpt-frontx-algo-i18n-infrastructure-language-file-map:p1:inst-1\n\n constructor(config: I18nConfig) {\n this.config = config;\n }\n\n // ============================================================================\n // Registration\n // ============================================================================\n\n // @cpt-begin:cpt-frontx-state-i18n-infrastructure-namespace-cache:p1:inst-1\n /**\n * Register translations for a namespace.\n */\n register(namespace: string, language: Language, translations: TranslationDictionary): void {\n if (!this.dictionaries.has(namespace)) {\n this.dictionaries.set(namespace, new Map());\n }\n this.dictionaries.get(namespace)!.set(language, translations);\n this.notifySubscribers();\n }\n // @cpt-end:cpt-frontx-state-i18n-infrastructure-namespace-cache:p1:inst-1\n\n /**\n * Subscribe to translation changes.\n * Returns an unsubscribe function.\n */\n subscribe(callback: () => void): () => void {\n this.subscribers.add(callback);\n return () => {\n this.subscribers.delete(callback);\n };\n }\n\n /**\n * Notify all subscribers of a change.\n */\n private notifySubscribers(): void {\n this.version++;\n this.subscribers.forEach((callback) => {\n callback();\n });\n }\n\n /**\n * Get the current version number.\n * Used by React to detect changes.\n */\n getVersion(): number {\n return this.version;\n }\n\n // @cpt-begin:cpt-frontx-flow-i18n-infrastructure-screenset-registration:p1:inst-1\n // @cpt-begin:cpt-frontx-flow-i18n-infrastructure-screen-lazy-load:p1:inst-1\n /**\n * Register a translation loader for a namespace.\n */\n registerLoader(namespace: string, loader: TranslationLoader): void {\n this.loaders.set(namespace, loader);\n }\n // @cpt-end:cpt-frontx-flow-i18n-infrastructure-screenset-registration:p1:inst-1\n // @cpt-end:cpt-frontx-flow-i18n-infrastructure-screen-lazy-load:p1:inst-1\n\n /**\n * Check if namespace is registered.\n */\n hasNamespace(namespace: string): boolean {\n return this.dictionaries.has(namespace) || this.loaders.has(namespace);\n }\n\n /**\n * Get all registered namespaces.\n */\n getNamespaces(): string[] {\n const namespaces = new Set<string>();\n this.dictionaries.forEach((_, key) => namespaces.add(key));\n this.loaders.forEach((_, key) => namespaces.add(key));\n return Array.from(namespaces);\n }\n\n // ============================================================================\n // Translation\n // ============================================================================\n\n // @cpt-begin:cpt-frontx-flow-i18n-infrastructure-key-resolution:p1:inst-1\n /**\n * Translate a key.\n * Format: 'namespace:key.subkey' or just 'key' for default namespace\n */\n t(key: string, params?: TranslationParams): string {\n // Parse namespace and path\n const { namespace, path } = this.parseKey(key);\n\n // Get translation from dictionary\n const translation = this.getTranslation(namespace, path);\n\n // Return key if no translation found\n if (translation === undefined) {\n return key;\n }\n\n // Interpolate parameters\n return this.interpolate(translation, params);\n }\n // @cpt-end:cpt-frontx-flow-i18n-infrastructure-key-resolution:p1:inst-1\n\n // @cpt-begin:cpt-frontx-flow-i18n-infrastructure-key-resolution:p1:inst-2\n /**\n * Parse a translation key into namespace and path.\n */\n private parseKey(key: string): { namespace: string; path: string } {\n const separatorIndex = key.indexOf(I18N_NAMESPACE_SEPARATOR);\n\n if (separatorIndex === -1) {\n return {\n namespace: I18N_DEFAULT_NAMESPACE,\n path: key,\n };\n }\n\n return {\n namespace: key.slice(0, separatorIndex),\n path: key.slice(separatorIndex + 1),\n };\n }\n // @cpt-end:cpt-frontx-flow-i18n-infrastructure-key-resolution:p1:inst-2\n\n // @cpt-begin:cpt-frontx-flow-i18n-infrastructure-key-resolution:p1:inst-3\n /**\n * Get a translation from the dictionary.\n */\n private getTranslation(namespace: string, path: string): string | undefined {\n const language = this.currentLanguage ?? this.config.defaultLanguage;\n const fallback = this.config.fallbackLanguage;\n\n // Try current language first\n let translation = this.findTranslation(namespace, language, path);\n if (translation !== undefined) {\n return translation;\n }\n\n // Try fallback language\n if (language !== fallback) {\n translation = this.findTranslation(namespace, fallback, path);\n if (translation !== undefined) {\n return translation;\n }\n }\n\n return undefined;\n }\n // @cpt-end:cpt-frontx-flow-i18n-infrastructure-key-resolution:p1:inst-3\n\n // @cpt-begin:cpt-frontx-flow-i18n-infrastructure-key-resolution:p1:inst-4\n // @cpt-begin:cpt-frontx-algo-i18n-infrastructure-path-traversal:p1:inst-1\n /**\n * Find a translation in the dictionary.\n */\n private findTranslation(\n namespace: string,\n language: Language,\n path: string\n ): string | undefined {\n const namespaceDicts = this.dictionaries.get(namespace);\n if (!namespaceDicts) {\n return undefined;\n }\n\n const dict = namespaceDicts.get(language);\n if (!dict) {\n return undefined;\n }\n\n // Navigate nested path\n const parts = path.split(I18N_PATH_SEPARATOR);\n let current: TranslationDictionary | string = dict;\n\n for (const part of parts) {\n if (typeof current !== 'object' || current === null) {\n return undefined;\n }\n current = current[part] as TranslationDictionary | string;\n if (current === undefined) {\n return undefined;\n }\n }\n\n return typeof current === 'string' ? current : undefined;\n }\n // @cpt-end:cpt-frontx-flow-i18n-infrastructure-key-resolution:p1:inst-4\n // @cpt-end:cpt-frontx-algo-i18n-infrastructure-path-traversal:p1:inst-1\n\n // @cpt-begin:cpt-frontx-flow-i18n-infrastructure-key-resolution:p1:inst-5\n /**\n * Interpolate parameters into a translation string.\n */\n private interpolate(text: string, params?: TranslationParams): string {\n if (!params) {\n return text;\n }\n\n return text.replace(/\\{(\\w+)\\}/g, (match, key) => {\n const value = params[key];\n return value !== undefined ? String(value) : match;\n });\n }\n // @cpt-end:cpt-frontx-flow-i18n-infrastructure-key-resolution:p1:inst-5\n\n // ============================================================================\n // Language Management\n // ============================================================================\n\n // @cpt-begin:cpt-frontx-flow-i18n-infrastructure-language-activation:p1:inst-1\n // @cpt-begin:cpt-frontx-state-i18n-infrastructure-registry:p1:inst-1\n /**\n * Set current language and load translations.\n */\n async setLanguage(language: Language): Promise<void> {\n this.currentLanguage = language;\n\n // Update HTML attributes\n this.updateHtmlAttributes(language);\n\n // Load translations for the language\n await this.loadLanguage(language);\n }\n // @cpt-end:cpt-frontx-flow-i18n-infrastructure-language-activation:p1:inst-1\n // @cpt-end:cpt-frontx-state-i18n-infrastructure-registry:p1:inst-1\n\n /**\n * Get current language.\n */\n getLanguage(): Language | null {\n return this.currentLanguage;\n }\n\n // @cpt-begin:cpt-frontx-algo-i18n-infrastructure-html-attrs:p1:inst-1\n /**\n * Update HTML lang and dir attributes.\n */\n private updateHtmlAttributes(language: Language): void {\n if (typeof document === 'undefined') {\n return; // Skip in SSR/Node.js environment\n }\n\n const htmlElement = document.documentElement;\n htmlElement.setAttribute(HTML_LANG_ATTRIBUTE, language);\n htmlElement.setAttribute(\n HTML_DIR_ATTRIBUTE,\n this.isRTL(language) ? TextDirection.RightToLeft : TextDirection.LeftToRight\n );\n }\n // @cpt-end:cpt-frontx-algo-i18n-infrastructure-html-attrs:p1:inst-1\n\n // ============================================================================\n // Language Metadata\n // ============================================================================\n\n /**\n * Get language metadata.\n */\n getLanguageMetadata(code?: Language): LanguageMetadata | undefined {\n const targetCode = code ?? this.currentLanguage;\n if (!targetCode) {\n return undefined;\n }\n return SUPPORTED_LANGUAGES.find((lang) => lang.code === targetCode);\n }\n\n /**\n * Get all supported languages.\n */\n getSupportedLanguages(): LanguageMetadata[] {\n return [...SUPPORTED_LANGUAGES];\n }\n\n /**\n * Check if a language is RTL.\n */\n isRTL(code?: Language): boolean {\n const targetCode = code ?? this.currentLanguage;\n if (!targetCode) {\n return false;\n }\n const metadata = this.getLanguageMetadata(targetCode);\n return metadata?.direction === TextDirection.RightToLeft;\n }\n\n // ============================================================================\n // Translation Loading\n // ============================================================================\n\n // @cpt-begin:cpt-frontx-algo-i18n-infrastructure-lazy-exclusion:p1:inst-1\n // @cpt-begin:cpt-frontx-flow-i18n-infrastructure-language-activation:p1:inst-2\n /**\n * Load translations for a language.\n * Excludes screen.* and screenset.* namespaces which are lazy-loaded:\n * - screen.* namespaces: loaded when screen mounts\n * - screenset.* namespaces: loaded when screenset is activated\n */\n async loadLanguage(language: Language): Promise<void> {\n const loadPromises: Promise<void>[] = [];\n\n this.loaders.forEach((_loader, namespace) => {\n // Skip screen and screenset namespaces (lazy-loaded on demand)\n if (namespace.startsWith('screen.') || namespace.startsWith('screenset.')) {\n return;\n }\n loadPromises.push(this.loadNamespace(namespace, language));\n });\n\n await Promise.all(loadPromises);\n }\n // @cpt-end:cpt-frontx-algo-i18n-infrastructure-lazy-exclusion:p1:inst-1\n // @cpt-end:cpt-frontx-flow-i18n-infrastructure-language-activation:p1:inst-2\n\n // @cpt-begin:cpt-frontx-flow-i18n-infrastructure-screen-lazy-load:p1:inst-2\n /**\n * Load translations for a specific namespace.\n */\n private async loadNamespace(namespace: string, language: Language): Promise<void> {\n const loader = this.loaders.get(namespace);\n if (!loader) {\n return;\n }\n\n try {\n const translations = await loader(language);\n this.register(namespace, language, translations);\n } catch (error) {\n console.warn(`Failed to load translations for ${namespace}/${language}:`, error);\n }\n }\n // @cpt-end:cpt-frontx-flow-i18n-infrastructure-screen-lazy-load:p1:inst-2\n\n // @cpt-begin:cpt-frontx-flow-i18n-infrastructure-screenset-registration:p1:inst-2\n /**\n * Load translations for a specific screenset.\n */\n async loadScreensetTranslations(screensetId: string, language?: Language): Promise<void> {\n const targetLanguage = language ?? this.currentLanguage ?? this.config.defaultLanguage;\n const namespace = `screenset.${screensetId}`;\n\n await this.loadNamespace(namespace, targetLanguage);\n }\n // @cpt-end:cpt-frontx-flow-i18n-infrastructure-screenset-registration:p1:inst-2\n\n /**\n * Preload translations for multiple languages.\n */\n async preloadLanguages(languages: Language[]): Promise<void> {\n const loadPromises = languages.map((language) => this.loadLanguage(language));\n await Promise.all(loadPromises);\n }\n\n // ============================================================================\n // Static Helpers\n // ============================================================================\n\n /**\n * Create a translation loader from a translation map.\n *\n * @example\n * ```typescript\n * const loader = I18nRegistry.createLoader({\n * [Language.English]: () => import('./i18n/en.json'),\n * [Language.Spanish]: () => import('./i18n/es.json'),\n * });\n * ```\n */\n // @cpt-begin:cpt-frontx-algo-i18n-infrastructure-create-loader:p1:inst-1\n // @cpt-begin:cpt-frontx-dod-i18n-infrastructure-lazy-chunks:p1:inst-1\n static createLoader(translationMap: TranslationMap): TranslationLoader {\n return async (language: Language | string): Promise<TranslationDictionary> => {\n const importFn = translationMap[language as Language];\n if (!importFn) {\n throw new Error(`No translation found for language: ${language}`);\n }\n const module = await importFn();\n return module.default;\n };\n }\n // @cpt-end:cpt-frontx-algo-i18n-infrastructure-create-loader:p1:inst-1\n // @cpt-end:cpt-frontx-dod-i18n-infrastructure-lazy-chunks:p1:inst-1\n\n /**\n * Create a translation loader from a directory.\n * Maps Language enum values to file names automatically.\n *\n * @param basePath - Base path for translation files\n * @param importFn - Dynamic import function\n */\n static createLoaderFromDirectory(\n importFn: (filename: string) => Promise<{ default: TranslationDictionary }>\n ): TranslationLoader {\n return async (language: Language | string): Promise<TranslationDictionary> => {\n const filename = I18nRegistryImpl.LANGUAGE_FILE_MAP[language as Language];\n const module = await importFn(filename);\n return module.default;\n };\n }\n}\n\n// ============================================================================\n// Singleton Instance\n// ============================================================================\n\n// @cpt-begin:cpt-frontx-state-i18n-infrastructure-registry:p1:inst-2\n// @cpt-begin:cpt-frontx-dod-i18n-infrastructure-language-support:p1:inst-1\n/**\n * Default i18n registry instance.\n * Use this instance throughout the application.\n */\nexport const i18nRegistry = new I18nRegistryImpl({\n defaultLanguage: Language.English,\n fallbackLanguage: Language.English,\n});\n// @cpt-end:cpt-frontx-state-i18n-infrastructure-registry:p1:inst-2\n// @cpt-end:cpt-frontx-dod-i18n-infrastructure-language-support:p1:inst-1\n\n/**\n * Create a new i18n registry with custom configuration.\n *\n * @param config - I18n configuration\n * @returns New I18nRegistry instance\n */\nexport function createI18nRegistry(config: I18nConfig): I18nRegistryImpl {\n return new I18nRegistryImpl(config);\n}\n","/**\n * Shared formatter utilities - locale and value coercion used by formatters.\n */\n// @cpt-algo:cpt-frontx-algo-i18n-infrastructure-locale-resolution:p1\n// @cpt-algo:cpt-frontx-algo-i18n-infrastructure-formatter-input-guard:p2\n// @cpt-dod:cpt-frontx-dod-i18n-infrastructure-formatters:p1\n\nimport { i18nRegistry } from '../I18nRegistry';\nimport { Language } from '../types';\n\n// @cpt-begin:cpt-frontx-algo-i18n-infrastructure-locale-resolution:p1:inst-1\nexport function getLocale(): string {\n return i18nRegistry.getLanguage() ?? Language.English;\n}\n// @cpt-end:cpt-frontx-algo-i18n-infrastructure-locale-resolution:p1:inst-1\n\n// @cpt-begin:cpt-frontx-algo-i18n-infrastructure-formatter-input-guard:p2:inst-1\nexport function toNumber(value: number | null | undefined): number | null {\n if (value === null || value === undefined) return null;\n const n = Number(value);\n return Number.isNaN(n) ? null : n;\n}\n// @cpt-end:cpt-frontx-algo-i18n-infrastructure-formatter-input-guard:p2:inst-1\n","/**\n * Date formatter - Locale-aware date and time formatting\n *\n * Uses i18nRegistry.getLanguage() for locale; fallback to Language.English when null.\n * Invalid date inputs return ''.\n */\n// @cpt-flow:cpt-frontx-flow-i18n-infrastructure-formatter-usage:p1\n// @cpt-dod:cpt-frontx-dod-i18n-infrastructure-formatters:p1\n\nimport { getLocale } from './utils';\n\nexport type DateFormatStyle = 'short' | 'medium' | 'long' | 'full';\nexport type TimeFormatStyle = 'short' | 'medium';\n\nexport type DateInput = Date | number | string | null | undefined;\n\nfunction toDate(value: DateInput): Date | null {\n if (value === null || value === undefined) return null;\n const d = new Date(value);\n return Number.isNaN(d.getTime()) ? null : d;\n}\n\n// @cpt-begin:cpt-frontx-flow-i18n-infrastructure-formatter-usage:p1:inst-1\n// @cpt-begin:cpt-frontx-dod-i18n-infrastructure-formatters:p1:inst-1\n/**\n * Format a date according to the current locale.\n *\n * @param date - Date, timestamp, or ISO string\n * @param format - 'short' | 'medium' | 'long' | 'full'\n * @returns Formatted date string, or '' if input is invalid\n */\nexport function formatDate(date: DateInput, format: DateFormatStyle): string {\n const d = toDate(date);\n if (!d) return '';\n const locale = getLocale();\n return new Intl.DateTimeFormat(locale, { dateStyle: format }).format(d);\n}\n// @cpt-end:cpt-frontx-flow-i18n-infrastructure-formatter-usage:p1:inst-1\n// @cpt-end:cpt-frontx-dod-i18n-infrastructure-formatters:p1:inst-1\n\n// @cpt-begin:cpt-frontx-dod-i18n-infrastructure-formatters:p1:inst-2\n/**\n * Format the time portion of a date according to the current locale.\n *\n * @param date - Date, timestamp, or ISO string\n * @param format - 'short' | 'medium'\n * @returns Formatted time string, or '' if input is invalid\n */\nexport function formatTime(date: DateInput, format: TimeFormatStyle): string {\n const d = toDate(date);\n if (!d) return '';\n const locale = getLocale();\n return new Intl.DateTimeFormat(locale, { timeStyle: format }).format(d);\n}\n// @cpt-end:cpt-frontx-dod-i18n-infrastructure-formatters:p1:inst-2\n\n// @cpt-begin:cpt-frontx-dod-i18n-infrastructure-formatters:p1:inst-3\n/**\n * Format date and time according to the current locale.\n *\n * @param date - Date, timestamp, or ISO string\n * @param dateFormat - Date style: 'short' | 'medium' | 'long' | 'full'\n * @param timeFormat - Time style: 'short' | 'medium'\n * @returns Formatted date-time string, or '' if input is invalid\n */\nexport function formatDateTime(\n date: DateInput,\n dateFormat: DateFormatStyle,\n timeFormat: TimeFormatStyle\n): string {\n const d = toDate(date);\n if (!d) return '';\n const locale = getLocale();\n return new Intl.DateTimeFormat(locale, {\n dateStyle: dateFormat,\n timeStyle: timeFormat,\n }).format(d);\n}\n// @cpt-end:cpt-frontx-dod-i18n-infrastructure-formatters:p1:inst-3\n\nconst MS_PER_SECOND = 1000;\nconst MS_PER_MINUTE = 60 * MS_PER_SECOND;\nconst MS_PER_HOUR = 60 * MS_PER_MINUTE;\nconst MS_PER_DAY = 24 * MS_PER_HOUR;\n\n/**\n * Picks relative-time unit and value using calendar-aware boundaries for day/month/year\n * (no 30d/365d approximations), and exact second/minute/hour for sub-day deltas.\n */\nfunction getRelativeUnit(\n date: Date,\n base: Date\n): { value: number; unit: Intl.RelativeTimeFormatUnit } {\n const diffMs = date.getTime() - base.getTime();\n const absMs = Math.abs(diffMs);\n const sign = diffMs < 0 ? -1 : 1;\n\n if (absMs < 60 * MS_PER_SECOND) {\n const value = Math.round(diffMs / MS_PER_SECOND);\n return { value: value === 0 ? 0 : value, unit: 'second' };\n }\n if (absMs < 60 * MS_PER_MINUTE) {\n return { value: sign * Math.round(absMs / MS_PER_MINUTE), unit: 'minute' };\n }\n if (absMs < MS_PER_DAY) {\n return { value: sign * Math.round(absMs / MS_PER_HOUR), unit: 'hour' };\n }\n\n const baseY = base.getUTCFullYear();\n const baseM = base.getUTCMonth();\n const baseD = base.getUTCDate();\n const dateY = date.getUTCFullYear();\n const dateM = date.getUTCMonth();\n const dateD = date.getUTCDate();\n\n const totalMonths = (dateY - baseY) * 12 + (dateM - baseM);\n const baseUTC = Date.UTC(baseY, baseM, baseD);\n const dateUTC = Date.UTC(dateY, dateM, dateD);\n const diffDays = Math.round((dateUTC - baseUTC) / MS_PER_DAY);\n\n if (Math.abs(totalMonths) >= 12) {\n const value = Math.round(totalMonths / 12);\n return { value, unit: 'year' };\n }\n if (Math.abs(totalMonths) >= 1) {\n return { value: totalMonths, unit: 'month' };\n }\n return { value: diffDays === 0 ? sign * 1 : diffDays, unit: 'day' };\n}\n\n// @cpt-begin:cpt-frontx-dod-i18n-infrastructure-formatters:p1:inst-4\n/**\n * Format a date as relative time (e.g. \"2 hours ago\", \"in 3 days\").\n *\n * @param date - Date, timestamp, or ISO string\n * @param base - Reference date for \"now\"; defaults to new Date()\n * @returns Relative time string, or '' if input is invalid\n */\nexport function formatRelative(date: DateInput, base?: DateInput): string {\n const d = toDate(date);\n if (!d) return '';\n const baseDate = base !== undefined ? toDate(base) : new Date();\n if (!baseDate) return '';\n const locale = getLocale();\n const rtf = new Intl.RelativeTimeFormat(locale, { numeric: 'auto' });\n const { value, unit } = getRelativeUnit(d, baseDate);\n return rtf.format(value, unit);\n}\n// @cpt-end:cpt-frontx-dod-i18n-infrastructure-formatters:p1:inst-4\n","/**\n * Number formatter - Locale-aware number formatting\n *\n * Uses i18nRegistry.getLanguage() for locale; fallback to Language.English when null.\n * null, undefined, and NaN return ''.\n */\n// @cpt-dod:cpt-frontx-dod-i18n-infrastructure-formatters:p1\n\nimport { getLocale, toNumber } from './utils';\n\n// @cpt-begin:cpt-frontx-dod-i18n-infrastructure-formatters:p1:inst-5\n/**\n * Format a number according to the current locale.\n *\n * @param value - Number to format\n * @param options - Intl.NumberFormatOptions (e.g. minimumFractionDigits)\n * @returns Formatted number string, or '' if input is null, undefined, or NaN\n */\nexport function formatNumber(\n value: number | null | undefined,\n options?: Intl.NumberFormatOptions\n): string {\n const n = toNumber(value);\n if (n === null) return '';\n const locale = getLocale();\n return new Intl.NumberFormat(locale, options).format(n);\n}\n// @cpt-end:cpt-frontx-dod-i18n-infrastructure-formatters:p1:inst-5\n\n// @cpt-begin:cpt-frontx-dod-i18n-infrastructure-formatters:p1:inst-6\n/**\n * Format a value as a percentage (0.15 -> \"15%\").\n *\n * @param value - Decimal value (e.g. 0.15 for 15%)\n * @param decimals - Optional decimal places\n * @returns Formatted percent string, or '' if input is null, undefined, or NaN\n */\nexport function formatPercent(\n value: number | null | undefined,\n decimals?: number\n): string {\n const n = toNumber(value);\n if (n === null) return '';\n const locale = getLocale();\n const opts: Intl.NumberFormatOptions = {\n style: 'percent',\n ...(decimals !== undefined && { minimumFractionDigits: decimals, maximumFractionDigits: decimals }),\n };\n return new Intl.NumberFormat(locale, opts).format(n);\n}\n// @cpt-end:cpt-frontx-dod-i18n-infrastructure-formatters:p1:inst-6\n\n// @cpt-begin:cpt-frontx-dod-i18n-infrastructure-formatters:p1:inst-7\n/**\n * Format a number in compact notation (e.g. \"1.2K\", \"3.4M\").\n *\n * @param value - Number to format\n * @returns Compact formatted string, or '' if input is null, undefined, or NaN\n */\nexport function formatCompact(value: number | null | undefined): string {\n const n = toNumber(value);\n if (n === null) return '';\n const locale = getLocale();\n return new Intl.NumberFormat(locale, { notation: 'compact' }).format(n);\n}\n// @cpt-end:cpt-frontx-dod-i18n-infrastructure-formatters:p1:inst-7\n","/**\n * Currency formatter - Locale-aware currency formatting\n *\n * Uses i18nRegistry.getLanguage() for locale; fallback to Language.English when null.\n * null, undefined, and NaN return ''; invalid currencyCode also returns '' and does not throw.\n */\n// @cpt-dod:cpt-frontx-dod-i18n-infrastructure-formatters:p1\n\nimport { getLocale, toNumber } from './utils';\n\n// @cpt-begin:cpt-frontx-dod-i18n-infrastructure-formatters:p1:inst-8\n/**\n * Format a value as currency for the given currency code.\n *\n * @param value - Numeric amount\n * @param currencyCode - ISO 4217 currency code (e.g. 'USD', 'EUR')\n * @returns Formatted currency string, or '' if value is null, undefined, NaN, or currencyCode is invalid\n */\nexport function formatCurrency(\n value: number | null | undefined,\n currencyCode: string\n): string {\n const n = toNumber(value);\n if (n === null) return '';\n if (!currencyCode || typeof currencyCode !== 'string') return '';\n const locale = getLocale();\n try {\n return new Intl.NumberFormat(locale, {\n style: 'currency',\n currency: currencyCode,\n }).format(n);\n } catch {\n return '';\n }\n}\n// @cpt-end:cpt-frontx-dod-i18n-infrastructure-formatters:p1:inst-8\n","/**\n * Sort utilities - Locale-aware string comparison\n *\n * Uses i18nRegistry.getLanguage() for locale; fallback to Language.English when null.\n */\n// @cpt-dod:cpt-frontx-dod-i18n-infrastructure-formatters:p1\n\nimport { getLocale } from './utils';\n\n// @cpt-begin:cpt-frontx-dod-i18n-infrastructure-formatters:p1:inst-9\n/**\n * Compare two strings according to the current locale (for sorting).\n *\n * @param a - First string\n * @param b - Second string\n * @param options - Intl.Collator options (e.g. sensitivity, numeric)\n * @returns Negative if a < b, 0 if equal, positive if a > b\n */\nexport function compareStrings(\n a: string,\n b: string,\n options?: Intl.CollatorOptions\n): number {\n const locale = getLocale();\n return new Intl.Collator(locale, options).compare(a, b);\n}\n// @cpt-end:cpt-frontx-dod-i18n-infrastructure-formatters:p1:inst-9\n\n// @cpt-begin:cpt-frontx-dod-i18n-infrastructure-formatters:p1:inst-10\n/**\n * Create a Collator for the current locale (reuse for many comparisons, e.g. in tables).\n *\n * @param options - Intl.Collator options\n * @returns Intl.Collator instance\n */\nexport function createCollator(options?: Intl.CollatorOptions): Intl.Collator {\n const locale = getLocale();\n return new Intl.Collator(locale, options);\n}\n// @cpt-end:cpt-frontx-dod-i18n-infrastructure-formatters:p1:inst-10\n"],"mappings":"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","names":["TextDirection","Language","LanguageDisplayMode","module"]}
|
package/dist/index.d.cts
CHANGED
|
@@ -165,7 +165,7 @@ declare const i18nRegistry: I18nRegistryImpl;
|
|
|
165
165
|
declare function createI18nRegistry(config: I18nConfig): I18nRegistryImpl;
|
|
166
166
|
|
|
167
167
|
/**
|
|
168
|
-
* Supported Languages - All 36
|
|
168
|
+
* Supported Languages - All 36 FrontX supported languages
|
|
169
169
|
*
|
|
170
170
|
* Based on major platforms (Google, Facebook, Microsoft, Apple).
|
|
171
171
|
* Includes native names, English names, and text direction.
|
package/dist/index.d.ts
CHANGED
|
@@ -165,7 +165,7 @@ declare const i18nRegistry: I18nRegistryImpl;
|
|
|
165
165
|
declare function createI18nRegistry(config: I18nConfig): I18nRegistryImpl;
|
|
166
166
|
|
|
167
167
|
/**
|
|
168
|
-
* Supported Languages - All 36
|
|
168
|
+
* Supported Languages - All 36 FrontX supported languages
|
|
169
169
|
*
|
|
170
170
|
* Based on major platforms (Google, Facebook, Microsoft, Apple).
|
|
171
171
|
* Includes native names, English names, and text direction.
|