/** * Internationalization system * Loads translations from flat text files */ export type Locale = 'fr' | 'en' export interface Translations { [key: string]: string } let currentLocale: Locale = 'fr' const translations: Map = new Map() /** * Set current locale */ export function setLocale(locale: Locale): void { currentLocale = locale } /** * Get current locale */ export function getLocale(): Locale { return currentLocale } /** * Load translations from a flat text file * Format: key=value (one per line, empty lines and lines starting with # are ignored) */ export function loadTranslations(locale: Locale, translationsText: string): void { const translationsMap: Translations = {} const lines = translationsText.split('\n') for (const line of lines) { const trimmed = line.trim() if (!trimmed || trimmed.startsWith('#')) { continue } const equalIndex = trimmed.indexOf('=') if (equalIndex === -1) { continue } const key = trimmed.substring(0, equalIndex).trim() const value = trimmed.substring(equalIndex + 1).trim() if (key && value) { translationsMap[key] = value } } translations.set(locale, translationsMap) } /** * Get translated string */ export function t(key: string, params?: Record): string { const localeTranslations = translations.get(currentLocale) ?? {} let text = localeTranslations[key] ?? key // Replace parameters if (params) { Object.entries(params).forEach(([paramKey, paramValue]) => { text = text.replace(new RegExp(`\\{\\{${paramKey}\\}\\}`, 'g'), String(paramValue)) }) } return text } /** * Get all available locales */ export function getAvailableLocales(): Locale[] { return Array.from(translations.keys()) }