@cocoar/localization 0.1.0-beta.155 → 0.1.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.
@@ -1 +1 @@
1
- {"version":3,"file":"cocoar-localization.mjs","sources":["../../../../libs/localization/src/lib/l10n/localization-data-store.ts","../../../../libs/localization/src/lib/l10n/localization-data-loader.ts","../../../../libs/localization/src/lib/l10n/intl-localization-data-loader.ts","../../../../libs/localization/src/lib/i18n/coar-i18n-provider.ts","../../../../libs/localization/src/lib/i18n/coar-interpolate.ts","../../../../libs/localization/src/lib/i18n/coar-translation-loader.ts","../../../../libs/localization/src/lib/i18n/coar-translation-store.ts","../../../../libs/localization/src/lib/i18n/coar-i18n.service.ts","../../../../libs/localization/src/lib/i18n/coar-intl-translation-loader.ts","../../../../libs/localization/src/lib/timezone/browser-timezone-provider.ts","../../../../libs/localization/src/lib/timezone/coar-timezone-providers.token.ts","../../../../libs/localization/src/lib/timezone/coar-timezone.service.ts","../../../../libs/localization/src/lib/provide-coar-localization.ts","../../../../libs/localization/src/lib/l10n/merge-localization-data.ts","../../../../libs/localization/src/lib/coar-localization.service.ts","../../../../libs/localization/src/lib/l10n/localization-data.ts","../../../../libs/localization/src/lib/l10n/provide-l10n-http-source.ts","../../../../libs/localization/src/lib/l10n/date.pipe.ts","../../../../libs/localization/src/lib/l10n/number.pipe.ts","../../../../libs/localization/src/lib/l10n/currency.pipe.ts","../../../../libs/localization/src/lib/l10n/percent.pipe.ts","../../../../libs/localization/src/lib/i18n/coar-is-missing-translation.ts","../../../../libs/localization/src/lib/i18n/coar-i18n.ts","../../../../libs/localization/src/lib/i18n/coar-i18n.pipe.ts","../../../../libs/localization/src/lib/i18n/coar-i18n-context.ts","../../../../libs/localization/src/lib/i18n/provide-coar-i18n-http-source.ts","../../../../libs/localization/src/index.ts","../../../../libs/localization/src/cocoar-localization.ts"],"sourcesContent":["import { computed, signal, Signal, WritableSignal } from '@angular/core';\nimport type { CoarLocalizationData } from './localization-data';\n\n/**\n * Signal-based storage for locale data.\n * Provides reactive access to loaded locale formatting rules.\n */\nexport class CoarLocalizationDataStore {\n private readonly store: WritableSignal<Map<string, CoarLocalizationData>> = signal(new Map());\n\n /**\n * Reactive signal that changes whenever any locale data is updated.\n * Use this in computed() to ensure reactivity to data loading.\n */\n readonly dataVersion: Signal<number> = computed(() => {\n // Reading store() creates the signal dependency\n return this.store().size;\n });\n\n /**\n * Set locale data for a specific locale.\n * @param locale Locale code (e.g., 'en', 'de', 'en-US')\n * @param data Locale data\n */\n setLocaleData(locale: string, data: CoarLocalizationData): void {\n const current = this.store();\n const updated = new Map(current);\n updated.set(locale, data);\n this.store.set(updated);\n }\n\n /**\n * Get locale data for a specific locale.\n * @param locale Locale code (e.g., 'en', 'de', 'en-US')\n * @returns Locale data or undefined if not loaded\n */\n getLocaleData(locale: string): CoarLocalizationData | undefined {\n return this.store().get(locale);\n }\n\n /**\n * Check if locale data is loaded for a specific locale.\n * @param locale Locale code (e.g., 'en', 'de', 'en-US')\n * @returns True if locale data is loaded\n */\n hasLocaleData(locale: string): boolean {\n return this.store().has(locale);\n }\n\n /**\n * Remove locale data for a specific locale.\n * @param locale Locale code (e.g., 'en', 'de', 'en-US')\n */\n removeLocaleData(locale: string): void {\n const current = this.store();\n const updated = new Map(current);\n updated.delete(locale);\n this.store.set(updated);\n }\n\n /**\n * Clear all loaded locale data.\n */\n clear(): void {\n this.store.set(new Map());\n }\n}\n","import { Injectable } from '@angular/core';\nimport { Observable } from 'rxjs';\nimport type { CoarLocalizationData } from './localization-data';\nimport { HttpClient } from '@angular/common/http';\n\n/**\n * Abstract loader for locale data.\n * Implement this interface to load locale data from any source (HTTP, memory, database, etc.).\n */\n@Injectable({ providedIn: 'root' })\nexport abstract class CoarLocalizationDataLoader {\n /**\n * Load locale data for a specific locale.\n * @param locale Locale code (e.g., 'en', 'de', 'en-US')\n * @returns Observable that emits the locale data\n */\n abstract loadLocaleData(locale: string): Observable<CoarLocalizationData>;\n}\n\n/**\n * HTTP-based locale data loader.\n * Loads locale data from JSON files via HTTP.\n *\n * Supports custom URL patterns and headers for authentication/configuration.\n * Typically used as a second source (after Intl) to provide business-specific overrides.\n *\n * @example\n * ```typescript\n * // Simple base path\n * new CoarHttpLocaleDataLoader(httpClient, (lang) => `/locales/${lang}.json`)\n *\n * // Custom URL pattern\n * new CoarHttpLocaleDataLoader(httpClient, (lang) => `/api/config/intl-${lang}.json`)\n *\n * // With headers\n * new CoarHttpLocaleDataLoader(\n * httpClient,\n * (lang) => `/api/locales/${lang}.json`,\n * { 'Authorization': 'Bearer token' }\n * )\n * ```\n */\nexport class CoarHttpLocaleDataLoader extends CoarLocalizationDataLoader {\n constructor(\n private readonly httpClient: HttpClient,\n private readonly urlFn: (language: string) => string,\n private readonly headers?: Record<string, string>\n ) {\n super();\n }\n\n loadLocaleData(locale: string): Observable<CoarLocalizationData> {\n const url = this.urlFn(locale);\n\n return this.httpClient.get<CoarLocalizationData>(url, {\n headers: this.headers,\n });\n }\n}\n","import { Injectable } from '@angular/core';\nimport { Observable, of } from 'rxjs';\nimport { CoarLocalizationData, CoarDateFormatData } from './localization-data';\nimport { CoarLocalizationDataLoader } from './localization-data-loader';\n\n/**\n * Locale data loader that detects formatting from browser's Intl API.\n *\n * This is the default loader and works for all locales without requiring JSON files.\n * Use this when you want formatting to match the user's browser locale automatically.\n *\n * For business-specific overrides (e.g., force Monday as first day of week),\n * use CoarHttpLocaleDataLoader to load custom JSON files.\n */\n@Injectable()\nexport class CoarIntlLocaleDataLoader extends CoarLocalizationDataLoader {\n loadLocaleData(locale: string): Observable<CoarLocalizationData> {\n return of(this.detectFromIntl(locale));\n }\n\n /**\n * Detect all locale formatting from browser Intl API.\n */\n private detectFromIntl(locale: string): CoarLocalizationData {\n return {\n code: locale,\n date: this.detectDateFormat(locale),\n number: this.detectNumberFormat(locale),\n currency: this.detectCurrencyFormat(locale),\n percent: this.detectPercentFormat(locale),\n };\n }\n\n /**\n * Detect date formatting from Intl.DateTimeFormat.\n */\n private detectDateFormat(locale: string): CoarDateFormatData {\n // Detect pattern and separator\n const formatter = new Intl.DateTimeFormat(locale, {\n day: '2-digit',\n month: '2-digit',\n year: 'numeric',\n });\n\n const parts = formatter.formatToParts(new Date(2024, 11, 25)); // Dec 25, 2024\n const order: string[] = [];\n\n for (const part of parts) {\n if (part.type === 'day') order.push('d');\n else if (part.type === 'month') order.push('m');\n else if (part.type === 'year') order.push('y');\n }\n\n const orderStr = order.join('');\n const formatted = formatter.format(new Date(2024, 11, 25));\n const separator = formatted.match(/[.\\-/]/)?.[0] ?? '.';\n\n let pattern: CoarDateFormatData['pattern'];\n if (orderStr === 'mdy') {\n pattern = 'mm/dd/yyyy';\n } else if (orderStr === 'ymd') {\n pattern = 'yyyy-mm-dd';\n } else if (separator === '/') {\n pattern = 'dd/mm/yyyy';\n } else {\n pattern = 'dd.mm.yyyy';\n }\n\n // Detect first day of week using Intl.Locale API\n let firstDayOfWeek = 1; // Default to Monday\n try {\n const localeObj = new Intl.Locale(locale);\n const weekInfo = (localeObj as any).weekInfo || (localeObj as any).getWeekInfo?.();\n if (weekInfo?.firstDay !== undefined) {\n // Intl.Locale uses ISO day numbers (1=Monday, 7=Sunday)\n // Our system uses 0=Sunday, 1=Monday for consistency with Date.getDay()\n firstDayOfWeek = weekInfo.firstDay === 7 ? 0 : weekInfo.firstDay;\n }\n } catch {\n // Modern browsers support Intl.Locale with weekInfo\n // If not available, default to Monday (international standard)\n }\n\n // Generate month names\n const monthFormatter = new Intl.DateTimeFormat(locale, { month: 'long' });\n const monthFormatterShort = new Intl.DateTimeFormat(locale, { month: 'short' });\n const monthNames: string[] = [];\n const monthNamesShort: string[] = [];\n for (let m = 0; m < 12; m++) {\n const date = new Date(2024, m, 1);\n monthNames.push(monthFormatter.format(date));\n monthNamesShort.push(monthFormatterShort.format(date));\n }\n\n // Generate day names (start from Monday)\n const dayFormatter = new Intl.DateTimeFormat(locale, { weekday: 'long' });\n const dayFormatterShort = new Intl.DateTimeFormat(locale, { weekday: 'short' });\n const dayNames: string[] = [];\n const dayNamesShort: string[] = [];\n for (let d = 0; d < 7; d++) {\n // Jan 1, 2024 is Monday\n const date = new Date(2024, 0, 1 + d);\n dayNames.push(dayFormatter.format(date));\n dayNamesShort.push(dayFormatterShort.format(date));\n }\n\n // Detect AM/PM\n const amPmFormatter = new Intl.DateTimeFormat(locale, { hour: 'numeric', hour12: true });\n const amDate = new Date(2024, 0, 1, 9, 0);\n const pmDate = new Date(2024, 0, 1, 21, 0);\n const amFormatted = amPmFormatter.format(amDate);\n const pmFormatted = amPmFormatter.format(pmDate);\n const amPm: [string, string] = [\n amFormatted.replace(/\\d+/g, '').trim() || 'AM',\n pmFormatted.replace(/\\d+/g, '').trim() || 'PM',\n ];\n\n return {\n pattern,\n firstDayOfWeek,\n monthNames,\n monthNamesShort,\n dayNames,\n dayNamesShort,\n amPm,\n };\n }\n\n /**\n * Detect number formatting from Intl.NumberFormat.\n */\n private detectNumberFormat(locale: string) {\n const formatter = new Intl.NumberFormat(locale);\n\n // Prefer formatToParts so we reliably distinguish decimal vs group.\n // Example (en): 1,234,567.89\n // Example (de): 1.234.567,89\n try {\n const parts = formatter.formatToParts(1234567.89);\n const decimalPart = parts.find((p) => p.type === 'decimal');\n const groupPart = parts.find((p) => p.type === 'group');\n\n return {\n decimal: decimalPart?.value ?? '.',\n group: groupPart?.value ?? ',',\n grouping: [3],\n };\n } catch {\n // Fallback for environments without formatToParts.\n const formatted = formatter.format(1234.56);\n const formattedThousands = formatter.format(1234567);\n\n const matchDecimal = formatted.match(/\\d([^\\d])\\d{2}$/);\n const decimal = matchDecimal?.[1] ?? '.';\n\n const matchGroup = formattedThousands.match(/1([^\\d])234/);\n const group = matchGroup?.[1] ?? ',';\n\n return {\n decimal,\n group,\n grouping: [3],\n };\n }\n }\n\n /**\n * Detect currency formatting from Intl.NumberFormat.\n */\n private detectCurrencyFormat(locale: string) {\n // Try to get default currency for the locale\n let defaultCurrency = 'USD';\n try {\n // Extract region from locale (e.g., 'US' from 'en-US')\n const region = locale.split('-')[1];\n if (region) {\n // Common currency mappings\n const currencyMap: Record<string, string> = {\n US: 'USD',\n GB: 'GBP',\n DE: 'EUR',\n FR: 'EUR',\n AT: 'EUR',\n JP: 'JPY',\n CN: 'CNY',\n IN: 'INR',\n };\n defaultCurrency = currencyMap[region] || 'USD';\n }\n } catch {\n // Fallback\n }\n\n const formatter = new Intl.NumberFormat(locale, {\n style: 'currency',\n currency: defaultCurrency,\n });\n const formatted = formatter.format(1234.56);\n\n // Detect symbol position\n const numberPart = formatted.match(/\\d/)?.[0];\n const symbolIndex = formatted.indexOf(defaultCurrency.substring(0, 1));\n const numberIndex = formatted.indexOf(numberPart || '1');\n const position: 'before' | 'after' = symbolIndex < numberIndex ? 'before' : 'after';\n\n // Detect spacing\n const spacing = /\\s/.test(formatted);\n\n // Get currency symbols\n const symbols: Record<string, string> = {\n USD: '$',\n EUR: '€',\n GBP: '£',\n JPY: '¥',\n CNY: '¥',\n INR: '₹',\n };\n\n return {\n default: defaultCurrency,\n symbols,\n position,\n spacing,\n decimals: 2,\n };\n }\n\n /**\n * Detect percent formatting from Intl.NumberFormat.\n */\n private detectPercentFormat(locale: string) {\n const formatter = new Intl.NumberFormat(locale, { style: 'percent' });\n const formatted = formatter.format(0.25);\n\n // Detect spacing\n const spacing = /\\d\\s%/.test(formatted);\n\n return {\n symbol: '%',\n spacing,\n decimals: 0,\n };\n }\n}\n","import { InjectionToken } from '@angular/core';\n\n/**\n * Core i18n provider interface for translation engines.\n *\n * Providers (Transloco, custom, etc.) only need to implement this minimal interface.\n * The CoarI18n service wraps this provider and adds convenience methods.\n */\nexport interface CoarI18nProvider {\n /**\n * Translate a key into a localized string.\n *\n * @param key i18n key, e.g. 'coar.datePicker.today'\n * @param params optional interpolation parameters for placeholders like {name}\n * @returns the translated and interpolated string\n */\n t(key: string, params?: Record<string, unknown>): string;\n}\n\n/**\n * Injection token for the i18n provider implementation.\n *\n * Apps should provide this token with their chosen i18n backend (Transloco, custom, etc.).\n */\nexport const COAR_I18N_PROVIDER = new InjectionToken<CoarI18nProvider>('COAR_I18N_PROVIDER');\n","/**\n * Interpolates {placeholders} in a template string using the given params.\n *\n * This is the official Cocoar placeholder syntax for i18n strings.\n * Placeholders use curly braces: {name}, {count}, etc.\n *\n * @param template - The template string containing {placeholder} patterns\n * @param params - Optional key-value pairs for interpolation\n * @returns The interpolated string\n *\n * @example\n * ```ts\n * coarInterpolate(\"Hello {name}, you have {count} items.\", { name: 'Alice', count: 3 })\n * // => \"Hello Alice, you have 3 items.\"\n * ```\n */\nexport function coarInterpolate(template: string, params?: Record<string, unknown>): string {\n if (!params) {\n return template;\n }\n\n return template.replace(/\\{(\\w+)\\}/g, (_, key: string) => {\n const value = params[key];\n return value == null ? '' : String(value);\n });\n}\n","import { Injectable, inject, InjectionToken } from '@angular/core';\nimport { HttpClient } from '@angular/common/http';\nimport { Observable } from 'rxjs';\nimport type { CoarTranslations } from './coar-translation-store';\n\n/**\n * Injection token for translation loaders (multi-provider).\n * Loaders are executed in order and results are deep-merged.\n * Intl loader is always first (provides common defaults from browser Intl API).\n */\nexport const COAR_TRANSLATION_LOADERS = new InjectionToken<CoarTranslationLoader[]>(\n 'COAR_TRANSLATION_LOADERS'\n);\n\n/**\n * Abstract loader for translation data.\n *\n * Implement this interface to load translations from any source:\n * - HTTP endpoints\n * - SignalR real-time updates\n * - Static imports\n * - IndexedDB\n * - etc.\n *\n * @example\n * ```ts\n * @Injectable()\n * export class MyCustomLoader implements CoarTranslationLoader {\n * loadTranslations(language: string): Observable<CoarTranslations> {\n * // Load from your custom source\n * return this.myService.getTranslations(language);\n * }\n * }\n * ```\n */\nexport abstract class CoarTranslationLoader {\n /**\n * Loads translation data for a specific language.\n *\n * @param language - Language code to load (e.g., 'en', 'de')\n * @returns Observable that emits translation key-value pairs\n */\n abstract loadTranslations(language: string): Observable<CoarTranslations>;\n}\n\n/**\n * HTTP-based translation loader.\n *\n * Loads translation JSON files from a configurable URL function.\n *\n * ## Usage\n * ```ts\n * const loader = new CoarHttpTranslationLoader();\n * loader.urlFn = (lang) => `/i18n/${lang}.json`;\n * loader.headers = { 'Authorization': 'Bearer token' };\n * ```\n *\n * ## Expected JSON format\n * ```json\n * {\n * \"hello\": \"Hello\",\n * \"goodbye\": \"Goodbye\",\n * \"welcome\": \"Welcome, {{name}}!\"\n * }\n * ```\n */\n@Injectable()\nexport class CoarHttpTranslationLoader implements CoarTranslationLoader {\n private readonly http = inject(HttpClient);\n\n /** URL generator function */\n urlFn: (language: string) => string = (lang) => `/i18n/${lang}.json`;\n\n /** Optional HTTP headers */\n headers?: Record<string, string>;\n\n loadTranslations(language: string): Observable<CoarTranslations> {\n const url = this.urlFn(language);\n return this.http.get<CoarTranslations>(url, {\n headers: this.headers,\n });\n }\n}\n","import { Injectable, Signal, WritableSignal, computed, signal } from '@angular/core';\n\n/**\n * Translation storage for a single language.\n * Maps translation keys to their values.\n */\nexport type CoarTranslations = Record<string, string>;\n\n/**\n * Flattens nested translation objects into dot notation.\n *\n * Supports both flat and nested JSON structures:\n * - Flat: { \"app.title\": \"My App\" }\n * - Nested: { \"app\": { \"title\": \"My App\" } }\n *\n * Both produce: { \"app.title\": \"My App\" }\n *\n * @example\n * Input: { app: { title: 'My App', subtitle: 'Welcome' } }\n * Output: { 'app.title': 'My App', 'app.subtitle': 'Welcome' }\n */\nfunction flattenTranslations(obj: unknown, prefix = ''): CoarTranslations {\n const result: CoarTranslations = {};\n\n if (typeof obj !== 'object' || obj === null) {\n return result;\n }\n\n for (const [key, value] of Object.entries(obj)) {\n const newKey = prefix ? `${prefix}.${key}` : key;\n\n if (typeof value === 'object' && value !== null && !Array.isArray(value)) {\n // Recursively flatten nested objects\n Object.assign(result, flattenTranslations(value, newKey));\n } else if (typeof value === 'string') {\n // Store string values\n result[newKey] = value;\n }\n // Skip non-string primitive values (numbers, booleans, arrays)\n }\n\n return result;\n}\n\n/**\n * Reactive store for translation data.\n *\n * Stores translations for multiple languages in memory and provides\n * Signal-based API for reactive updates.\n *\n * ## Features\n * - Signal-based reactive API\n * - Language-scoped storage\n * - Simple Map-based implementation\n * - Zero dependencies beyond Angular core\n *\n * @example\n * ```ts\n * const store = inject(CoarTranslationStore);\n *\n * // Load translations\n * store.setTranslations('en', { 'hello': 'Hello' });\n * store.setTranslations('de', { 'hello': 'Hallo' });\n *\n * // Check if language is loaded\n * if (store.hasLanguage('en')) {\n * const translations = store.getTranslations('en');\n * }\n *\n * // Get specific translation\n * const value = store.getTranslation('en', 'hello'); // 'Hello'\n *\n * // Check for missing keys\n * const missing = store.getTranslation('en', 'unknown'); // undefined\n * ```\n */\n@Injectable({ providedIn: 'root' })\nexport class CoarTranslationStore {\n /**\n * Internal storage: Map<language, Map<key, translation>>\n *\n * Why nested Maps instead of Record:\n * - Faster lookups for large translation sets\n * - No prototype chain pollution\n * - Clear separation between languages\n */\n private readonly storage: WritableSignal<Map<string, Map<string, string>>> = signal(new Map());\n\n /**\n * Set of all loaded languages.\n * Used for quick existence checks.\n */\n readonly loadedLanguages: Signal<Set<string>> = computed(() => {\n const map = this.storage();\n return new Set(map.keys());\n });\n\n /**\n * Stores all translations for a specific language.\n *\n * Replaces any existing translations for that language.\n * Automatically flattens nested objects into dot notation.\n *\n * @param language - Language code (e.g., 'en', 'de')\n * @param translations - Translation key-value pairs (flat or nested)\n *\n * @example\n * ```ts\n * // Flat format\n * store.setTranslations('en', { 'hello': 'Hello', 'app.title': 'My App' });\n *\n * // Nested format (auto-flattened)\n * store.setTranslations('en', { app: { title: 'My App' }, hello: 'Hello' });\n * // Both produce the same result\n * ```\n */\n setTranslations(\n language: string,\n translations: CoarTranslations | Record<string, unknown>\n ): void {\n // Flatten nested structures into dot notation\n const flattened = flattenTranslations(translations);\n const translationMap = new Map<string, string>(Object.entries(flattened));\n\n this.storage.update((current) => {\n const next = new Map(current);\n next.set(language, translationMap);\n return next;\n });\n }\n\n /**\n * Updates a single translation key for a specific language.\n *\n * Creates the language if it doesn't exist.\n * Useful for real-time updates via SignalR.\n *\n * @param language - Language code\n * @param key - Translation key\n * @param value - Translation value\n *\n * @example\n * ```ts\n * // SignalR: Update single key in real-time\n * signalR.on('TranslationUpdated', ({ lang, key, value }) => {\n * store.setTranslation(lang, key, value);\n * });\n * ```\n */\n setTranslation(language: string, key: string, value: string): void {\n this.storage.update((current) => {\n const next = new Map(current);\n const langMap = next.get(language) ?? new Map<string, string>();\n const updatedLangMap = new Map(langMap);\n updatedLangMap.set(key, value);\n next.set(language, updatedLangMap);\n return next;\n });\n }\n\n /**\n * Merges partial translations into an existing language.\n *\n * Only updates/adds the provided keys, keeps existing keys intact.\n * Creates the language if it doesn't exist.\n * Automatically flattens nested objects into dot notation.\n *\n * @param language - Language code\n * @param partialTranslations - Partial translation key-value pairs to merge (flat or nested)\n *\n * @example\n * ```ts\n * // Flat format\n * // Existing: { 'hello': 'Hello', 'goodbye': 'Goodbye' }\n * store.updateTranslations('en', { 'hello': 'Hi' });\n * // Result: { 'hello': 'Hi', 'goodbye': 'Goodbye' }\n * ```\n *\n * @example\n * ```ts\n * // Nested format (auto-flattened)\n * store.updateTranslations('en', { app: { title: 'New Title' } });\n * // Updates 'app.title' key\n * ```\n *\n * @example\n * ```ts\n * // SignalR: Batch update multiple keys\n * signalR.on('TranslationsBatchUpdated', ({ lang, updates }) => {\n * store.updateTranslations(lang, updates);\n * });\n * ```\n */\n updateTranslations(\n language: string,\n partialTranslations: CoarTranslations | Record<string, unknown>\n ): void {\n // Flatten nested structures into dot notation\n const flattened = flattenTranslations(partialTranslations);\n\n this.storage.update((current) => {\n const next = new Map(current);\n const langMap = next.get(language) ?? new Map<string, string>();\n const updatedLangMap = new Map(langMap);\n\n // Merge partial updates into existing translations\n for (const [key, value] of Object.entries(flattened)) {\n updatedLangMap.set(key, value);\n }\n\n next.set(language, updatedLangMap);\n return next;\n });\n }\n\n /**\n * Checks if translations for a language are loaded.\n *\n * @param language - Language code to check\n * @returns True if language is loaded\n */\n hasLanguage(language: string): boolean {\n return this.storage().has(language);\n }\n\n /**\n * Gets all translations for a specific language.\n *\n * @param language - Language code\n * @returns Translation map, or undefined if language not loaded\n */\n getTranslations(language: string): Map<string, string> | undefined {\n return this.storage().get(language);\n }\n\n /**\n * Gets a specific translation value.\n *\n * @param language - Language code\n * @param key - Translation key\n * @returns Translation value, or undefined if not found\n */\n getTranslation(language: string, key: string): string | undefined {\n return this.storage().get(language)?.get(key);\n }\n\n /**\n * Clears all translations from the store.\n *\n * Used primarily for testing.\n */\n clear(): void {\n this.storage.set(new Map());\n }\n}\n","import { DestroyRef, Injectable, inject } from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { Observable, of, switchMap, tap, catchError, forkJoin } from 'rxjs';\nimport { CoarLocalizationService } from '../coar-localization.service';\nimport { CoarI18nProvider } from './coar-i18n-provider';\nimport { coarInterpolate } from './coar-interpolate';\nimport { COAR_TRANSLATION_LOADERS } from './coar-translation-loader';\nimport { CoarTranslationStore, CoarTranslations } from './coar-translation-store';\n\n/**\n * Core i18n service implementation.\n *\n * Integrates:\n * - `CoarLocalizationService` - Language state management\n * - `CoarTranslationStore` - Translation storage\n * - `CoarTranslationLoader` - Translation loading\n * - `CoarI18nContext` - Coordination layer\n *\n * ## Features\n * - Automatic translation loading when language changes\n * - Missing translation detection\n * - Parameter interpolation\n * - Reactive Signal-based API\n *\n * ## Usage\n * Use `provideCoarLocalization()` + `provideCoarI18nHttpSource()` to configure.\n *\n * @example\n * ```ts\n * export const appConfig: ApplicationConfig = {\n * providers: [\n * provideCoarLocalization({\n * defaultLanguage: 'en',\n * }),\n * provideCoarI18nHttpSource(),\n * ],\n * };\n * ```\n */\n@Injectable()\nexport class CoarI18nService implements CoarI18nProvider {\n private readonly locale = inject(CoarLocalizationService);\n private readonly store = inject(CoarTranslationStore);\n private readonly loaders = inject(COAR_TRANSLATION_LOADERS, { optional: true }) ?? [];\n private readonly destroyRef = inject(DestroyRef);\n\n constructor() {\n // Coordination: Wait for pending language changes, load translations, then resolve\n // This ensures translations are ready BEFORE the language state changes\n this.locale.pendingLanguageChange$\n .pipe(\n takeUntilDestroyed(this.destroyRef),\n switchMap(({ language, resolve }) => {\n // Load translations if not already loaded\n if (this.store.hasLanguage(language)) {\n resolve(); // Already loaded, resolve immediately\n return of(void 0);\n }\n\n // Load and then resolve\n return this.loadLanguage(language).pipe(\n tap(() => resolve()) // Signal that translations are ready\n );\n })\n )\n .subscribe();\n\n // Fallback: Auto-load translations when language changes without coordination\n // (for backwards compatibility if someone directly mutates the subject)\n this.locale.languageState.value$.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((lang) => {\n if (this.store.hasLanguage(lang)) {\n return;\n }\n\n this.loadLanguage(lang).subscribe();\n });\n }\n\n t(key: string, params?: Record<string, unknown>): string {\n const lang = this.locale.languageState.value;\n const translations = this.store.getTranslations(lang);\n\n // Language not loaded yet - return key\n if (!translations) {\n return key;\n }\n\n const value = translations.get(key);\n\n // Missing translation - return key\n if (value === undefined) {\n return key;\n }\n\n // No params - return value as-is\n if (!params) {\n return value;\n }\n\n // Interpolate params\n return coarInterpolate(value, params);\n }\n\n /**\n * Loads translations from all sources and deep-merges them.\n *\n * Sources are executed in order:\n * 1. Intl (always first, provides common translations from browser APIs)\n * 2. HTTP (if configured, merges application-specific overrides)\n * 3. Custom sources (if provided, can add dynamic updates)\n *\n * Later sources override earlier sources at the key level.\n *\n * @param language - Language code to load\n * @returns Observable that completes when loading finishes\n */\n private loadLanguage(language: string): Observable<void> {\n // No loaders configured - mark as loaded with empty translations\n if (this.loaders.length === 0) {\n this.store.setTranslations(language, {});\n return of(void 0);\n }\n\n // Load from all sources in parallel\n const loadObservables = this.loaders.map((loader) =>\n loader.loadTranslations(language).pipe(\n catchError((err) => {\n console.warn(`[CoarI18n] Translation loader failed for '${language}':`, err);\n return of(null); // Return null for failed sources\n })\n )\n );\n\n return forkJoin(loadObservables).pipe(\n tap((results) => {\n // Deep merge all sources (nulls are ignored)\n const merged = this.mergeTranslations(\n results.filter((r) => r !== null) as CoarTranslations[]\n );\n this.store.setTranslations(language, merged);\n }),\n switchMap(() => of(void 0)),\n catchError((error) => {\n console.error(`[CoarI18n] Failed to load translations for '${language}':`, error);\n // Store empty translations to prevent repeated load attempts\n this.store.setTranslations(language, {});\n return of(void 0);\n })\n );\n }\n\n /**\n * Merges multiple translation sources.\n * Later sources override earlier sources at the key level.\n */\n private mergeTranslations(sources: CoarTranslations[]): CoarTranslations {\n const result: CoarTranslations = {};\n\n for (const source of sources) {\n if (!source) continue;\n\n // Merge all keys from this source\n for (const [key, value] of Object.entries(source)) {\n result[key] = value;\n }\n }\n\n return result;\n }\n\n /**\n * Preloads translations for a specific language.\n *\n * Used by APP_INITIALIZER to prevent flash of untranslated content.\n *\n * @param language - Language code to preload\n * @returns Promise that resolves when loading completes\n */\n preloadLanguage(language: string): Promise<void> {\n // Already loaded - return immediately\n if (this.store.hasLanguage(language)) {\n return Promise.resolve();\n }\n\n return new Promise((resolve) => {\n this.loadLanguage(language).subscribe(() => resolve());\n });\n }\n}\n","import { Injectable } from '@angular/core';\nimport { Observable, of } from 'rxjs';\nimport type { CoarTranslations } from './coar-translation-store';\nimport { CoarTranslationLoader } from './coar-translation-loader';\n\n/**\n * Translation loader that generates common translations from browser's Intl API.\n *\n * This loader provides default translations for common UI elements that can be\n * automatically localized using browser APIs, without requiring JSON files.\n *\n * Translations generated:\n * - Relative time labels (today, yesterday, tomorrow)\n * - Month names (full and abbreviated)\n * - Weekday names (full and abbreviated)\n * - Common date/time units\n *\n * These translations can be overridden by registering additional loaders\n * (e.g., HTTP loader) that provide custom values.\n *\n * @example\n * ```ts\n * // Automatic registration via provideCoarLocalization()\n * provideCoarLocalization({ defaultLanguage: 'en' })\n *\n * // Intl loader provides: { 'common.today': 'today' }\n * // HTTP loader can override: { 'common.today': 'Now' }\n * ```\n */\n@Injectable()\nexport class CoarIntlTranslationLoader extends CoarTranslationLoader {\n loadTranslations(locale: string): Observable<CoarTranslations> {\n return of(this.generateFromIntl(locale));\n }\n\n /**\n * Generate translations from browser Intl API.\n */\n private generateFromIntl(locale: string): CoarTranslations {\n const translations: CoarTranslations = {};\n\n // Relative time labels (for date pickers, calendars, etc.)\n try {\n const rtf = new Intl.RelativeTimeFormat(locale, { numeric: 'auto' });\n translations['common.today'] = rtf.format(0, 'day');\n translations['common.yesterday'] = rtf.format(-1, 'day');\n translations['common.tomorrow'] = rtf.format(1, 'day');\n } catch {\n // Fallback for older browsers without RelativeTimeFormat\n translations['common.today'] = 'today';\n translations['common.yesterday'] = 'yesterday';\n translations['common.tomorrow'] = 'tomorrow';\n }\n\n // Month names (full)\n const monthFormatter = new Intl.DateTimeFormat(locale, { month: 'long' });\n for (let m = 0; m < 12; m++) {\n const date = new Date(2024, m, 1);\n const monthName = monthFormatter.format(date);\n translations[`common.month.${m + 1}`] = monthName;\n }\n\n // Month names (abbreviated)\n const monthFormatterShort = new Intl.DateTimeFormat(locale, { month: 'short' });\n for (let m = 0; m < 12; m++) {\n const date = new Date(2024, m, 1);\n const monthName = monthFormatterShort.format(date);\n translations[`common.month.short.${m + 1}`] = monthName;\n }\n\n // Weekday names (full) - Monday=1, Sunday=7\n const dayFormatter = new Intl.DateTimeFormat(locale, { weekday: 'long' });\n for (let d = 0; d < 7; d++) {\n // Jan 1, 2024 is Monday\n const date = new Date(2024, 0, 1 + d);\n const dayName = dayFormatter.format(date);\n translations[`common.weekday.${d + 1}`] = dayName;\n }\n\n // Weekday names (abbreviated)\n const dayFormatterShort = new Intl.DateTimeFormat(locale, { weekday: 'short' });\n for (let d = 0; d < 7; d++) {\n const date = new Date(2024, 0, 1 + d);\n const dayName = dayFormatterShort.format(date);\n translations[`common.weekday.short.${d + 1}`] = dayName;\n }\n\n return translations;\n }\n}\n","import { Injectable } from '@angular/core';\nimport { Observable, of } from 'rxjs';\nimport { CoarTimeZoneProvider } from './coar-timezone-provider';\n\n/**\n * Built-in timezone provider using browser's Intl API.\n *\n * Always present as guaranteed baseline fallback.\n * Returns the user's operating system timezone.\n *\n * Note: This is a one-time snapshot. If user changes OS timezone\n * while app is running, this will not update (browser limitation).\n *\n * @internal\n */\n@Injectable()\nexport class BrowserTimeZoneProvider implements CoarTimeZoneProvider {\n readonly timeZone$: Observable<string | null>;\n\n constructor() {\n // Detect browser timezone using Intl API\n // This is a one-time snapshot (browser doesn't provide reactive updates)\n const browserTimeZone = this.detectBrowserTimeZone();\n this.timeZone$ = of(browserTimeZone);\n }\n\n private detectBrowserTimeZone(): string {\n try {\n // Use Intl API to get user's timezone\n // Example return values: \"America/New_York\", \"Europe/Paris\", \"Asia/Tokyo\"\n const timeZone = Intl.DateTimeFormat().resolvedOptions().timeZone;\n\n // Fallback to UTC if browser returns undefined (shouldn't happen in modern browsers)\n return timeZone || 'UTC';\n } catch {\n // Fallback to UTC if Intl API fails\n return 'UTC';\n }\n }\n}\n","import { InjectionToken } from '@angular/core';\nimport { CoarTimeZoneProvider } from './coar-timezone-provider';\n\n/**\n * Injection token for custom timezone providers (multi-provider).\n *\n * Providers are resolved in array order (first to last).\n * First non-null value wins.\n *\n * Browser provider is always present as guaranteed baseline (automatically added).\n *\n * @internal\n */\nexport const COAR_TIMEZONE_PROVIDERS = new InjectionToken<CoarTimeZoneProvider[]>(\n 'COAR_TIMEZONE_PROVIDERS'\n);\n","import { Injectable, Optional, inject } from '@angular/core';\nimport { toSignal } from '@angular/core/rxjs-interop';\nimport { Observable, combineLatest, of } from 'rxjs';\nimport { distinctUntilChanged, map } from 'rxjs/operators';\nimport { CoarTimeZoneProvider } from './coar-timezone-provider';\nimport { BrowserTimeZoneProvider } from './browser-timezone-provider';\nimport { COAR_TIMEZONE_PROVIDERS } from './coar-timezone-providers.token';\n\n/**\n * Service for timezone resolution with pluggable provider hierarchy.\n *\n * Resolution order:\n * 1. Custom providers (from config, in array order)\n * 2. Browser provider (Intl API, always present as guaranteed baseline)\n * 3. UTC safety net (if all providers return null)\n *\n * First non-null value wins. Changes propagate reactively.\n *\n * @example\n * ```ts\n * // In component\n * export class MyComponent {\n * private timeZoneService = inject(CoarTimeZoneService);\n *\n * // Reactive signal (updates when timezone changes)\n * currentTimeZone = this.timeZoneService.currentTimeZone;\n *\n * // Observable stream\n * timeZone$ = this.timeZoneService.timeZone$;\n * }\n * ```\n */\n@Injectable({ providedIn: 'root' })\nexport class CoarTimeZoneService {\n private readonly browserProvider = inject(BrowserTimeZoneProvider);\n private readonly customProviders = inject(COAR_TIMEZONE_PROVIDERS, { optional: true }) ?? [];\n\n /**\n * Observable stream of the current timezone (IANA identifier).\n *\n * Emits when any provider in the hierarchy changes.\n * Uses `distinctUntilChanged()` to prevent unnecessary emissions.\n *\n * Resolution order: Custom providers → Browser → UTC\n */\n readonly timeZone$: Observable<string>;\n\n /**\n * Signal of the current timezone (IANA identifier).\n *\n * Automatically updates when timezone changes.\n * Use this in templates or reactive contexts.\n */\n readonly currentTimeZone;\n\n constructor() {\n // Build provider chain: Custom providers → Browser (always last)\n const allProviders: CoarTimeZoneProvider[] = [\n ...this.customProviders,\n this.browserProvider, // Browser is guaranteed baseline, always present\n ];\n\n // Combine all provider streams\n const providerStreams = allProviders.map((provider) => provider.timeZone$);\n\n this.timeZone$ = combineLatest(providerStreams).pipe(\n // Find first non-null value in priority order\n map((timeZones) => {\n const resolved = timeZones.find((tz) => tz !== null);\n // UTC as safety net if all providers return null (shouldn't happen)\n return resolved ?? 'UTC';\n }),\n // Prevent unnecessary emissions when value doesn't actually change\n distinctUntilChanged()\n );\n\n // Initialize signal after timeZone$ is set up\n this.currentTimeZone = toSignal(this.timeZone$, { requireSync: true });\n }\n}\n","import {\n APP_INITIALIZER,\n EnvironmentProviders,\n InjectionToken,\n inject,\n makeEnvironmentProviders,\n} from '@angular/core';\nimport { CoarLocalizationService } from './coar-localization.service';\nimport { CoarLocalizationDataLoader } from './l10n/localization-data-loader';\nimport { CoarLocalizationDataStore } from './l10n/localization-data-store';\nimport { CoarIntlLocaleDataLoader } from './l10n/intl-localization-data-loader';\nimport { COAR_I18N_PROVIDER } from './i18n/coar-i18n-provider';\nimport { CoarI18nService } from './i18n/coar-i18n.service';\nimport { COAR_TRANSLATION_LOADERS } from './i18n/coar-translation-loader';\nimport { CoarIntlTranslationLoader } from './i18n/coar-intl-translation-loader';\nimport { CoarTimeZoneProvider } from './timezone/coar-timezone-provider';\nimport { BrowserTimeZoneProvider } from './timezone/browser-timezone-provider';\nimport { CoarTimeZoneService } from './timezone/coar-timezone.service';\nimport { COAR_TIMEZONE_PROVIDERS } from './timezone/coar-timezone-providers.token';\n\n/**\n * Configuration for the locale system.\n */\nexport interface CoarLocalizationConfig {\n /**\n * Default language to use on initialization.\n */\n defaultLanguage: string;\n\n /**\n * Optional custom timezone providers.\n *\n * Providers are resolved in array order (first to last).\n * First non-null value wins.\n *\n * Browser provider (Intl API) is always present as guaranteed baseline\n * and automatically added after custom providers.\n *\n * @example\n * ```ts\n * // With custom profile provider\n * provideCoarLocalization({\n * defaultLanguage: 'en',\n * timeZoneProviders: [\n * inject(ProfileTimeZoneProvider)\n * ]\n * })\n * ```\n */\n timeZoneProviders?: CoarTimeZoneProvider[];\n}\n\n/**\n * Injection token for locale configuration.\n */\nexport const COAR_LOCALIZATION_CONFIG = new InjectionToken<CoarLocalizationConfig>(\n 'COAR_LOCALIZATION_CONFIG'\n);\n\n/**\n * Injection token for locale data loaders (multi-provider).\n * Loaders are executed in order and results are deep-merged.\n * Intl loader is always first (provides complete defaults).\n */\nexport const COAR_LOCALIZATION_DATA_LOADERS = new InjectionToken<CoarLocalizationDataLoader[]>(\n 'COAR_LOCALIZATION_DATA_LOADERS'\n);\n\n/**\n * Provides the core localization system (language management + L10n + i18n).\n *\n * Automatically includes:\n * - Language management (CoarLocalizationService)\n * - L10n: Browser Intl API for number/date formatting (always first source)\n * - i18n: Translation system (CoarI18nService + CoarTranslationStore)\n *\n * Add optional data sources with:\n * - `provideCoarL10nHttpSource()` - Load L10n overrides from JSON files\n * - `provideCoarI18nHttpSource()` - Load i18n translations from JSON files\n * - Custom sources via multi-providers\n *\n * Sources are executed in registration order and deep-merged.\n *\n * @example\n * ```ts\n * // Basic setup (Intl formatting only, no i18n loader)\n * provideCoarLocalization({\n * defaultLanguage: 'en',\n * })\n *\n * // With L10n overrides and i18n translations\n * provideCoarLocalization({ defaultLanguage: 'en' }),\n * provideCoarL10nHttpSource({\n * url: (lang) => `/locales/${lang}.json`\n * }),\n * provideCoarI18nHttpSource(), // Defaults to /i18n/{lang}.json\n * ```\n */\nexport function provideCoarLocalization(config: CoarLocalizationConfig): EnvironmentProviders {\n return makeEnvironmentProviders([\n {\n provide: COAR_LOCALIZATION_CONFIG,\n useValue: config,\n },\n CoarLocalizationService,\n CoarLocalizationDataStore,\n\n // TimeZone: Provide the timezone service\n CoarTimeZoneService,\n\n // TimeZone: Browser provider (always present as guaranteed baseline)\n BrowserTimeZoneProvider,\n\n // TimeZone: Register custom providers from config (if any)\n ...(config.timeZoneProviders?.map((provider) => ({\n provide: COAR_TIMEZONE_PROVIDERS,\n multi: true,\n useValue: provider,\n })) ?? []),\n\n // L10n: Auto-include Intl source as first loader (provides complete defaults)\n {\n provide: COAR_LOCALIZATION_DATA_LOADERS,\n multi: true,\n useClass: CoarIntlLocaleDataLoader,\n },\n\n // i18n: Provide the i18n service (translations)\n {\n provide: COAR_I18N_PROVIDER,\n useClass: CoarI18nService,\n },\n\n // i18n: Auto-include Intl source as first translation loader (provides common defaults)\n {\n provide: COAR_TRANSLATION_LOADERS,\n multi: true,\n useClass: CoarIntlTranslationLoader,\n },\n\n // APP_INITIALIZER: Preload default language (L10n + i18n if loader registered)\n {\n provide: APP_INITIALIZER,\n multi: true,\n useFactory: () => {\n const localeService = inject(CoarLocalizationService);\n const i18nService = inject(COAR_I18N_PROVIDER) as CoarI18nService;\n\n return async () => {\n // Preload L10n data for default language\n try {\n await localeService.setLanguage(config.defaultLanguage);\n } catch (error) {\n console.warn(\n `[CoarLocale] Failed to preload locale data for '${config.defaultLanguage}':`,\n error\n );\n }\n\n // Preload i18n translations if loader is available\n try {\n await i18nService.preloadLanguage(config.defaultLanguage);\n } catch (error) {\n // Silently ignore if no loader is registered\n // This allows using L10n without i18n\n }\n };\n },\n },\n ]);\n}\n","import { CoarLocalizationData } from './localization-data';\n\n/**\n * Deep merge utility for locale data.\n * Later sources override earlier sources at the field level.\n *\n * @example\n * ```ts\n * const intl = { date: { pattern: 'dd.mm.yyyy', firstDayOfWeek: 1 }, number: {...} };\n * const http = { date: { firstDayOfWeek: 0 } }; // Only override firstDayOfWeek\n *\n * const result = mergeLocalizationData([intl, http]);\n * // Result: { date: { pattern: 'dd.mm.yyyy', firstDayOfWeek: 0 }, number: {...} }\n * ```\n */\nexport function mergeLocalizationData(sources: Partial<CoarLocalizationData>[]): CoarLocalizationData | null {\n if (sources.length === 0) return null;\n\n const result: Partial<CoarLocalizationData> = {};\n\n for (const source of sources) {\n if (!source) continue;\n\n // Merge code\n if (source.code) {\n result.code = source.code;\n }\n\n // Deep merge date\n if (source.date) {\n result.date = { ...result.date, ...source.date };\n }\n\n // Deep merge number\n if (source.number) {\n result.number = { ...result.number, ...source.number };\n }\n\n // Deep merge currency\n if (source.currency) {\n result.currency = {\n ...result.currency,\n ...source.currency,\n symbols: { ...result.currency?.symbols, ...source.currency.symbols },\n };\n }\n\n // Deep merge percent\n if (source.percent) {\n result.percent = { ...result.percent, ...source.percent };\n }\n }\n\n // Ensure we have at least a code\n if (!result.code) return null;\n\n return result as CoarLocalizationData;\n}\n","import { inject, Injectable } from '@angular/core';\nimport { BehaviorSubject, Subject, lastValueFrom } from 'rxjs';\nimport { ReadonlyState } from '@cocoar/ts-utils';\nimport {\n COAR_LOCALIZATION_CONFIG,\n COAR_LOCALIZATION_DATA_LOADERS,\n} from './provide-coar-localization';\nimport { CoarLocalizationDataStore } from './l10n/localization-data-store';\nimport { mergeLocalizationData } from './l10n/merge-localization-data';\n\n/**\n * Represents a pending language change that needs coordination with i18n.\n */\ninterface PendingLanguageChange {\n language: string;\n resolve: () => void;\n}\n\n/**\n * Core locale service responsible for language management.\n *\n * This service manages the current language state and notifies consumers\n * about language changes. It serves as the single source of truth for\n * the application's current language.\n *\n * Other systems (i18n, localization/formatting) can subscribe to language\n * changes and react accordingly.\n *\n * @example\n * ```typescript\n * import { inject } from '@angular/core';\n * import { CoarLocalizationService } from '@cocoar/localization';\n *\n * export class MyComponent {\n * private readonly locale = inject(CoarLocalizationService);\n *\n * constructor() {\n * // Get current language\n * console.log(this.locale.languageState.value);\n *\n * // React to changes via Observable\n * this.locale.languageState.value$.subscribe(lang => {\n * console.log('Language changed:', lang);\n * });\n * }\n *\n * changeLanguage() {\n * this.locale.setLanguage('de');\n * }\n * }\n * ```\n */\n@Injectable({\n providedIn: 'root',\n})\nexport class CoarLocalizationService {\n private readonly config = inject(COAR_LOCALIZATION_CONFIG, { optional: true });\n private readonly localeDataStore = inject(CoarLocalizationDataStore);\n private readonly localeDataLoaders =\n inject(COAR_LOCALIZATION_DATA_LOADERS, { optional: true }) ?? [];\n private readonly defaultLanguage = this.config?.defaultLanguage ?? 'en';\n\n private readonly languageSubject = new BehaviorSubject<string>(this.defaultLanguage);\n\n /**\n * Subject for coordinating language changes with i18n service.\n * The i18n service subscribes to this to load translations BEFORE the language change is emitted.\n * @internal\n */\n readonly pendingLanguageChange$ = new Subject<PendingLanguageChange>();\n\n /**\n * Canonical language state.\n *\n * - `languageState.value` gives synchronous access\n * - `languageState.value$` is the canonical stream (emits current value immediately)\n */\n readonly languageState = new ReadonlyState(this.languageSubject);\n\n constructor() {\n // Expose to window for debugging\n if (typeof window !== 'undefined') {\n (\n window as unknown as { __coarLocalizationStore?: CoarLocalizationDataStore }\n ).__coarLocalizationStore = this.localeDataStore;\n }\n\n // Load locale data for the default language on initialization\n // This ensures firstDayOfWeek and other formatting data is available immediately\n this.loadAndmergeLocalizationData(this.defaultLanguage).catch((error) => {\n console.warn(\n `[CoarLocalizationService] Failed to load initial locale data for '${this.defaultLanguage}':`,\n error\n );\n });\n }\n\n /**\n * Set the current language.\n *\n * Automatically loads locale data from all configured sources (Intl, HTTP, etc.)\n * and deep-merges them in order. Later sources override earlier ones.\n *\n * Cached data is not reloaded, so switching back to a previous language is instant.\n *\n * @param language - The new language code (e.g., 'en', 'de', 'en-US')\n *\n * @example\n * ```typescript\n * // Change to German (loads from Intl + HTTP, merges overrides)\n * await locale.setLanguage('de');\n *\n * // Change back to English (uses cached data, instant)\n * await locale.setLanguage('en');\n * ```\n */\n async setLanguage(language: string): Promise<void> {\n const current = this.languageState.value;\n\n // Skip if language hasn't changed\n if (current === language) {\n return;\n }\n\n // Load locale data if not already loaded (cached)\n if (!this.localeDataStore.hasLocaleData(language)) {\n try {\n await this.loadAndmergeLocalizationData(language);\n } catch (error) {\n console.warn(\n `[CoarLocalizationService] Failed to load locale data for '${language}':`,\n error\n );\n // Continue with language switch even if locale data fails to load\n // Formatting pipes will use fallback values\n }\n }\n\n // Wait for i18n service to load translations before emitting language change\n // Use a timeout in case i18n service is not injected (e.g., in tests)\n await Promise.race([\n new Promise<void>((resolve) => {\n this.pendingLanguageChange$.next({ language, resolve });\n }),\n new Promise<void>((resolve) => setTimeout(resolve, 100)), // Fallback timeout\n ]);\n\n // Now emit the language change (UI will react with translations ready)\n this.languageSubject.next(language);\n }\n\n /**\n * Load locale data from all sources and deep-merge them.\n *\n * Sources are executed in order:\n * 1. Intl (always first, provides complete defaults)\n * 2. HTTP (if configured, merges business overrides)\n * 3. Custom sources (if provided, can add dynamic updates)\n *\n * @param language - Language code to load\n */\n private async loadAndmergeLocalizationData(language: string): Promise<void> {\n if (this.localeDataLoaders.length === 0) {\n return;\n }\n\n // Load from all sources in parallel\n const loadPromises = this.localeDataLoaders.map((loader) =>\n lastValueFrom(loader.loadLocaleData(language)).catch((err) => {\n console.warn(`[CoarLocale] Source failed to load '${language}':`, err);\n return null; // Return null for failed sources\n })\n );\n\n const results = await Promise.all(loadPromises);\n\n // Deep merge all sources (nulls are ignored)\n const merged = mergeLocalizationData(results.filter((r) => r !== null));\n\n if (merged) {\n this.localeDataStore.setLocaleData(language, merged);\n }\n }\n\n /**\n * Preload locale data for a language without switching to it.\n * Useful for avoiding UI flicker when switching languages.\n *\n * @param language - The language code to preload\n *\n * @example\n * ```typescript\n * // Preload German locale data before switching\n * await locale.preloadLocaleData('de');\n * await locale.setLanguage('de'); // Instant switch, no loading delay\n * ```\n */\n async preloadLocaleData(language: string): Promise<void> {\n // Skip if already loaded\n if (this.localeDataStore.hasLocaleData(language)) {\n return;\n }\n\n try {\n await this.loadAndmergeLocalizationData(language);\n } catch (error) {\n console.warn(\n `[CoarLocalizationService] Failed to preload locale data for '${language}':`,\n error\n );\n throw error;\n }\n }\n\n /**\n * Get the default language configured for the application.\n *\n * @returns The default language code\n *\n * @example\n * ```typescript\n * const defaultLang = locale.getDefaultLanguage(); // 'en'\n * ```\n */\n getDefaultLanguage(): string {\n return this.defaultLanguage;\n }\n}\n","/**\n * Locale data structure for date and number formatting.\n * \n * This data can be loaded from various sources:\n * - Browser Intl API (CoarIntlLocaleDataLoader) - default\n * - JSON files (CoarHttpLocaleDataLoader) - for overrides\n * - SignalR (future) - for dynamic backend-controlled formatting\n */\n\n/**\n * Complete locale data for a specific language/region.\n */\nexport interface CoarLocalizationData {\n /** Locale code (e.g., 'en', 'de', 'en-US', 'de-DE') */\n code: string;\n\n /** Date formatting configuration */\n date: CoarDateFormatData;\n\n /** Number formatting configuration */\n number: CoarNumberFormatData;\n\n /** Currency formatting configuration */\n currency: CoarCurrencyFormatData;\n\n /** Percent formatting configuration */\n percent: CoarPercentFormatData;\n}\n\n/**\n * Date formatting configuration.\n */\nexport interface CoarDateFormatData {\n /** \n * Date format pattern: 'dd.mm.yyyy', 'dd/mm/yyyy', 'mm/dd/yyyy', 'yyyy-mm-dd'\n */\n pattern: 'dd.mm.yyyy' | 'dd/mm/yyyy' | 'mm/dd/yyyy' | 'yyyy-mm-dd';\n\n /** \n * First day of week (0 = Sunday, 1 = Monday, ..., 6 = Saturday).\n */\n firstDayOfWeek: number;\n\n /** Localized month names (full) */\n monthNames: string[];\n\n /** Localized month names (short) */\n monthNamesShort: string[];\n\n /** Localized day names (full) */\n dayNames: string[];\n\n /** Localized day names (short) */\n dayNamesShort: string[];\n\n /** AM/PM labels */\n amPm: [string, string];\n}\n\n/**\n * Number formatting configuration.\n */\nexport interface CoarNumberFormatData {\n /** Decimal separator (e.g., \".\" for English, \",\" for German) */\n decimal: string;\n\n /** Thousands/group separator (e.g., \",\" for English, \".\" for German) */\n group: string;\n\n /** Grouping pattern ([3] means group every 3 digits) */\n grouping: number[];\n}\n\n/**\n * Currency formatting configuration.\n */\nexport interface CoarCurrencyFormatData {\n /** Default currency code (e.g., \"USD\", \"EUR\") */\n default: string;\n\n /** Currency symbols map (e.g., { \"USD\": \"$\", \"EUR\": \"€\" }) */\n symbols: Record<string, string>;\n\n /** Symbol position: 'before' ($1,234) or 'after' (1,234 €) */\n position: 'before' | 'after';\n\n /** Space between symbol and number */\n spacing: boolean;\n\n /** Decimal places for currency display */\n decimals: number;\n}\n\n/**\n * Percent formatting configuration.\n */\nexport interface CoarPercentFormatData {\n /** Percent symbol (usually \"%\") */\n symbol: string;\n\n /** Space between number and symbol (e.g., \"25%\" vs \"25 %\") */\n spacing: boolean;\n\n /** Decimal places for percent display */\n decimals: number;\n}\n","import { EnvironmentProviders, makeEnvironmentProviders } from '@angular/core';\nimport { HttpClient } from '@angular/common/http';\nimport { COAR_LOCALIZATION_DATA_LOADERS } from '../provide-coar-localization';\nimport { CoarHttpLocaleDataLoader } from './localization-data-loader';\n\n/**\n * Configuration for HTTP locale data source.\n */\nexport interface CoarHttpLocaleSourceConfig {\n /**\n * URL generator function that returns the URL for a given language.\n *\n * @default (lang) => `/locales/${lang}.json`\n *\n * @param language - Language code (e.g., 'en', 'de', 'en-US')\n * @returns URL to load locale data from\n *\n * @example\n * ```ts\n * url: (lang) => `/locales/${lang}.json`\n * url: (lang) => `/api/config/intl-${lang}.json`\n * url: (lang) => `https://cdn.example.com/locales/${lang}.json`\n * ```\n */\n url?: (language: string) => string;\n\n /**\n * Optional HTTP headers to include in requests.\n *\n * @example\n * ```ts\n * headers: {\n * 'Authorization': 'Bearer token123',\n * 'X-Custom-Header': 'value'\n * }\n * ```\n */\n headers?: Record<string, string>;\n}\n\n/**\n * Provides HTTP as a locale data source.\n *\n * This loader fetches locale data from JSON files via HTTP.\n * Typically used as a second source (after Intl) to provide business-specific\n * overrides like forced firstDayOfWeek, custom separators, etc.\n *\n * @example\n * ```ts\n * // Basic usage (default: /locales/{lang}.json)\n * provideCoarL10nHttpSource()\n *\n * // Custom URL pattern\n * provideCoarL10nHttpSource({\n * url: (lang) => `/api/config/intl-${lang}.json`\n * })\n *\n * // With authentication\n * provideCoarL10nHttpSource({\n * url: (lang) => `/api/locales/${lang}.json`,\n * headers: {\n * 'Authorization': 'Bearer ' + getToken()\n * }\n * })\n * ```\n *\n * Expected file structure:\n * ```\n * public/locales/\n * en.json - English overrides\n * de.json - German overrides\n * ```\n *\n * JSON files should contain partial CoarLocalizationData:\n * ```json\n * {\n * \"code\": \"de\",\n * \"date\": {\n * \"firstDayOfWeek\": 1\n * }\n * }\n * ```\n */\nexport function provideCoarL10nHttpSource(\n config?: CoarHttpLocaleSourceConfig\n): EnvironmentProviders {\n const urlFn = config?.url ?? ((lang: string) => `/locales/${lang}.json`);\n const headers = config?.headers;\n\n return makeEnvironmentProviders([\n {\n provide: COAR_LOCALIZATION_DATA_LOADERS,\n multi: true,\n useFactory: (http: HttpClient) => {\n return new CoarHttpLocaleDataLoader(http, urlFn, headers);\n },\n deps: [HttpClient],\n },\n ]);\n}\n","import { Pipe, PipeTransform, inject } from '@angular/core';\nimport { Temporal } from '@js-temporal/polyfill';\nimport { CoarLocalizationDataStore } from './localization-data-store';\nimport { CoarLocalizationService } from '../coar-localization.service';\n\n/**\n * Pipe for formatting dates using locale-specific configuration.\n *\n * @example\n * ```html\n * <span>{{ myDate | coarDate }}</span>\n * <span>{{ myDate | coarDate:'de' }}</span>\n * ```\n */\n@Pipe({\n name: 'coarDate',\n standalone: true,\n pure: false, // Impure to react to language changes\n})\nexport class CoarDatePipe implements PipeTransform {\n private readonly localeDataStore = inject(CoarLocalizationDataStore);\n private readonly localeService = inject(CoarLocalizationService);\n\n transform(value: Temporal.PlainDate | Date | string | null | undefined, locale?: string): string {\n if (!value) return '';\n\n // Convert to Temporal.PlainDate\n let date: Temporal.PlainDate;\n if (value instanceof Date) {\n date = Temporal.PlainDate.from({\n year: value.getFullYear(),\n month: value.getMonth() + 1,\n day: value.getDate(),\n });\n } else if (typeof value === 'string') {\n try {\n date = Temporal.PlainDate.from(value);\n } catch {\n return '';\n }\n } else {\n date = value;\n }\n\n const effectiveLocale = locale ?? this.localeService.languageState.value;\n const localeData = this.localeDataStore.getLocaleData(effectiveLocale);\n\n if (!localeData) {\n // Fallback to ISO format\n return date.toString();\n }\n\n const { pattern } = localeData.date;\n const sep = pattern.includes('.') ? '.' : pattern.includes('/') ? '/' : '-';\n\n const day = String(date.day).padStart(2, '0');\n const month = String(date.month).padStart(2, '0');\n const year = String(date.year);\n\n switch (pattern) {\n case 'dd.mm.yyyy':\n case 'dd/mm/yyyy':\n return `${day}${sep}${month}${sep}${year}`;\n case 'mm/dd/yyyy':\n return `${month}${sep}${day}${sep}${year}`;\n case 'yyyy-mm-dd':\n return `${year}${sep}${month}${sep}${day}`;\n default:\n return `${day}${sep}${month}${sep}${year}`;\n }\n }\n}\n","import { Pipe, PipeTransform, inject } from '@angular/core';\nimport { CoarLocalizationDataStore } from './localization-data-store';\nimport { CoarLocalizationService } from '../coar-localization.service';\n\n/**\n * Pipe for formatting numbers using locale-specific configuration.\n *\n * @example\n * ```html\n * <span>{{ 1234.56 | coarNumber }}</span>\n * <span>{{ 1234.56 | coarNumber:'de':2 }}</span>\n * ```\n */\n@Pipe({\n name: 'coarNumber',\n standalone: true,\n pure: false, // Impure to react to language changes\n})\nexport class CoarNumberPipe implements PipeTransform {\n private readonly localeDataStore = inject(CoarLocalizationDataStore);\n private readonly localeService = inject(CoarLocalizationService);\n\n transform(value: number | null | undefined, locale?: string, decimals = 2): string {\n if (value == null || isNaN(value)) return '';\n\n const effectiveLocale = locale ?? this.localeService.languageState.value;\n const localeData = this.localeDataStore.getLocaleData(effectiveLocale);\n\n if (!localeData) {\n // Fallback to standard formatting\n return value.toFixed(decimals);\n }\n\n const { decimal, group } = localeData.number;\n\n // Split into integer and decimal parts\n const [integerPart, decimalPart = ''] = value.toFixed(decimals).split('.');\n\n // Add thousand separators\n const formattedInteger = integerPart.replace(/\\B(?=(\\d{3})+(?!\\d))/g, group);\n\n // Combine with decimal separator\n if (decimals > 0 && decimalPart) {\n return `${formattedInteger}${decimal}${decimalPart}`;\n }\n\n return formattedInteger;\n }\n}\n","import { Pipe, PipeTransform, inject } from '@angular/core';\nimport { CoarLocalizationDataStore } from './localization-data-store';\nimport { CoarLocalizationService } from '../coar-localization.service';\n\n/**\n * Pipe for formatting currency using locale-specific configuration.\n *\n * @example\n * ```html\n * <span>{{ 1234.56 | coarCurrency }}</span>\n * <span>{{ 1234.56 | coarCurrency:'de':'EUR' }}</span>\n * ```\n */\n@Pipe({\n name: 'coarCurrency',\n standalone: true,\n pure: false, // Impure to react to language changes\n})\nexport class CoarCurrencyPipe implements PipeTransform {\n private readonly localeDataStore = inject(CoarLocalizationDataStore);\n private readonly localeService = inject(CoarLocalizationService);\n\n transform(value: number | null | undefined, locale?: string, currency?: string): string {\n if (value == null || isNaN(value)) return '';\n\n const effectiveLocale = locale ?? this.localeService.languageState.value;\n const localeData = this.localeDataStore.getLocaleData(effectiveLocale);\n\n if (!localeData) {\n // Fallback to standard formatting\n return `${currency ?? 'USD'} ${value.toFixed(2)}`;\n }\n\n const { decimal, group } = localeData.number;\n const currencyConfig = localeData.currency;\n const effectiveCurrency = currency ?? currencyConfig.default;\n const symbol = currencyConfig.symbols[effectiveCurrency] ?? effectiveCurrency;\n const decimals = currencyConfig.decimals;\n\n // Format number part\n const [integerPart, decimalPart = ''] = value.toFixed(decimals).split('.');\n const formattedInteger = integerPart.replace(/\\B(?=(\\d{3})+(?!\\d))/g, group);\n const formattedNumber =\n decimals > 0 && decimalPart\n ? `${formattedInteger}${decimal}${decimalPart}`\n : formattedInteger;\n\n // Add currency symbol\n const space = currencyConfig.spacing ? '\\u00A0' : '';\n if (currencyConfig.position === 'before') {\n return `${symbol}${space}${formattedNumber}`;\n } else {\n return `${formattedNumber}${space}${symbol}`;\n }\n }\n}\n","import { Pipe, PipeTransform, inject } from '@angular/core';\nimport { CoarLocalizationDataStore } from './localization-data-store';\nimport { CoarLocalizationService } from '../coar-localization.service';\n\n/**\n * Pipe for formatting percentages using locale-specific configuration.\n *\n * Expects a decimal value (0.25 = 25%).\n *\n * @example\n * ```html\n * <span>{{ 0.25 | coarPercent }}</span>\n * <span>{{ 0.25 | coarPercent:'de':1 }}</span>\n * ```\n */\n@Pipe({\n name: 'coarPercent',\n standalone: true,\n pure: false, // Impure to react to language changes\n})\nexport class CoarPercentPipe implements PipeTransform {\n private readonly localeDataStore = inject(CoarLocalizationDataStore);\n private readonly localeService = inject(CoarLocalizationService);\n\n transform(value: number | null | undefined, locale?: string, decimals?: number): string {\n if (value == null || isNaN(value)) return '';\n\n const effectiveLocale = locale ?? this.localeService.languageState.value;\n const localeData = this.localeDataStore.getLocaleData(effectiveLocale);\n\n if (!localeData) {\n // Fallback to standard formatting\n return `${(value * 100).toFixed(decimals ?? 0)}%`;\n }\n\n const { decimal, group } = localeData.number;\n const percentConfig = localeData.percent;\n const effectiveDecimals = decimals ?? percentConfig.decimals;\n\n // Convert to percentage (0.25 -> 25)\n const percentValue = value * 100;\n\n // Format number part\n const [integerPart, decimalPart = ''] = percentValue.toFixed(effectiveDecimals).split('.');\n const formattedInteger = integerPart.replace(/\\B(?=(\\d{3})+(?!\\d))/g, group);\n const formattedNumber =\n effectiveDecimals > 0 && decimalPart\n ? `${formattedInteger}${decimal}${decimalPart}`\n : formattedInteger;\n\n // Add percent symbol\n const space = percentConfig.spacing ? '\\u00A0' : '';\n return `${formattedNumber}${space}${percentConfig.symbol}`;\n }\n}\n","/**\n * Determines if a translation result should be considered \"missing\".\n *\n * A translation is considered missing if it is:\n * - null or undefined\n * - an empty string (after trim)\n * - exactly equal to the requested key\n *\n * This provides unified missing-key semantics across different i18n engines.\n *\n * @param key - The translation key that was requested\n * @param result - The result returned by the i18n service\n * @returns true if the translation is missing, false otherwise\n *\n * @example\n * ```ts\n * coarIsMissingTranslation('coar.button.save', null) // true\n * coarIsMissingTranslation('coar.button.save', '') // true\n * coarIsMissingTranslation('coar.button.save', 'coar.button.save') // true\n * coarIsMissingTranslation('coar.button.save', 'Save') // false\n * ```\n */\nexport function coarIsMissingTranslation(key: string, result: string | null | undefined): boolean {\n if (result == null) {\n return true;\n }\n\n const trimmed = result.trim();\n\n if (!trimmed) {\n return true;\n }\n\n return trimmed === key;\n}\n","import { Injectable, Signal, inject } from '@angular/core';\nimport { COAR_I18N_PROVIDER } from './coar-i18n-provider';\nimport { coarIsMissingTranslation } from './coar-is-missing-translation';\nimport { coarInterpolate } from './coar-interpolate';\nimport { distinctUntilChanged, map, Observable } from 'rxjs';\nimport { toSignal } from '@angular/core/rxjs-interop';\nimport { CoarLocalizationService } from '../coar-localization.service';\n\n@Injectable({ providedIn: 'root' })\nexport class CoarI18n {\n private readonly provider = inject(COAR_I18N_PROVIDER);\n private readonly locale = inject(CoarLocalizationService);\n\n /**\n * Translate a key into a localized string.\n *\n * Overloads:\n * - t(key)\n * - t(key, fallback)\n * - t(key, params)\n * - t(key, fallback, params)\n */\n t(key: string): string;\n t(key: string, fallback: string): string;\n t(key: string, params: Record<string, unknown>): string;\n t(key: string, fallback: string, params?: Record<string, unknown>): string;\n t(key: string, fallbackOrParams?: string | Record<string, unknown>, maybeParams?: Record<string, unknown>): string {\n let fallback: string | undefined;\n let params: Record<string, unknown> | undefined;\n\n if (typeof fallbackOrParams === 'string') {\n // t(key, 'Fallback') or t(key, 'Fallback', params)\n fallback = fallbackOrParams;\n params = maybeParams;\n } else {\n // t(key) or t(key, params)\n params = fallbackOrParams;\n fallback = undefined;\n }\n\n const raw = this.provider.t(key, params);\n\n const base = coarIsMissingTranslation(key, raw) ? (fallback ?? key) : (raw ?? '');\n\n // Important: the fallback (and even the key) may contain {placeholders}\n return coarInterpolate(base, params);\n }\n\n /**\n * Reactive variant that updates when the language changes.\n * Uses CoarLocalizationService to detect language changes.\n */\n t$(key: string, params?: Record<string, unknown>, fallback?: string): Observable<string> {\n // Re-evaluate on every language change from CoarLocalizationService\n return this.locale.languageState.value$.pipe(\n map(() => this.callT(key, params, fallback)),\n distinctUntilChanged()\n );\n }\n\n /**\n * Signal variant that updates when the language changes.\n * Uses CoarLocalizationService to detect language changes.\n */\n tSignal(key: string, params?: Record<string, unknown>, fallback?: string): Signal<string> {\n const obs$ = this.t$(key, params, fallback);\n return toSignal(obs$, {\n initialValue: this.callT(key, params, fallback),\n });\n }\n\n // Small helper so t$ doesn't need to replicate the overload matrix.\n private callT(key: string, params?: Record<string, unknown>, fallback?: string): string {\n if (params && fallback !== undefined) {\n // t(key, fallback, params)\n return this.t(key, fallback, params);\n }\n\n if (params) {\n // t(key, params)\n return this.t(key, params);\n }\n\n if (fallback !== undefined) {\n // t(key, fallback)\n return this.t(key, fallback);\n }\n\n // t(key)\n return this.t(key);\n }\n}\n","import { ChangeDetectorRef, Pipe, PipeTransform, inject, OnDestroy } from '@angular/core';\nimport { CoarI18n } from './coar-i18n';\nimport { BehaviorSubjectProxy } from '@cocoar/ts-utils';\n\n@Pipe({\n name: 'coarI18n',\n standalone: true,\n pure: false, // Required because translations can change at runtime\n})\nexport class CoarI18nPipe implements PipeTransform, OnDestroy {\n private readonly i18n = inject(CoarI18n);\n private readonly cdr = inject(ChangeDetectorRef);\n\n private readonly subject = new BehaviorSubjectProxy<string>('');\n\n private lastKey?: string;\n private lastParamsJson?: string;\n private lastFallback?: string;\n\n transform(\n key: string | null | undefined,\n paramsOrFallback?: Record<string, unknown> | string,\n maybeFallbackOrParams?: string | Record<string, unknown>\n ): string {\n if (!key) {\n // If there's no key, return fallback if one exists\n if (typeof paramsOrFallback === 'string') {\n return paramsOrFallback;\n }\n if (typeof maybeFallbackOrParams === 'string') {\n return maybeFallbackOrParams;\n }\n return '';\n }\n\n // Normal param/fallback dispatching\n let params: Record<string, unknown> | undefined;\n let fallback: string | undefined;\n\n // Case A — first argument is fallback (string)\n if (typeof paramsOrFallback === 'string') {\n fallback = paramsOrFallback;\n if (maybeFallbackOrParams && typeof maybeFallbackOrParams === 'object') {\n params = maybeFallbackOrParams as Record<string, unknown>;\n }\n } else {\n // Case B — first argument is params (object)\n params = paramsOrFallback ?? undefined;\n if (typeof maybeFallbackOrParams === 'string') {\n fallback = maybeFallbackOrParams;\n }\n }\n\n // Compare inputs to determine if a new subscription is needed\n const paramsJson = params ? JSON.stringify(params) : undefined;\n\n if (\n key !== this.lastKey ||\n fallback !== this.lastFallback ||\n paramsJson !== this.lastParamsJson\n ) {\n this.lastKey = key;\n this.lastFallback = fallback;\n this.lastParamsJson = paramsJson;\n\n // Switch Observable completely using BehaviorSubjectProxy\n this.subject.next(this.i18n.t$(key, params, fallback));\n\n // Update the view when new translated values arrive\n this.subject.subscribe(() => {\n this.cdr.markForCheck();\n });\n }\n\n return this.subject.value;\n }\n\n ngOnDestroy(): void {\n this.subject.unsubscribe();\n }\n}\n","import { Injectable, inject } from '@angular/core';\nimport { CoarLocalizationService } from '../coar-localization.service';\n\n/**\n * Context service providing i18n-related information to translation providers.\n *\n * This service acts as a coordination layer between the core locale system\n * and translation provider implementations (e.g., Transloco, custom providers).\n *\n * Providers should inject this service to:\n * - Get the current language\n * - Subscribe to language changes\n * - Access future i18n-related features (caching, preloading, etc.)\n *\n * This abstraction decouples providers from direct CoarLocalizationService dependency,\n * making the system more maintainable and testable.\n *\n * @example\n * ```typescript\n * // In a translation provider implementation\n * export function provideMyI18nBackend(): Provider {\n * return {\n * provide: COAR_I18N_PROVIDER,\n * useFactory: (context: CoarI18nContext, backend: MyBackend) => {\n * // Subscribe to language changes\n * context.languageState.value$.subscribe(lang => {\n * backend.switchLanguage(lang);\n * });\n *\n * return {\n * t(key: string): string {\n * return backend.translate(key);\n * }\n * };\n * },\n * deps: [CoarI18nContext, MyBackend],\n * };\n * }\n * ```\n */\n@Injectable({ providedIn: 'root' })\nexport class CoarI18nContext {\n private readonly localeService = inject(CoarLocalizationService);\n\n /**\n * Canonical language state.\n *\n * - `languageState.value` gives synchronous access\n * - `languageState.value$` is the canonical stream (emits current value immediately)\n */\n readonly languageState = this.localeService.languageState;\n\n // Future additions:\n // - Translation cache management\n // - Preloaded language files\n // - Fallback language chain configuration\n // - Missing translation tracking/reporting\n // - Translation loading state\n}\n","import { EnvironmentProviders, makeEnvironmentProviders } from '@angular/core';\nimport { COAR_TRANSLATION_LOADERS, CoarHttpTranslationLoader } from './coar-translation-loader';\n\n/**\n * Configuration for HTTP translation source.\n */\nexport interface CoarI18nHttpSourceConfig {\n /**\n * URL generator function that returns the URL for a given language.\n *\n * @default (lang) => `/i18n/${lang}.json`\n *\n * @param language - Language code (e.g., 'en', 'de', 'en-US')\n * @returns URL to load translations from\n *\n * @example\n * ```ts\n * url: (lang) => `/i18n/${lang}.json`\n * url: (lang) => `/api/translations/${lang}.json`\n * url: (lang) => `https://cdn.example.com/i18n/${lang}.json`\n * ```\n */\n url?: (language: string) => string;\n\n /**\n * Optional HTTP headers to include in requests.\n *\n * @example\n * ```ts\n * headers: {\n * 'Authorization': 'Bearer token123',\n * 'X-Custom-Header': 'value'\n * }\n * ```\n */\n headers?: Record<string, string>;\n}\n\n/**\n * Provides HTTP as a translation source.\n *\n * This loader fetches translation files from HTTP endpoints.\n * Typically used for standard i18n scenarios where translations are stored as JSON files.\n *\n * **Note:** The i18n system is automatically included by `provideCoarLocalization()`.\n * This function only registers the HTTP loader for loading translations.\n *\n * @example\n * ```ts\n * // Basic usage (default: /i18n/{lang}.json)\n * provideCoarI18nHttpSource()\n *\n * // Custom path\n * provideCoarI18nHttpSource({\n * url: (lang) => `/assets/translations/${lang}.json`\n * })\n *\n * // With authentication\n * provideCoarI18nHttpSource({\n * url: (lang) => `/api/translations/${lang}.json`,\n * headers: {\n * 'Authorization': 'Bearer ' + getToken()\n * }\n * })\n * ```\n *\n * Expected file structure:\n * ```\n * public/i18n/\n * en.json - English translations\n * de.json - German translations\n * ```\n *\n * JSON files should contain flat or nested translations:\n * ```json\n * {\n * \"app\": {\n * \"title\": \"My App\",\n * \"button\": {\n * \"save\": \"Save\",\n * \"cancel\": \"Cancel\"\n * }\n * }\n * }\n * ```\n *\n * @param config - Optional configuration\n * @returns Angular environment providers\n *\n * @see {@link CoarI18nHttpSourceConfig} for configuration options\n */\nexport function provideCoarI18nHttpSource(config?: CoarI18nHttpSourceConfig): EnvironmentProviders {\n const urlFn = config?.url ?? ((lang: string) => `/i18n/${lang}.json`);\n const headers = config?.headers;\n\n return makeEnvironmentProviders([\n {\n provide: COAR_TRANSLATION_LOADERS,\n multi: true,\n useFactory: () => {\n const loader = new CoarHttpTranslationLoader();\n loader.urlFn = urlFn;\n loader.headers = headers;\n return loader;\n },\n },\n ]);\n}\n","// Locale (language management)\nexport * from './lib/coar-localization.service';\nexport * from './lib/provide-coar-localization';\nexport * from './lib/timezone/index';\n\n// L10n (localization data and formatting pipes)\nexport * from './lib/l10n/localization-data';\nexport * from './lib/l10n/localization-data-store';\nexport * from './lib/l10n/localization-data-loader';\nexport * from './lib/l10n/intl-localization-data-loader';\nexport * from './lib/l10n/provide-l10n-http-source';\nexport * from './lib/l10n/merge-localization-data';\nexport * from './lib/l10n/date.pipe';\nexport * from './lib/l10n/number.pipe';\nexport * from './lib/l10n/currency.pipe';\nexport * from './lib/l10n/percent.pipe';\n\n// i18n (translations)\nexport * from './lib/i18n/coar-i18n';\nexport * from './lib/i18n/coar-i18n.pipe';\nexport * from './lib/i18n/coar-i18n-provider';\nexport * from './lib/i18n/coar-i18n-context';\nexport * from './lib/i18n/coar-i18n.service';\nexport * from './lib/i18n/coar-interpolate';\nexport * from './lib/i18n/coar-is-missing-translation';\nexport * from './lib/i18n/coar-translation-store';\nexport * from './lib/i18n/coar-translation-loader';\nexport * from './lib/i18n/coar-intl-translation-loader';\nexport * from './lib/i18n/provide-coar-i18n-http-source';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":["map","distinctUntilChanged"],"mappings":"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"}
1
+ {"version":3,"file":"cocoar-localization.mjs","sources":["../../../../libs/localization/src/lib/l10n/localization-data-store.ts","../../../../libs/localization/src/lib/l10n/merge-localization-data.ts","../../../../libs/localization/src/lib/l10n/localization-data-loader.ts","../../../../libs/localization/src/lib/l10n/intl-localization-data-loader.ts","../../../../libs/localization/src/lib/i18n/coar-i18n-provider.ts","../../../../libs/localization/src/lib/i18n/coar-is-missing-translation.ts","../../../../libs/localization/src/lib/i18n/coar-interpolate.ts","../../../../libs/localization/src/lib/i18n/coar-i18n.ts","../../../../libs/localization/src/lib/i18n/coar-translation-loader.ts","../../../../libs/localization/src/lib/i18n/coar-translation-store.ts","../../../../libs/localization/src/lib/i18n/coar-i18n.service.ts","../../../../libs/localization/src/lib/i18n/coar-intl-translation-loader.ts","../../../../libs/localization/src/lib/timezone/browser-timezone-provider.ts","../../../../libs/localization/src/lib/timezone/coar-timezone-providers.token.ts","../../../../libs/localization/src/lib/timezone/coar-timezone.service.ts","../../../../libs/localization/src/lib/provide-coar-localization.ts","../../../../libs/localization/src/lib/coar-localization.service.ts","../../../../libs/localization/src/lib/l10n/localization-data.ts","../../../../libs/localization/src/lib/l10n/provide-l10n-http-source.ts","../../../../libs/localization/src/lib/l10n/date.pipe.ts","../../../../libs/localization/src/lib/l10n/number.pipe.ts","../../../../libs/localization/src/lib/l10n/currency.pipe.ts","../../../../libs/localization/src/lib/l10n/percent.pipe.ts","../../../../libs/localization/src/lib/i18n/coar-i18n.pipe.ts","../../../../libs/localization/src/lib/i18n/coar-i18n-context.ts","../../../../libs/localization/src/lib/i18n/provide-coar-i18n-http-source.ts","../../../../libs/localization/src/index.ts","../../../../libs/localization/src/cocoar-localization.ts"],"sourcesContent":["import { computed, Injectable, signal, Signal, WritableSignal } from '@angular/core';\nimport type { CoarLocalizationData } from './localization-data';\n\n/**\n * Signal-based storage for locale data.\n * Provides reactive access to loaded locale formatting rules.\n */\n@Injectable({ providedIn: 'root' })\nexport class CoarLocalizationDataStore {\n private readonly store: WritableSignal<Map<string, CoarLocalizationData>> = signal(new Map());\n\n /**\n * Reactive signal that changes whenever any locale data is updated.\n * Use this in computed() to ensure reactivity to data loading.\n */\n readonly dataVersion: Signal<number> = computed(() => {\n // Reading store() creates the signal dependency\n return this.store().size;\n });\n\n /**\n * Set locale data for a specific locale.\n * @param locale Locale code (e.g., 'en', 'de', 'en-US')\n * @param data Locale data\n */\n setLocaleData(locale: string, data: CoarLocalizationData): void {\n const current = this.store();\n const updated = new Map(current);\n updated.set(locale, data);\n this.store.set(updated);\n }\n\n /**\n * Get locale data for a specific locale.\n * @param locale Locale code (e.g., 'en', 'de', 'en-US')\n * @returns Locale data or undefined if not loaded\n */\n getLocaleData(locale: string): CoarLocalizationData | undefined {\n return this.store().get(locale);\n }\n\n /**\n * Check if locale data is loaded for a specific locale.\n * @param locale Locale code (e.g., 'en', 'de', 'en-US')\n * @returns True if locale data is loaded\n */\n hasLocaleData(locale: string): boolean {\n return this.store().has(locale);\n }\n\n /**\n * Remove locale data for a specific locale.\n * @param locale Locale code (e.g., 'en', 'de', 'en-US')\n */\n removeLocaleData(locale: string): void {\n const current = this.store();\n const updated = new Map(current);\n updated.delete(locale);\n this.store.set(updated);\n }\n\n /**\n * Clear all loaded locale data.\n */\n clear(): void {\n this.store.set(new Map());\n }\n}\n","import { CoarLocalizationData } from './localization-data';\n\n/**\n * Deep merge utility for locale data.\n * Later sources override earlier sources at the field level.\n *\n * @example\n * ```ts\n * const intl = { date: { pattern: 'dd.mm.yyyy', firstDayOfWeek: 1 }, number: {...} };\n * const http = { date: { firstDayOfWeek: 0 } }; // Only override firstDayOfWeek\n *\n * const result = mergeLocalizationData([intl, http]);\n * // Result: { date: { pattern: 'dd.mm.yyyy', firstDayOfWeek: 0 }, number: {...} }\n * ```\n */\nexport function mergeLocalizationData(sources: Partial<CoarLocalizationData>[]): CoarLocalizationData | null {\n if (sources.length === 0) return null;\n\n const result: Partial<CoarLocalizationData> = {};\n\n for (const source of sources) {\n if (!source) continue;\n\n // Merge code\n if (source.code) {\n result.code = source.code;\n }\n\n // Deep merge date\n if (source.date) {\n result.date = { ...result.date, ...source.date };\n }\n\n // Deep merge number\n if (source.number) {\n result.number = { ...result.number, ...source.number };\n }\n\n // Deep merge currency\n if (source.currency) {\n result.currency = {\n ...result.currency,\n ...source.currency,\n symbols: { ...result.currency?.symbols, ...source.currency.symbols },\n };\n }\n\n // Deep merge percent\n if (source.percent) {\n result.percent = { ...result.percent, ...source.percent };\n }\n }\n\n // Ensure we have at least a code\n if (!result.code) return null;\n\n return result as CoarLocalizationData;\n}\n","import { Injectable } from '@angular/core';\nimport { Observable, of, forkJoin, map, catchError } from 'rxjs';\nimport type { CoarLocalizationData } from './localization-data';\nimport { HttpClient } from '@angular/common/http';\nimport { mergeLocalizationData } from './merge-localization-data';\n\n/**\n * Abstract loader for locale data.\n * Implement this interface to load locale data from any source (HTTP, memory, database, etc.).\n */\n@Injectable({ providedIn: 'root' })\nexport abstract class CoarLocalizationDataLoader {\n /**\n * Load locale data for a specific locale.\n * @param locale Locale code (e.g., 'en', 'de', 'en-US')\n * @returns Observable that emits the locale data\n */\n abstract loadLocaleData(locale: string): Observable<CoarLocalizationData>;\n}\n\n/**\n * HTTP-based locale data loader with BCP 47 fallback.\n *\n * Loads locale data from JSON files via HTTP.\n * Typically used as a second source (after Intl) to provide business-specific overrides.\n *\n * When a full BCP 47 tag is used (e.g., `de-AT`), the loader:\n * 1. Loads the base language file (`de.json`)\n * 2. Tries to load the regional file (`de-AT.json`)\n * 3. Deep-merges them — regional fields override base fields\n *\n * If the regional file doesn't exist, the base file is used as-is.\n * If the base file doesn't exist either, the loader fails (propagated to caller).\n *\n * @example\n * ```typescript\n * // Simple base path\n * new CoarHttpLocaleDataLoader(httpClient, (lang) => `/locales/${lang}.json`)\n *\n * // Custom URL pattern\n * new CoarHttpLocaleDataLoader(httpClient, (lang) => `/api/config/intl-${lang}.json`)\n *\n * // With headers\n * new CoarHttpLocaleDataLoader(\n * httpClient,\n * (lang) => `/api/locales/${lang}.json`,\n * { 'Authorization': 'Bearer token' }\n * )\n * ```\n *\n * ## Expected file structure\n * ```\n * /locales/\n * en.json ← base English overrides\n * en-AT.json ← optional: Austrian-specific overrides on top of en.json\n * de.json ← base German overrides\n * de-AT.json ← optional: Austrian-specific overrides on top of de.json\n * ```\n */\nexport class CoarHttpLocaleDataLoader extends CoarLocalizationDataLoader {\n constructor(\n private readonly httpClient: HttpClient,\n private readonly urlFn: (language: string) => string,\n private readonly headers?: Record<string, string>\n ) {\n super();\n }\n\n loadLocaleData(locale: string): Observable<CoarLocalizationData> {\n const baseLanguage = extractBaseLanguage(locale);\n\n if (baseLanguage) {\n // BCP 47 tag with region (e.g., 'de-AT'):\n // Load base ('de') first, then try regional ('de-AT'), deep-merge them.\n return forkJoin([\n this.loadFile(baseLanguage),\n this.loadFile(locale).pipe(catchError(() => of(null))),\n ]).pipe(\n map(([base, regional]) => {\n if (!regional) return base;\n return mergeLocalizationData([base, regional]) ?? base;\n })\n );\n }\n\n // Simple language code (e.g., 'de'): load directly.\n return this.loadFile(locale);\n }\n\n private loadFile(locale: string): Observable<CoarLocalizationData> {\n const url = this.urlFn(locale);\n return this.httpClient.get<CoarLocalizationData>(url, {\n headers: this.headers,\n });\n }\n}\n\n/**\n * Extract the base language from a BCP 47 tag.\n * Returns `null` if the tag has no region component.\n *\n * @example\n * extractBaseLanguage('de-AT') // → 'de'\n * extractBaseLanguage('en-US') // → 'en'\n * extractBaseLanguage('de') // → null\n */\nfunction extractBaseLanguage(language: string): string | null {\n const hyphenIndex = language.indexOf('-');\n return hyphenIndex > 0 ? language.substring(0, hyphenIndex) : null;\n}\n","import { Injectable } from '@angular/core';\nimport { Observable, of } from 'rxjs';\nimport { CoarLocalizationData, CoarDateFormatData } from './localization-data';\nimport { CoarLocalizationDataLoader } from './localization-data-loader';\n\n/**\n * Locale data loader that detects formatting from browser's Intl API.\n *\n * This is the default loader and works for all locales without requiring JSON files.\n * Use this when you want formatting to match the user's browser locale automatically.\n *\n * For business-specific overrides (e.g., force Monday as first day of week),\n * use CoarHttpLocaleDataLoader to load custom JSON files.\n */\n@Injectable()\nexport class CoarIntlLocaleDataLoader extends CoarLocalizationDataLoader {\n loadLocaleData(locale: string): Observable<CoarLocalizationData> {\n return of(this.detectFromIntl(locale));\n }\n\n /**\n * Detect all locale formatting from browser Intl API.\n */\n private detectFromIntl(locale: string): CoarLocalizationData {\n return {\n code: locale,\n date: this.detectDateFormat(locale),\n number: this.detectNumberFormat(locale),\n currency: this.detectCurrencyFormat(locale),\n percent: this.detectPercentFormat(locale),\n };\n }\n\n /**\n * Detect date formatting from Intl.DateTimeFormat.\n */\n private detectDateFormat(locale: string): CoarDateFormatData {\n // Detect pattern and separator\n const formatter = new Intl.DateTimeFormat(locale, {\n day: '2-digit',\n month: '2-digit',\n year: 'numeric',\n });\n\n const parts = formatter.formatToParts(new Date(2024, 11, 25)); // Dec 25, 2024\n const order: string[] = [];\n\n for (const part of parts) {\n if (part.type === 'day') order.push('d');\n else if (part.type === 'month') order.push('m');\n else if (part.type === 'year') order.push('y');\n }\n\n const orderStr = order.join('');\n const formatted = formatter.format(new Date(2024, 11, 25));\n const separator = formatted.match(/[.\\-/]/)?.[0] ?? '.';\n\n let pattern: CoarDateFormatData['pattern'];\n if (orderStr === 'mdy') {\n pattern = 'mm/dd/yyyy';\n } else if (orderStr === 'ymd') {\n pattern = 'yyyy-mm-dd';\n } else if (separator === '/') {\n pattern = 'dd/mm/yyyy';\n } else {\n pattern = 'dd.mm.yyyy';\n }\n\n // Detect first day of week using Intl.Locale API\n let firstDayOfWeek = 1; // Default to Monday\n try {\n const localeObj = new Intl.Locale(locale);\n const weekInfo = (localeObj as any).weekInfo || (localeObj as any).getWeekInfo?.();\n if (weekInfo?.firstDay !== undefined) {\n // Intl.Locale uses ISO day numbers (1=Monday, 7=Sunday)\n // Our system uses 0=Sunday, 1=Monday for consistency with Date.getDay()\n firstDayOfWeek = weekInfo.firstDay === 7 ? 0 : weekInfo.firstDay;\n }\n } catch {\n // Modern browsers support Intl.Locale with weekInfo\n // If not available, default to Monday (international standard)\n }\n\n // Generate month names\n const monthFormatter = new Intl.DateTimeFormat(locale, { month: 'long' });\n const monthFormatterShort = new Intl.DateTimeFormat(locale, { month: 'short' });\n const monthNames: string[] = [];\n const monthNamesShort: string[] = [];\n for (let m = 0; m < 12; m++) {\n const date = new Date(2024, m, 1);\n monthNames.push(monthFormatter.format(date));\n monthNamesShort.push(monthFormatterShort.format(date));\n }\n\n // Generate day names (start from Monday)\n const dayFormatter = new Intl.DateTimeFormat(locale, { weekday: 'long' });\n const dayFormatterShort = new Intl.DateTimeFormat(locale, { weekday: 'short' });\n const dayNames: string[] = [];\n const dayNamesShort: string[] = [];\n for (let d = 0; d < 7; d++) {\n // Jan 1, 2024 is Monday\n const date = new Date(2024, 0, 1 + d);\n dayNames.push(dayFormatter.format(date));\n dayNamesShort.push(dayFormatterShort.format(date));\n }\n\n // Detect AM/PM\n const amPmFormatter = new Intl.DateTimeFormat(locale, { hour: 'numeric', hour12: true });\n const amDate = new Date(2024, 0, 1, 9, 0);\n const pmDate = new Date(2024, 0, 1, 21, 0);\n const amFormatted = amPmFormatter.format(amDate);\n const pmFormatted = amPmFormatter.format(pmDate);\n const amPm: [string, string] = [\n amFormatted.replace(/\\d+/g, '').trim() || 'AM',\n pmFormatted.replace(/\\d+/g, '').trim() || 'PM',\n ];\n\n return {\n pattern,\n firstDayOfWeek,\n monthNames,\n monthNamesShort,\n dayNames,\n dayNamesShort,\n amPm,\n };\n }\n\n /**\n * Detect number formatting from Intl.NumberFormat.\n */\n private detectNumberFormat(locale: string) {\n const formatter = new Intl.NumberFormat(locale);\n\n // Prefer formatToParts so we reliably distinguish decimal vs group.\n // Example (en): 1,234,567.89\n // Example (de): 1.234.567,89\n try {\n const parts = formatter.formatToParts(1234567.89);\n const decimalPart = parts.find((p) => p.type === 'decimal');\n const groupPart = parts.find((p) => p.type === 'group');\n\n return {\n decimal: decimalPart?.value ?? '.',\n group: groupPart?.value ?? ',',\n grouping: [3],\n };\n } catch {\n // Fallback for environments without formatToParts.\n const formatted = formatter.format(1234.56);\n const formattedThousands = formatter.format(1234567);\n\n const matchDecimal = formatted.match(/\\d([^\\d])\\d{2}$/);\n const decimal = matchDecimal?.[1] ?? '.';\n\n const matchGroup = formattedThousands.match(/1([^\\d])234/);\n const group = matchGroup?.[1] ?? ',';\n\n return {\n decimal,\n group,\n grouping: [3],\n };\n }\n }\n\n /**\n * Detect currency formatting from Intl.NumberFormat.\n */\n private detectCurrencyFormat(locale: string) {\n // Try to get default currency for the locale\n let defaultCurrency = 'USD';\n try {\n // Extract region from locale (e.g., 'US' from 'en-US')\n const region = locale.split('-')[1];\n if (region) {\n // Common currency mappings\n const currencyMap: Record<string, string> = {\n US: 'USD',\n GB: 'GBP',\n DE: 'EUR',\n FR: 'EUR',\n AT: 'EUR',\n JP: 'JPY',\n CN: 'CNY',\n IN: 'INR',\n };\n defaultCurrency = currencyMap[region] || 'USD';\n }\n } catch {\n // Fallback\n }\n\n const formatter = new Intl.NumberFormat(locale, {\n style: 'currency',\n currency: defaultCurrency,\n });\n const formatted = formatter.format(1234.56);\n\n // Detect symbol position\n const numberPart = formatted.match(/\\d/)?.[0];\n const symbolIndex = formatted.indexOf(defaultCurrency.substring(0, 1));\n const numberIndex = formatted.indexOf(numberPart || '1');\n const position: 'before' | 'after' = symbolIndex < numberIndex ? 'before' : 'after';\n\n // Detect spacing\n const spacing = /\\s/.test(formatted);\n\n // Get currency symbols\n const symbols: Record<string, string> = {\n USD: '$',\n EUR: '€',\n GBP: '£',\n JPY: '¥',\n CNY: '¥',\n INR: '₹',\n };\n\n return {\n default: defaultCurrency,\n symbols,\n position,\n spacing,\n decimals: 2,\n };\n }\n\n /**\n * Detect percent formatting from Intl.NumberFormat.\n */\n private detectPercentFormat(locale: string) {\n const formatter = new Intl.NumberFormat(locale, { style: 'percent' });\n const formatted = formatter.format(0.25);\n\n // Detect spacing\n const spacing = /\\d\\s%/.test(formatted);\n\n return {\n symbol: '%',\n spacing,\n decimals: 0,\n };\n }\n}\n","import { InjectionToken } from '@angular/core';\n\n/**\n * Core i18n provider interface for translation engines.\n *\n * Providers (Transloco, custom, etc.) only need to implement this minimal interface.\n * The CoarI18n service wraps this provider and adds convenience methods.\n */\nexport interface CoarI18nProvider {\n /**\n * Translate a key into a localized string.\n *\n * @param key i18n key, e.g. 'coar.datePicker.today'\n * @param params optional interpolation parameters for placeholders like {name}\n * @returns the translated and interpolated string\n */\n t(key: string, params?: Record<string, unknown>): string;\n}\n\n/**\n * Injection token for the i18n provider implementation.\n *\n * Apps should provide this token with their chosen i18n backend (Transloco, custom, etc.).\n */\nexport const COAR_I18N_PROVIDER = new InjectionToken<CoarI18nProvider>('COAR_I18N_PROVIDER');\n","/**\n * Determines if a translation result should be considered \"missing\".\n *\n * A translation is considered missing if it is:\n * - null or undefined\n * - an empty string (after trim)\n * - exactly equal to the requested key\n *\n * This provides unified missing-key semantics across different i18n engines.\n *\n * @param key - The translation key that was requested\n * @param result - The result returned by the i18n service\n * @returns true if the translation is missing, false otherwise\n *\n * @example\n * ```ts\n * coarIsMissingTranslation('coar.button.save', null) // true\n * coarIsMissingTranslation('coar.button.save', '') // true\n * coarIsMissingTranslation('coar.button.save', 'coar.button.save') // true\n * coarIsMissingTranslation('coar.button.save', 'Save') // false\n * ```\n */\nexport function coarIsMissingTranslation(key: string, result: string | null | undefined): boolean {\n if (result == null) {\n return true;\n }\n\n const trimmed = result.trim();\n\n if (!trimmed) {\n return true;\n }\n\n return trimmed === key;\n}\n","/**\n * Interpolates {placeholders} in a template string using the given params.\n *\n * This is the official Cocoar placeholder syntax for i18n strings.\n * Placeholders use curly braces: {name}, {count}, etc.\n *\n * @param template - The template string containing {placeholder} patterns\n * @param params - Optional key-value pairs for interpolation\n * @returns The interpolated string\n *\n * @example\n * ```ts\n * coarInterpolate(\"Hello {name}, you have {count} items.\", { name: 'Alice', count: 3 })\n * // => \"Hello Alice, you have 3 items.\"\n * ```\n */\nexport function coarInterpolate(template: string, params?: Record<string, unknown>): string {\n if (!params) {\n return template;\n }\n\n return template.replace(/\\{(\\w+)\\}/g, (_, key: string) => {\n const value = params[key];\n return value == null ? '' : String(value);\n });\n}\n","import { Injectable, Signal, inject } from '@angular/core';\nimport { COAR_I18N_PROVIDER } from './coar-i18n-provider';\nimport { coarIsMissingTranslation } from './coar-is-missing-translation';\nimport { coarInterpolate } from './coar-interpolate';\nimport { distinctUntilChanged, map, Observable, of } from 'rxjs';\nimport { toSignal } from '@angular/core/rxjs-interop';\nimport { CoarLocalizationService } from '../coar-localization.service';\n\n@Injectable()\nexport class CoarI18n {\n private readonly provider = inject(COAR_I18N_PROVIDER, { optional: true });\n private readonly locale = inject(CoarLocalizationService, { optional: true });\n\n /**\n * Translate a key into a localized string.\n *\n * Overloads:\n * - t(key)\n * - t(key, fallback)\n * - t(key, params)\n * - t(key, fallback, params)\n */\n t(key: string): string;\n t(key: string, fallback: string): string;\n t(key: string, params: Record<string, unknown>): string;\n t(key: string, fallback: string, params?: Record<string, unknown>): string;\n t(key: string, fallbackOrParams?: string | Record<string, unknown>, maybeParams?: Record<string, unknown>): string {\n let fallback: string | undefined;\n let params: Record<string, unknown> | undefined;\n\n if (typeof fallbackOrParams === 'string') {\n // t(key, 'Fallback') or t(key, 'Fallback', params)\n fallback = fallbackOrParams;\n params = maybeParams;\n } else {\n // t(key) or t(key, params)\n params = fallbackOrParams;\n fallback = undefined;\n }\n\n if (!this.provider) {\n return coarInterpolate(fallback ?? key, params);\n }\n\n const raw = this.provider.t(key, params);\n\n const base = coarIsMissingTranslation(key, raw) ? (fallback ?? key) : (raw ?? '');\n\n // Important: the fallback (and even the key) may contain {placeholders}\n return coarInterpolate(base, params);\n }\n\n /**\n * Reactive variant that updates when the language changes.\n * Uses CoarLocalizationService to detect language changes.\n */\n t$(key: string, params?: Record<string, unknown>, fallback?: string): Observable<string> {\n if (!this.locale) {\n return of(this.callT(key, params, fallback));\n }\n\n // Re-evaluate on every language change from CoarLocalizationService\n return this.locale.languageState.value$.pipe(\n map(() => this.callT(key, params, fallback)),\n distinctUntilChanged()\n );\n }\n\n /**\n * Signal variant that updates when the language changes.\n * Uses CoarLocalizationService to detect language changes.\n */\n tSignal(key: string, params?: Record<string, unknown>, fallback?: string): Signal<string> {\n const obs$ = this.t$(key, params, fallback);\n return toSignal(obs$, {\n initialValue: this.callT(key, params, fallback),\n });\n }\n\n // Small helper so t$ doesn't need to replicate the overload matrix.\n private callT(key: string, params?: Record<string, unknown>, fallback?: string): string {\n if (params && fallback !== undefined) {\n // t(key, fallback, params)\n return this.t(key, fallback, params);\n }\n\n if (params) {\n // t(key, params)\n return this.t(key, params);\n }\n\n if (fallback !== undefined) {\n // t(key, fallback)\n return this.t(key, fallback);\n }\n\n // t(key)\n return this.t(key);\n }\n}\n","import { Injectable, inject, InjectionToken } from '@angular/core';\nimport { HttpClient } from '@angular/common/http';\nimport { Observable, of, forkJoin, map, catchError } from 'rxjs';\nimport type { CoarTranslations } from './coar-translation-store';\n\n/**\n * Injection token for translation loaders (multi-provider).\n * Loaders are executed in order and results are deep-merged.\n * Intl loader is always first (provides common defaults from browser Intl API).\n */\nexport const COAR_TRANSLATION_LOADERS = new InjectionToken<CoarTranslationLoader[]>(\n 'COAR_TRANSLATION_LOADERS'\n);\n\n/**\n * Abstract loader for translation data.\n *\n * Implement this interface to load translations from any source:\n * - HTTP endpoints\n * - SignalR real-time updates\n * - Static imports\n * - IndexedDB\n * - etc.\n *\n * @example\n * ```ts\n * @Injectable()\n * export class MyCustomLoader implements CoarTranslationLoader {\n * loadTranslations(language: string): Observable<CoarTranslations> {\n * // Load from your custom source\n * return this.myService.getTranslations(language);\n * }\n * }\n * ```\n */\nexport abstract class CoarTranslationLoader {\n /**\n * Loads translation data for a specific language.\n *\n * @param language - Language code to load (e.g., 'en', 'de')\n * @returns Observable that emits translation key-value pairs\n */\n abstract loadTranslations(language: string): Observable<CoarTranslations>;\n}\n\n/**\n * HTTP-based translation loader with BCP 47 fallback.\n *\n * Loads translation JSON files from a configurable URL function.\n *\n * When a full BCP 47 tag is used (e.g., `de-AT`), the loader:\n * 1. Loads the base language file (`de.json`)\n * 2. Tries to load the regional file (`de-AT.json`)\n * 3. Merges them — regional keys override base keys\n *\n * If the regional file doesn't exist, the base file is used as-is.\n * If the base file doesn't exist either, the loader fails (propagated to caller).\n *\n * This means `en.json` serves all English variants. An optional `en-AT.json`\n * only needs to contain keys that differ from the base.\n *\n * ## Usage\n * ```ts\n * const loader = new CoarHttpTranslationLoader();\n * loader.urlFn = (lang) => `/i18n/${lang}.json`;\n * loader.headers = { 'Authorization': 'Bearer token' };\n * ```\n *\n * ## Expected file structure\n * ```\n * /i18n/\n * en.json ← base English (used for en-US, en-GB, en-AT, etc.)\n * en-AT.json ← optional: only keys that differ from en.json\n * de.json ← base German\n * de-AT.json ← optional: Austrian overrides (if any)\n * ```\n *\n * ## Expected JSON format\n * ```json\n * {\n * \"hello\": \"Hello\",\n * \"goodbye\": \"Goodbye\",\n * \"welcome\": \"Welcome, {{name}}!\"\n * }\n * ```\n */\n@Injectable()\nexport class CoarHttpTranslationLoader implements CoarTranslationLoader {\n private readonly http = inject(HttpClient);\n\n /** URL generator function */\n urlFn: (language: string) => string = (lang) => `/i18n/${lang}.json`;\n\n /** Optional HTTP headers */\n headers?: Record<string, string>;\n\n loadTranslations(language: string): Observable<CoarTranslations> {\n const baseLanguage = extractBaseLanguage(language);\n\n if (baseLanguage) {\n // BCP 47 tag with region (e.g., 'de-AT'):\n // Load base ('de') first, then try regional ('de-AT'), merge them.\n return forkJoin([\n this.loadFile(baseLanguage),\n this.loadFile(language).pipe(catchError(() => of(null))),\n ]).pipe(\n map(([base, regional]) => ({\n ...base,\n ...(regional ?? {}),\n }))\n );\n }\n\n // Simple language code (e.g., 'de'): load directly.\n return this.loadFile(language);\n }\n\n private loadFile(language: string): Observable<CoarTranslations> {\n const url = this.urlFn(language);\n return this.http.get<CoarTranslations>(url, {\n headers: this.headers,\n });\n }\n}\n\n/**\n * Extract the base language from a BCP 47 tag.\n * Returns `null` if the tag has no region component.\n *\n * @example\n * extractBaseLanguage('de-AT') // → 'de'\n * extractBaseLanguage('en-US') // → 'en'\n * extractBaseLanguage('de') // → null\n */\nfunction extractBaseLanguage(language: string): string | null {\n const hyphenIndex = language.indexOf('-');\n return hyphenIndex > 0 ? language.substring(0, hyphenIndex) : null;\n}\n","import { Injectable, Signal, WritableSignal, computed, signal } from '@angular/core';\n\n/**\n * Translation storage for a single language.\n * Maps translation keys to their values.\n */\nexport type CoarTranslations = Record<string, string>;\n\n/**\n * Flattens nested translation objects into dot notation.\n *\n * Supports both flat and nested JSON structures:\n * - Flat: { \"app.title\": \"My App\" }\n * - Nested: { \"app\": { \"title\": \"My App\" } }\n *\n * Both produce: { \"app.title\": \"My App\" }\n *\n * @example\n * Input: { app: { title: 'My App', subtitle: 'Welcome' } }\n * Output: { 'app.title': 'My App', 'app.subtitle': 'Welcome' }\n */\nfunction flattenTranslations(obj: unknown, prefix = ''): CoarTranslations {\n const result: CoarTranslations = {};\n\n if (typeof obj !== 'object' || obj === null) {\n return result;\n }\n\n for (const [key, value] of Object.entries(obj)) {\n const newKey = prefix ? `${prefix}.${key}` : key;\n\n if (typeof value === 'object' && value !== null && !Array.isArray(value)) {\n // Recursively flatten nested objects\n Object.assign(result, flattenTranslations(value, newKey));\n } else if (typeof value === 'string') {\n // Store string values\n result[newKey] = value;\n }\n // Skip non-string primitive values (numbers, booleans, arrays)\n }\n\n return result;\n}\n\n/**\n * Reactive store for translation data.\n *\n * Stores translations for multiple languages in memory and provides\n * Signal-based API for reactive updates.\n *\n * ## Features\n * - Signal-based reactive API\n * - Language-scoped storage\n * - Simple Map-based implementation\n * - Zero dependencies beyond Angular core\n *\n * @example\n * ```ts\n * const store = inject(CoarTranslationStore);\n *\n * // Load translations\n * store.setTranslations('en', { 'hello': 'Hello' });\n * store.setTranslations('de', { 'hello': 'Hallo' });\n *\n * // Check if language is loaded\n * if (store.hasLanguage('en')) {\n * const translations = store.getTranslations('en');\n * }\n *\n * // Get specific translation\n * const value = store.getTranslation('en', 'hello'); // 'Hello'\n *\n * // Check for missing keys\n * const missing = store.getTranslation('en', 'unknown'); // undefined\n * ```\n */\n@Injectable({ providedIn: 'root' })\nexport class CoarTranslationStore {\n /**\n * Internal storage: Map<language, Map<key, translation>>\n *\n * Why nested Maps instead of Record:\n * - Faster lookups for large translation sets\n * - No prototype chain pollution\n * - Clear separation between languages\n */\n private readonly storage: WritableSignal<Map<string, Map<string, string>>> = signal(new Map());\n\n /**\n * Set of all loaded languages.\n * Used for quick existence checks.\n */\n readonly loadedLanguages: Signal<Set<string>> = computed(() => {\n const map = this.storage();\n return new Set(map.keys());\n });\n\n /**\n * Stores all translations for a specific language.\n *\n * Replaces any existing translations for that language.\n * Automatically flattens nested objects into dot notation.\n *\n * @param language - Language code (e.g., 'en', 'de')\n * @param translations - Translation key-value pairs (flat or nested)\n *\n * @example\n * ```ts\n * // Flat format\n * store.setTranslations('en', { 'hello': 'Hello', 'app.title': 'My App' });\n *\n * // Nested format (auto-flattened)\n * store.setTranslations('en', { app: { title: 'My App' }, hello: 'Hello' });\n * // Both produce the same result\n * ```\n */\n setTranslations(\n language: string,\n translations: CoarTranslations | Record<string, unknown>\n ): void {\n // Flatten nested structures into dot notation\n const flattened = flattenTranslations(translations);\n const translationMap = new Map<string, string>(Object.entries(flattened));\n\n this.storage.update((current) => {\n const next = new Map(current);\n next.set(language, translationMap);\n return next;\n });\n }\n\n /**\n * Updates a single translation key for a specific language.\n *\n * Creates the language if it doesn't exist.\n * Useful for real-time updates via SignalR.\n *\n * @param language - Language code\n * @param key - Translation key\n * @param value - Translation value\n *\n * @example\n * ```ts\n * // SignalR: Update single key in real-time\n * signalR.on('TranslationUpdated', ({ lang, key, value }) => {\n * store.setTranslation(lang, key, value);\n * });\n * ```\n */\n setTranslation(language: string, key: string, value: string): void {\n this.storage.update((current) => {\n const next = new Map(current);\n const langMap = next.get(language) ?? new Map<string, string>();\n const updatedLangMap = new Map(langMap);\n updatedLangMap.set(key, value);\n next.set(language, updatedLangMap);\n return next;\n });\n }\n\n /**\n * Merges partial translations into an existing language.\n *\n * Only updates/adds the provided keys, keeps existing keys intact.\n * Creates the language if it doesn't exist.\n * Automatically flattens nested objects into dot notation.\n *\n * @param language - Language code\n * @param partialTranslations - Partial translation key-value pairs to merge (flat or nested)\n *\n * @example\n * ```ts\n * // Flat format\n * // Existing: { 'hello': 'Hello', 'goodbye': 'Goodbye' }\n * store.updateTranslations('en', { 'hello': 'Hi' });\n * // Result: { 'hello': 'Hi', 'goodbye': 'Goodbye' }\n * ```\n *\n * @example\n * ```ts\n * // Nested format (auto-flattened)\n * store.updateTranslations('en', { app: { title: 'New Title' } });\n * // Updates 'app.title' key\n * ```\n *\n * @example\n * ```ts\n * // SignalR: Batch update multiple keys\n * signalR.on('TranslationsBatchUpdated', ({ lang, updates }) => {\n * store.updateTranslations(lang, updates);\n * });\n * ```\n */\n updateTranslations(\n language: string,\n partialTranslations: CoarTranslations | Record<string, unknown>\n ): void {\n // Flatten nested structures into dot notation\n const flattened = flattenTranslations(partialTranslations);\n\n this.storage.update((current) => {\n const next = new Map(current);\n const langMap = next.get(language) ?? new Map<string, string>();\n const updatedLangMap = new Map(langMap);\n\n // Merge partial updates into existing translations\n for (const [key, value] of Object.entries(flattened)) {\n updatedLangMap.set(key, value);\n }\n\n next.set(language, updatedLangMap);\n return next;\n });\n }\n\n /**\n * Checks if translations for a language are loaded.\n *\n * @param language - Language code to check\n * @returns True if language is loaded\n */\n hasLanguage(language: string): boolean {\n return this.storage().has(language);\n }\n\n /**\n * Gets all translations for a specific language.\n *\n * @param language - Language code\n * @returns Translation map, or undefined if language not loaded\n */\n getTranslations(language: string): Map<string, string> | undefined {\n return this.storage().get(language);\n }\n\n /**\n * Gets a specific translation value.\n *\n * @param language - Language code\n * @param key - Translation key\n * @returns Translation value, or undefined if not found\n */\n getTranslation(language: string, key: string): string | undefined {\n return this.storage().get(language)?.get(key);\n }\n\n /**\n * Clears all translations from the store.\n *\n * Used primarily for testing.\n */\n clear(): void {\n this.storage.set(new Map());\n }\n}\n","import { DestroyRef, Injectable, inject } from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { Observable, of, switchMap, tap, catchError, forkJoin } from 'rxjs';\nimport { CoarLocalizationService } from '../coar-localization.service';\nimport { CoarI18nProvider } from './coar-i18n-provider';\nimport { coarInterpolate } from './coar-interpolate';\nimport { COAR_TRANSLATION_LOADERS } from './coar-translation-loader';\nimport { CoarTranslationStore, CoarTranslations } from './coar-translation-store';\n\n/**\n * Core i18n service implementation.\n *\n * Integrates:\n * - `CoarLocalizationService` - Language state management\n * - `CoarTranslationStore` - Translation storage\n * - `CoarTranslationLoader` - Translation loading\n * - `CoarI18nContext` - Coordination layer\n *\n * ## Features\n * - Automatic translation loading when language changes\n * - Missing translation detection\n * - Parameter interpolation\n * - Reactive Signal-based API\n *\n * ## Usage\n * Use `provideCoarLocalization()` + `provideCoarI18nHttpSource()` to configure.\n *\n * @example\n * ```ts\n * export const appConfig: ApplicationConfig = {\n * providers: [\n * provideCoarLocalization({\n * defaultLanguage: 'en',\n * }),\n * provideCoarI18nHttpSource(),\n * ],\n * };\n * ```\n */\n@Injectable()\nexport class CoarI18nService implements CoarI18nProvider {\n private readonly locale = inject(CoarLocalizationService);\n private readonly store = inject(CoarTranslationStore);\n private readonly loaders = inject(COAR_TRANSLATION_LOADERS, { optional: true }) ?? [];\n private readonly destroyRef = inject(DestroyRef);\n\n constructor() {\n // Coordination: Wait for pending language changes, load translations, then resolve\n // This ensures translations are ready BEFORE the language state changes\n this.locale.pendingLanguageChange$\n .pipe(\n takeUntilDestroyed(this.destroyRef),\n switchMap(({ language, resolve }) => {\n // Load translations if not already loaded\n if (this.store.hasLanguage(language)) {\n resolve(); // Already loaded, resolve immediately\n return of(void 0);\n }\n\n // Load and then resolve\n return this.loadLanguage(language).pipe(\n tap(() => resolve()) // Signal that translations are ready\n );\n })\n )\n .subscribe();\n\n // Fallback: Auto-load translations when language changes without coordination\n // (for backwards compatibility if someone directly mutates the subject)\n this.locale.languageState.value$.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((lang) => {\n if (this.store.hasLanguage(lang)) {\n return;\n }\n\n this.loadLanguage(lang).subscribe();\n });\n }\n\n t(key: string, params?: Record<string, unknown>): string {\n const lang = this.locale.languageState.value;\n const translations = this.store.getTranslations(lang);\n\n // Language not loaded yet - return key\n if (!translations) {\n return key;\n }\n\n const value = translations.get(key);\n\n // Missing translation - return key\n if (value === undefined) {\n return key;\n }\n\n // No params - return value as-is\n if (!params) {\n return value;\n }\n\n // Interpolate params\n return coarInterpolate(value, params);\n }\n\n /**\n * Loads translations from all sources and deep-merges them.\n *\n * Sources are executed in order:\n * 1. Intl (always first, provides common translations from browser APIs)\n * 2. HTTP (if configured, merges application-specific overrides)\n * 3. Custom sources (if provided, can add dynamic updates)\n *\n * Later sources override earlier sources at the key level.\n *\n * @param language - Language code to load\n * @returns Observable that completes when loading finishes\n */\n private loadLanguage(language: string): Observable<void> {\n // No loaders configured - mark as loaded with empty translations\n if (this.loaders.length === 0) {\n this.store.setTranslations(language, {});\n return of(void 0);\n }\n\n // Load from all sources in parallel\n const loadObservables = this.loaders.map((loader) =>\n loader.loadTranslations(language).pipe(\n catchError((err) => {\n console.warn(`[CoarI18n] Translation loader failed for '${language}':`, err);\n return of(null); // Return null for failed sources\n })\n )\n );\n\n return forkJoin(loadObservables).pipe(\n tap((results) => {\n // Deep merge all sources (nulls are ignored)\n const merged = this.mergeTranslations(\n results.filter((r) => r !== null) as CoarTranslations[]\n );\n this.store.setTranslations(language, merged);\n }),\n switchMap(() => of(void 0)),\n catchError((error) => {\n console.error(`[CoarI18n] Failed to load translations for '${language}':`, error);\n // Store empty translations to prevent repeated load attempts\n this.store.setTranslations(language, {});\n return of(void 0);\n })\n );\n }\n\n /**\n * Merges multiple translation sources.\n * Later sources override earlier sources at the key level.\n */\n private mergeTranslations(sources: CoarTranslations[]): CoarTranslations {\n const result: CoarTranslations = {};\n\n for (const source of sources) {\n if (!source) continue;\n\n // Merge all keys from this source\n for (const [key, value] of Object.entries(source)) {\n result[key] = value;\n }\n }\n\n return result;\n }\n\n /**\n * Preloads translations for a specific language.\n *\n * Used by APP_INITIALIZER to prevent flash of untranslated content.\n *\n * @param language - Language code to preload\n * @returns Promise that resolves when loading completes\n */\n preloadLanguage(language: string): Promise<void> {\n // Already loaded - return immediately\n if (this.store.hasLanguage(language)) {\n return Promise.resolve();\n }\n\n return new Promise((resolve) => {\n this.loadLanguage(language).subscribe(() => resolve());\n });\n }\n}\n","import { Injectable } from '@angular/core';\nimport { Observable, of } from 'rxjs';\nimport type { CoarTranslations } from './coar-translation-store';\nimport { CoarTranslationLoader } from './coar-translation-loader';\n\n/**\n * Translation loader that generates common translations from browser's Intl API.\n *\n * This loader provides default translations for common UI elements that can be\n * automatically localized using browser APIs, without requiring JSON files.\n *\n * Translations generated:\n * - Relative time labels (today, yesterday, tomorrow)\n * - Month names (full and abbreviated)\n * - Weekday names (full and abbreviated)\n * - Common date/time units\n *\n * These translations can be overridden by registering additional loaders\n * (e.g., HTTP loader) that provide custom values.\n *\n * @example\n * ```ts\n * // Automatic registration via provideCoarLocalization()\n * provideCoarLocalization({ defaultLanguage: 'en' })\n *\n * // Intl loader provides: { 'common.today': 'today' }\n * // HTTP loader can override: { 'common.today': 'Now' }\n * ```\n */\n@Injectable()\nexport class CoarIntlTranslationLoader extends CoarTranslationLoader {\n loadTranslations(locale: string): Observable<CoarTranslations> {\n return of(this.generateFromIntl(locale));\n }\n\n /**\n * Generate translations from browser Intl API.\n */\n private generateFromIntl(locale: string): CoarTranslations {\n const translations: CoarTranslations = {};\n\n // Relative time labels (for date pickers, calendars, etc.)\n try {\n const rtf = new Intl.RelativeTimeFormat(locale, { numeric: 'auto' });\n translations['common.today'] = rtf.format(0, 'day');\n translations['common.yesterday'] = rtf.format(-1, 'day');\n translations['common.tomorrow'] = rtf.format(1, 'day');\n } catch {\n // Fallback for older browsers without RelativeTimeFormat\n translations['common.today'] = 'today';\n translations['common.yesterday'] = 'yesterday';\n translations['common.tomorrow'] = 'tomorrow';\n }\n\n // Month names (full)\n const monthFormatter = new Intl.DateTimeFormat(locale, { month: 'long' });\n for (let m = 0; m < 12; m++) {\n const date = new Date(2024, m, 1);\n const monthName = monthFormatter.format(date);\n translations[`common.month.${m + 1}`] = monthName;\n }\n\n // Month names (abbreviated)\n const monthFormatterShort = new Intl.DateTimeFormat(locale, { month: 'short' });\n for (let m = 0; m < 12; m++) {\n const date = new Date(2024, m, 1);\n const monthName = monthFormatterShort.format(date);\n translations[`common.month.short.${m + 1}`] = monthName;\n }\n\n // Weekday names (full) - Monday=1, Sunday=7\n const dayFormatter = new Intl.DateTimeFormat(locale, { weekday: 'long' });\n for (let d = 0; d < 7; d++) {\n // Jan 1, 2024 is Monday\n const date = new Date(2024, 0, 1 + d);\n const dayName = dayFormatter.format(date);\n translations[`common.weekday.${d + 1}`] = dayName;\n }\n\n // Weekday names (abbreviated)\n const dayFormatterShort = new Intl.DateTimeFormat(locale, { weekday: 'short' });\n for (let d = 0; d < 7; d++) {\n const date = new Date(2024, 0, 1 + d);\n const dayName = dayFormatterShort.format(date);\n translations[`common.weekday.short.${d + 1}`] = dayName;\n }\n\n return translations;\n }\n}\n","import { Injectable } from '@angular/core';\nimport { Observable, of } from 'rxjs';\nimport { CoarTimeZoneProvider } from './coar-timezone-provider';\n\n/**\n * Built-in timezone provider using browser's Intl API.\n *\n * Always present as guaranteed baseline fallback.\n * Returns the user's operating system timezone.\n *\n * Note: This is a one-time snapshot. If user changes OS timezone\n * while app is running, this will not update (browser limitation).\n *\n * @internal\n */\n@Injectable()\nexport class BrowserTimeZoneProvider implements CoarTimeZoneProvider {\n readonly timeZone$: Observable<string | null>;\n\n constructor() {\n // Detect browser timezone using Intl API\n // This is a one-time snapshot (browser doesn't provide reactive updates)\n const browserTimeZone = this.detectBrowserTimeZone();\n this.timeZone$ = of(browserTimeZone);\n }\n\n private detectBrowserTimeZone(): string {\n try {\n // Use Intl API to get user's timezone\n // Example return values: \"America/New_York\", \"Europe/Paris\", \"Asia/Tokyo\"\n const timeZone = Intl.DateTimeFormat().resolvedOptions().timeZone;\n\n // Fallback to UTC if browser returns undefined (shouldn't happen in modern browsers)\n return timeZone || 'UTC';\n } catch {\n // Fallback to UTC if Intl API fails\n return 'UTC';\n }\n }\n}\n","import { InjectionToken } from '@angular/core';\nimport { CoarTimeZoneProvider } from './coar-timezone-provider';\n\n/**\n * Injection token for custom timezone providers (multi-provider).\n *\n * Providers are resolved in array order (first to last).\n * First non-null value wins.\n *\n * Browser provider is always present as guaranteed baseline (automatically added).\n *\n * @internal\n */\nexport const COAR_TIMEZONE_PROVIDERS = new InjectionToken<CoarTimeZoneProvider[]>(\n 'COAR_TIMEZONE_PROVIDERS'\n);\n","import { Injectable, Optional, inject } from '@angular/core';\nimport { toSignal } from '@angular/core/rxjs-interop';\nimport { Observable, combineLatest, of } from 'rxjs';\nimport { distinctUntilChanged, map } from 'rxjs/operators';\nimport { CoarTimeZoneProvider } from './coar-timezone-provider';\nimport { BrowserTimeZoneProvider } from './browser-timezone-provider';\nimport { COAR_TIMEZONE_PROVIDERS } from './coar-timezone-providers.token';\n\n/**\n * Service for timezone resolution with pluggable provider hierarchy.\n *\n * Resolution order:\n * 1. Custom providers (from config, in array order)\n * 2. Browser provider (Intl API, always present as guaranteed baseline)\n * 3. UTC safety net (if all providers return null)\n *\n * First non-null value wins. Changes propagate reactively.\n *\n * @example\n * ```ts\n * // In component\n * export class MyComponent {\n * private timeZoneService = inject(CoarTimeZoneService);\n *\n * // Reactive signal (updates when timezone changes)\n * currentTimeZone = this.timeZoneService.currentTimeZone;\n *\n * // Observable stream\n * timeZone$ = this.timeZoneService.timeZone$;\n * }\n * ```\n */\n@Injectable({ providedIn: 'root' })\nexport class CoarTimeZoneService {\n private readonly browserProvider = inject(BrowserTimeZoneProvider);\n private readonly customProviders = inject(COAR_TIMEZONE_PROVIDERS, { optional: true }) ?? [];\n\n /**\n * Observable stream of the current timezone (IANA identifier).\n *\n * Emits when any provider in the hierarchy changes.\n * Uses `distinctUntilChanged()` to prevent unnecessary emissions.\n *\n * Resolution order: Custom providers → Browser → UTC\n */\n readonly timeZone$: Observable<string>;\n\n /**\n * Signal of the current timezone (IANA identifier).\n *\n * Automatically updates when timezone changes.\n * Use this in templates or reactive contexts.\n */\n readonly currentTimeZone;\n\n constructor() {\n // Build provider chain: Custom providers → Browser (always last)\n const allProviders: CoarTimeZoneProvider[] = [\n ...this.customProviders,\n this.browserProvider, // Browser is guaranteed baseline, always present\n ];\n\n // Combine all provider streams\n const providerStreams = allProviders.map((provider) => provider.timeZone$);\n\n this.timeZone$ = combineLatest(providerStreams).pipe(\n // Find first non-null value in priority order\n map((timeZones) => {\n const resolved = timeZones.find((tz) => tz !== null);\n // UTC as safety net if all providers return null (shouldn't happen)\n return resolved ?? 'UTC';\n }),\n // Prevent unnecessary emissions when value doesn't actually change\n distinctUntilChanged()\n );\n\n // Initialize signal after timeZone$ is set up\n this.currentTimeZone = toSignal(this.timeZone$, { requireSync: true });\n }\n}\n","import {\n APP_INITIALIZER,\n EnvironmentProviders,\n InjectionToken,\n inject,\n makeEnvironmentProviders,\n} from '@angular/core';\nimport { CoarLocalizationService } from './coar-localization.service';\nimport { CoarLocalizationDataLoader } from './l10n/localization-data-loader';\nimport { CoarLocalizationDataStore } from './l10n/localization-data-store';\nimport { CoarIntlLocaleDataLoader } from './l10n/intl-localization-data-loader';\nimport { CoarI18n } from './i18n/coar-i18n';\nimport { COAR_I18N_PROVIDER } from './i18n/coar-i18n-provider';\nimport { CoarI18nService } from './i18n/coar-i18n.service';\nimport { COAR_TRANSLATION_LOADERS } from './i18n/coar-translation-loader';\nimport { CoarIntlTranslationLoader } from './i18n/coar-intl-translation-loader';\nimport { CoarTimeZoneProvider } from './timezone/coar-timezone-provider';\nimport { BrowserTimeZoneProvider } from './timezone/browser-timezone-provider';\nimport { CoarTimeZoneService } from './timezone/coar-timezone.service';\nimport { COAR_TIMEZONE_PROVIDERS } from './timezone/coar-timezone-providers.token';\n\n/**\n * Configuration for the locale system.\n */\nexport interface CoarLocalizationConfig {\n /**\n * Default language to use on initialization.\n */\n defaultLanguage: string;\n\n /**\n * Optional custom timezone providers.\n *\n * Providers are resolved in array order (first to last).\n * First non-null value wins.\n *\n * Browser provider (Intl API) is always present as guaranteed baseline\n * and automatically added after custom providers.\n *\n * @example\n * ```ts\n * // With custom profile provider\n * provideCoarLocalization({\n * defaultLanguage: 'en',\n * timeZoneProviders: [\n * inject(ProfileTimeZoneProvider)\n * ]\n * })\n * ```\n */\n timeZoneProviders?: CoarTimeZoneProvider[];\n}\n\n/**\n * Injection token for locale configuration.\n */\nexport const COAR_LOCALIZATION_CONFIG = new InjectionToken<CoarLocalizationConfig>(\n 'COAR_LOCALIZATION_CONFIG'\n);\n\n/**\n * Injection token for locale data loaders (multi-provider).\n * Loaders are executed in order and results are deep-merged.\n * Intl loader is always first (provides complete defaults).\n */\nexport const COAR_LOCALIZATION_DATA_LOADERS = new InjectionToken<CoarLocalizationDataLoader[]>(\n 'COAR_LOCALIZATION_DATA_LOADERS'\n);\n\n/**\n * Provides the core localization system (language management + L10n + i18n).\n *\n * Automatically includes:\n * - Language management (CoarLocalizationService)\n * - L10n: Browser Intl API for number/date formatting (always first source)\n * - i18n: Translation system (CoarI18nService + CoarTranslationStore)\n *\n * Add optional data sources with:\n * - `provideCoarL10nHttpSource()` - Load L10n overrides from JSON files\n * - `provideCoarI18nHttpSource()` - Load i18n translations from JSON files\n * - Custom sources via multi-providers\n *\n * Sources are executed in registration order and deep-merged.\n *\n * @example\n * ```ts\n * // Basic setup (Intl formatting only, no i18n loader)\n * provideCoarLocalization({\n * defaultLanguage: 'en',\n * })\n *\n * // With L10n overrides and i18n translations\n * provideCoarLocalization({ defaultLanguage: 'en' }),\n * provideCoarL10nHttpSource({\n * url: (lang) => `/locales/${lang}.json`\n * }),\n * provideCoarI18nHttpSource(), // Defaults to /i18n/{lang}.json\n * ```\n */\nexport function provideCoarLocalization(config: CoarLocalizationConfig): EnvironmentProviders {\n return makeEnvironmentProviders([\n {\n provide: COAR_LOCALIZATION_CONFIG,\n useValue: config,\n },\n CoarLocalizationService,\n CoarLocalizationDataStore,\n\n // TimeZone: Provide the timezone service\n CoarTimeZoneService,\n\n // TimeZone: Browser provider (always present as guaranteed baseline)\n BrowserTimeZoneProvider,\n\n // TimeZone: Register custom providers from config (if any)\n ...(config.timeZoneProviders?.map((provider) => ({\n provide: COAR_TIMEZONE_PROVIDERS,\n multi: true,\n useValue: provider,\n })) ?? []),\n\n // L10n: Auto-include Intl source as first loader (provides complete defaults)\n {\n provide: COAR_LOCALIZATION_DATA_LOADERS,\n multi: true,\n useClass: CoarIntlLocaleDataLoader,\n },\n\n // i18n: Provide the i18n service (translations)\n {\n provide: COAR_I18N_PROVIDER,\n useClass: CoarI18nService,\n },\n\n // i18n: Convenience service used by CoarI18nPipe and consumers\n CoarI18n,\n\n // i18n: Auto-include Intl source as first translation loader (provides common defaults)\n {\n provide: COAR_TRANSLATION_LOADERS,\n multi: true,\n useClass: CoarIntlTranslationLoader,\n },\n\n // APP_INITIALIZER: Preload default language (L10n + i18n if loader registered)\n {\n provide: APP_INITIALIZER,\n multi: true,\n useFactory: () => {\n const localeService = inject(CoarLocalizationService);\n const i18nService = inject(COAR_I18N_PROVIDER) as CoarI18nService;\n\n return async () => {\n // Preload L10n data for default language\n try {\n await localeService.setLanguage(config.defaultLanguage);\n } catch (error) {\n console.warn(\n `[CoarLocale] Failed to preload locale data for '${config.defaultLanguage}':`,\n error\n );\n }\n\n // Preload i18n translations if loader is available\n try {\n await i18nService.preloadLanguage(config.defaultLanguage);\n } catch (error) {\n // Silently ignore if no loader is registered\n // This allows using L10n without i18n\n }\n };\n },\n },\n ]);\n}\n","import { inject, Injectable } from '@angular/core';\nimport { BehaviorSubject, Subject, lastValueFrom } from 'rxjs';\nimport { ReadonlyState } from '@cocoar/ts-utils';\nimport {\n COAR_LOCALIZATION_CONFIG,\n COAR_LOCALIZATION_DATA_LOADERS,\n} from './provide-coar-localization';\nimport { CoarLocalizationDataStore } from './l10n/localization-data-store';\nimport { mergeLocalizationData } from './l10n/merge-localization-data';\n\n/**\n * Represents a pending language change that needs coordination with i18n.\n */\ninterface PendingLanguageChange {\n language: string;\n resolve: () => void;\n}\n\n/**\n * Core locale service responsible for language management.\n *\n * This service manages the current language state and notifies consumers\n * about language changes. It serves as the single source of truth for\n * the application's current language.\n *\n * Other systems (i18n, localization/formatting) can subscribe to language\n * changes and react accordingly.\n *\n * @example\n * ```typescript\n * import { inject } from '@angular/core';\n * import { CoarLocalizationService } from '@cocoar/localization';\n *\n * export class MyComponent {\n * private readonly locale = inject(CoarLocalizationService);\n *\n * constructor() {\n * // Get current language\n * console.log(this.locale.languageState.value);\n *\n * // React to changes via Observable\n * this.locale.languageState.value$.subscribe(lang => {\n * console.log('Language changed:', lang);\n * });\n * }\n *\n * changeLanguage() {\n * this.locale.setLanguage('de');\n * }\n * }\n * ```\n */\n@Injectable({\n providedIn: 'root',\n})\nexport class CoarLocalizationService {\n private readonly config = inject(COAR_LOCALIZATION_CONFIG, { optional: true });\n private readonly localeDataStore = inject(CoarLocalizationDataStore);\n private readonly localeDataLoaders =\n inject(COAR_LOCALIZATION_DATA_LOADERS, { optional: true }) ?? [];\n private readonly defaultLanguage = this.config?.defaultLanguage ?? 'en';\n\n private readonly languageSubject = new BehaviorSubject<string>(this.defaultLanguage);\n\n /**\n * Subject for coordinating language changes with i18n service.\n * The i18n service subscribes to this to load translations BEFORE the language change is emitted.\n * @internal\n */\n readonly pendingLanguageChange$ = new Subject<PendingLanguageChange>();\n\n /**\n * Canonical language state.\n *\n * - `languageState.value` gives synchronous access\n * - `languageState.value$` is the canonical stream (emits current value immediately)\n */\n readonly languageState = new ReadonlyState(this.languageSubject);\n\n constructor() {\n // Expose to window for debugging\n if (typeof window !== 'undefined') {\n (\n window as unknown as { __coarLocalizationStore?: CoarLocalizationDataStore }\n ).__coarLocalizationStore = this.localeDataStore;\n }\n\n // Load locale data for the default language on initialization\n // This ensures firstDayOfWeek and other formatting data is available immediately\n this.loadAndmergeLocalizationData(this.defaultLanguage).catch((error) => {\n console.warn(\n `[CoarLocalizationService] Failed to load initial locale data for '${this.defaultLanguage}':`,\n error\n );\n });\n }\n\n /**\n * Set the current language.\n *\n * Automatically loads locale data from all configured sources (Intl, HTTP, etc.)\n * and deep-merges them in order. Later sources override earlier ones.\n *\n * Cached data is not reloaded, so switching back to a previous language is instant.\n *\n * @param language - The new language code (e.g., 'en', 'de', 'en-US')\n *\n * @example\n * ```typescript\n * // Change to German (loads from Intl + HTTP, merges overrides)\n * await locale.setLanguage('de');\n *\n * // Change back to English (uses cached data, instant)\n * await locale.setLanguage('en');\n * ```\n */\n async setLanguage(language: string): Promise<void> {\n const current = this.languageState.value;\n\n // Skip if language hasn't changed\n if (current === language) {\n return;\n }\n\n // Load locale data if not already loaded (cached)\n if (!this.localeDataStore.hasLocaleData(language)) {\n try {\n await this.loadAndmergeLocalizationData(language);\n } catch (error) {\n console.warn(\n `[CoarLocalizationService] Failed to load locale data for '${language}':`,\n error\n );\n // Continue with language switch even if locale data fails to load\n // Formatting pipes will use fallback values\n }\n }\n\n // Wait for i18n service to load translations before emitting language change\n // Use a timeout in case i18n service is not injected (e.g., in tests)\n await Promise.race([\n new Promise<void>((resolve) => {\n this.pendingLanguageChange$.next({ language, resolve });\n }),\n new Promise<void>((resolve) => setTimeout(resolve, 100)), // Fallback timeout\n ]);\n\n // Now emit the language change (UI will react with translations ready)\n this.languageSubject.next(language);\n }\n\n /**\n * Load locale data from all sources and deep-merge them.\n *\n * Sources are executed in order:\n * 1. Intl (always first, provides complete defaults)\n * 2. HTTP (if configured, merges business overrides)\n * 3. Custom sources (if provided, can add dynamic updates)\n *\n * @param language - Language code to load\n */\n private async loadAndmergeLocalizationData(language: string): Promise<void> {\n if (this.localeDataLoaders.length === 0) {\n return;\n }\n\n // Load from all sources in parallel\n const loadPromises = this.localeDataLoaders.map((loader) =>\n lastValueFrom(loader.loadLocaleData(language)).catch((err) => {\n console.warn(`[CoarLocale] Source failed to load '${language}':`, err);\n return null; // Return null for failed sources\n })\n );\n\n const results = await Promise.all(loadPromises);\n\n // Deep merge all sources (nulls are ignored)\n const merged = mergeLocalizationData(results.filter((r) => r !== null));\n\n if (merged) {\n this.localeDataStore.setLocaleData(language, merged);\n }\n }\n\n /**\n * Preload locale data for a language without switching to it.\n * Useful for avoiding UI flicker when switching languages.\n *\n * @param language - The language code to preload\n *\n * @example\n * ```typescript\n * // Preload German locale data before switching\n * await locale.preloadLocaleData('de');\n * await locale.setLanguage('de'); // Instant switch, no loading delay\n * ```\n */\n async preloadLocaleData(language: string): Promise<void> {\n // Skip if already loaded\n if (this.localeDataStore.hasLocaleData(language)) {\n return;\n }\n\n try {\n await this.loadAndmergeLocalizationData(language);\n } catch (error) {\n console.warn(\n `[CoarLocalizationService] Failed to preload locale data for '${language}':`,\n error\n );\n throw error;\n }\n }\n\n /**\n * Get the default language configured for the application.\n *\n * @returns The default language code\n *\n * @example\n * ```typescript\n * const defaultLang = locale.getDefaultLanguage(); // 'en'\n * ```\n */\n getDefaultLanguage(): string {\n return this.defaultLanguage;\n }\n}\n","/**\n * Locale data structure for date and number formatting.\n * \n * This data can be loaded from various sources:\n * - Browser Intl API (CoarIntlLocaleDataLoader) - default\n * - JSON files (CoarHttpLocaleDataLoader) - for overrides\n * - SignalR (future) - for dynamic backend-controlled formatting\n */\n\n/**\n * Complete locale data for a specific language/region.\n */\nexport interface CoarLocalizationData {\n /** Locale code (e.g., 'en', 'de', 'en-US', 'de-DE') */\n code: string;\n\n /** Date formatting configuration */\n date: CoarDateFormatData;\n\n /** Number formatting configuration */\n number: CoarNumberFormatData;\n\n /** Currency formatting configuration */\n currency: CoarCurrencyFormatData;\n\n /** Percent formatting configuration */\n percent: CoarPercentFormatData;\n}\n\n/**\n * Date formatting configuration.\n */\nexport interface CoarDateFormatData {\n /** \n * Date format pattern: 'dd.mm.yyyy', 'dd/mm/yyyy', 'mm/dd/yyyy', 'yyyy-mm-dd'\n */\n pattern: 'dd.mm.yyyy' | 'dd/mm/yyyy' | 'mm/dd/yyyy' | 'yyyy-mm-dd';\n\n /** \n * First day of week (0 = Sunday, 1 = Monday, ..., 6 = Saturday).\n */\n firstDayOfWeek: number;\n\n /** Localized month names (full) */\n monthNames: string[];\n\n /** Localized month names (short) */\n monthNamesShort: string[];\n\n /** Localized day names (full) */\n dayNames: string[];\n\n /** Localized day names (short) */\n dayNamesShort: string[];\n\n /** AM/PM labels */\n amPm: [string, string];\n}\n\n/**\n * Number formatting configuration.\n */\nexport interface CoarNumberFormatData {\n /** Decimal separator (e.g., \".\" for English, \",\" for German) */\n decimal: string;\n\n /** Thousands/group separator (e.g., \",\" for English, \".\" for German) */\n group: string;\n\n /** Grouping pattern ([3] means group every 3 digits) */\n grouping: number[];\n}\n\n/**\n * Currency formatting configuration.\n */\nexport interface CoarCurrencyFormatData {\n /** Default currency code (e.g., \"USD\", \"EUR\") */\n default: string;\n\n /** Currency symbols map (e.g., { \"USD\": \"$\", \"EUR\": \"€\" }) */\n symbols: Record<string, string>;\n\n /** Symbol position: 'before' ($1,234) or 'after' (1,234 €) */\n position: 'before' | 'after';\n\n /** Space between symbol and number */\n spacing: boolean;\n\n /** Decimal places for currency display */\n decimals: number;\n}\n\n/**\n * Percent formatting configuration.\n */\nexport interface CoarPercentFormatData {\n /** Percent symbol (usually \"%\") */\n symbol: string;\n\n /** Space between number and symbol (e.g., \"25%\" vs \"25 %\") */\n spacing: boolean;\n\n /** Decimal places for percent display */\n decimals: number;\n}\n","import { EnvironmentProviders, makeEnvironmentProviders } from '@angular/core';\nimport { HttpClient } from '@angular/common/http';\nimport { COAR_LOCALIZATION_DATA_LOADERS } from '../provide-coar-localization';\nimport { CoarHttpLocaleDataLoader } from './localization-data-loader';\n\n/**\n * Configuration for HTTP locale data source.\n */\nexport interface CoarHttpLocaleSourceConfig {\n /**\n * URL generator function that returns the URL for a given language.\n *\n * @default (lang) => `/locales/${lang}.json`\n *\n * @param language - Language code (e.g., 'en', 'de', 'en-US')\n * @returns URL to load locale data from\n *\n * @example\n * ```ts\n * url: (lang) => `/locales/${lang}.json`\n * url: (lang) => `/api/config/intl-${lang}.json`\n * url: (lang) => `https://cdn.example.com/locales/${lang}.json`\n * ```\n */\n url?: (language: string) => string;\n\n /**\n * Optional HTTP headers to include in requests.\n *\n * @example\n * ```ts\n * headers: {\n * 'Authorization': 'Bearer token123',\n * 'X-Custom-Header': 'value'\n * }\n * ```\n */\n headers?: Record<string, string>;\n}\n\n/**\n * Provides HTTP as a locale data source.\n *\n * This loader fetches locale data from JSON files via HTTP.\n * Typically used as a second source (after Intl) to provide business-specific\n * overrides like forced firstDayOfWeek, custom separators, etc.\n *\n * @example\n * ```ts\n * // Basic usage (default: /locales/{lang}.json)\n * provideCoarL10nHttpSource()\n *\n * // Custom URL pattern\n * provideCoarL10nHttpSource({\n * url: (lang) => `/api/config/intl-${lang}.json`\n * })\n *\n * // With authentication\n * provideCoarL10nHttpSource({\n * url: (lang) => `/api/locales/${lang}.json`,\n * headers: {\n * 'Authorization': 'Bearer ' + getToken()\n * }\n * })\n * ```\n *\n * Expected file structure:\n * ```\n * public/locales/\n * en.json - English overrides\n * de.json - German overrides\n * ```\n *\n * JSON files should contain partial CoarLocalizationData:\n * ```json\n * {\n * \"code\": \"de\",\n * \"date\": {\n * \"firstDayOfWeek\": 1\n * }\n * }\n * ```\n */\nexport function provideCoarL10nHttpSource(\n config?: CoarHttpLocaleSourceConfig\n): EnvironmentProviders {\n const urlFn = config?.url ?? ((lang: string) => `/locales/${lang}.json`);\n const headers = config?.headers;\n\n return makeEnvironmentProviders([\n {\n provide: COAR_LOCALIZATION_DATA_LOADERS,\n multi: true,\n useFactory: (http: HttpClient) => {\n return new CoarHttpLocaleDataLoader(http, urlFn, headers);\n },\n deps: [HttpClient],\n },\n ]);\n}\n","import { Pipe, PipeTransform, inject } from '@angular/core';\nimport { Temporal } from '@js-temporal/polyfill';\nimport { CoarLocalizationDataStore } from './localization-data-store';\nimport { CoarLocalizationService } from '../coar-localization.service';\n\n/**\n * Pipe for formatting dates using locale-specific configuration.\n *\n * @example\n * ```html\n * <span>{{ myDate | coarDate }}</span>\n * <span>{{ myDate | coarDate:'de' }}</span>\n * ```\n */\n@Pipe({\n name: 'coarDate',\n standalone: true,\n pure: false, // Impure to react to language changes\n})\nexport class CoarDatePipe implements PipeTransform {\n private readonly localeDataStore = inject(CoarLocalizationDataStore);\n private readonly localeService = inject(CoarLocalizationService);\n\n transform(value: Temporal.PlainDate | Date | string | null | undefined, locale?: string): string {\n if (!value) return '';\n\n // Convert to Temporal.PlainDate\n let date: Temporal.PlainDate;\n if (value instanceof Date) {\n date = Temporal.PlainDate.from({\n year: value.getFullYear(),\n month: value.getMonth() + 1,\n day: value.getDate(),\n });\n } else if (typeof value === 'string') {\n try {\n date = Temporal.PlainDate.from(value);\n } catch {\n return '';\n }\n } else {\n date = value;\n }\n\n const effectiveLocale = locale ?? this.localeService.languageState.value;\n const localeData = this.localeDataStore.getLocaleData(effectiveLocale);\n\n if (!localeData) {\n // Fallback to ISO format\n return date.toString();\n }\n\n const { pattern } = localeData.date;\n const sep = pattern.includes('.') ? '.' : pattern.includes('/') ? '/' : '-';\n\n const day = String(date.day).padStart(2, '0');\n const month = String(date.month).padStart(2, '0');\n const year = String(date.year);\n\n switch (pattern) {\n case 'dd.mm.yyyy':\n case 'dd/mm/yyyy':\n return `${day}${sep}${month}${sep}${year}`;\n case 'mm/dd/yyyy':\n return `${month}${sep}${day}${sep}${year}`;\n case 'yyyy-mm-dd':\n return `${year}${sep}${month}${sep}${day}`;\n default:\n return `${day}${sep}${month}${sep}${year}`;\n }\n }\n}\n","import { Pipe, PipeTransform, inject } from '@angular/core';\nimport { CoarLocalizationDataStore } from './localization-data-store';\nimport { CoarLocalizationService } from '../coar-localization.service';\n\n/**\n * Pipe for formatting numbers using locale-specific configuration.\n *\n * @example\n * ```html\n * <span>{{ 1234.56 | coarNumber }}</span>\n * <span>{{ 1234.56 | coarNumber:'de':2 }}</span>\n * ```\n */\n@Pipe({\n name: 'coarNumber',\n standalone: true,\n pure: false, // Impure to react to language changes\n})\nexport class CoarNumberPipe implements PipeTransform {\n private readonly localeDataStore = inject(CoarLocalizationDataStore);\n private readonly localeService = inject(CoarLocalizationService);\n\n transform(value: number | null | undefined, locale?: string, decimals = 2): string {\n if (value == null || isNaN(value)) return '';\n\n const effectiveLocale = locale ?? this.localeService.languageState.value;\n const localeData = this.localeDataStore.getLocaleData(effectiveLocale);\n\n if (!localeData) {\n // Fallback to standard formatting\n return value.toFixed(decimals);\n }\n\n const { decimal, group } = localeData.number;\n\n // Split into integer and decimal parts\n const [integerPart, decimalPart = ''] = value.toFixed(decimals).split('.');\n\n // Add thousand separators\n const formattedInteger = integerPart.replace(/\\B(?=(\\d{3})+(?!\\d))/g, group);\n\n // Combine with decimal separator\n if (decimals > 0 && decimalPart) {\n return `${formattedInteger}${decimal}${decimalPart}`;\n }\n\n return formattedInteger;\n }\n}\n","import { Pipe, PipeTransform, inject } from '@angular/core';\nimport { CoarLocalizationDataStore } from './localization-data-store';\nimport { CoarLocalizationService } from '../coar-localization.service';\n\n/**\n * Pipe for formatting currency using locale-specific configuration.\n *\n * @example\n * ```html\n * <span>{{ 1234.56 | coarCurrency }}</span>\n * <span>{{ 1234.56 | coarCurrency:'de':'EUR' }}</span>\n * ```\n */\n@Pipe({\n name: 'coarCurrency',\n standalone: true,\n pure: false, // Impure to react to language changes\n})\nexport class CoarCurrencyPipe implements PipeTransform {\n private readonly localeDataStore = inject(CoarLocalizationDataStore);\n private readonly localeService = inject(CoarLocalizationService);\n\n transform(value: number | null | undefined, locale?: string, currency?: string): string {\n if (value == null || isNaN(value)) return '';\n\n const effectiveLocale = locale ?? this.localeService.languageState.value;\n const localeData = this.localeDataStore.getLocaleData(effectiveLocale);\n\n if (!localeData) {\n // Fallback to standard formatting\n return `${currency ?? 'USD'} ${value.toFixed(2)}`;\n }\n\n const { decimal, group } = localeData.number;\n const currencyConfig = localeData.currency;\n const effectiveCurrency = currency ?? currencyConfig.default;\n const symbol = currencyConfig.symbols[effectiveCurrency] ?? effectiveCurrency;\n const decimals = currencyConfig.decimals;\n\n // Format number part\n const [integerPart, decimalPart = ''] = value.toFixed(decimals).split('.');\n const formattedInteger = integerPart.replace(/\\B(?=(\\d{3})+(?!\\d))/g, group);\n const formattedNumber =\n decimals > 0 && decimalPart\n ? `${formattedInteger}${decimal}${decimalPart}`\n : formattedInteger;\n\n // Add currency symbol\n const space = currencyConfig.spacing ? '\\u00A0' : '';\n if (currencyConfig.position === 'before') {\n return `${symbol}${space}${formattedNumber}`;\n } else {\n return `${formattedNumber}${space}${symbol}`;\n }\n }\n}\n","import { Pipe, PipeTransform, inject } from '@angular/core';\nimport { CoarLocalizationDataStore } from './localization-data-store';\nimport { CoarLocalizationService } from '../coar-localization.service';\n\n/**\n * Pipe for formatting percentages using locale-specific configuration.\n *\n * Expects a decimal value (0.25 = 25%).\n *\n * @example\n * ```html\n * <span>{{ 0.25 | coarPercent }}</span>\n * <span>{{ 0.25 | coarPercent:'de':1 }}</span>\n * ```\n */\n@Pipe({\n name: 'coarPercent',\n standalone: true,\n pure: false, // Impure to react to language changes\n})\nexport class CoarPercentPipe implements PipeTransform {\n private readonly localeDataStore = inject(CoarLocalizationDataStore);\n private readonly localeService = inject(CoarLocalizationService);\n\n transform(value: number | null | undefined, locale?: string, decimals?: number): string {\n if (value == null || isNaN(value)) return '';\n\n const effectiveLocale = locale ?? this.localeService.languageState.value;\n const localeData = this.localeDataStore.getLocaleData(effectiveLocale);\n\n if (!localeData) {\n // Fallback to standard formatting\n return `${(value * 100).toFixed(decimals ?? 0)}%`;\n }\n\n const { decimal, group } = localeData.number;\n const percentConfig = localeData.percent;\n const effectiveDecimals = decimals ?? percentConfig.decimals;\n\n // Convert to percentage (0.25 -> 25)\n const percentValue = value * 100;\n\n // Format number part\n const [integerPart, decimalPart = ''] = percentValue.toFixed(effectiveDecimals).split('.');\n const formattedInteger = integerPart.replace(/\\B(?=(\\d{3})+(?!\\d))/g, group);\n const formattedNumber =\n effectiveDecimals > 0 && decimalPart\n ? `${formattedInteger}${decimal}${decimalPart}`\n : formattedInteger;\n\n // Add percent symbol\n const space = percentConfig.spacing ? '\\u00A0' : '';\n return `${formattedNumber}${space}${percentConfig.symbol}`;\n }\n}\n","import { ChangeDetectorRef, Pipe, PipeTransform, inject, OnDestroy } from '@angular/core';\nimport { CoarI18n } from './coar-i18n';\nimport { coarInterpolate } from './coar-interpolate';\nimport { BehaviorSubjectProxy } from '@cocoar/ts-utils';\n\n@Pipe({\n name: 'coarI18n',\n standalone: true,\n pure: false, // Required because translations can change at runtime\n})\nexport class CoarI18nPipe implements PipeTransform, OnDestroy {\n private readonly i18n = inject(CoarI18n, { optional: true });\n private readonly cdr = inject(ChangeDetectorRef);\n\n private readonly subject = new BehaviorSubjectProxy<string>('');\n\n private lastKey?: string;\n private lastParamsJson?: string;\n private lastFallback?: string;\n\n transform(\n key: string | null | undefined,\n paramsOrFallback?: Record<string, unknown> | string,\n maybeFallbackOrParams?: string | Record<string, unknown>\n ): string {\n if (!key) {\n // If there's no key, return fallback if one exists\n if (typeof paramsOrFallback === 'string') {\n return paramsOrFallback;\n }\n if (typeof maybeFallbackOrParams === 'string') {\n return maybeFallbackOrParams;\n }\n return '';\n }\n\n // Normal param/fallback dispatching\n let params: Record<string, unknown> | undefined;\n let fallback: string | undefined;\n\n // Case A — first argument is fallback (string)\n if (typeof paramsOrFallback === 'string') {\n fallback = paramsOrFallback;\n if (maybeFallbackOrParams && typeof maybeFallbackOrParams === 'object') {\n params = maybeFallbackOrParams as Record<string, unknown>;\n }\n } else {\n // Case B — first argument is params (object)\n params = paramsOrFallback ?? undefined;\n if (typeof maybeFallbackOrParams === 'string') {\n fallback = maybeFallbackOrParams;\n }\n }\n\n // No i18n service available — return fallback or key\n if (!this.i18n) {\n return coarInterpolate(fallback ?? key, params);\n }\n\n // Compare inputs to determine if a new subscription is needed\n const paramsJson = params ? JSON.stringify(params) : undefined;\n\n if (\n key !== this.lastKey ||\n fallback !== this.lastFallback ||\n paramsJson !== this.lastParamsJson\n ) {\n this.lastKey = key;\n this.lastFallback = fallback;\n this.lastParamsJson = paramsJson;\n\n // Switch Observable completely using BehaviorSubjectProxy\n this.subject.next(this.i18n.t$(key, params, fallback));\n\n // Update the view when new translated values arrive\n this.subject.subscribe(() => {\n this.cdr.markForCheck();\n });\n }\n\n return this.subject.value;\n }\n\n ngOnDestroy(): void {\n this.subject.unsubscribe();\n }\n}\n","import { Injectable, inject } from '@angular/core';\nimport { CoarLocalizationService } from '../coar-localization.service';\n\n/**\n * Context service providing i18n-related information to translation providers.\n *\n * This service acts as a coordination layer between the core locale system\n * and translation provider implementations (e.g., Transloco, custom providers).\n *\n * Providers should inject this service to:\n * - Get the current language\n * - Subscribe to language changes\n * - Access future i18n-related features (caching, preloading, etc.)\n *\n * This abstraction decouples providers from direct CoarLocalizationService dependency,\n * making the system more maintainable and testable.\n *\n * @example\n * ```typescript\n * // In a translation provider implementation\n * export function provideMyI18nBackend(): Provider {\n * return {\n * provide: COAR_I18N_PROVIDER,\n * useFactory: (context: CoarI18nContext, backend: MyBackend) => {\n * // Subscribe to language changes\n * context.languageState.value$.subscribe(lang => {\n * backend.switchLanguage(lang);\n * });\n *\n * return {\n * t(key: string): string {\n * return backend.translate(key);\n * }\n * };\n * },\n * deps: [CoarI18nContext, MyBackend],\n * };\n * }\n * ```\n */\n@Injectable({ providedIn: 'root' })\nexport class CoarI18nContext {\n private readonly localeService = inject(CoarLocalizationService);\n\n /**\n * Canonical language state.\n *\n * - `languageState.value` gives synchronous access\n * - `languageState.value$` is the canonical stream (emits current value immediately)\n */\n readonly languageState = this.localeService.languageState;\n\n // Future additions:\n // - Translation cache management\n // - Preloaded language files\n // - Fallback language chain configuration\n // - Missing translation tracking/reporting\n // - Translation loading state\n}\n","import { EnvironmentProviders, makeEnvironmentProviders } from '@angular/core';\nimport { COAR_TRANSLATION_LOADERS, CoarHttpTranslationLoader } from './coar-translation-loader';\n\n/**\n * Configuration for HTTP translation source.\n */\nexport interface CoarI18nHttpSourceConfig {\n /**\n * URL generator function that returns the URL for a given language.\n *\n * @default (lang) => `/i18n/${lang}.json`\n *\n * @param language - Language code (e.g., 'en', 'de', 'en-US')\n * @returns URL to load translations from\n *\n * @example\n * ```ts\n * url: (lang) => `/i18n/${lang}.json`\n * url: (lang) => `/api/translations/${lang}.json`\n * url: (lang) => `https://cdn.example.com/i18n/${lang}.json`\n * ```\n */\n url?: (language: string) => string;\n\n /**\n * Optional HTTP headers to include in requests.\n *\n * @example\n * ```ts\n * headers: {\n * 'Authorization': 'Bearer token123',\n * 'X-Custom-Header': 'value'\n * }\n * ```\n */\n headers?: Record<string, string>;\n}\n\n/**\n * Provides HTTP as a translation source.\n *\n * This loader fetches translation files from HTTP endpoints.\n * Typically used for standard i18n scenarios where translations are stored as JSON files.\n *\n * **Note:** The i18n system is automatically included by `provideCoarLocalization()`.\n * This function only registers the HTTP loader for loading translations.\n *\n * @example\n * ```ts\n * // Basic usage (default: /i18n/{lang}.json)\n * provideCoarI18nHttpSource()\n *\n * // Custom path\n * provideCoarI18nHttpSource({\n * url: (lang) => `/assets/translations/${lang}.json`\n * })\n *\n * // With authentication\n * provideCoarI18nHttpSource({\n * url: (lang) => `/api/translations/${lang}.json`,\n * headers: {\n * 'Authorization': 'Bearer ' + getToken()\n * }\n * })\n * ```\n *\n * Expected file structure:\n * ```\n * public/i18n/\n * en.json - English translations\n * de.json - German translations\n * ```\n *\n * JSON files should contain flat or nested translations:\n * ```json\n * {\n * \"app\": {\n * \"title\": \"My App\",\n * \"button\": {\n * \"save\": \"Save\",\n * \"cancel\": \"Cancel\"\n * }\n * }\n * }\n * ```\n *\n * @param config - Optional configuration\n * @returns Angular environment providers\n *\n * @see {@link CoarI18nHttpSourceConfig} for configuration options\n */\nexport function provideCoarI18nHttpSource(config?: CoarI18nHttpSourceConfig): EnvironmentProviders {\n const urlFn = config?.url ?? ((lang: string) => `/i18n/${lang}.json`);\n const headers = config?.headers;\n\n return makeEnvironmentProviders([\n {\n provide: COAR_TRANSLATION_LOADERS,\n multi: true,\n useFactory: () => {\n const loader = new CoarHttpTranslationLoader();\n loader.urlFn = urlFn;\n loader.headers = headers;\n return loader;\n },\n },\n ]);\n}\n","// Locale (language management)\nexport * from './lib/coar-localization.service';\nexport * from './lib/provide-coar-localization';\nexport * from './lib/timezone/index';\n\n// L10n (localization data and formatting pipes)\nexport * from './lib/l10n/localization-data';\nexport * from './lib/l10n/localization-data-store';\nexport * from './lib/l10n/localization-data-loader';\nexport * from './lib/l10n/intl-localization-data-loader';\nexport * from './lib/l10n/provide-l10n-http-source';\nexport * from './lib/l10n/merge-localization-data';\nexport * from './lib/l10n/date.pipe';\nexport * from './lib/l10n/number.pipe';\nexport * from './lib/l10n/currency.pipe';\nexport * from './lib/l10n/percent.pipe';\n\n// i18n (translations)\nexport * from './lib/i18n/coar-i18n';\nexport * from './lib/i18n/coar-i18n.pipe';\nexport * from './lib/i18n/coar-i18n-provider';\nexport * from './lib/i18n/coar-i18n-context';\nexport * from './lib/i18n/coar-i18n.service';\nexport * from './lib/i18n/coar-interpolate';\nexport * from './lib/i18n/coar-is-missing-translation';\nexport * from './lib/i18n/coar-translation-store';\nexport * from './lib/i18n/coar-translation-loader';\nexport * from './lib/i18n/coar-intl-translation-loader';\nexport * from './lib/i18n/provide-coar-i18n-http-source';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":["extractBaseLanguage","map","distinctUntilChanged"],"mappings":"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"}