{"version":3,"sources":["../src/config/constants.ts","../src/core/translator.ts","../src/errors/index.ts","../src/core/loader.ts","../src/services/I18nService.ts","../src/reactivity/signals.ts","../src/core/resolve-locale.ts","../src/config/config.ts","../src/i18n.ts","../src/types/index.ts"],"names":["Predicate","Data","Effect","Schedule","Duration","Context","Layer","signal","Config","loaded","createRuntimeContext"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * MIT License\n *\n * Copyright (c) 2025 Chris M. Perez\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\nexport const DEFAULT_LOCALE = 'en';\n\nexport const DEFAULT_FALLBACK_LOCALE = 'en';\n\nexport const LOCALE_STORAGE_KEY = 'effuse-i18n-locale';\n\nexport const INTERPOLATION_PATTERN = /\\{\\{(\\w+)\\}\\}/g;\n\nexport const PLURAL_SUFFIXES = {\n\tZERO: '_zero',\n\tONE: '_one',\n\tTWO: '_two',\n\tFEW: '_few',\n\tMANY: '_many',\n\tOTHER: '_other',\n} as const;\n\nexport const KEY_SEPARATOR = '.';\n\nexport const CACHE_TTL_MS = 5 * 60 * 1000;\n\nexport const MAX_LOAD_RETRIES = 3;\n\nexport const RETRY_DELAY_MS = 1000;\n","/**\n * MIT License\n *\n * Copyright (c) 2025 Chris M. Perez\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\nimport { Predicate } from 'effect';\nimport type { Translations, TranslationParams } from '../types/index.js';\nimport {\n\tINTERPOLATION_PATTERN,\n\tKEY_SEPARATOR,\n\tPLURAL_SUFFIXES,\n} from '../config/constants.js';\n\n// Keys that would reach the prototype chain. Translations can be loaded from\n// remote JSON, so these are never merged or traversed.\nconst UNSAFE_KEYS = new Set(['__proto__', 'constructor', 'prototype']);\n\nconst isUnsafeKey = (key: string): boolean => UNSAFE_KEYS.has(key);\n\n// Retrieves a nested value from a translation object using a dot-notation key.\nexport const getNestedValue = (\n\ttranslations: Translations,\n\tkey: string\n): string | Translations | undefined => {\n\tconst parts = key.split(KEY_SEPARATOR);\n\tlet current: string | Translations | undefined = translations;\n\n\tfor (const part of parts) {\n\t\tif (current === undefined || typeof current === 'string') {\n\t\t\treturn undefined;\n\t\t}\n\t\tif (\n\t\t\tisUnsafeKey(part) ||\n\t\t\t!Object.prototype.hasOwnProperty.call(current, part)\n\t\t) {\n\t\t\treturn undefined;\n\t\t}\n\t\tcurrent = current[part];\n\t}\n\n\treturn current;\n};\n\n// Checks if a translation key exists.\nexport const hasTranslationKey = (\n\ttranslations: Translations,\n\tkey: string\n): boolean => {\n\tconst value = getNestedValue(translations, key);\n\treturn value !== undefined;\n};\n\n// Determines the correct plural suffix for a count and locale.\nexport const getPluralSuffix = (count: number, locale: string): string => {\n\ttry {\n\t\tconst rules = new Intl.PluralRules(locale);\n\t\tconst category = rules.select(count);\n\n\t\tswitch (category) {\n\t\t\tcase 'zero':\n\t\t\t\treturn PLURAL_SUFFIXES.ZERO;\n\t\t\tcase 'one':\n\t\t\t\treturn PLURAL_SUFFIXES.ONE;\n\t\t\tcase 'two':\n\t\t\t\treturn PLURAL_SUFFIXES.TWO;\n\t\t\tcase 'few':\n\t\t\t\treturn PLURAL_SUFFIXES.FEW;\n\t\t\tcase 'many':\n\t\t\t\treturn PLURAL_SUFFIXES.MANY;\n\t\t\tdefault:\n\t\t\t\treturn PLURAL_SUFFIXES.OTHER;\n\t\t}\n\t} catch {\n\t\treturn count === 1 ? PLURAL_SUFFIXES.ONE : PLURAL_SUFFIXES.OTHER;\n\t}\n};\n\n// Replaces placeholders in a template string with values.\nexport const interpolate = (\n\ttemplate: string,\n\tparams: TranslationParams\n): string => {\n\treturn template.replace(INTERPOLATION_PATTERN, (_, key: string) => {\n\t\tconst value = params[key];\n\t\tif (value === undefined || value === null) {\n\t\t\treturn `{{${key}}}`;\n\t\t}\n\t\tif (\n\t\t\ttypeof value === 'string' ||\n\t\t\ttypeof value === 'number' ||\n\t\t\ttypeof value === 'boolean'\n\t\t) {\n\t\t\treturn String(value);\n\t\t}\n\t\treturn `{{${key}}}`;\n\t});\n};\n\n// The core translation function handles lookup, fallback, pluralization, and interpolation.\nexport const translate = (\n\ttranslations: Translations | undefined,\n\tfallbackTranslations: Translations | undefined,\n\tkey: string,\n\tparams: TranslationParams | undefined,\n\tlocale: string\n): string => {\n\tlet lookupKey = key;\n\tif (\n\t\tPredicate.isNotNullable(params) &&\n\t\tPredicate.isNotNullable(params.count)\n\t) {\n\t\tconst pluralSuffix = getPluralSuffix(params.count, locale);\n\t\tconst pluralKey = `${key}${pluralSuffix}`;\n\n\t\tif (\n\t\t\t(translations && hasTranslationKey(translations, pluralKey)) ||\n\t\t\t(fallbackTranslations &&\n\t\t\t\thasTranslationKey(fallbackTranslations, pluralKey))\n\t\t) {\n\t\t\tlookupKey = pluralKey;\n\t\t}\n\t}\n\n\tlet value: string | Translations | undefined;\n\tif (translations) {\n\t\tvalue = getNestedValue(translations, lookupKey);\n\t}\n\n\tif (value === undefined && fallbackTranslations) {\n\t\tvalue = getNestedValue(fallbackTranslations, lookupKey);\n\t}\n\n\tif (value === undefined || typeof value !== 'string') {\n\t\treturn key;\n\t}\n\n\tif (params && Object.keys(params).length > 0) {\n\t\treturn interpolate(value, params);\n\t}\n\n\treturn value;\n};\n\n// Deeply merges two translation objects.\nexport const mergeTranslations = (\n\ttarget: Translations,\n\tsource: Translations\n): Translations => {\n\tconst result: Translations = { ...target };\n\n\tfor (const key of Object.keys(source)) {\n\t\tif (isUnsafeKey(key)) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst sourceValue = source[key];\n\t\tconst targetValue = result[key];\n\n\t\tif (sourceValue === undefined) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (Predicate.isObject(sourceValue) && Predicate.isObject(targetValue)) {\n\t\t\tresult[key] = mergeTranslations(targetValue, sourceValue);\n\t\t} else {\n\t\t\tresult[key] = sourceValue;\n\t\t}\n\t}\n\n\treturn result;\n};\n\n// Flattens a nested translation object into a single-level object with dot-notation keys.\nexport const flattenTranslations = (\n\ttranslations: Translations,\n\tprefix = ''\n): Record<string, string> => {\n\tconst result: Record<string, string> = {};\n\n\tfor (const key of Object.keys(translations)) {\n\t\tconst value = translations[key];\n\t\tconst fullKey = prefix ? `${prefix}${KEY_SEPARATOR}${key}` : key;\n\n\t\tif (typeof value === 'string') {\n\t\t\tresult[fullKey] = value;\n\t\t} else if (Predicate.isObject(value)) {\n\t\t\tObject.assign(result, flattenTranslations(value, fullKey));\n\t\t}\n\t}\n\n\treturn result;\n};\n","/**\n * MIT License\n *\n * Copyright (c) 2025 Chris M. Perez\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\nimport { Data } from 'effect';\n\nexport class MissingTranslationError extends Data.TaggedError(\n\t'MissingTranslationError'\n)<{\n\treadonly key: string;\n\treadonly locale: string;\n}> {}\n\nexport class LocaleLoadError extends Data.TaggedError('LocaleLoadError')<{\n\treadonly locale: string;\n\treadonly cause?: unknown;\n}> {}\n\nexport class InvalidLocaleError extends Data.TaggedError('InvalidLocaleError')<{\n\treadonly locale: string;\n}> {}\n\nexport class I18nNotInitializedError extends Data.TaggedError(\n\t'I18nNotInitializedError'\n)<Record<string, never>> {}\n\nexport type I18nError =\n\t| MissingTranslationError\n\t| LocaleLoadError\n\t| InvalidLocaleError\n\t| I18nNotInitializedError;\n","/**\n * MIT License\n *\n * Copyright (c) 2025 Chris M. Perez\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\nimport { Effect, Schedule, Duration } from 'effect';\nimport type { Translations, TranslationLoader } from '../types/index.js';\nimport { LocaleLoadError } from '../errors/index.js';\nimport { MAX_LOAD_RETRIES, RETRY_DELAY_MS } from '../config/constants.js';\n\nexport const loadFromPath = (\n\tpath: string,\n\tlocale: string\n): Effect.Effect<Translations, LocaleLoadError> =>\n\tEffect.gen(function* () {\n\t\tconst response = yield* Effect.tryPromise({\n\t\t\ttry: () => fetch(path),\n\t\t\tcatch: (error) => new LocaleLoadError({ locale, cause: error }),\n\t\t});\n\n\t\tif (!response.ok) {\n\t\t\treturn yield* Effect.fail(\n\t\t\t\tnew LocaleLoadError({\n\t\t\t\t\tlocale,\n\t\t\t\t\tcause: `HTTP ${String(response.status)}: ${response.statusText}`,\n\t\t\t\t})\n\t\t\t);\n\t\t}\n\n\t\tconst data = yield* Effect.tryPromise({\n\t\t\ttry: () => response.json() as Promise<Translations>,\n\t\t\tcatch: (error) => new LocaleLoadError({ locale, cause: error }),\n\t\t});\n\n\t\treturn data;\n\t});\n\nexport const loadFromPathWithRetry = (\n\tpath: string,\n\tlocale: string\n): Effect.Effect<Translations, LocaleLoadError> =>\n\tloadFromPath(path, locale).pipe(\n\t\tEffect.retry(\n\t\t\tSchedule.exponential(Duration.millis(RETRY_DELAY_MS)).pipe(\n\t\t\t\tSchedule.compose(Schedule.recurs(MAX_LOAD_RETRIES - 1))\n\t\t\t)\n\t\t)\n\t);\n\nexport const loadFromLoader = (\n\tloader: TranslationLoader,\n\tlocale: string\n): Effect.Effect<Translations, LocaleLoadError> =>\n\tEffect.gen(function* () {\n\t\tconst result = yield* Effect.tryPromise({\n\t\t\ttry: async () => {\n\t\t\t\tconst translations = loader(locale);\n\t\t\t\treturn translations instanceof Promise\n\t\t\t\t\t? await translations\n\t\t\t\t\t: translations;\n\t\t\t},\n\t\t\tcatch: (error) => new LocaleLoadError({ locale, cause: error }),\n\t\t});\n\n\t\treturn result;\n\t});\n\nexport const loadFromObject = (\n\ttranslations: Translations\n): Effect.Effect<Translations> => Effect.succeed(translations);\n\nexport const resolveLoadPath = (\n\tpattern: string | ((locale: string) => string),\n\tlocale: string\n): string => {\n\tif (typeof pattern === 'function') {\n\t\treturn pattern(locale);\n\t}\n\treturn pattern.replace(/\\{\\{locale\\}\\}/g, locale);\n};\n\nexport const loadTranslationsSync = (\n\ttranslations: Record<string, Translations>,\n\tlocale: string\n): Translations | undefined => {\n\treturn translations[locale];\n};\n\nexport const runLoader = (\n\teffect: Effect.Effect<Translations, LocaleLoadError>\n): Promise<Translations | undefined> =>\n\tEffect.runPromise(\n\t\teffect.pipe(\n\t\t\tEffect.catchAll(() =>\n\t\t\t\tEffect.succeed(undefined as Translations | undefined)\n\t\t\t)\n\t\t)\n\t);\n","/**\n * MIT License\n *\n * Copyright (c) 2025 Chris M. Perez\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\nimport { Context, Effect, Layer } from 'effect';\nimport type {\n\tTranslations,\n\tTranslationParams,\n\tI18nOptions,\n} from '../types/index.js';\nimport {\n\ttranslate,\n\thasTranslationKey,\n\tmergeTranslations,\n} from '../core/translator.js';\nimport {\n\tloadFromPathWithRetry,\n\tloadFromLoader,\n\tresolveLoadPath,\n} from '../core/loader.js';\nimport { LocaleLoadError, MissingTranslationError } from '../errors/index.js';\nimport {\n\tDEFAULT_LOCALE,\n\tDEFAULT_FALLBACK_LOCALE,\n} from '../config/constants.js';\n\nexport interface I18nServiceApi {\n\tgetLocale: () => Effect.Effect<string>;\n\tsetLocale: (locale: string) => Effect.Effect<void, LocaleLoadError>;\n\tgetFallbackLocale: () => Effect.Effect<string>;\n\ttranslate: (\n\t\tkey: string,\n\t\tparams?: TranslationParams\n\t) => Effect.Effect<string, MissingTranslationError>;\n\thasKey: (key: string) => Effect.Effect<boolean>;\n\tgetAvailableLocales: () => Effect.Effect<string[]>;\n\taddTranslations: (\n\t\tlocale: string,\n\t\ttranslations: Translations\n\t) => Effect.Effect<void>;\n\tloadTranslations: (\n\t\tlocale: string\n\t) => Effect.Effect<Translations, LocaleLoadError>;\n\tgetTranslations: (locale: string) => Effect.Effect<Translations | undefined>;\n}\n\nexport class I18nService extends Context.Tag('effuse/i18n/I18nService')<\n\tI18nService,\n\tI18nServiceApi\n>() {}\n\nexport const makeI18nServiceLayer = (\n\toptions: I18nOptions\n): Layer.Layer<I18nService> => {\n\tlet currentLocale = options.defaultLocale ?? DEFAULT_LOCALE;\n\tconst fallbackLocale = options.fallbackLocale ?? DEFAULT_FALLBACK_LOCALE;\n\tconst translationsMap = new Map<string, Translations>();\n\n\tif (options.translations) {\n\t\tfor (const [locale, translations] of Object.entries(options.translations)) {\n\t\t\ttranslationsMap.set(locale, translations);\n\t\t}\n\t}\n\n\tconst loadTranslationsForLocale = (\n\t\tlocale: string\n\t): Effect.Effect<Translations, LocaleLoadError> =>\n\t\tEffect.gen(function* () {\n\t\t\tconst existing = translationsMap.get(locale);\n\t\t\tif (existing) {\n\t\t\t\treturn existing;\n\t\t\t}\n\t\t\tif (options.loader) {\n\t\t\t\tconst loaded = yield* loadFromLoader(options.loader, locale);\n\t\t\t\ttranslationsMap.set(locale, loaded);\n\t\t\t\treturn loaded;\n\t\t\t}\n\n\t\t\tif (options.loadPath) {\n\t\t\t\tconst path = resolveLoadPath(options.loadPath, locale);\n\t\t\t\tconst loaded = yield* loadFromPathWithRetry(path, locale);\n\t\t\t\ttranslationsMap.set(locale, loaded);\n\t\t\t\treturn loaded;\n\t\t\t}\n\n\t\t\treturn yield* Effect.fail(\n\t\t\t\tnew LocaleLoadError({\n\t\t\t\t\tlocale,\n\t\t\t\t\tcause: 'No loader or translations configured',\n\t\t\t\t})\n\t\t\t);\n\t\t});\n\n\treturn Layer.succeed(I18nService, {\n\t\tgetLocale: () => Effect.succeed(currentLocale),\n\n\t\tsetLocale: (locale: string) =>\n\t\t\tEffect.gen(function* () {\n\t\t\t\tyield* loadTranslationsForLocale(locale);\n\t\t\t\tcurrentLocale = locale;\n\t\t\t}),\n\n\t\tgetFallbackLocale: () => Effect.succeed(fallbackLocale),\n\n\t\ttranslate: (key: string, params?: TranslationParams) =>\n\t\t\tEffect.gen(function* () {\n\t\t\t\tconst translations = translationsMap.get(currentLocale);\n\t\t\t\tconst fallbackTranslations = translationsMap.get(fallbackLocale);\n\n\t\t\t\tconst result = translate(\n\t\t\t\t\ttranslations,\n\t\t\t\t\tfallbackTranslations,\n\t\t\t\t\tkey,\n\t\t\t\t\tparams,\n\t\t\t\t\tcurrentLocale\n\t\t\t\t);\n\n\t\t\t\tif (\n\t\t\t\t\tresult === key &&\n\t\t\t\t\t!hasTranslationKey(translations ?? {}, key) &&\n\t\t\t\t\t!hasTranslationKey(fallbackTranslations ?? {}, key)\n\t\t\t\t) {\n\t\t\t\t\tif (options.onMissingKey) {\n\t\t\t\t\t\tconst handled = options.onMissingKey(key, currentLocale);\n\t\t\t\t\t\tif (handled !== undefined) {\n\t\t\t\t\t\t\treturn handled;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn yield* Effect.fail(\n\t\t\t\t\t\tnew MissingTranslationError({ key, locale: currentLocale })\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\treturn result;\n\t\t\t}),\n\n\t\thasKey: (key: string) =>\n\t\t\tEffect.sync(() => {\n\t\t\t\tconst translations = translationsMap.get(currentLocale);\n\t\t\t\tconst fallbackTranslations = translationsMap.get(fallbackLocale);\n\t\t\t\treturn (\n\t\t\t\t\thasTranslationKey(translations ?? {}, key) ||\n\t\t\t\t\thasTranslationKey(fallbackTranslations ?? {}, key)\n\t\t\t\t);\n\t\t\t}),\n\n\t\tgetAvailableLocales: () =>\n\t\t\tEffect.sync(() => Array.from(translationsMap.keys())),\n\n\t\taddTranslations: (locale: string, translations: Translations) =>\n\t\t\tEffect.sync(() => {\n\t\t\t\tconst existing = translationsMap.get(locale);\n\t\t\t\tif (existing) {\n\t\t\t\t\ttranslationsMap.set(\n\t\t\t\t\t\tlocale,\n\t\t\t\t\t\tmergeTranslations(existing, translations)\n\t\t\t\t\t);\n\t\t\t\t} else {\n\t\t\t\t\ttranslationsMap.set(locale, translations);\n\t\t\t\t}\n\t\t\t}),\n\n\t\tloadTranslations: loadTranslationsForLocale,\n\n\t\tgetTranslations: (locale: string) =>\n\t\t\tEffect.sync(() => translationsMap.get(locale)),\n\t});\n};\n","/**\n * MIT License\n *\n * Copyright (c) 2025 Chris M. Perez\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\nimport { signal, type Signal } from '@effuse/core';\n\nexport const createLocaleSignal = (initialLocale: string): Signal<string> => {\n\treturn signal(initialLocale);\n};\n\nexport const createTranslationsVersion = (): Signal<number> => {\n\treturn signal(0);\n};\n\nexport const bumpTranslationsVersion = (version: Signal<number>): void => {\n\tversion.value++;\n};\n","/**\n * MIT License\n *\n * Copyright (c) 2025 Chris M. Perez\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\ninterface LocaleCandidate {\n\treadonly tag: string;\n\treadonly quality: number;\n\treadonly order: number;\n}\n\n/**\n * Resolves an Accept-Language header against the locales an application\n * actually ships. Quality values order the candidates, region tags fall back\n * to their base locale (en-US matches en), the wildcard resolves to the\n * fallback, and anything unmatched or malformed degrades to the fallback.\n */\nexport const resolveLocale = (\n\theader: string | null | undefined,\n\tavailableLocales: readonly string[],\n\tfallbackLocale: string\n): string => {\n\tif (header == null || header.trim() === '') {\n\t\treturn fallbackLocale;\n\t}\n\n\tconst candidates: LocaleCandidate[] = [];\n\tconst parts = header.split(',');\n\tfor (let index = 0; index < parts.length; index += 1) {\n\t\tconst part = parts[index];\n\t\tif (part === undefined) continue;\n\t\tconst [rawTag, ...rawParams] = part.trim().split(';');\n\t\tconst tag = rawTag?.trim().toLowerCase() ?? '';\n\t\tif (tag === '') continue;\n\n\t\t// Malformed quality values keep the default weight of 1.\n\t\tlet quality = 1;\n\t\tfor (const rawParam of rawParams) {\n\t\t\tconst [name, value] = rawParam.trim().split('=');\n\t\t\tif (name?.trim() !== 'q' || value === undefined) continue;\n\t\t\tconst parsed = Number(value.trim());\n\t\t\tif (Number.isFinite(parsed)) {\n\t\t\t\tquality = parsed;\n\t\t\t}\n\t\t}\n\n\t\tcandidates.push({ tag, quality, order: index });\n\t}\n\n\tcandidates.sort((a, b) => b.quality - a.quality || a.order - b.order);\n\n\tconst lowered = new Map(\n\t\tavailableLocales.map((locale) => [locale.toLowerCase(), locale])\n\t);\n\n\tfor (const { tag, quality } of candidates) {\n\t\tif (quality <= 0) continue;\n\t\tif (tag === '*') {\n\t\t\treturn fallbackLocale;\n\t\t}\n\n\t\tconst exact = lowered.get(tag);\n\t\tif (exact !== undefined) {\n\t\t\treturn exact;\n\t\t}\n\n\t\tconst base = tag.split('-')[0];\n\t\tif (base !== undefined) {\n\t\t\tconst baseMatch = lowered.get(base);\n\t\t\tif (baseMatch !== undefined) {\n\t\t\t\treturn baseMatch;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn fallbackLocale;\n};\n","/**\n * MIT License\n *\n * Copyright (c) 2025 Chris M. Perez\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\nimport { Config, Effect } from 'effect';\nimport { DEFAULT_LOCALE, DEFAULT_FALLBACK_LOCALE } from './constants.js';\n\nexport interface I18nConfigValues {\n\tdefaultLocale: string;\n\tfallbackLocale: string;\n\tdetectLocale: boolean;\n\tpersistLocale: boolean;\n}\n\nexport const I18nConfig = Config.all({\n\tdefaultLocale: Config.string('EFFUSE_I18N_LOCALE').pipe(\n\t\tConfig.withDefault(DEFAULT_LOCALE)\n\t),\n\tfallbackLocale: Config.string('EFFUSE_I18N_FALLBACK').pipe(\n\t\tConfig.withDefault(DEFAULT_FALLBACK_LOCALE)\n\t),\n\tdetectLocale: Config.boolean('EFFUSE_I18N_DETECT').pipe(\n\t\tConfig.withDefault(true)\n\t),\n\tpersistLocale: Config.boolean('EFFUSE_I18N_PERSIST').pipe(\n\t\tConfig.withDefault(true)\n\t),\n});\n\nlet cachedConfig: I18nConfigValues | null = null;\n\nexport const getI18nConfig = (): I18nConfigValues => {\n\tif (cachedConfig) {\n\t\treturn cachedConfig;\n\t}\n\n\tconst result = Effect.runSync(Effect.either(I18nConfig));\n\n\tif (result._tag === 'Right') {\n\t\tcachedConfig = result.right;\n\t} else {\n\t\tcachedConfig = {\n\t\t\tdefaultLocale: DEFAULT_LOCALE,\n\t\t\tfallbackLocale: DEFAULT_FALLBACK_LOCALE,\n\t\t\tdetectLocale: true,\n\t\t\tpersistLocale: true,\n\t\t};\n\t}\n\n\treturn cachedConfig;\n};\n\nexport const resetI18nConfigCache = (): void => {\n\tcachedConfig = null;\n};\n","/**\n * MIT License\n *\n * Copyright (c) 2025 Chris M. Perez\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\nimport { Effect, Predicate } from 'effect';\nimport { createRuntimeContext, type Signal } from '@effuse/core';\nimport type {\n\tI18n,\n\tI18nOptions,\n\tTranslations,\n\tTranslationParams,\n\tUseTranslationReturn,\n\tTypedI18n,\n\tTypedUseTranslationReturn,\n\tTypedI18nOptions,\n} from './types/index.js';\nimport { I18nService, makeI18nServiceLayer } from './services/index.js';\nimport {\n\tcreateLocaleSignal,\n\tcreateTranslationsVersion,\n\tbumpTranslationsVersion,\n} from './reactivity/index.js';\nimport {\n\ttranslate,\n\thasTranslationKey,\n\tmergeTranslations,\n} from './core/index.js';\nimport { getI18nConfig } from './config/index.js';\nimport { I18nNotInitializedError } from './errors/index.js';\nimport {\n\tDEFAULT_LOCALE,\n\tDEFAULT_FALLBACK_LOCALE,\n\tLOCALE_STORAGE_KEY,\n} from './config/constants.js';\n\nconst hasLocalStorage = (): boolean =>\n\ttypeof localStorage !== 'undefined' &&\n\ttypeof localStorage.getItem === 'function' &&\n\ttypeof localStorage.setItem === 'function';\n\nlet globalI18nInstance: I18nInstance | null = null;\n\nclass I18nInstance implements I18n {\n\tprivate readonly _locale: Signal<string>;\n\tprivate readonly _version: Signal<number>;\n\tprivate readonly _translations: Map<string, Translations>;\n\tprivate readonly _pendingLoads = new Map<\n\t\tstring,\n\t\tPromise<Translations>\n\t>();\n\tprivate readonly _fallbackLocale: string;\n\tprivate readonly _options: I18nOptions | TypedI18nOptions<Translations>;\n\tprivate _localeTransition = 0;\n\n\tconstructor(options: I18nOptions | TypedI18nOptions<Translations>) {\n\t\tthis._options = options;\n\n\t\tconst envConfig = getI18nConfig();\n\t\tconst defaultLocale = options.defaultLocale ?? DEFAULT_LOCALE;\n\t\tthis._fallbackLocale = options.fallbackLocale ?? DEFAULT_FALLBACK_LOCALE;\n\n\t\tlet initialLocale = defaultLocale;\n\t\tconst detectEnabled = options.detectLocale ?? envConfig.detectLocale;\n\t\tif (detectEnabled && typeof navigator !== 'undefined') {\n\t\t\tconst browserLocale = navigator.language.split('-')[0];\n\t\t\tif (\n\t\t\t\tPredicate.isNotNullable(browserLocale) &&\n\t\t\t\tPredicate.isNotNullable(options.translations) &&\n\t\t\t\tPredicate.isNotNullable(options.translations[browserLocale])\n\t\t\t) {\n\t\t\t\tinitialLocale = browserLocale;\n\t\t\t}\n\t\t}\n\n\t\tconst persistEnabled = options.persistLocale ?? envConfig.persistLocale;\n\t\tif (persistEnabled && hasLocalStorage()) {\n\t\t\tconst stored = localStorage.getItem(LOCALE_STORAGE_KEY);\n\t\t\tif (\n\t\t\t\tPredicate.isNotNullable(stored) &&\n\t\t\t\tPredicate.isNotNullable(options.translations) &&\n\t\t\t\tPredicate.isNotNullable(options.translations[stored])\n\t\t\t) {\n\t\t\t\tinitialLocale = stored;\n\t\t\t}\n\t\t}\n\n\t\tthis._locale = createLocaleSignal(initialLocale);\n\t\tthis._version = createTranslationsVersion();\n\n\t\tthis._translations = new Map<string, Translations>();\n\t\tif (options.translations) {\n\t\t\tfor (const [locale, translations] of Object.entries(\n\t\t\t\toptions.translations\n\t\t\t)) {\n\t\t\t\tthis._translations.set(locale, translations);\n\t\t\t}\n\t\t}\n\t}\n\n\tget locale(): Signal<string> {\n\t\treturn this._locale;\n\t}\n\n\tt = (key: string, params?: TranslationParams): string => {\n\t\tvoid this._version.value;\n\n\t\tconst currentLocale = this._locale.value;\n\t\tconst translations = this._translations.get(currentLocale);\n\t\tconst fallbackTranslations = this._translations.get(this._fallbackLocale);\n\n\t\tconst result = translate(\n\t\t\ttranslations,\n\t\t\tfallbackTranslations,\n\t\t\tkey,\n\t\t\tparams,\n\t\t\tcurrentLocale\n\t\t);\n\n\t\tif (\n\t\t\tresult === key &&\n\t\t\t!hasTranslationKey(translations ?? {}, key) &&\n\t\t\t!hasTranslationKey(fallbackTranslations ?? {}, key)\n\t\t) {\n\t\t\tif (this._options.onMissingKey) {\n\t\t\t\tconst handled = this._options.onMissingKey(key, currentLocale);\n\t\t\t\tif (handled !== undefined) {\n\t\t\t\t\treturn handled;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn result;\n\t};\n\n\tsetLocale = async (locale: string): Promise<void> => {\n\t\tconst transition = ++this._localeTransition;\n\n\t\tif (!this._translations.has(locale)) {\n\t\t\tawait this._loadTranslationsForLocale(locale);\n\t\t}\n\n\t\tif (transition !== this._localeTransition) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis._locale.value = locale;\n\n\t\tconst persistEnabled =\n\t\t\tthis._options.persistLocale ?? getI18nConfig().persistLocale;\n\t\tif (persistEnabled && hasLocalStorage()) {\n\t\t\tlocalStorage.setItem(LOCALE_STORAGE_KEY, locale);\n\t\t}\n\n\t\tbumpTranslationsVersion(this._version);\n\t};\n\n\tgetLocale = (): string => {\n\t\treturn this._locale.value;\n\t};\n\n\thasKey = (key: string): boolean => {\n\t\tconst currentLocale = this._locale.value;\n\t\tconst translations = this._translations.get(currentLocale);\n\t\tconst fallbackTranslations = this._translations.get(this._fallbackLocale);\n\n\t\treturn (\n\t\t\thasTranslationKey(translations ?? {}, key) ||\n\t\t\thasTranslationKey(fallbackTranslations ?? {}, key)\n\t\t);\n\t};\n\n\tgetAvailableLocales = (): string[] => {\n\t\treturn Array.from(this._translations.keys());\n\t};\n\n\taddTranslations = (locale: string, translations: Translations): void => {\n\t\tconst existing = this._translations.get(locale);\n\t\tif (existing) {\n\t\t\tthis._translations.set(locale, mergeTranslations(existing, translations));\n\t\t} else {\n\t\t\tthis._translations.set(locale, translations);\n\t\t}\n\t\tbumpTranslationsVersion(this._version);\n\t};\n\n\tprivate _loadTranslationsForLocale(locale: string): Promise<Translations> {\n\t\tconst loaded = this._translations.get(locale);\n\t\tif (loaded) {\n\t\t\treturn Promise.resolve(loaded);\n\t\t}\n\n\t\tconst pending = this._pendingLoads.get(locale);\n\t\tif (pending) {\n\t\t\treturn pending;\n\t\t}\n\n\t\tconst layer = makeI18nServiceLayer(this._options);\n\n\t\tconst loadEffect = Effect.gen(function* () {\n\t\t\tconst service = yield* I18nService;\n\t\t\tconst loaded = yield* service.loadTranslations(locale);\n\t\t\treturn loaded;\n\t\t});\n\n\t\tconst program = Effect.provide(loadEffect, layer);\n\t\tconst loadPromise = Effect.runPromise(Effect.either(program))\n\t\t\t.then((result) => {\n\t\t\t\tif (result._tag === 'Left') {\n\t\t\t\t\tthrow result.left;\n\t\t\t\t}\n\n\t\t\t\tconst translations = result.right;\n\t\t\t\tthis._translations.set(locale, translations);\n\t\t\t\treturn translations;\n\t\t\t})\n\t\t\t.finally(() => {\n\t\t\t\tif (this._pendingLoads.get(locale) === loadPromise) {\n\t\t\t\t\tthis._pendingLoads.delete(locale);\n\t\t\t\t}\n\t\t\t});\n\n\t\tthis._pendingLoads.set(locale, loadPromise);\n\t\treturn loadPromise;\n\t}\n}\n\n// Initializes the i18n instance.\nexport function createI18n<const T>(options: TypedI18nOptions<T>): TypedI18n<T>;\nexport function createI18n(options?: I18nOptions): I18n;\nexport function createI18n<const T>(\n\toptions: I18nOptions | TypedI18nOptions<T> = {}\n): I18n | TypedI18n<T> {\n\tconst instance = new I18nInstance(options as I18nOptions);\n\tglobalI18nInstance = instance;\n\treturn instance as I18n | TypedI18n<T>;\n}\n\n// Creates an i18n instance without registering it globally. Use for\n// request-scoped instances on the server, bound per render via withI18n.\n// Environment detection and persistence default to off: the locale of a\n// request-scoped instance must come from the request, not from the server\n// process (Node 21+ exposes a global navigator, so detection would silently\n// override defaultLocale on servers).\nexport function createI18nInstance<const T>(\n\toptions: TypedI18nOptions<T>\n): TypedI18n<T>;\nexport function createI18nInstance(options?: I18nOptions): I18n;\nexport function createI18nInstance<const T>(\n\toptions: I18nOptions | TypedI18nOptions<T> = {}\n): I18n | TypedI18n<T> {\n\tconst scopedOptions = {\n\t\tdetectLocale: false,\n\t\tpersistLocale: false,\n\t\t...(options as I18nOptions),\n\t};\n\treturn new I18nInstance(scopedOptions) as I18n | TypedI18n<T>;\n}\n\nconst i18nRuntimeContext = createRuntimeContext<I18nInstance>();\n\n// Runs fn with the given instance bound as the current i18n resolution\n// target for getI18n/t/useTranslation. Restores the previous binding even\n// when fn throws.\nexport function withI18n<R>(instance: I18n, fn: () => R): R;\nexport function withI18n<T, R>(instance: TypedI18n<T>, fn: () => R): R;\nexport function withI18n<R>(instance: unknown, fn: () => R): R {\n\treturn i18nRuntimeContext.run(instance as I18nInstance, fn);\n}\n\n// Retrieves the bound (scoped) instance if inside withI18n, otherwise the\n// global instance. Throws if neither exists.\nexport function getI18n(): I18n;\nexport function getI18n<T>(): TypedI18n<T>;\nexport function getI18n<T>(): I18n | TypedI18n<T> {\n\tconst scoped = i18nRuntimeContext.current();\n\tif (scoped) {\n\t\treturn scoped as I18n | TypedI18n<T>;\n\t}\n\tif (!globalI18nInstance) {\n\t\tthrow new I18nNotInitializedError({});\n\t}\n\treturn globalI18nInstance as I18n | TypedI18n<T>;\n}\n\n// Translates a key with optional parameters.\nexport const t = (key: string, params?: TranslationParams): string => {\n\treturn getI18n().t(key, params);\n};\n\n// Changes the current locale and loads translations if needed.\nexport const setLocale = async (locale: string): Promise<void> => {\n\tawait getI18n().setLocale(locale);\n};\n\n// Returns the current active locale code.\nexport const getLocale = (): string => {\n\treturn getI18n().getLocale();\n};\n\n// Hook for using translations in components.\nexport function useTranslation(): UseTranslationReturn;\nexport function useTranslation<T>(): TypedUseTranslationReturn<T>;\nexport function useTranslation<T>():\n\t| UseTranslationReturn\n\t| TypedUseTranslationReturn<T> {\n\tconst i18n = getI18n();\n\n\treturn {\n\t\tt: i18n.t,\n\t\tlocale: i18n.locale,\n\t\tsetLocale: i18n.setLocale,\n\t\thasKey: i18n.hasKey,\n\t};\n}\n\n// Resets the global i18n instance (useful for testing).\nexport const resetI18n = (): void => {\n\tglobalI18nInstance = null;\n};\n","/**\n * MIT License\n *\n * Copyright (c) 2025 Chris M. Perez\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\nimport type { Signal } from '@effuse/core';\n\ntype Prev = [never, 0, 1, 2, 3, 4];\n\nexport type FlattenKeys<T, Depth extends number = 4> = Depth extends 0\n\t? never\n\t: T extends string\n\t\t? never\n\t\t: T extends object\n\t\t\t? {\n\t\t\t\t\t[K in keyof T & string]: T[K] extends string\n\t\t\t\t\t\t? K\n\t\t\t\t\t\t: T[K] extends object\n\t\t\t\t\t\t\t? K | `${K}.${FlattenKeys<T[K], Prev[Depth]>}`\n\t\t\t\t\t\t\t: K;\n\t\t\t\t}[keyof T & string]\n\t\t\t: never;\n\nexport type GetNestedType<T, Path extends string> = Path extends keyof T\n\t? T[Path]\n\t: Path extends `${infer Key}.${infer Rest}`\n\t\t? Key extends keyof T\n\t\t\t? T[Key] extends object\n\t\t\t\t? GetNestedType<T[Key], Rest>\n\t\t\t\t: never\n\t\t\t: never\n\t\t: never;\n\nexport type ExtractVariables<T extends string> =\n\tT extends `${string}{{${infer Var}}}${infer Rest}`\n\t\t? Var | ExtractVariables<Rest>\n\t\t: never;\n\nexport type ParamsFor<T> = T extends string\n\t? ExtractVariables<T> extends never\n\t\t? TranslationParams | undefined\n\t\t: { [K in ExtractVariables<T>]: string | number } & { count?: number }\n\t: TranslationParams | undefined;\n\nexport type InferParams<TTranslations, TKey extends string> = ParamsFor<\n\tGetNestedType<TTranslations, TKey>\n>;\n\nexport interface Translations {\n\t[key: string]: string | Translations;\n}\n\nexport interface TranslationParams {\n\tcount?: number;\n\t[key: string]: unknown;\n}\n\nexport interface PluralRules {\n\tzero?: string;\n\tone?: string;\n\ttwo?: string;\n\tfew?: string;\n\tmany?: string;\n\tother: string;\n}\n\nexport type TranslationLoader = (\n\tlocale: string\n) => Promise<Translations> | Translations;\n\nexport interface I18nOptions {\n\tdefaultLocale?: string;\n\tfallbackLocale?: string;\n\ttranslations?: Record<string, Translations>;\n\tloader?: TranslationLoader;\n\tloadPath?: string | ((locale: string) => string);\n\tdetectLocale?: boolean;\n\tpersistLocale?: boolean;\n\tonMissingKey?: (key: string, locale: string) => string | undefined;\n}\n\nexport interface TypedI18nOptions<TTranslations> {\n\tdefaultLocale?: string;\n\tfallbackLocale?: string;\n\ttranslations: Record<string, TTranslations>;\n\tloader?: TranslationLoader;\n\tloadPath?: string | ((locale: string) => string);\n\tdetectLocale?: boolean;\n\tpersistLocale?: boolean;\n\tonMissingKey?: (key: string, locale: string) => string | undefined;\n}\n\nexport interface TypedI18n<TTranslations> {\n\tt: <K extends FlattenKeys<TTranslations>>(\n\t\tkey: K,\n\t\tparams?: InferParams<TTranslations, K>\n\t) => string;\n\tsetLocale: (locale: string) => Promise<void>;\n\tgetLocale: () => string;\n\tlocale: Signal<string>;\n\thasKey: (key: FlattenKeys<TTranslations>) => boolean;\n\tgetAvailableLocales: () => string[];\n\taddTranslations: (locale: string, translations: Translations) => void;\n}\n\nexport interface I18n {\n\tt: (key: string, params?: TranslationParams) => string;\n\tsetLocale: (locale: string) => Promise<void>;\n\tgetLocale: () => string;\n\tlocale: Signal<string>;\n\thasKey: (key: string) => boolean;\n\tgetAvailableLocales: () => string[];\n\taddTranslations: (locale: string, translations: Translations) => void;\n}\n\nexport interface TypedUseTranslationReturn<TTranslations> {\n\tt: <K extends FlattenKeys<TTranslations>>(\n\t\tkey: K,\n\t\tparams?: InferParams<TTranslations, K>\n\t) => string;\n\tlocale: Signal<string>;\n\tsetLocale: (locale: string) => Promise<void>;\n\thasKey: (key: FlattenKeys<TTranslations>) => boolean;\n}\n\nexport interface UseTranslationReturn {\n\tt: (key: string, params?: TranslationParams) => string;\n\tlocale: Signal<string>;\n\tsetLocale: (locale: string) => Promise<void>;\n\thasKey: (key: string) => boolean;\n}\n\nexport interface TranslationCacheEntry {\n\ttranslations: Translations;\n\tloadedAt: number;\n}\n\nexport interface I18nState {\n\tcurrentLocale: string;\n\tfallbackLocale: string;\n\ttranslations: Map<string, Translations>;\n\tisLoading: boolean;\n}\n\n// Define translations with `as const` for type inference.\nexport function defineTranslations<const T>(translations: T): T {\n\treturn translations;\n}\n"]}