experimental-ciao-react 1.1.7 → 1.1.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +15 -5
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +4 -0
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +15 -5
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -281,6 +281,7 @@ const useTranslationStore = (0, zustand.create)()((0, zustand_middleware.persist
|
|
|
281
281
|
isHydrated: false,
|
|
282
282
|
serverVersion: null,
|
|
283
283
|
lastVersionCheck: null,
|
|
284
|
+
cachedLanguages: [],
|
|
284
285
|
setLanguage: (language) => {
|
|
285
286
|
set({
|
|
286
287
|
currentLanguage: language,
|
|
@@ -325,12 +326,16 @@ const useTranslationStore = (0, zustand.create)()((0, zustand_middleware.persist
|
|
|
325
326
|
serverVersion: version,
|
|
326
327
|
lastVersionCheck: Date.now()
|
|
327
328
|
});
|
|
329
|
+
},
|
|
330
|
+
setCachedLanguages: (languages) => {
|
|
331
|
+
set({ cachedLanguages: languages });
|
|
328
332
|
}
|
|
329
333
|
}), {
|
|
330
334
|
name: "ciao-tools-language",
|
|
331
335
|
partialize: (state) => ({
|
|
332
336
|
currentLanguage: state.currentLanguage,
|
|
333
|
-
serverVersion: state.serverVersion
|
|
337
|
+
serverVersion: state.serverVersion,
|
|
338
|
+
cachedLanguages: state.cachedLanguages
|
|
334
339
|
}),
|
|
335
340
|
onRehydrateStorage: () => (_, error) => {
|
|
336
341
|
if (!error && hydrationResolver) hydrationResolver();
|
|
@@ -369,7 +374,7 @@ async function fetchTranslations(url) {
|
|
|
369
374
|
function useHotUpdates(config, projectId) {
|
|
370
375
|
const isCheckingRef = (0, react.useRef)(false);
|
|
371
376
|
const hasCheckedOnMountRef = (0, react.useRef)(false);
|
|
372
|
-
const { serverVersion, setServerVersion, addLanguage } = useTranslationStore();
|
|
377
|
+
const { serverVersion, setServerVersion, addLanguage, cachedLanguages, setCachedLanguages } = useTranslationStore();
|
|
373
378
|
const checkForUpdates = (0, react.useCallback)(async () => {
|
|
374
379
|
if (!config || !projectId || isCheckingRef.current) return;
|
|
375
380
|
if (config.enabled !== true) return;
|
|
@@ -384,9 +389,11 @@ function useHotUpdates(config, projectId) {
|
|
|
384
389
|
console.log("[ciao-tools] Found latest.json, version:", manifest.version);
|
|
385
390
|
const isFirstCheck = serverVersion === null;
|
|
386
391
|
const hasNewVersion = serverVersion !== null && manifest.version > serverVersion;
|
|
387
|
-
|
|
392
|
+
const hasNoCache = cachedLanguages.length === 0;
|
|
393
|
+
if (isFirstCheck || hasNewVersion || hasNoCache) {
|
|
388
394
|
if (Object.keys(manifest.urls).length > 0) {
|
|
389
|
-
|
|
395
|
+
const reason = hasNewVersion ? "new version" : hasNoCache ? "no cached translations" : "first check";
|
|
396
|
+
console.log(`[ciao-tools] Fetching translations (${reason})...`);
|
|
390
397
|
await clearCache(projectId);
|
|
391
398
|
const updatedLanguages = [];
|
|
392
399
|
for (const [langCode, url] of Object.entries(manifest.urls)) try {
|
|
@@ -398,6 +405,7 @@ function useHotUpdates(config, projectId) {
|
|
|
398
405
|
console.error(`[ciao-tools] Failed to fetch ${langCode} translations:`, err);
|
|
399
406
|
}
|
|
400
407
|
if (updatedLanguages.length > 0) {
|
|
408
|
+
setCachedLanguages(updatedLanguages);
|
|
401
409
|
console.log("[ciao-tools] Updated translations for:", updatedLanguages);
|
|
402
410
|
if (hasNewVersion && config.onTranslationsUpdated) config.onTranslationsUpdated(updatedLanguages);
|
|
403
411
|
}
|
|
@@ -414,7 +422,9 @@ function useHotUpdates(config, projectId) {
|
|
|
414
422
|
projectId,
|
|
415
423
|
serverVersion,
|
|
416
424
|
setServerVersion,
|
|
417
|
-
addLanguage
|
|
425
|
+
addLanguage,
|
|
426
|
+
cachedLanguages,
|
|
427
|
+
setCachedLanguages
|
|
418
428
|
]);
|
|
419
429
|
(0, react.useEffect)(() => {
|
|
420
430
|
if (!config || !projectId) return;
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","names":["dbPromise: Promise<IDBDatabase> | null","entry: CacheEntry","options: Intl.DateTimeFormatOptions","result: string","key: string","format: string | undefined","hydrationResolver: (() => void) | null","updatedLanguages: string[]","LANGUAGE_DATA: Record<\n\tstring,\n\t{ name: string; nativeName: string; flag: string }\n>","values: InterpolationValues | undefined","elements: ReactElement[]","result: ReactNode[]","match: RegExpExecArray | null","translated: string"],"sources":["../src/components/CTContextBlock.tsx","../src/cache.ts","../src/interpolate.ts","../src/store.ts","../src/hooks/useHotUpdates.ts","../src/components/CTProvider.tsx","../src/components/LanguageSwitcher.tsx","../src/hooks/useCt.ts","../src/components/Trans.tsx","../src/hooks/useLanguage.ts"],"sourcesContent":["import React from \"react\";\nimport type { CTContextBlockProps } from \"../types\";\n\nexport function CTContextBlock({ children }: CTContextBlockProps) {\n\treturn <>{children}</>;\n}\n","import type { TranslationMap } from \"./types\";\n\nconst DB_NAME = \"ciao-tools-translations\";\nconst DB_VERSION = 1;\nconst STORE_NAME = \"translations\";\n\ninterface CacheEntry {\n\tlanguage: string;\n\tprojectId: string;\n\tdata: TranslationMap;\n\turl: string;\n\tcachedAt: number;\n}\n\nlet dbPromise: Promise<IDBDatabase> | null = null;\n\nfunction openDB(): Promise<IDBDatabase> {\n\tif (dbPromise) return dbPromise;\n\n\tdbPromise = new Promise((resolve, reject) => {\n\t\tif (typeof indexedDB === \"undefined\") {\n\t\t\treject(new Error(\"IndexedDB not available\"));\n\t\t\treturn;\n\t\t}\n\n\t\tconst request = indexedDB.open(DB_NAME, DB_VERSION);\n\n\t\trequest.onerror = () => reject(request.error);\n\t\trequest.onsuccess = () => resolve(request.result);\n\n\t\trequest.onupgradeneeded = (event) => {\n\t\t\tconst db = (event.target as IDBOpenDBRequest).result;\n\t\t\tif (!db.objectStoreNames.contains(STORE_NAME)) {\n\t\t\t\tconst store = db.createObjectStore(STORE_NAME, { keyPath: \"url\" });\n\t\t\t\tstore.createIndex(\"language\", \"language\", { unique: false });\n\t\t\t\tstore.createIndex(\"projectId\", \"projectId\", { unique: false });\n\t\t\t}\n\t\t};\n\t});\n\n\treturn dbPromise;\n}\n\nexport async function getCachedTranslation(\n\turl: string,\n): Promise<TranslationMap | null> {\n\ttry {\n\t\tconst db = await openDB();\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tconst transaction = db.transaction(STORE_NAME, \"readonly\");\n\t\t\tconst store = transaction.objectStore(STORE_NAME);\n\t\t\tconst request = store.get(url);\n\n\t\t\trequest.onerror = () => reject(request.error);\n\t\t\trequest.onsuccess = () => {\n\t\t\t\tconst entry = request.result as CacheEntry | undefined;\n\t\t\t\tresolve(entry?.data ?? null);\n\t\t\t};\n\t\t});\n\t} catch {\n\t\treturn null;\n\t}\n}\n\nexport async function cacheTranslation(\n\turl: string,\n\tlanguage: string,\n\tprojectId: string,\n\tdata: TranslationMap,\n): Promise<void> {\n\ttry {\n\t\tconst db = await openDB();\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tconst transaction = db.transaction(STORE_NAME, \"readwrite\");\n\t\t\tconst store = transaction.objectStore(STORE_NAME);\n\n\t\t\tconst entry: CacheEntry = {\n\t\t\t\turl,\n\t\t\t\tlanguage,\n\t\t\t\tprojectId,\n\t\t\t\tdata,\n\t\t\t\tcachedAt: Date.now(),\n\t\t\t};\n\n\t\t\tconst request = store.put(entry);\n\t\t\trequest.onerror = () => reject(request.error);\n\t\t\trequest.onsuccess = () => resolve();\n\t\t});\n\t} catch {\n\t\t// Silently fail - caching is optional\n\t}\n}\n\nexport async function clearCache(projectId?: string): Promise<void> {\n\ttry {\n\t\tconst db = await openDB();\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tconst transaction = db.transaction(STORE_NAME, \"readwrite\");\n\t\t\tconst store = transaction.objectStore(STORE_NAME);\n\n\t\t\tif (projectId) {\n\t\t\t\tconst index = store.index(\"projectId\");\n\t\t\t\tconst request = index.openCursor(IDBKeyRange.only(projectId));\n\t\t\t\trequest.onsuccess = (event) => {\n\t\t\t\t\tconst cursor = (event.target as IDBRequest).result;\n\t\t\t\t\tif (cursor) {\n\t\t\t\t\t\tcursor.delete();\n\t\t\t\t\t\tcursor.continue();\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t\t\ttransaction.oncomplete = () => resolve();\n\t\t\t\ttransaction.onerror = () => reject(transaction.error);\n\t\t\t} else {\n\t\t\t\tconst request = store.clear();\n\t\t\t\trequest.onerror = () => reject(request.error);\n\t\t\t\trequest.onsuccess = () => resolve();\n\t\t\t}\n\t\t});\n\t} catch {\n\t\t// Silently fail\n\t}\n}\n\nexport async function getCacheStats(): Promise<{\n\tcount: number;\n\tlanguages: string[];\n}> {\n\ttry {\n\t\tconst db = await openDB();\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tconst transaction = db.transaction(STORE_NAME, \"readonly\");\n\t\t\tconst store = transaction.objectStore(STORE_NAME);\n\n\t\t\tconst countRequest = store.count();\n\t\t\tconst languages = new Set<string>();\n\n\t\t\tconst cursorRequest = store.openCursor();\n\t\t\tcursorRequest.onsuccess = (event) => {\n\t\t\t\tconst cursor = (event.target as IDBRequest).result;\n\t\t\t\tif (cursor) {\n\t\t\t\t\tlanguages.add((cursor.value as CacheEntry).language);\n\t\t\t\t\tcursor.continue();\n\t\t\t\t}\n\t\t\t};\n\n\t\t\ttransaction.oncomplete = () => {\n\t\t\t\tresolve({\n\t\t\t\t\tcount: countRequest.result,\n\t\t\t\t\tlanguages: Array.from(languages),\n\t\t\t\t});\n\t\t\t};\n\t\t\ttransaction.onerror = () => reject(transaction.error);\n\t\t});\n\t} catch {\n\t\treturn { count: 0, languages: [] };\n\t}\n}\n","export type InterpolationValues = Record<string, unknown>;\n\nconst numberFormatCache = new Map<string, Intl.NumberFormat>();\nconst dateFormatCache = new Map<string, Intl.DateTimeFormat>();\nconst pluralRulesCache = new Map<string, Intl.PluralRules>();\n\nexport function clearFormatterCache(): void {\n\tnumberFormatCache.clear();\n\tdateFormatCache.clear();\n\tpluralRulesCache.clear();\n}\n\nfunction getNumberFormatter(locale: string): Intl.NumberFormat {\n\tconst key = `number:${locale}`;\n\tif (!numberFormatCache.has(key)) {\n\t\tnumberFormatCache.set(\n\t\t\tkey,\n\t\t\tnew Intl.NumberFormat(locale, {\n\t\t\t\tmaximumFractionDigits: 20,\n\t\t\t}),\n\t\t);\n\t}\n\treturn numberFormatCache.get(key)!;\n}\n\nfunction getCurrencyFormatter(\n\tlocale: string,\n\tcurrency: string,\n): Intl.NumberFormat {\n\tconst key = `currency:${locale}:${currency}`;\n\tif (!numberFormatCache.has(key)) {\n\t\tnumberFormatCache.set(\n\t\t\tkey,\n\t\t\tnew Intl.NumberFormat(locale, {\n\t\t\t\tstyle: \"currency\",\n\t\t\t\tcurrency,\n\t\t\t}),\n\t\t);\n\t}\n\treturn numberFormatCache.get(key)!;\n}\n\nfunction getPercentFormatter(locale: string): Intl.NumberFormat {\n\tconst key = `percent:${locale}`;\n\tif (!numberFormatCache.has(key)) {\n\t\tnumberFormatCache.set(\n\t\t\tkey,\n\t\t\tnew Intl.NumberFormat(locale, {\n\t\t\t\tstyle: \"percent\",\n\t\t\t\tminimumFractionDigits: 0,\n\t\t\t\tmaximumFractionDigits: 2,\n\t\t\t}),\n\t\t);\n\t}\n\treturn numberFormatCache.get(key)!;\n}\n\nfunction getDateFormatter(\n\tlocale: string,\n\tstyle: \"short\" | \"medium\" | \"long\" | \"full\",\n): Intl.DateTimeFormat {\n\tconst key = `date:${locale}:${style}`;\n\tif (!dateFormatCache.has(key)) {\n\t\tconst options: Intl.DateTimeFormatOptions = {\n\t\t\tdateStyle: style,\n\t\t};\n\t\tdateFormatCache.set(key, new Intl.DateTimeFormat(locale, options));\n\t}\n\treturn dateFormatCache.get(key)!;\n}\n\nfunction getTimeFormatter(\n\tlocale: string,\n\tstyle: \"short\" | \"medium\" | \"long\" | \"full\",\n): Intl.DateTimeFormat {\n\tconst key = `time:${locale}:${style}`;\n\tif (!dateFormatCache.has(key)) {\n\t\tconst options: Intl.DateTimeFormatOptions = {\n\t\t\ttimeStyle: style,\n\t\t};\n\t\tdateFormatCache.set(key, new Intl.DateTimeFormat(locale, options));\n\t}\n\treturn dateFormatCache.get(key)!;\n}\n\nfunction getPluralRules(locale: string): Intl.PluralRules {\n\tif (!pluralRulesCache.has(locale)) {\n\t\tpluralRulesCache.set(locale, new Intl.PluralRules(locale));\n\t}\n\treturn pluralRulesCache.get(locale)!;\n}\n\nfunction formatValue(\n\tvalue: unknown,\n\tformat: string | undefined,\n\tlocale: string,\n): string {\n\tif (value === null || value === undefined) {\n\t\treturn \"\";\n\t}\n\n\tif (!format) {\n\t\treturn String(value);\n\t}\n\n\tconst parts = format.split(\":\");\n\tconst formatType = parts[0];\n\n\tswitch (formatType) {\n\t\tcase \"number\": {\n\t\t\tconst num = typeof value === \"number\" ? value : Number(value);\n\t\t\tif (Number.isNaN(num)) {\n\t\t\t\treturn String(value);\n\t\t\t}\n\t\t\treturn getNumberFormatter(locale).format(num);\n\t\t}\n\n\t\tcase \"currency\": {\n\t\t\tconst currency = parts[1];\n\t\t\tif (!currency) {\n\t\t\t\treturn String(value);\n\t\t\t}\n\t\t\tconst num = typeof value === \"number\" ? value : Number(value);\n\t\t\tif (Number.isNaN(num)) {\n\t\t\t\treturn String(value);\n\t\t\t}\n\t\t\treturn getCurrencyFormatter(locale, currency).format(num);\n\t\t}\n\n\t\tcase \"percent\": {\n\t\t\tconst num = typeof value === \"number\" ? value : Number(value);\n\t\t\tif (Number.isNaN(num)) {\n\t\t\t\treturn String(value);\n\t\t\t}\n\t\t\treturn getPercentFormatter(locale).format(num);\n\t\t}\n\n\t\tcase \"date\": {\n\t\t\tif (!(value instanceof Date)) {\n\t\t\t\treturn String(value);\n\t\t\t}\n\t\t\tconst style =\n\t\t\t\t(parts[1] as \"short\" | \"medium\" | \"long\" | \"full\") || \"medium\";\n\t\t\treturn getDateFormatter(locale, style).format(value);\n\t\t}\n\n\t\tcase \"time\": {\n\t\t\tif (!(value instanceof Date)) {\n\t\t\t\treturn String(value);\n\t\t\t}\n\t\t\tconst style =\n\t\t\t\t(parts[1] as \"short\" | \"medium\" | \"long\" | \"full\") || \"medium\";\n\t\t\treturn getTimeFormatter(locale, style).format(value);\n\t\t}\n\n\t\tcase \"plural\": {\n\t\t\tconst singular = parts[1];\n\t\t\tconst plural = parts[2];\n\t\t\tif (!singular || !plural) {\n\t\t\t\treturn String(value);\n\t\t\t}\n\t\t\tconst num = typeof value === \"number\" ? value : Number(value);\n\t\t\tconst rules = getPluralRules(locale);\n\t\t\tconst category = rules.select(num);\n\t\t\treturn category === \"one\" ? singular : plural;\n\t\t}\n\n\t\tdefault:\n\t\t\treturn String(value);\n\t}\n}\n\nexport function interpolate(\n\ttext: string,\n\tvalues: InterpolationValues | undefined,\n\tlocale: string,\n): string {\n\t// Temporarily replace escaped braces with placeholder characters\n\tconst escaped = text.replace(/\\{\\{/g, \"\\x00\").replace(/\\}\\}/g, \"\\x01\");\n\n\tlet result: string;\n\tif (!values || Object.keys(values).length === 0) {\n\t\tresult = escaped;\n\t} else {\n\t\tresult = escaped.replace(/\\{([^}]+)\\}/g, (match, placeholder) => {\n\t\t\tconst trimmed = placeholder.trim();\n\t\t\tconst colonIndex = trimmed.indexOf(\":\");\n\n\t\t\tlet key: string;\n\t\t\tlet format: string | undefined;\n\n\t\t\tif (colonIndex === -1) {\n\t\t\t\tkey = trimmed;\n\t\t\t\tformat = undefined;\n\t\t\t} else {\n\t\t\t\tkey = trimmed.substring(0, colonIndex);\n\t\t\t\tformat = trimmed.substring(colonIndex + 1);\n\t\t\t}\n\n\t\t\tif (!(key in values)) {\n\t\t\t\treturn match;\n\t\t\t}\n\n\t\t\tconst value = values[key];\n\t\t\treturn formatValue(value, format, locale);\n\t\t});\n\t}\n\n\t// Restore escaped braces\n\treturn result.replace(/\\x00/g, \"{\").replace(/\\x01/g, \"}\");\n}\n","import { create } from \"zustand\";\nimport { persist } from \"zustand/middleware\";\nimport { interpolate } from \"./interpolate\";\nimport type {\n\tInterpolationValues,\n\tLanguageTranslations,\n\tTranslationMap,\n\tTranslationStore,\n} from \"./types\";\n\nlet hydrationResolver: (() => void) | null = null;\nconst hydrationPromise = new Promise<void>((resolve) => {\n\thydrationResolver = resolve;\n});\n\nexport const useTranslationStore = create<TranslationStore>()(\n\tpersist(\n\t\t(set) => ({\n\t\t\tcurrentLanguage: \"en\",\n\t\t\tdefaultLanguage: \"en\",\n\t\t\tavailableLanguages: [\"en\"],\n\t\t\ttranslations: {},\n\t\t\tisLoading: false,\n\t\t\tisReady: false,\n\t\t\tisHydrated: false,\n\t\t\tserverVersion: null,\n\t\t\tlastVersionCheck: null,\n\n\t\t\tsetLanguage: (language: string) => {\n\t\t\t\tset({ currentLanguage: language, isReady: false });\n\t\t\t},\n\n\t\t\tloadTranslations: (translations: LanguageTranslations) => {\n\t\t\t\tset((state) => {\n\t\t\t\t\tconst languages = Object.keys(translations);\n\t\t\t\t\tconst availableLanguages = [\n\t\t\t\t\t\t...new Set([...state.availableLanguages, ...languages]),\n\t\t\t\t\t];\n\t\t\t\t\tconst merged = { ...state.translations };\n\t\t\t\t\tfor (const lang of languages) {\n\t\t\t\t\t\tmerged[lang] = { ...merged[lang], ...translations[lang] };\n\t\t\t\t\t}\n\t\t\t\t\treturn {\n\t\t\t\t\t\ttranslations: merged,\n\t\t\t\t\t\tavailableLanguages,\n\t\t\t\t\t};\n\t\t\t\t});\n\t\t\t},\n\n\t\t\taddLanguage: (language: string, translations: TranslationMap) => {\n\t\t\t\tset((state) => ({\n\t\t\t\t\ttranslations: {\n\t\t\t\t\t\t...state.translations,\n\t\t\t\t\t\t[language]: { ...state.translations[language], ...translations },\n\t\t\t\t\t},\n\t\t\t\t\tavailableLanguages: state.availableLanguages.includes(language)\n\t\t\t\t\t\t? state.availableLanguages\n\t\t\t\t\t\t: [...state.availableLanguages, language],\n\t\t\t\t}));\n\t\t\t},\n\n\t\t\tsetLoading: (loading: boolean) => {\n\t\t\t\tset({ isLoading: loading });\n\t\t\t},\n\n\t\t\tsetReady: (ready: boolean) => {\n\t\t\t\tset({ isReady: ready });\n\t\t\t},\n\n\t\t\tsetServerVersion: (version: number) => {\n\t\t\t\tset({ serverVersion: version, lastVersionCheck: Date.now() });\n\t\t\t},\n\t\t}),\n\t\t{\n\t\t\tname: \"ciao-tools-language\",\n\t\t\tpartialize: (state) => ({\n\t\t\t\tcurrentLanguage: state.currentLanguage,\n\t\t\t\tserverVersion: state.serverVersion,\n\t\t\t}),\n\t\t\tonRehydrateStorage: () => (_, error) => {\n\t\t\t\tif (!error && hydrationResolver) {\n\t\t\t\t\thydrationResolver();\n\t\t\t\t}\n\t\t\t},\n\t\t},\n\t),\n);\n\nhydrationPromise.then(() => {\n\tuseTranslationStore.setState({ isHydrated: true });\n});\n\nexport function getTranslation(\n\ttranslations: LanguageTranslations,\n\tlanguage: string,\n\ttext: string,\n\tvalues?: InterpolationValues,\n): string {\n\tconst translated = translations[language]?.[text] ?? text;\n\n\tif (!values || Object.keys(values).length === 0) {\n\t\treturn translated;\n\t}\n\n\treturn interpolate(translated, values, language);\n}\n","import { useCallback, useEffect, useRef } from \"react\";\nimport { clearCache, cacheTranslation } from \"../cache\";\nimport { useTranslationStore } from \"../store\";\nimport type { HotUpdateConfig, TranslationMap } from \"../types\";\n\nconst CDN_BASE_URL = \"https://t1.ciao-tools.com\";\n\ninterface LatestManifest {\n\tversion: number;\n\tupdatedAt: string;\n\turls: Record<string, string>;\n}\n\nasync function fetchLatestManifest(projectId: string): Promise<LatestManifest | null> {\n\tconst url = `${CDN_BASE_URL}/translations/${projectId}/latest.json`;\n\ttry {\n\t\tconst response = await fetch(url, { cache: \"no-cache\" });\n\t\tif (!response.ok) {\n\t\t\tif (response.status === 404) {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tthrow new Error(`Failed to fetch latest manifest: ${response.statusText}`);\n\t\t}\n\t\treturn response.json();\n\t} catch {\n\t\treturn null;\n\t}\n}\n\nasync function fetchTranslations(url: string): Promise<TranslationMap> {\n\tconst response = await fetch(url);\n\tif (!response.ok) {\n\t\tthrow new Error(`Failed to fetch translations: ${response.statusText}`);\n\t}\n\treturn response.json();\n}\n\nexport function useHotUpdates(\n\tconfig: HotUpdateConfig | undefined,\n\tprojectId: string | undefined,\n) {\n\tconst isCheckingRef = useRef(false);\n\tconst hasCheckedOnMountRef = useRef(false);\n\n\tconst { serverVersion, setServerVersion, addLanguage } = useTranslationStore();\n\n\tconst checkForUpdates = useCallback(async () => {\n\t\tif (!config || !projectId || isCheckingRef.current) return;\n\t\tif (config.enabled !== true) return;\n\n\t\tisCheckingRef.current = true;\n\n\t\ttry {\n\t\t\tconsole.log(\"[ciao-tools] Checking for hot updates...\");\n\t\t\tconst manifest = await fetchLatestManifest(projectId);\n\n\t\t\tif (!manifest) {\n\t\t\t\tconsole.log(\"[ciao-tools] No latest.json found (project may not have hot updates yet)\");\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconsole.log(\"[ciao-tools] Found latest.json, version:\", manifest.version);\n\n\t\t\tconst isFirstCheck = serverVersion === null;\n\t\t\tconst hasNewVersion = serverVersion !== null && manifest.version > serverVersion;\n\n\t\t\tif (isFirstCheck || hasNewVersion) {\n\t\t\t\tif (Object.keys(manifest.urls).length > 0) {\n\t\t\t\t\tconsole.log(\"[ciao-tools] Fetching updated translations...\");\n\t\t\t\t\tawait clearCache(projectId);\n\n\t\t\t\t\tconst updatedLanguages: string[] = [];\n\n\t\t\t\t\tfor (const [langCode, url] of Object.entries(manifest.urls)) {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tconst translations = await fetchTranslations(url);\n\t\t\t\t\t\t\taddLanguage(langCode, translations);\n\t\t\t\t\t\t\tawait cacheTranslation(url, langCode, projectId, translations);\n\t\t\t\t\t\t\tupdatedLanguages.push(langCode);\n\t\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\t\tconsole.error(`[ciao-tools] Failed to fetch ${langCode} translations:`, err);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif (updatedLanguages.length > 0) {\n\t\t\t\t\t\tconsole.log(\"[ciao-tools] Updated translations for:\", updatedLanguages);\n\t\t\t\t\t\tif (hasNewVersion && config.onTranslationsUpdated) {\n\t\t\t\t\t\t\tconfig.onTranslationsUpdated(updatedLanguages);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tconsole.log(\"[ciao-tools] Already up to date (version \" + manifest.version + \")\");\n\t\t\t}\n\n\t\t\tsetServerVersion(manifest.version);\n\t\t} catch (error) {\n\t\t\tconsole.error(\"[ciao-tools] Hot update check failed:\", error);\n\t\t} finally {\n\t\t\tisCheckingRef.current = false;\n\t\t}\n\t}, [config, projectId, serverVersion, setServerVersion, addLanguage]);\n\n\tuseEffect(() => {\n\t\tif (!config || !projectId) return;\n\t\tif (config.enabled !== true) return;\n\n\t\tif (!hasCheckedOnMountRef.current) {\n\t\t\thasCheckedOnMountRef.current = true;\n\t\t\tcheckForUpdates();\n\t\t}\n\n\t\tconst handleVisibilityChange = () => {\n\t\t\tif (document.visibilityState === \"visible\") {\n\t\t\t\tcheckForUpdates();\n\t\t\t}\n\t\t};\n\n\t\tdocument.addEventListener(\"visibilitychange\", handleVisibilityChange);\n\n\t\treturn () => {\n\t\t\tdocument.removeEventListener(\"visibilitychange\", handleVisibilityChange);\n\t\t};\n\t}, [config, projectId, checkForUpdates]);\n\n\treturn { checkForUpdates };\n}\n","import React, { useCallback, useEffect, useRef, type ReactNode } from \"react\";\nimport { getCachedTranslation, cacheTranslation } from \"../cache\";\nimport { useTranslationStore } from \"../store\";\nimport { useHotUpdates } from \"../hooks/useHotUpdates\";\nimport type { CiaoManifest, CTProviderProps, TranslationMap } from \"../types\";\n\nconst PRELOAD_DELAY_MS = 5000;\n\nasync function fetchTranslationsFromCDN(url: string): Promise<TranslationMap> {\n\tconst response = await fetch(url);\n\tif (!response.ok) {\n\t\tthrow new Error(`Failed to fetch translations: ${response.statusText}`);\n\t}\n\treturn response.json();\n}\n\nfunction detectBrowserLanguage(availableLanguages: string[]): string | null {\n\tif (typeof navigator === \"undefined\") return null;\n\n\tconst browserLangs = navigator.languages || [navigator.language];\n\n\tfor (const browserLang of browserLangs) {\n\t\tconst normalized = browserLang.toLowerCase();\n\t\tif (availableLanguages.includes(normalized)) {\n\t\t\treturn normalized;\n\t\t}\n\t\tconst langCode = normalized.split(\"-\")[0];\n\t\tif (availableLanguages.includes(langCode)) {\n\t\t\treturn langCode;\n\t\t}\n\t}\n\n\treturn null;\n}\n\nfunction getManifestUrlsHash(manifest: CiaoManifest | undefined): string {\n\tif (!manifest) return \"\";\n\treturn JSON.stringify(manifest.cdnUrls);\n}\n\nexport function CTProvider({\n\tchildren,\n\ttranslations,\n\tmanifest,\n\tdefaultLanguage = \"en\",\n\tavailableLanguages,\n\tonLanguageChange,\n\tdetectLanguage = true,\n\tblockUntilReady = true,\n\tfallback = null,\n\tpreloadLanguages = true,\n\tpreloadDelay = PRELOAD_DELAY_MS,\n\thotUpdates,\n}: CTProviderProps) {\n\tconst {\n\t\tloadTranslations,\n\t\tsetLanguage,\n\t\taddLanguage,\n\t\tsetLoading,\n\t\tsetReady,\n\t\tcurrentLanguage,\n\t\ttranslations: storeTranslations,\n\t\tisReady,\n\t\tisHydrated,\n\t} = useTranslationStore();\n\n\tconst manifestRef = useRef<CiaoManifest | undefined>(manifest);\n\tconst loadedUrlsRef = useRef<Map<string, string>>(new Map());\n\tconst previousManifestHashRef = useRef<string>(\"\");\n\tconst initializedRef = useRef(false);\n\tconst preloadTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n\tuseEffect(() => {\n\t\tmanifestRef.current = manifest;\n\n\t\tconst newHash = getManifestUrlsHash(manifest);\n\t\tconst oldHash = previousManifestHashRef.current;\n\n\t\tif (oldHash && newHash && oldHash !== newHash) {\n\t\t\tloadedUrlsRef.current.clear();\n\t\t\tuseTranslationStore.setState({ translations: {} });\n\t\t}\n\n\t\tpreviousManifestHashRef.current = newHash;\n\t}, [manifest]);\n\n\tuseEffect(() => {\n\t\tif (translations) {\n\t\t\tloadTranslations(translations);\n\t\t\tsetReady(true);\n\t\t}\n\t}, [translations, loadTranslations, setReady]);\n\n\tuseEffect(() => {\n\t\tif (!isHydrated) return;\n\t\tif (initializedRef.current) return;\n\t\tinitializedRef.current = true;\n\n\t\tconst store = useTranslationStore.getState();\n\t\tconst effectiveLanguages = manifest\n\t\t\t? [...manifest.languages]\n\t\t\t: availableLanguages || [];\n\n\t\tconst hasPersistedLanguage =\n\t\t\tstore.currentLanguage &&\n\t\t\tstore.currentLanguage !== \"en\" &&\n\t\t\teffectiveLanguages.includes(store.currentLanguage);\n\n\t\tif (hasPersistedLanguage) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (detectLanguage && effectiveLanguages.length > 0) {\n\t\t\tconst detected = detectBrowserLanguage(effectiveLanguages);\n\t\t\tif (detected) {\n\t\t\t\tsetLanguage(detected);\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\tif (defaultLanguage && defaultLanguage !== store.currentLanguage) {\n\t\t\tsetLanguage(defaultLanguage);\n\t\t}\n\t}, [\n\t\tmanifest,\n\t\tavailableLanguages,\n\t\tdefaultLanguage,\n\t\tdetectLanguage,\n\t\tsetLanguage,\n\t\tisHydrated,\n\t]);\n\n\tuseEffect(() => {\n\t\tconst effectiveLanguages = manifest\n\t\t\t? [...manifest.languages]\n\t\t\t: availableLanguages;\n\n\t\tif (effectiveLanguages) {\n\t\t\tconst store = useTranslationStore.getState();\n\t\t\tconst merged = [\n\t\t\t\t...new Set([...store.availableLanguages, ...effectiveLanguages]),\n\t\t\t];\n\t\t\tuseTranslationStore.setState({\n\t\t\t\tavailableLanguages: merged,\n\t\t\t\tdefaultLanguage,\n\t\t\t});\n\t\t}\n\t}, [availableLanguages, manifest, defaultLanguage]);\n\n\tconst loadLanguageFromCDN = useCallback(\n\t\tasync (language: string, isPreload = false): Promise<boolean> => {\n\t\t\tconst currentManifest = manifestRef.current;\n\t\t\tif (!currentManifest) {\n\t\t\t\tif (!isPreload) setReady(true);\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tconst cdnUrl = currentManifest.cdnUrls[language];\n\t\t\tif (!cdnUrl) {\n\t\t\t\tif (!isPreload) setReady(true);\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tconst loadedUrl = loadedUrlsRef.current.get(language);\n\t\t\tif (loadedUrl === cdnUrl) {\n\t\t\t\tif (!isPreload) setReady(true);\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\tif (!isPreload) {\n\t\t\t\tsetLoading(true);\n\t\t\t\tsetReady(false);\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tconst cached = await getCachedTranslation(cdnUrl);\n\t\t\t\tif (cached) {\n\t\t\t\t\taddLanguage(language, cached);\n\t\t\t\t\tloadedUrlsRef.current.set(language, cdnUrl);\n\t\t\t\t\tif (!isPreload) {\n\t\t\t\t\t\tsetReady(true);\n\t\t\t\t\t\tsetLoading(false);\n\t\t\t\t\t}\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\n\t\t\t\tconst translationData = await fetchTranslationsFromCDN(cdnUrl);\n\t\t\t\taddLanguage(language, translationData);\n\t\t\t\tloadedUrlsRef.current.set(language, cdnUrl);\n\n\t\t\t\tawait cacheTranslation(\n\t\t\t\t\tcdnUrl,\n\t\t\t\t\tlanguage,\n\t\t\t\t\tcurrentManifest.projectId,\n\t\t\t\t\ttranslationData,\n\t\t\t\t);\n\n\t\t\t\tif (!isPreload) setReady(true);\n\t\t\t\treturn true;\n\t\t\t} catch (error) {\n\t\t\t\tconsole.error(\n\t\t\t\t\t`[ciao-tools] Failed to load translations for ${language}:`,\n\t\t\t\t\terror,\n\t\t\t\t);\n\t\t\t\tif (!isPreload) setReady(true);\n\t\t\t\treturn false;\n\t\t\t} finally {\n\t\t\t\tif (!isPreload) setLoading(false);\n\t\t\t}\n\t\t},\n\t\t[addLanguage, setLoading, setReady],\n\t);\n\n\tuseEffect(() => {\n\t\tif (!isHydrated) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (currentLanguage === manifest?.sourceLanguage) {\n\t\t\tsetReady(true);\n\t\t\treturn;\n\t\t}\n\n\t\tif (manifest && currentLanguage) {\n\t\t\tloadLanguageFromCDN(currentLanguage, false);\n\t\t} else if (!manifest) {\n\t\t\tsetReady(true);\n\t\t}\n\t}, [manifest, currentLanguage, loadLanguageFromCDN, setReady, isHydrated]);\n\n\tuseEffect(() => {\n\t\tif (!preloadLanguages || !manifest) return;\n\n\t\tif (preloadTimeoutRef.current) {\n\t\t\tclearTimeout(preloadTimeoutRef.current);\n\t\t}\n\n\t\tpreloadTimeoutRef.current = setTimeout(async () => {\n\t\t\tconst languages = [...manifest.languages];\n\t\t\tfor (const language of languages) {\n\t\t\t\tif (language === manifest.sourceLanguage) continue;\n\t\t\t\tif (language === currentLanguage) continue;\n\n\t\t\t\tawait loadLanguageFromCDN(language, true);\n\t\t\t}\n\t\t}, preloadDelay);\n\n\t\treturn () => {\n\t\t\tif (preloadTimeoutRef.current) {\n\t\t\t\tclearTimeout(preloadTimeoutRef.current);\n\t\t\t}\n\t\t};\n\t}, [\n\t\tmanifest,\n\t\tcurrentLanguage,\n\t\tpreloadLanguages,\n\t\tpreloadDelay,\n\t\tloadLanguageFromCDN,\n\t]);\n\n\tuseEffect(() => {\n\t\tif (onLanguageChange) {\n\t\t\tonLanguageChange(currentLanguage);\n\t\t}\n\t}, [currentLanguage, onLanguageChange]);\n\n\tuseHotUpdates(hotUpdates, manifest?.projectId);\n\n\tif (blockUntilReady && (!isReady || !isHydrated)) {\n\t\treturn <>{fallback}</>;\n\t}\n\n\treturn <>{children}</>;\n}\n","import React, { createContext, useContext, useCallback, type ReactNode } from \"react\";\nimport { useTranslationStore } from \"../store\";\n\nexport const LANGUAGE_DATA: Record<\n\tstring,\n\t{ name: string; nativeName: string; flag: string }\n> = {\n\ten: { name: \"English\", nativeName: \"English\", flag: \"🇺🇸\" },\n\tes: { name: \"Spanish\", nativeName: \"Español\", flag: \"🇪🇸\" },\n\tfr: { name: \"French\", nativeName: \"Français\", flag: \"🇫🇷\" },\n\tde: { name: \"German\", nativeName: \"Deutsch\", flag: \"🇩🇪\" },\n\tit: { name: \"Italian\", nativeName: \"Italiano\", flag: \"🇮🇹\" },\n\tpt: { name: \"Portuguese\", nativeName: \"Português\", flag: \"🇵🇹\" },\n\tja: { name: \"Japanese\", nativeName: \"日本語\", flag: \"🇯🇵\" },\n\tko: { name: \"Korean\", nativeName: \"한국어\", flag: \"🇰🇷\" },\n\tzh: { name: \"Chinese\", nativeName: \"中文\", flag: \"🇨🇳\" },\n\tar: { name: \"Arabic\", nativeName: \"العربية\", flag: \"🇸🇦\" },\n\tru: { name: \"Russian\", nativeName: \"Русский\", flag: \"🇷🇺\" },\n\tnl: { name: \"Dutch\", nativeName: \"Nederlands\", flag: \"🇳🇱\" },\n\tpl: { name: \"Polish\", nativeName: \"Polski\", flag: \"🇵🇱\" },\n\tsv: { name: \"Swedish\", nativeName: \"Svenska\", flag: \"🇸🇪\" },\n\tda: { name: \"Danish\", nativeName: \"Dansk\", flag: \"🇩🇰\" },\n\tfi: { name: \"Finnish\", nativeName: \"Suomi\", flag: \"🇫🇮\" },\n\tno: { name: \"Norwegian\", nativeName: \"Norsk\", flag: \"🇳🇴\" },\n\ttr: { name: \"Turkish\", nativeName: \"Türkçe\", flag: \"🇹🇷\" },\n\tcs: { name: \"Czech\", nativeName: \"Čeština\", flag: \"🇨🇿\" },\n\tel: { name: \"Greek\", nativeName: \"Ελληνικά\", flag: \"🇬🇷\" },\n\the: { name: \"Hebrew\", nativeName: \"עברית\", flag: \"🇮🇱\" },\n\thu: { name: \"Hungarian\", nativeName: \"Magyar\", flag: \"🇭🇺\" },\n\tid: { name: \"Indonesian\", nativeName: \"Bahasa Indonesia\", flag: \"🇮🇩\" },\n\tth: { name: \"Thai\", nativeName: \"ไทย\", flag: \"🇹🇭\" },\n\tvi: { name: \"Vietnamese\", nativeName: \"Tiếng Việt\", flag: \"🇻🇳\" },\n\tuk: { name: \"Ukrainian\", nativeName: \"Українська\", flag: \"🇺🇦\" },\n\tro: { name: \"Romanian\", nativeName: \"Română\", flag: \"🇷🇴\" },\n\tbg: { name: \"Bulgarian\", nativeName: \"Български\", flag: \"🇧🇬\" },\n\tsk: { name: \"Slovak\", nativeName: \"Slovenčina\", flag: \"🇸🇰\" },\n\tlt: { name: \"Lithuanian\", nativeName: \"Lietuvių\", flag: \"🇱🇹\" },\n\tlv: { name: \"Latvian\", nativeName: \"Latviešu\", flag: \"🇱🇻\" },\n\tet: { name: \"Estonian\", nativeName: \"Eesti\", flag: \"🇪🇪\" },\n\tsl: { name: \"Slovenian\", nativeName: \"Slovenščina\", flag: \"🇸🇮\" },\n\tbs: { name: \"Bosnian\", nativeName: \"Bosanski\", flag: \"🇧🇦\" },\n\thr: { name: \"Croatian\", nativeName: \"Hrvatski\", flag: \"🇭🇷\" },\n\tsr: { name: \"Serbian\", nativeName: \"Српски\", flag: \"🇷🇸\" },\n\tkmr: { name: \"Kurdish\", nativeName: \"Kurdî\", flag: \"🇮🇶\" },\n\tfa: { name: \"Persian\", nativeName: \"فارسی\", flag: \"🇮🇷\" },\n\thi: { name: \"Hindi\", nativeName: \"हिन्दी\", flag: \"🇮🇳\" },\n\tbn: { name: \"Bengali\", nativeName: \"বাংলা\", flag: \"🇧🇩\" },\n\tms: { name: \"Malay\", nativeName: \"Bahasa Melayu\", flag: \"🇲🇾\" },\n};\n\nexport interface LanguageInfo {\n\tcode: string;\n\tname: string;\n\tnativeName: string;\n\tflag: string;\n}\n\nexport function getLanguageInfo(code: string): Omit<LanguageInfo, \"code\"> {\n\tconst normalized = code.toLowerCase();\n\treturn (\n\t\tLANGUAGE_DATA[normalized] ?? {\n\t\t\tname: code.toUpperCase(),\n\t\t\tnativeName: code.toUpperCase(),\n\t\t\tflag: \"🌐\",\n\t\t}\n\t);\n}\n\nexport function getFullLanguageInfo(code: string): LanguageInfo {\n\treturn {\n\t\tcode,\n\t\t...getLanguageInfo(code),\n\t};\n}\n\nexport type LanguageSwitcherDisplay =\n\t| \"flag\"\n\t| \"name\"\n\t| \"native\"\n\t| \"flag-name\"\n\t| \"flag-native\"\n\t| \"code\";\n\nexport function formatLanguageDisplay(\n\tcode: string,\n\tdisplay: LanguageSwitcherDisplay = \"flag-native\",\n): string {\n\tconst info = getLanguageInfo(code);\n\tswitch (display) {\n\t\tcase \"flag\":\n\t\t\treturn info.flag;\n\t\tcase \"name\":\n\t\t\treturn info.name;\n\t\tcase \"native\":\n\t\t\treturn info.nativeName;\n\t\tcase \"flag-name\":\n\t\t\treturn `${info.flag} ${info.name}`;\n\t\tcase \"flag-native\":\n\t\t\treturn `${info.flag} ${info.nativeName}`;\n\t\tcase \"code\":\n\t\t\treturn code.toUpperCase();\n\t\tdefault:\n\t\t\treturn `${info.flag} ${info.nativeName}`;\n\t}\n}\n\n// Simple default LanguageSwitcher (backward compatible)\nexport type LanguageSwitcherVariant = \"dropdown\" | \"buttons\" | \"minimal\";\n\nexport interface LanguageSwitcherProps {\n\tclassName?: string;\n\tvariant?: LanguageSwitcherVariant;\n\tdisplay?: LanguageSwitcherDisplay;\n\tonChange?: (language: string) => void;\n}\n\nexport default function LanguageSwitcher({\n\tclassName,\n\tvariant = \"dropdown\",\n\tdisplay = \"flag-native\",\n\tonChange,\n}: LanguageSwitcherProps) {\n\tconst { currentLanguage, availableLanguages, setLanguage } =\n\t\tuseTranslationStore();\n\n\tconst handleChange = (newLanguage: string) => {\n\t\tsetLanguage(newLanguage);\n\t\tonChange?.(newLanguage);\n\t};\n\n\tif (variant === \"buttons\") {\n\t\treturn (\n\t\t\t<div className={className} role=\"group\" aria-label=\"Language selection\">\n\t\t\t\t{availableLanguages.map((lang) => (\n\t\t\t\t\t<button\n\t\t\t\t\t\tkey={lang}\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tonClick={() => handleChange(lang)}\n\t\t\t\t\t\taria-pressed={currentLanguage === lang}\n\t\t\t\t\t\tdata-active={currentLanguage === lang}\n\t\t\t\t\t>\n\t\t\t\t\t\t{formatLanguageDisplay(lang, display)}\n\t\t\t\t\t</button>\n\t\t\t\t))}\n\t\t\t</div>\n\t\t);\n\t}\n\n\tif (variant === \"minimal\") {\n\t\treturn (\n\t\t\t<button\n\t\t\t\ttype=\"button\"\n\t\t\t\tclassName={className}\n\t\t\t\tonClick={() => {\n\t\t\t\t\tconst currentIndex = availableLanguages.indexOf(currentLanguage);\n\t\t\t\t\tconst nextIndex = (currentIndex + 1) % availableLanguages.length;\n\t\t\t\t\thandleChange(availableLanguages[nextIndex]);\n\t\t\t\t}}\n\t\t\t\taria-label={`Current language: ${getLanguageInfo(currentLanguage).name}. Click to change.`}\n\t\t\t>\n\t\t\t\t{formatLanguageDisplay(currentLanguage, display)}\n\t\t\t</button>\n\t\t);\n\t}\n\n\treturn (\n\t\t<select\n\t\t\tvalue={currentLanguage}\n\t\t\tonChange={(e) => handleChange(e.target.value)}\n\t\t\tclassName={className}\n\t\t\taria-label=\"Select language\"\n\t\t>\n\t\t\t{availableLanguages.map((lang) => (\n\t\t\t\t<option key={lang} value={lang}>\n\t\t\t\t\t{formatLanguageDisplay(lang, display)}\n\t\t\t\t</option>\n\t\t\t))}\n\t\t</select>\n\t);\n}\n","import { useCallback } from \"react\";\nimport { getTranslation, useTranslationStore } from \"../store\";\nimport type { CTFunction, InterpolationValues } from \"../types\";\n\nfunction isInterpolationValues(arg: unknown): arg is InterpolationValues {\n\treturn (\n\t\ttypeof arg === \"object\" &&\n\t\targ !== null &&\n\t\t!Array.isArray(arg) &&\n\t\t!(arg instanceof Date)\n\t);\n}\n\nexport function useCt(): CTFunction {\n\tconst { translations, currentLanguage } = useTranslationStore();\n\n\tconst ct = useCallback(\n\t\t(\n\t\t\ttext: string,\n\t\t\tcontextOrValues?: string | InterpolationValues,\n\t\t\tmaybeValues?: InterpolationValues,\n\t\t): string => {\n\t\t\tlet values: InterpolationValues | undefined;\n\n\t\t\tif (typeof contextOrValues === \"string\") {\n\t\t\t\tvalues = maybeValues;\n\t\t\t} else if (isInterpolationValues(contextOrValues)) {\n\t\t\t\tvalues = contextOrValues;\n\t\t\t}\n\n\t\t\treturn getTranslation(translations, currentLanguage, text, values);\n\t\t},\n\t\t[translations, currentLanguage],\n\t) as CTFunction;\n\n\treturn ct;\n}\n","import React, {\n\tChildren,\n\tcloneElement,\n\tisValidElement,\n\ttype ReactNode,\n\ttype ReactElement,\n} from \"react\";\nimport { useCt } from \"../hooks/useCt\";\nimport type { InterpolationValues } from \"../types\";\n\nexport interface TransProps {\n\tchildren: ReactNode;\n\tcontext?: string;\n\tvalues?: InterpolationValues;\n}\n\ninterface ParsedChild {\n\ttype: \"text\" | \"element\";\n\tcontent: string;\n\telement?: ReactElement;\n\tindex?: number;\n}\n\nfunction parseChildren(children: ReactNode): {\n\ttemplate: string;\n\telements: ReactElement[];\n} {\n\tconst elements: ReactElement[] = [];\n\tlet template = \"\";\n\n\tconst processNode = (node: ReactNode): string => {\n\t\tif (node === null || node === undefined) {\n\t\t\treturn \"\";\n\t\t}\n\n\t\tif (typeof node === \"string\") {\n\t\t\treturn node;\n\t\t}\n\n\t\tif (typeof node === \"number\") {\n\t\t\treturn String(node);\n\t\t}\n\n\t\tif (isValidElement(node)) {\n\t\t\tconst index = elements.length;\n\t\t\telements.push(node);\n\t\t\tconst innerContent = processNode(node.props.children);\n\t\t\treturn `<${index}>${innerContent}</${index}>`;\n\t\t}\n\n\t\tif (Array.isArray(node)) {\n\t\t\treturn node.map(processNode).join(\"\");\n\t\t}\n\n\t\treturn \"\";\n\t};\n\n\ttemplate = processNode(children);\n\treturn { template, elements };\n}\n\nfunction reconstructChildren(\n\ttranslated: string,\n\telements: ReactElement[],\n): ReactNode {\n\tif (elements.length === 0) {\n\t\treturn translated;\n\t}\n\n\tconst result: ReactNode[] = [];\n\tlet remaining = translated;\n\tlet keyCounter = 0;\n\n\tconst tagRegex = /<(\\d+)>(.*?)<\\/\\1>/gs;\n\n\tlet lastIndex = 0;\n\tlet match: RegExpExecArray | null;\n\n\t// Reset regex state\n\ttagRegex.lastIndex = 0;\n\n\twhile ((match = tagRegex.exec(translated)) !== null) {\n\t\t// Add text before the match\n\t\tif (match.index > lastIndex) {\n\t\t\tconst textBefore = translated.slice(lastIndex, match.index);\n\t\t\tif (textBefore) {\n\t\t\t\tresult.push(textBefore);\n\t\t\t}\n\t\t}\n\n\t\tconst elementIndex = parseInt(match[1], 10);\n\t\tconst innerContent = match[2];\n\t\tconst originalElement = elements[elementIndex];\n\n\t\tif (originalElement) {\n\t\t\t// Recursively process inner content in case of nested tags\n\t\t\tconst processedInner = reconstructChildren(innerContent, elements);\n\t\t\tconst cloned = cloneElement(originalElement, {\n\t\t\t\tkey: `trans-${keyCounter++}`,\n\t\t\t\tchildren: processedInner,\n\t\t\t});\n\t\t\tresult.push(cloned);\n\t\t}\n\n\t\tlastIndex = match.index + match[0].length;\n\t}\n\n\t// Add remaining text after last match\n\tif (lastIndex < translated.length) {\n\t\tresult.push(translated.slice(lastIndex));\n\t}\n\n\t// If no matches found, return the original string\n\tif (result.length === 0) {\n\t\treturn translated;\n\t}\n\n\treturn result.length === 1 ? result[0] : result;\n}\n\nexport function Trans({ children, context, values }: TransProps) {\n\tconst ct = useCt();\n\n\t// Parse children to extract template and elements\n\tconst { template, elements } = parseChildren(children);\n\n\t// Translate the template\n\tlet translated: string;\n\tif (context && values) {\n\t\ttranslated = ct(template, context, values);\n\t} else if (context) {\n\t\ttranslated = ct(template, context);\n\t} else if (values) {\n\t\ttranslated = ct(template, values);\n\t} else {\n\t\ttranslated = ct(template);\n\t}\n\n\t// Reconstruct with original elements\n\treturn <>{reconstructChildren(translated, elements)}</>;\n}\n","import { useCallback } from \"react\";\nimport { useTranslationStore } from \"../store\";\nimport {\n\tgetLanguageInfo,\n\tgetFullLanguageInfo,\n\tLANGUAGE_DATA,\n\ttype LanguageInfo,\n} from \"../components/LanguageSwitcher\";\n\nexport function useCurrentLanguage(): string {\n\treturn useTranslationStore((state) => state.currentLanguage);\n}\n\nexport function useSetLanguage(): (language: string) => void {\n\treturn useTranslationStore((state) => state.setLanguage);\n}\n\nexport function useAvailableLanguages(): string[] {\n\treturn useTranslationStore((state) => state.availableLanguages);\n}\n\nexport function useIsLoading(): boolean {\n\treturn useTranslationStore((state) => state.isLoading);\n}\n\nexport function useIsReady(): boolean {\n\treturn useTranslationStore((state) => state.isReady);\n}\n\nexport function useLanguageInfo(code?: string): LanguageInfo {\n\tconst currentLanguage = useTranslationStore((state) => state.currentLanguage);\n\tconst targetCode = code ?? currentLanguage;\n\treturn getFullLanguageInfo(targetCode);\n}\n\nexport function useAvailableLanguagesInfo(): LanguageInfo[] {\n\tconst availableLanguages = useTranslationStore(\n\t\t(state) => state.availableLanguages,\n\t);\n\treturn availableLanguages.map(getFullLanguageInfo);\n}\n\nexport function useLanguage() {\n\tconst currentLanguage = useTranslationStore((state) => state.currentLanguage);\n\tconst availableLanguages = useTranslationStore(\n\t\t(state) => state.availableLanguages,\n\t);\n\tconst setLanguage = useTranslationStore((state) => state.setLanguage);\n\tconst isLoading = useTranslationStore((state) => state.isLoading);\n\tconst isReady = useTranslationStore((state) => state.isReady);\n\n\tconst currentLanguageInfo = getFullLanguageInfo(currentLanguage);\n\tconst availableLanguagesInfo = availableLanguages.map(getFullLanguageInfo);\n\n\tconst cycleLanguage = useCallback(() => {\n\t\tconst currentIndex = availableLanguages.indexOf(currentLanguage);\n\t\tconst nextIndex = (currentIndex + 1) % availableLanguages.length;\n\t\tsetLanguage(availableLanguages[nextIndex]);\n\t}, [availableLanguages, currentLanguage, setLanguage]);\n\n\treturn {\n\t\tcurrentLanguage,\n\t\tcurrentLanguageInfo,\n\t\tavailableLanguages,\n\t\tavailableLanguagesInfo,\n\t\tsetLanguage,\n\t\tcycleLanguage,\n\t\tisLoading,\n\t\tisReady,\n\t};\n}\n\nexport {\n\tgetLanguageInfo,\n\tgetFullLanguageInfo,\n\tLANGUAGE_DATA,\n\ttype LanguageInfo,\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.cjs","names":["dbPromise: Promise<IDBDatabase> | null","entry: CacheEntry","options: Intl.DateTimeFormatOptions","result: string","key: string","format: string | undefined","hydrationResolver: (() => void) | null","updatedLanguages: string[]","LANGUAGE_DATA: Record<\n\tstring,\n\t{ name: string; nativeName: string; flag: string }\n>","values: InterpolationValues | undefined","elements: ReactElement[]","result: ReactNode[]","match: RegExpExecArray | null","translated: string"],"sources":["../src/components/CTContextBlock.tsx","../src/cache.ts","../src/interpolate.ts","../src/store.ts","../src/hooks/useHotUpdates.ts","../src/components/CTProvider.tsx","../src/components/LanguageSwitcher.tsx","../src/hooks/useCt.ts","../src/components/Trans.tsx","../src/hooks/useLanguage.ts"],"sourcesContent":["import React from \"react\";\nimport type { CTContextBlockProps } from \"../types\";\n\nexport function CTContextBlock({ children }: CTContextBlockProps) {\n\treturn <>{children}</>;\n}\n","import type { TranslationMap } from \"./types\";\n\nconst DB_NAME = \"ciao-tools-translations\";\nconst DB_VERSION = 1;\nconst STORE_NAME = \"translations\";\n\ninterface CacheEntry {\n\tlanguage: string;\n\tprojectId: string;\n\tdata: TranslationMap;\n\turl: string;\n\tcachedAt: number;\n}\n\nlet dbPromise: Promise<IDBDatabase> | null = null;\n\nfunction openDB(): Promise<IDBDatabase> {\n\tif (dbPromise) return dbPromise;\n\n\tdbPromise = new Promise((resolve, reject) => {\n\t\tif (typeof indexedDB === \"undefined\") {\n\t\t\treject(new Error(\"IndexedDB not available\"));\n\t\t\treturn;\n\t\t}\n\n\t\tconst request = indexedDB.open(DB_NAME, DB_VERSION);\n\n\t\trequest.onerror = () => reject(request.error);\n\t\trequest.onsuccess = () => resolve(request.result);\n\n\t\trequest.onupgradeneeded = (event) => {\n\t\t\tconst db = (event.target as IDBOpenDBRequest).result;\n\t\t\tif (!db.objectStoreNames.contains(STORE_NAME)) {\n\t\t\t\tconst store = db.createObjectStore(STORE_NAME, { keyPath: \"url\" });\n\t\t\t\tstore.createIndex(\"language\", \"language\", { unique: false });\n\t\t\t\tstore.createIndex(\"projectId\", \"projectId\", { unique: false });\n\t\t\t}\n\t\t};\n\t});\n\n\treturn dbPromise;\n}\n\nexport async function getCachedTranslation(\n\turl: string,\n): Promise<TranslationMap | null> {\n\ttry {\n\t\tconst db = await openDB();\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tconst transaction = db.transaction(STORE_NAME, \"readonly\");\n\t\t\tconst store = transaction.objectStore(STORE_NAME);\n\t\t\tconst request = store.get(url);\n\n\t\t\trequest.onerror = () => reject(request.error);\n\t\t\trequest.onsuccess = () => {\n\t\t\t\tconst entry = request.result as CacheEntry | undefined;\n\t\t\t\tresolve(entry?.data ?? null);\n\t\t\t};\n\t\t});\n\t} catch {\n\t\treturn null;\n\t}\n}\n\nexport async function cacheTranslation(\n\turl: string,\n\tlanguage: string,\n\tprojectId: string,\n\tdata: TranslationMap,\n): Promise<void> {\n\ttry {\n\t\tconst db = await openDB();\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tconst transaction = db.transaction(STORE_NAME, \"readwrite\");\n\t\t\tconst store = transaction.objectStore(STORE_NAME);\n\n\t\t\tconst entry: CacheEntry = {\n\t\t\t\turl,\n\t\t\t\tlanguage,\n\t\t\t\tprojectId,\n\t\t\t\tdata,\n\t\t\t\tcachedAt: Date.now(),\n\t\t\t};\n\n\t\t\tconst request = store.put(entry);\n\t\t\trequest.onerror = () => reject(request.error);\n\t\t\trequest.onsuccess = () => resolve();\n\t\t});\n\t} catch {\n\t\t// Silently fail - caching is optional\n\t}\n}\n\nexport async function clearCache(projectId?: string): Promise<void> {\n\ttry {\n\t\tconst db = await openDB();\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tconst transaction = db.transaction(STORE_NAME, \"readwrite\");\n\t\t\tconst store = transaction.objectStore(STORE_NAME);\n\n\t\t\tif (projectId) {\n\t\t\t\tconst index = store.index(\"projectId\");\n\t\t\t\tconst request = index.openCursor(IDBKeyRange.only(projectId));\n\t\t\t\trequest.onsuccess = (event) => {\n\t\t\t\t\tconst cursor = (event.target as IDBRequest).result;\n\t\t\t\t\tif (cursor) {\n\t\t\t\t\t\tcursor.delete();\n\t\t\t\t\t\tcursor.continue();\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t\t\ttransaction.oncomplete = () => resolve();\n\t\t\t\ttransaction.onerror = () => reject(transaction.error);\n\t\t\t} else {\n\t\t\t\tconst request = store.clear();\n\t\t\t\trequest.onerror = () => reject(request.error);\n\t\t\t\trequest.onsuccess = () => resolve();\n\t\t\t}\n\t\t});\n\t} catch {\n\t\t// Silently fail\n\t}\n}\n\nexport async function getCacheStats(): Promise<{\n\tcount: number;\n\tlanguages: string[];\n}> {\n\ttry {\n\t\tconst db = await openDB();\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tconst transaction = db.transaction(STORE_NAME, \"readonly\");\n\t\t\tconst store = transaction.objectStore(STORE_NAME);\n\n\t\t\tconst countRequest = store.count();\n\t\t\tconst languages = new Set<string>();\n\n\t\t\tconst cursorRequest = store.openCursor();\n\t\t\tcursorRequest.onsuccess = (event) => {\n\t\t\t\tconst cursor = (event.target as IDBRequest).result;\n\t\t\t\tif (cursor) {\n\t\t\t\t\tlanguages.add((cursor.value as CacheEntry).language);\n\t\t\t\t\tcursor.continue();\n\t\t\t\t}\n\t\t\t};\n\n\t\t\ttransaction.oncomplete = () => {\n\t\t\t\tresolve({\n\t\t\t\t\tcount: countRequest.result,\n\t\t\t\t\tlanguages: Array.from(languages),\n\t\t\t\t});\n\t\t\t};\n\t\t\ttransaction.onerror = () => reject(transaction.error);\n\t\t});\n\t} catch {\n\t\treturn { count: 0, languages: [] };\n\t}\n}\n","export type InterpolationValues = Record<string, unknown>;\n\nconst numberFormatCache = new Map<string, Intl.NumberFormat>();\nconst dateFormatCache = new Map<string, Intl.DateTimeFormat>();\nconst pluralRulesCache = new Map<string, Intl.PluralRules>();\n\nexport function clearFormatterCache(): void {\n\tnumberFormatCache.clear();\n\tdateFormatCache.clear();\n\tpluralRulesCache.clear();\n}\n\nfunction getNumberFormatter(locale: string): Intl.NumberFormat {\n\tconst key = `number:${locale}`;\n\tif (!numberFormatCache.has(key)) {\n\t\tnumberFormatCache.set(\n\t\t\tkey,\n\t\t\tnew Intl.NumberFormat(locale, {\n\t\t\t\tmaximumFractionDigits: 20,\n\t\t\t}),\n\t\t);\n\t}\n\treturn numberFormatCache.get(key)!;\n}\n\nfunction getCurrencyFormatter(\n\tlocale: string,\n\tcurrency: string,\n): Intl.NumberFormat {\n\tconst key = `currency:${locale}:${currency}`;\n\tif (!numberFormatCache.has(key)) {\n\t\tnumberFormatCache.set(\n\t\t\tkey,\n\t\t\tnew Intl.NumberFormat(locale, {\n\t\t\t\tstyle: \"currency\",\n\t\t\t\tcurrency,\n\t\t\t}),\n\t\t);\n\t}\n\treturn numberFormatCache.get(key)!;\n}\n\nfunction getPercentFormatter(locale: string): Intl.NumberFormat {\n\tconst key = `percent:${locale}`;\n\tif (!numberFormatCache.has(key)) {\n\t\tnumberFormatCache.set(\n\t\t\tkey,\n\t\t\tnew Intl.NumberFormat(locale, {\n\t\t\t\tstyle: \"percent\",\n\t\t\t\tminimumFractionDigits: 0,\n\t\t\t\tmaximumFractionDigits: 2,\n\t\t\t}),\n\t\t);\n\t}\n\treturn numberFormatCache.get(key)!;\n}\n\nfunction getDateFormatter(\n\tlocale: string,\n\tstyle: \"short\" | \"medium\" | \"long\" | \"full\",\n): Intl.DateTimeFormat {\n\tconst key = `date:${locale}:${style}`;\n\tif (!dateFormatCache.has(key)) {\n\t\tconst options: Intl.DateTimeFormatOptions = {\n\t\t\tdateStyle: style,\n\t\t};\n\t\tdateFormatCache.set(key, new Intl.DateTimeFormat(locale, options));\n\t}\n\treturn dateFormatCache.get(key)!;\n}\n\nfunction getTimeFormatter(\n\tlocale: string,\n\tstyle: \"short\" | \"medium\" | \"long\" | \"full\",\n): Intl.DateTimeFormat {\n\tconst key = `time:${locale}:${style}`;\n\tif (!dateFormatCache.has(key)) {\n\t\tconst options: Intl.DateTimeFormatOptions = {\n\t\t\ttimeStyle: style,\n\t\t};\n\t\tdateFormatCache.set(key, new Intl.DateTimeFormat(locale, options));\n\t}\n\treturn dateFormatCache.get(key)!;\n}\n\nfunction getPluralRules(locale: string): Intl.PluralRules {\n\tif (!pluralRulesCache.has(locale)) {\n\t\tpluralRulesCache.set(locale, new Intl.PluralRules(locale));\n\t}\n\treturn pluralRulesCache.get(locale)!;\n}\n\nfunction formatValue(\n\tvalue: unknown,\n\tformat: string | undefined,\n\tlocale: string,\n): string {\n\tif (value === null || value === undefined) {\n\t\treturn \"\";\n\t}\n\n\tif (!format) {\n\t\treturn String(value);\n\t}\n\n\tconst parts = format.split(\":\");\n\tconst formatType = parts[0];\n\n\tswitch (formatType) {\n\t\tcase \"number\": {\n\t\t\tconst num = typeof value === \"number\" ? value : Number(value);\n\t\t\tif (Number.isNaN(num)) {\n\t\t\t\treturn String(value);\n\t\t\t}\n\t\t\treturn getNumberFormatter(locale).format(num);\n\t\t}\n\n\t\tcase \"currency\": {\n\t\t\tconst currency = parts[1];\n\t\t\tif (!currency) {\n\t\t\t\treturn String(value);\n\t\t\t}\n\t\t\tconst num = typeof value === \"number\" ? value : Number(value);\n\t\t\tif (Number.isNaN(num)) {\n\t\t\t\treturn String(value);\n\t\t\t}\n\t\t\treturn getCurrencyFormatter(locale, currency).format(num);\n\t\t}\n\n\t\tcase \"percent\": {\n\t\t\tconst num = typeof value === \"number\" ? value : Number(value);\n\t\t\tif (Number.isNaN(num)) {\n\t\t\t\treturn String(value);\n\t\t\t}\n\t\t\treturn getPercentFormatter(locale).format(num);\n\t\t}\n\n\t\tcase \"date\": {\n\t\t\tif (!(value instanceof Date)) {\n\t\t\t\treturn String(value);\n\t\t\t}\n\t\t\tconst style =\n\t\t\t\t(parts[1] as \"short\" | \"medium\" | \"long\" | \"full\") || \"medium\";\n\t\t\treturn getDateFormatter(locale, style).format(value);\n\t\t}\n\n\t\tcase \"time\": {\n\t\t\tif (!(value instanceof Date)) {\n\t\t\t\treturn String(value);\n\t\t\t}\n\t\t\tconst style =\n\t\t\t\t(parts[1] as \"short\" | \"medium\" | \"long\" | \"full\") || \"medium\";\n\t\t\treturn getTimeFormatter(locale, style).format(value);\n\t\t}\n\n\t\tcase \"plural\": {\n\t\t\tconst singular = parts[1];\n\t\t\tconst plural = parts[2];\n\t\t\tif (!singular || !plural) {\n\t\t\t\treturn String(value);\n\t\t\t}\n\t\t\tconst num = typeof value === \"number\" ? value : Number(value);\n\t\t\tconst rules = getPluralRules(locale);\n\t\t\tconst category = rules.select(num);\n\t\t\treturn category === \"one\" ? singular : plural;\n\t\t}\n\n\t\tdefault:\n\t\t\treturn String(value);\n\t}\n}\n\nexport function interpolate(\n\ttext: string,\n\tvalues: InterpolationValues | undefined,\n\tlocale: string,\n): string {\n\t// Temporarily replace escaped braces with placeholder characters\n\tconst escaped = text.replace(/\\{\\{/g, \"\\x00\").replace(/\\}\\}/g, \"\\x01\");\n\n\tlet result: string;\n\tif (!values || Object.keys(values).length === 0) {\n\t\tresult = escaped;\n\t} else {\n\t\tresult = escaped.replace(/\\{([^}]+)\\}/g, (match, placeholder) => {\n\t\t\tconst trimmed = placeholder.trim();\n\t\t\tconst colonIndex = trimmed.indexOf(\":\");\n\n\t\t\tlet key: string;\n\t\t\tlet format: string | undefined;\n\n\t\t\tif (colonIndex === -1) {\n\t\t\t\tkey = trimmed;\n\t\t\t\tformat = undefined;\n\t\t\t} else {\n\t\t\t\tkey = trimmed.substring(0, colonIndex);\n\t\t\t\tformat = trimmed.substring(colonIndex + 1);\n\t\t\t}\n\n\t\t\tif (!(key in values)) {\n\t\t\t\treturn match;\n\t\t\t}\n\n\t\t\tconst value = values[key];\n\t\t\treturn formatValue(value, format, locale);\n\t\t});\n\t}\n\n\t// Restore escaped braces\n\treturn result.replace(/\\x00/g, \"{\").replace(/\\x01/g, \"}\");\n}\n","import { create } from \"zustand\";\nimport { persist } from \"zustand/middleware\";\nimport { interpolate } from \"./interpolate\";\nimport type {\n\tInterpolationValues,\n\tLanguageTranslations,\n\tTranslationMap,\n\tTranslationStore,\n} from \"./types\";\n\nlet hydrationResolver: (() => void) | null = null;\nconst hydrationPromise = new Promise<void>((resolve) => {\n\thydrationResolver = resolve;\n});\n\nexport const useTranslationStore = create<TranslationStore>()(\n\tpersist(\n\t\t(set) => ({\n\t\t\tcurrentLanguage: \"en\",\n\t\t\tdefaultLanguage: \"en\",\n\t\t\tavailableLanguages: [\"en\"],\n\t\t\ttranslations: {},\n\t\t\tisLoading: false,\n\t\t\tisReady: false,\n\t\t\tisHydrated: false,\n\t\t\tserverVersion: null,\n\t\t\tlastVersionCheck: null,\n\t\t\tcachedLanguages: [],\n\n\t\t\tsetLanguage: (language: string) => {\n\t\t\t\tset({ currentLanguage: language, isReady: false });\n\t\t\t},\n\n\t\t\tloadTranslations: (translations: LanguageTranslations) => {\n\t\t\t\tset((state) => {\n\t\t\t\t\tconst languages = Object.keys(translations);\n\t\t\t\t\tconst availableLanguages = [\n\t\t\t\t\t\t...new Set([...state.availableLanguages, ...languages]),\n\t\t\t\t\t];\n\t\t\t\t\tconst merged = { ...state.translations };\n\t\t\t\t\tfor (const lang of languages) {\n\t\t\t\t\t\tmerged[lang] = { ...merged[lang], ...translations[lang] };\n\t\t\t\t\t}\n\t\t\t\t\treturn {\n\t\t\t\t\t\ttranslations: merged,\n\t\t\t\t\t\tavailableLanguages,\n\t\t\t\t\t};\n\t\t\t\t});\n\t\t\t},\n\n\t\t\taddLanguage: (language: string, translations: TranslationMap) => {\n\t\t\t\tset((state) => ({\n\t\t\t\t\ttranslations: {\n\t\t\t\t\t\t...state.translations,\n\t\t\t\t\t\t[language]: { ...state.translations[language], ...translations },\n\t\t\t\t\t},\n\t\t\t\t\tavailableLanguages: state.availableLanguages.includes(language)\n\t\t\t\t\t\t? state.availableLanguages\n\t\t\t\t\t\t: [...state.availableLanguages, language],\n\t\t\t\t}));\n\t\t\t},\n\n\t\t\tsetLoading: (loading: boolean) => {\n\t\t\t\tset({ isLoading: loading });\n\t\t\t},\n\n\t\t\tsetReady: (ready: boolean) => {\n\t\t\t\tset({ isReady: ready });\n\t\t\t},\n\n\t\t\tsetServerVersion: (version: number) => {\n\t\t\t\tset({ serverVersion: version, lastVersionCheck: Date.now() });\n\t\t\t},\n\n\t\t\tsetCachedLanguages: (languages: string[]) => {\n\t\t\t\tset({ cachedLanguages: languages });\n\t\t\t},\n\t\t}),\n\t\t{\n\t\t\tname: \"ciao-tools-language\",\n\t\t\tpartialize: (state) => ({\n\t\t\t\tcurrentLanguage: state.currentLanguage,\n\t\t\t\tserverVersion: state.serverVersion,\n\t\t\t\tcachedLanguages: state.cachedLanguages,\n\t\t\t}),\n\t\t\tonRehydrateStorage: () => (_, error) => {\n\t\t\t\tif (!error && hydrationResolver) {\n\t\t\t\t\thydrationResolver();\n\t\t\t\t}\n\t\t\t},\n\t\t},\n\t),\n);\n\nhydrationPromise.then(() => {\n\tuseTranslationStore.setState({ isHydrated: true });\n});\n\nexport function getTranslation(\n\ttranslations: LanguageTranslations,\n\tlanguage: string,\n\ttext: string,\n\tvalues?: InterpolationValues,\n): string {\n\tconst translated = translations[language]?.[text] ?? text;\n\n\tif (!values || Object.keys(values).length === 0) {\n\t\treturn translated;\n\t}\n\n\treturn interpolate(translated, values, language);\n}\n","import { useCallback, useEffect, useRef } from \"react\";\nimport { clearCache, cacheTranslation } from \"../cache\";\nimport { useTranslationStore } from \"../store\";\nimport type { HotUpdateConfig, TranslationMap } from \"../types\";\n\nconst CDN_BASE_URL = \"https://t1.ciao-tools.com\";\n\ninterface LatestManifest {\n\tversion: number;\n\tupdatedAt: string;\n\turls: Record<string, string>;\n}\n\nasync function fetchLatestManifest(projectId: string): Promise<LatestManifest | null> {\n\tconst url = `${CDN_BASE_URL}/translations/${projectId}/latest.json`;\n\ttry {\n\t\tconst response = await fetch(url, { cache: \"no-cache\" });\n\t\tif (!response.ok) {\n\t\t\tif (response.status === 404) {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tthrow new Error(`Failed to fetch latest manifest: ${response.statusText}`);\n\t\t}\n\t\treturn response.json();\n\t} catch {\n\t\treturn null;\n\t}\n}\n\nasync function fetchTranslations(url: string): Promise<TranslationMap> {\n\tconst response = await fetch(url);\n\tif (!response.ok) {\n\t\tthrow new Error(`Failed to fetch translations: ${response.statusText}`);\n\t}\n\treturn response.json();\n}\n\nexport function useHotUpdates(\n\tconfig: HotUpdateConfig | undefined,\n\tprojectId: string | undefined,\n) {\n\tconst isCheckingRef = useRef(false);\n\tconst hasCheckedOnMountRef = useRef(false);\n\n\tconst { serverVersion, setServerVersion, addLanguage, cachedLanguages, setCachedLanguages } = useTranslationStore();\n\n\tconst checkForUpdates = useCallback(async () => {\n\t\tif (!config || !projectId || isCheckingRef.current) return;\n\t\tif (config.enabled !== true) return;\n\n\t\tisCheckingRef.current = true;\n\n\t\ttry {\n\t\t\tconsole.log(\"[ciao-tools] Checking for hot updates...\");\n\t\t\tconst manifest = await fetchLatestManifest(projectId);\n\n\t\t\tif (!manifest) {\n\t\t\t\tconsole.log(\"[ciao-tools] No latest.json found (project may not have hot updates yet)\");\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconsole.log(\"[ciao-tools] Found latest.json, version:\", manifest.version);\n\n\t\t\tconst isFirstCheck = serverVersion === null;\n\t\t\tconst hasNewVersion = serverVersion !== null && manifest.version > serverVersion;\n\t\t\tconst hasNoCache = cachedLanguages.length === 0;\n\n\t\t\tif (isFirstCheck || hasNewVersion || hasNoCache) {\n\t\t\t\tif (Object.keys(manifest.urls).length > 0) {\n\t\t\t\t\tconst reason = hasNewVersion ? \"new version\" : hasNoCache ? \"no cached translations\" : \"first check\";\n\t\t\t\t\tconsole.log(`[ciao-tools] Fetching translations (${reason})...`);\n\t\t\t\t\tawait clearCache(projectId);\n\n\t\t\t\t\tconst updatedLanguages: string[] = [];\n\n\t\t\t\t\tfor (const [langCode, url] of Object.entries(manifest.urls)) {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tconst translations = await fetchTranslations(url);\n\t\t\t\t\t\t\taddLanguage(langCode, translations);\n\t\t\t\t\t\t\tawait cacheTranslation(url, langCode, projectId, translations);\n\t\t\t\t\t\t\tupdatedLanguages.push(langCode);\n\t\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\t\tconsole.error(`[ciao-tools] Failed to fetch ${langCode} translations:`, err);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif (updatedLanguages.length > 0) {\n\t\t\t\t\t\tsetCachedLanguages(updatedLanguages);\n\t\t\t\t\t\tconsole.log(\"[ciao-tools] Updated translations for:\", updatedLanguages);\n\t\t\t\t\t\tif (hasNewVersion && config.onTranslationsUpdated) {\n\t\t\t\t\t\t\tconfig.onTranslationsUpdated(updatedLanguages);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tconsole.log(\"[ciao-tools] Already up to date (version \" + manifest.version + \")\");\n\t\t\t}\n\n\t\t\tsetServerVersion(manifest.version);\n\t\t} catch (error) {\n\t\t\tconsole.error(\"[ciao-tools] Hot update check failed:\", error);\n\t\t} finally {\n\t\t\tisCheckingRef.current = false;\n\t\t}\n\t}, [config, projectId, serverVersion, setServerVersion, addLanguage, cachedLanguages, setCachedLanguages]);\n\n\tuseEffect(() => {\n\t\tif (!config || !projectId) return;\n\t\tif (config.enabled !== true) return;\n\n\t\tif (!hasCheckedOnMountRef.current) {\n\t\t\thasCheckedOnMountRef.current = true;\n\t\t\tcheckForUpdates();\n\t\t}\n\n\t\tconst handleVisibilityChange = () => {\n\t\t\tif (document.visibilityState === \"visible\") {\n\t\t\t\tcheckForUpdates();\n\t\t\t}\n\t\t};\n\n\t\tdocument.addEventListener(\"visibilitychange\", handleVisibilityChange);\n\n\t\treturn () => {\n\t\t\tdocument.removeEventListener(\"visibilitychange\", handleVisibilityChange);\n\t\t};\n\t}, [config, projectId, checkForUpdates]);\n\n\treturn { checkForUpdates };\n}\n","import React, { useCallback, useEffect, useRef, type ReactNode } from \"react\";\nimport { getCachedTranslation, cacheTranslation } from \"../cache\";\nimport { useTranslationStore } from \"../store\";\nimport { useHotUpdates } from \"../hooks/useHotUpdates\";\nimport type { CiaoManifest, CTProviderProps, TranslationMap } from \"../types\";\n\nconst PRELOAD_DELAY_MS = 5000;\n\nasync function fetchTranslationsFromCDN(url: string): Promise<TranslationMap> {\n\tconst response = await fetch(url);\n\tif (!response.ok) {\n\t\tthrow new Error(`Failed to fetch translations: ${response.statusText}`);\n\t}\n\treturn response.json();\n}\n\nfunction detectBrowserLanguage(availableLanguages: string[]): string | null {\n\tif (typeof navigator === \"undefined\") return null;\n\n\tconst browserLangs = navigator.languages || [navigator.language];\n\n\tfor (const browserLang of browserLangs) {\n\t\tconst normalized = browserLang.toLowerCase();\n\t\tif (availableLanguages.includes(normalized)) {\n\t\t\treturn normalized;\n\t\t}\n\t\tconst langCode = normalized.split(\"-\")[0];\n\t\tif (availableLanguages.includes(langCode)) {\n\t\t\treturn langCode;\n\t\t}\n\t}\n\n\treturn null;\n}\n\nfunction getManifestUrlsHash(manifest: CiaoManifest | undefined): string {\n\tif (!manifest) return \"\";\n\treturn JSON.stringify(manifest.cdnUrls);\n}\n\nexport function CTProvider({\n\tchildren,\n\ttranslations,\n\tmanifest,\n\tdefaultLanguage = \"en\",\n\tavailableLanguages,\n\tonLanguageChange,\n\tdetectLanguage = true,\n\tblockUntilReady = true,\n\tfallback = null,\n\tpreloadLanguages = true,\n\tpreloadDelay = PRELOAD_DELAY_MS,\n\thotUpdates,\n}: CTProviderProps) {\n\tconst {\n\t\tloadTranslations,\n\t\tsetLanguage,\n\t\taddLanguage,\n\t\tsetLoading,\n\t\tsetReady,\n\t\tcurrentLanguage,\n\t\ttranslations: storeTranslations,\n\t\tisReady,\n\t\tisHydrated,\n\t} = useTranslationStore();\n\n\tconst manifestRef = useRef<CiaoManifest | undefined>(manifest);\n\tconst loadedUrlsRef = useRef<Map<string, string>>(new Map());\n\tconst previousManifestHashRef = useRef<string>(\"\");\n\tconst initializedRef = useRef(false);\n\tconst preloadTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n\tuseEffect(() => {\n\t\tmanifestRef.current = manifest;\n\n\t\tconst newHash = getManifestUrlsHash(manifest);\n\t\tconst oldHash = previousManifestHashRef.current;\n\n\t\tif (oldHash && newHash && oldHash !== newHash) {\n\t\t\tloadedUrlsRef.current.clear();\n\t\t\tuseTranslationStore.setState({ translations: {} });\n\t\t}\n\n\t\tpreviousManifestHashRef.current = newHash;\n\t}, [manifest]);\n\n\tuseEffect(() => {\n\t\tif (translations) {\n\t\t\tloadTranslations(translations);\n\t\t\tsetReady(true);\n\t\t}\n\t}, [translations, loadTranslations, setReady]);\n\n\tuseEffect(() => {\n\t\tif (!isHydrated) return;\n\t\tif (initializedRef.current) return;\n\t\tinitializedRef.current = true;\n\n\t\tconst store = useTranslationStore.getState();\n\t\tconst effectiveLanguages = manifest\n\t\t\t? [...manifest.languages]\n\t\t\t: availableLanguages || [];\n\n\t\tconst hasPersistedLanguage =\n\t\t\tstore.currentLanguage &&\n\t\t\tstore.currentLanguage !== \"en\" &&\n\t\t\teffectiveLanguages.includes(store.currentLanguage);\n\n\t\tif (hasPersistedLanguage) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (detectLanguage && effectiveLanguages.length > 0) {\n\t\t\tconst detected = detectBrowserLanguage(effectiveLanguages);\n\t\t\tif (detected) {\n\t\t\t\tsetLanguage(detected);\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\tif (defaultLanguage && defaultLanguage !== store.currentLanguage) {\n\t\t\tsetLanguage(defaultLanguage);\n\t\t}\n\t}, [\n\t\tmanifest,\n\t\tavailableLanguages,\n\t\tdefaultLanguage,\n\t\tdetectLanguage,\n\t\tsetLanguage,\n\t\tisHydrated,\n\t]);\n\n\tuseEffect(() => {\n\t\tconst effectiveLanguages = manifest\n\t\t\t? [...manifest.languages]\n\t\t\t: availableLanguages;\n\n\t\tif (effectiveLanguages) {\n\t\t\tconst store = useTranslationStore.getState();\n\t\t\tconst merged = [\n\t\t\t\t...new Set([...store.availableLanguages, ...effectiveLanguages]),\n\t\t\t];\n\t\t\tuseTranslationStore.setState({\n\t\t\t\tavailableLanguages: merged,\n\t\t\t\tdefaultLanguage,\n\t\t\t});\n\t\t}\n\t}, [availableLanguages, manifest, defaultLanguage]);\n\n\tconst loadLanguageFromCDN = useCallback(\n\t\tasync (language: string, isPreload = false): Promise<boolean> => {\n\t\t\tconst currentManifest = manifestRef.current;\n\t\t\tif (!currentManifest) {\n\t\t\t\tif (!isPreload) setReady(true);\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tconst cdnUrl = currentManifest.cdnUrls[language];\n\t\t\tif (!cdnUrl) {\n\t\t\t\tif (!isPreload) setReady(true);\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tconst loadedUrl = loadedUrlsRef.current.get(language);\n\t\t\tif (loadedUrl === cdnUrl) {\n\t\t\t\tif (!isPreload) setReady(true);\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\tif (!isPreload) {\n\t\t\t\tsetLoading(true);\n\t\t\t\tsetReady(false);\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tconst cached = await getCachedTranslation(cdnUrl);\n\t\t\t\tif (cached) {\n\t\t\t\t\taddLanguage(language, cached);\n\t\t\t\t\tloadedUrlsRef.current.set(language, cdnUrl);\n\t\t\t\t\tif (!isPreload) {\n\t\t\t\t\t\tsetReady(true);\n\t\t\t\t\t\tsetLoading(false);\n\t\t\t\t\t}\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\n\t\t\t\tconst translationData = await fetchTranslationsFromCDN(cdnUrl);\n\t\t\t\taddLanguage(language, translationData);\n\t\t\t\tloadedUrlsRef.current.set(language, cdnUrl);\n\n\t\t\t\tawait cacheTranslation(\n\t\t\t\t\tcdnUrl,\n\t\t\t\t\tlanguage,\n\t\t\t\t\tcurrentManifest.projectId,\n\t\t\t\t\ttranslationData,\n\t\t\t\t);\n\n\t\t\t\tif (!isPreload) setReady(true);\n\t\t\t\treturn true;\n\t\t\t} catch (error) {\n\t\t\t\tconsole.error(\n\t\t\t\t\t`[ciao-tools] Failed to load translations for ${language}:`,\n\t\t\t\t\terror,\n\t\t\t\t);\n\t\t\t\tif (!isPreload) setReady(true);\n\t\t\t\treturn false;\n\t\t\t} finally {\n\t\t\t\tif (!isPreload) setLoading(false);\n\t\t\t}\n\t\t},\n\t\t[addLanguage, setLoading, setReady],\n\t);\n\n\tuseEffect(() => {\n\t\tif (!isHydrated) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (currentLanguage === manifest?.sourceLanguage) {\n\t\t\tsetReady(true);\n\t\t\treturn;\n\t\t}\n\n\t\tif (manifest && currentLanguage) {\n\t\t\tloadLanguageFromCDN(currentLanguage, false);\n\t\t} else if (!manifest) {\n\t\t\tsetReady(true);\n\t\t}\n\t}, [manifest, currentLanguage, loadLanguageFromCDN, setReady, isHydrated]);\n\n\tuseEffect(() => {\n\t\tif (!preloadLanguages || !manifest) return;\n\n\t\tif (preloadTimeoutRef.current) {\n\t\t\tclearTimeout(preloadTimeoutRef.current);\n\t\t}\n\n\t\tpreloadTimeoutRef.current = setTimeout(async () => {\n\t\t\tconst languages = [...manifest.languages];\n\t\t\tfor (const language of languages) {\n\t\t\t\tif (language === manifest.sourceLanguage) continue;\n\t\t\t\tif (language === currentLanguage) continue;\n\n\t\t\t\tawait loadLanguageFromCDN(language, true);\n\t\t\t}\n\t\t}, preloadDelay);\n\n\t\treturn () => {\n\t\t\tif (preloadTimeoutRef.current) {\n\t\t\t\tclearTimeout(preloadTimeoutRef.current);\n\t\t\t}\n\t\t};\n\t}, [\n\t\tmanifest,\n\t\tcurrentLanguage,\n\t\tpreloadLanguages,\n\t\tpreloadDelay,\n\t\tloadLanguageFromCDN,\n\t]);\n\n\tuseEffect(() => {\n\t\tif (onLanguageChange) {\n\t\t\tonLanguageChange(currentLanguage);\n\t\t}\n\t}, [currentLanguage, onLanguageChange]);\n\n\tuseHotUpdates(hotUpdates, manifest?.projectId);\n\n\tif (blockUntilReady && (!isReady || !isHydrated)) {\n\t\treturn <>{fallback}</>;\n\t}\n\n\treturn <>{children}</>;\n}\n","import React, { createContext, useContext, useCallback, type ReactNode } from \"react\";\nimport { useTranslationStore } from \"../store\";\n\nexport const LANGUAGE_DATA: Record<\n\tstring,\n\t{ name: string; nativeName: string; flag: string }\n> = {\n\ten: { name: \"English\", nativeName: \"English\", flag: \"🇺🇸\" },\n\tes: { name: \"Spanish\", nativeName: \"Español\", flag: \"🇪🇸\" },\n\tfr: { name: \"French\", nativeName: \"Français\", flag: \"🇫🇷\" },\n\tde: { name: \"German\", nativeName: \"Deutsch\", flag: \"🇩🇪\" },\n\tit: { name: \"Italian\", nativeName: \"Italiano\", flag: \"🇮🇹\" },\n\tpt: { name: \"Portuguese\", nativeName: \"Português\", flag: \"🇵🇹\" },\n\tja: { name: \"Japanese\", nativeName: \"日本語\", flag: \"🇯🇵\" },\n\tko: { name: \"Korean\", nativeName: \"한국어\", flag: \"🇰🇷\" },\n\tzh: { name: \"Chinese\", nativeName: \"中文\", flag: \"🇨🇳\" },\n\tar: { name: \"Arabic\", nativeName: \"العربية\", flag: \"🇸🇦\" },\n\tru: { name: \"Russian\", nativeName: \"Русский\", flag: \"🇷🇺\" },\n\tnl: { name: \"Dutch\", nativeName: \"Nederlands\", flag: \"🇳🇱\" },\n\tpl: { name: \"Polish\", nativeName: \"Polski\", flag: \"🇵🇱\" },\n\tsv: { name: \"Swedish\", nativeName: \"Svenska\", flag: \"🇸🇪\" },\n\tda: { name: \"Danish\", nativeName: \"Dansk\", flag: \"🇩🇰\" },\n\tfi: { name: \"Finnish\", nativeName: \"Suomi\", flag: \"🇫🇮\" },\n\tno: { name: \"Norwegian\", nativeName: \"Norsk\", flag: \"🇳🇴\" },\n\ttr: { name: \"Turkish\", nativeName: \"Türkçe\", flag: \"🇹🇷\" },\n\tcs: { name: \"Czech\", nativeName: \"Čeština\", flag: \"🇨🇿\" },\n\tel: { name: \"Greek\", nativeName: \"Ελληνικά\", flag: \"🇬🇷\" },\n\the: { name: \"Hebrew\", nativeName: \"עברית\", flag: \"🇮🇱\" },\n\thu: { name: \"Hungarian\", nativeName: \"Magyar\", flag: \"🇭🇺\" },\n\tid: { name: \"Indonesian\", nativeName: \"Bahasa Indonesia\", flag: \"🇮🇩\" },\n\tth: { name: \"Thai\", nativeName: \"ไทย\", flag: \"🇹🇭\" },\n\tvi: { name: \"Vietnamese\", nativeName: \"Tiếng Việt\", flag: \"🇻🇳\" },\n\tuk: { name: \"Ukrainian\", nativeName: \"Українська\", flag: \"🇺🇦\" },\n\tro: { name: \"Romanian\", nativeName: \"Română\", flag: \"🇷🇴\" },\n\tbg: { name: \"Bulgarian\", nativeName: \"Български\", flag: \"🇧🇬\" },\n\tsk: { name: \"Slovak\", nativeName: \"Slovenčina\", flag: \"🇸🇰\" },\n\tlt: { name: \"Lithuanian\", nativeName: \"Lietuvių\", flag: \"🇱🇹\" },\n\tlv: { name: \"Latvian\", nativeName: \"Latviešu\", flag: \"🇱🇻\" },\n\tet: { name: \"Estonian\", nativeName: \"Eesti\", flag: \"🇪🇪\" },\n\tsl: { name: \"Slovenian\", nativeName: \"Slovenščina\", flag: \"🇸🇮\" },\n\tbs: { name: \"Bosnian\", nativeName: \"Bosanski\", flag: \"🇧🇦\" },\n\thr: { name: \"Croatian\", nativeName: \"Hrvatski\", flag: \"🇭🇷\" },\n\tsr: { name: \"Serbian\", nativeName: \"Српски\", flag: \"🇷🇸\" },\n\tkmr: { name: \"Kurdish\", nativeName: \"Kurdî\", flag: \"🇮🇶\" },\n\tfa: { name: \"Persian\", nativeName: \"فارسی\", flag: \"🇮🇷\" },\n\thi: { name: \"Hindi\", nativeName: \"हिन्दी\", flag: \"🇮🇳\" },\n\tbn: { name: \"Bengali\", nativeName: \"বাংলা\", flag: \"🇧🇩\" },\n\tms: { name: \"Malay\", nativeName: \"Bahasa Melayu\", flag: \"🇲🇾\" },\n};\n\nexport interface LanguageInfo {\n\tcode: string;\n\tname: string;\n\tnativeName: string;\n\tflag: string;\n}\n\nexport function getLanguageInfo(code: string): Omit<LanguageInfo, \"code\"> {\n\tconst normalized = code.toLowerCase();\n\treturn (\n\t\tLANGUAGE_DATA[normalized] ?? {\n\t\t\tname: code.toUpperCase(),\n\t\t\tnativeName: code.toUpperCase(),\n\t\t\tflag: \"🌐\",\n\t\t}\n\t);\n}\n\nexport function getFullLanguageInfo(code: string): LanguageInfo {\n\treturn {\n\t\tcode,\n\t\t...getLanguageInfo(code),\n\t};\n}\n\nexport type LanguageSwitcherDisplay =\n\t| \"flag\"\n\t| \"name\"\n\t| \"native\"\n\t| \"flag-name\"\n\t| \"flag-native\"\n\t| \"code\";\n\nexport function formatLanguageDisplay(\n\tcode: string,\n\tdisplay: LanguageSwitcherDisplay = \"flag-native\",\n): string {\n\tconst info = getLanguageInfo(code);\n\tswitch (display) {\n\t\tcase \"flag\":\n\t\t\treturn info.flag;\n\t\tcase \"name\":\n\t\t\treturn info.name;\n\t\tcase \"native\":\n\t\t\treturn info.nativeName;\n\t\tcase \"flag-name\":\n\t\t\treturn `${info.flag} ${info.name}`;\n\t\tcase \"flag-native\":\n\t\t\treturn `${info.flag} ${info.nativeName}`;\n\t\tcase \"code\":\n\t\t\treturn code.toUpperCase();\n\t\tdefault:\n\t\t\treturn `${info.flag} ${info.nativeName}`;\n\t}\n}\n\n// Simple default LanguageSwitcher (backward compatible)\nexport type LanguageSwitcherVariant = \"dropdown\" | \"buttons\" | \"minimal\";\n\nexport interface LanguageSwitcherProps {\n\tclassName?: string;\n\tvariant?: LanguageSwitcherVariant;\n\tdisplay?: LanguageSwitcherDisplay;\n\tonChange?: (language: string) => void;\n}\n\nexport default function LanguageSwitcher({\n\tclassName,\n\tvariant = \"dropdown\",\n\tdisplay = \"flag-native\",\n\tonChange,\n}: LanguageSwitcherProps) {\n\tconst { currentLanguage, availableLanguages, setLanguage } =\n\t\tuseTranslationStore();\n\n\tconst handleChange = (newLanguage: string) => {\n\t\tsetLanguage(newLanguage);\n\t\tonChange?.(newLanguage);\n\t};\n\n\tif (variant === \"buttons\") {\n\t\treturn (\n\t\t\t<div className={className} role=\"group\" aria-label=\"Language selection\">\n\t\t\t\t{availableLanguages.map((lang) => (\n\t\t\t\t\t<button\n\t\t\t\t\t\tkey={lang}\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tonClick={() => handleChange(lang)}\n\t\t\t\t\t\taria-pressed={currentLanguage === lang}\n\t\t\t\t\t\tdata-active={currentLanguage === lang}\n\t\t\t\t\t>\n\t\t\t\t\t\t{formatLanguageDisplay(lang, display)}\n\t\t\t\t\t</button>\n\t\t\t\t))}\n\t\t\t</div>\n\t\t);\n\t}\n\n\tif (variant === \"minimal\") {\n\t\treturn (\n\t\t\t<button\n\t\t\t\ttype=\"button\"\n\t\t\t\tclassName={className}\n\t\t\t\tonClick={() => {\n\t\t\t\t\tconst currentIndex = availableLanguages.indexOf(currentLanguage);\n\t\t\t\t\tconst nextIndex = (currentIndex + 1) % availableLanguages.length;\n\t\t\t\t\thandleChange(availableLanguages[nextIndex]);\n\t\t\t\t}}\n\t\t\t\taria-label={`Current language: ${getLanguageInfo(currentLanguage).name}. Click to change.`}\n\t\t\t>\n\t\t\t\t{formatLanguageDisplay(currentLanguage, display)}\n\t\t\t</button>\n\t\t);\n\t}\n\n\treturn (\n\t\t<select\n\t\t\tvalue={currentLanguage}\n\t\t\tonChange={(e) => handleChange(e.target.value)}\n\t\t\tclassName={className}\n\t\t\taria-label=\"Select language\"\n\t\t>\n\t\t\t{availableLanguages.map((lang) => (\n\t\t\t\t<option key={lang} value={lang}>\n\t\t\t\t\t{formatLanguageDisplay(lang, display)}\n\t\t\t\t</option>\n\t\t\t))}\n\t\t</select>\n\t);\n}\n","import { useCallback } from \"react\";\nimport { getTranslation, useTranslationStore } from \"../store\";\nimport type { CTFunction, InterpolationValues } from \"../types\";\n\nfunction isInterpolationValues(arg: unknown): arg is InterpolationValues {\n\treturn (\n\t\ttypeof arg === \"object\" &&\n\t\targ !== null &&\n\t\t!Array.isArray(arg) &&\n\t\t!(arg instanceof Date)\n\t);\n}\n\nexport function useCt(): CTFunction {\n\tconst { translations, currentLanguage } = useTranslationStore();\n\n\tconst ct = useCallback(\n\t\t(\n\t\t\ttext: string,\n\t\t\tcontextOrValues?: string | InterpolationValues,\n\t\t\tmaybeValues?: InterpolationValues,\n\t\t): string => {\n\t\t\tlet values: InterpolationValues | undefined;\n\n\t\t\tif (typeof contextOrValues === \"string\") {\n\t\t\t\tvalues = maybeValues;\n\t\t\t} else if (isInterpolationValues(contextOrValues)) {\n\t\t\t\tvalues = contextOrValues;\n\t\t\t}\n\n\t\t\treturn getTranslation(translations, currentLanguage, text, values);\n\t\t},\n\t\t[translations, currentLanguage],\n\t) as CTFunction;\n\n\treturn ct;\n}\n","import React, {\n\tChildren,\n\tcloneElement,\n\tisValidElement,\n\ttype ReactNode,\n\ttype ReactElement,\n} from \"react\";\nimport { useCt } from \"../hooks/useCt\";\nimport type { InterpolationValues } from \"../types\";\n\nexport interface TransProps {\n\tchildren: ReactNode;\n\tcontext?: string;\n\tvalues?: InterpolationValues;\n}\n\ninterface ParsedChild {\n\ttype: \"text\" | \"element\";\n\tcontent: string;\n\telement?: ReactElement;\n\tindex?: number;\n}\n\nfunction parseChildren(children: ReactNode): {\n\ttemplate: string;\n\telements: ReactElement[];\n} {\n\tconst elements: ReactElement[] = [];\n\tlet template = \"\";\n\n\tconst processNode = (node: ReactNode): string => {\n\t\tif (node === null || node === undefined) {\n\t\t\treturn \"\";\n\t\t}\n\n\t\tif (typeof node === \"string\") {\n\t\t\treturn node;\n\t\t}\n\n\t\tif (typeof node === \"number\") {\n\t\t\treturn String(node);\n\t\t}\n\n\t\tif (isValidElement(node)) {\n\t\t\tconst index = elements.length;\n\t\t\telements.push(node);\n\t\t\tconst innerContent = processNode(node.props.children);\n\t\t\treturn `<${index}>${innerContent}</${index}>`;\n\t\t}\n\n\t\tif (Array.isArray(node)) {\n\t\t\treturn node.map(processNode).join(\"\");\n\t\t}\n\n\t\treturn \"\";\n\t};\n\n\ttemplate = processNode(children);\n\treturn { template, elements };\n}\n\nfunction reconstructChildren(\n\ttranslated: string,\n\telements: ReactElement[],\n): ReactNode {\n\tif (elements.length === 0) {\n\t\treturn translated;\n\t}\n\n\tconst result: ReactNode[] = [];\n\tlet remaining = translated;\n\tlet keyCounter = 0;\n\n\tconst tagRegex = /<(\\d+)>(.*?)<\\/\\1>/gs;\n\n\tlet lastIndex = 0;\n\tlet match: RegExpExecArray | null;\n\n\t// Reset regex state\n\ttagRegex.lastIndex = 0;\n\n\twhile ((match = tagRegex.exec(translated)) !== null) {\n\t\t// Add text before the match\n\t\tif (match.index > lastIndex) {\n\t\t\tconst textBefore = translated.slice(lastIndex, match.index);\n\t\t\tif (textBefore) {\n\t\t\t\tresult.push(textBefore);\n\t\t\t}\n\t\t}\n\n\t\tconst elementIndex = parseInt(match[1], 10);\n\t\tconst innerContent = match[2];\n\t\tconst originalElement = elements[elementIndex];\n\n\t\tif (originalElement) {\n\t\t\t// Recursively process inner content in case of nested tags\n\t\t\tconst processedInner = reconstructChildren(innerContent, elements);\n\t\t\tconst cloned = cloneElement(originalElement, {\n\t\t\t\tkey: `trans-${keyCounter++}`,\n\t\t\t\tchildren: processedInner,\n\t\t\t});\n\t\t\tresult.push(cloned);\n\t\t}\n\n\t\tlastIndex = match.index + match[0].length;\n\t}\n\n\t// Add remaining text after last match\n\tif (lastIndex < translated.length) {\n\t\tresult.push(translated.slice(lastIndex));\n\t}\n\n\t// If no matches found, return the original string\n\tif (result.length === 0) {\n\t\treturn translated;\n\t}\n\n\treturn result.length === 1 ? result[0] : result;\n}\n\nexport function Trans({ children, context, values }: TransProps) {\n\tconst ct = useCt();\n\n\t// Parse children to extract template and elements\n\tconst { template, elements } = parseChildren(children);\n\n\t// Translate the template\n\tlet translated: string;\n\tif (context && values) {\n\t\ttranslated = ct(template, context, values);\n\t} else if (context) {\n\t\ttranslated = ct(template, context);\n\t} else if (values) {\n\t\ttranslated = ct(template, values);\n\t} else {\n\t\ttranslated = ct(template);\n\t}\n\n\t// Reconstruct with original elements\n\treturn <>{reconstructChildren(translated, elements)}</>;\n}\n","import { useCallback } from \"react\";\nimport { useTranslationStore } from \"../store\";\nimport {\n\tgetLanguageInfo,\n\tgetFullLanguageInfo,\n\tLANGUAGE_DATA,\n\ttype LanguageInfo,\n} from \"../components/LanguageSwitcher\";\n\nexport function useCurrentLanguage(): string {\n\treturn useTranslationStore((state) => state.currentLanguage);\n}\n\nexport function useSetLanguage(): (language: string) => void {\n\treturn useTranslationStore((state) => state.setLanguage);\n}\n\nexport function useAvailableLanguages(): string[] {\n\treturn useTranslationStore((state) => state.availableLanguages);\n}\n\nexport function useIsLoading(): boolean {\n\treturn useTranslationStore((state) => state.isLoading);\n}\n\nexport function useIsReady(): boolean {\n\treturn useTranslationStore((state) => state.isReady);\n}\n\nexport function useLanguageInfo(code?: string): LanguageInfo {\n\tconst currentLanguage = useTranslationStore((state) => state.currentLanguage);\n\tconst targetCode = code ?? currentLanguage;\n\treturn getFullLanguageInfo(targetCode);\n}\n\nexport function useAvailableLanguagesInfo(): LanguageInfo[] {\n\tconst availableLanguages = useTranslationStore(\n\t\t(state) => state.availableLanguages,\n\t);\n\treturn availableLanguages.map(getFullLanguageInfo);\n}\n\nexport function useLanguage() {\n\tconst currentLanguage = useTranslationStore((state) => state.currentLanguage);\n\tconst availableLanguages = useTranslationStore(\n\t\t(state) => state.availableLanguages,\n\t);\n\tconst setLanguage = useTranslationStore((state) => state.setLanguage);\n\tconst isLoading = useTranslationStore((state) => state.isLoading);\n\tconst isReady = useTranslationStore((state) => state.isReady);\n\n\tconst currentLanguageInfo = getFullLanguageInfo(currentLanguage);\n\tconst availableLanguagesInfo = availableLanguages.map(getFullLanguageInfo);\n\n\tconst cycleLanguage = useCallback(() => {\n\t\tconst currentIndex = availableLanguages.indexOf(currentLanguage);\n\t\tconst nextIndex = (currentIndex + 1) % availableLanguages.length;\n\t\tsetLanguage(availableLanguages[nextIndex]);\n\t}, [availableLanguages, currentLanguage, setLanguage]);\n\n\treturn {\n\t\tcurrentLanguage,\n\t\tcurrentLanguageInfo,\n\t\tavailableLanguages,\n\t\tavailableLanguagesInfo,\n\t\tsetLanguage,\n\t\tcycleLanguage,\n\t\tisLoading,\n\t\tisReady,\n\t};\n}\n\nexport {\n\tgetLanguageInfo,\n\tgetFullLanguageInfo,\n\tLANGUAGE_DATA,\n\ttype LanguageInfo,\n};\n"],"mappings":"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"}
|
package/dist/index.d.cts
CHANGED
|
@@ -16,6 +16,7 @@ interface TranslationState {
|
|
|
16
16
|
isHydrated: boolean;
|
|
17
17
|
serverVersion: number | null;
|
|
18
18
|
lastVersionCheck: number | null;
|
|
19
|
+
cachedLanguages: string[];
|
|
19
20
|
}
|
|
20
21
|
interface TranslationActions {
|
|
21
22
|
setLanguage: (language: string) => void;
|
|
@@ -24,6 +25,7 @@ interface TranslationActions {
|
|
|
24
25
|
setLoading: (isLoading: boolean) => void;
|
|
25
26
|
setReady: (isReady: boolean) => void;
|
|
26
27
|
setServerVersion: (version: number) => void;
|
|
28
|
+
setCachedLanguages: (languages: string[]) => void;
|
|
27
29
|
}
|
|
28
30
|
type TranslationStore = TranslationState & TranslationActions;
|
|
29
31
|
interface CiaoManifest {
|
|
@@ -164,6 +166,7 @@ declare const useTranslationStore: zustand0.UseBoundStore<Omit<zustand0.StoreApi
|
|
|
164
166
|
setOptions: (options: Partial<zustand_middleware0.PersistOptions<TranslationStore, {
|
|
165
167
|
currentLanguage: string;
|
|
166
168
|
serverVersion: number | null;
|
|
169
|
+
cachedLanguages: string[];
|
|
167
170
|
}>>) => void;
|
|
168
171
|
clearStorage: () => void;
|
|
169
172
|
rehydrate: () => Promise<void> | void;
|
|
@@ -173,6 +176,7 @@ declare const useTranslationStore: zustand0.UseBoundStore<Omit<zustand0.StoreApi
|
|
|
173
176
|
getOptions: () => Partial<zustand_middleware0.PersistOptions<TranslationStore, {
|
|
174
177
|
currentLanguage: string;
|
|
175
178
|
serverVersion: number | null;
|
|
179
|
+
cachedLanguages: string[];
|
|
176
180
|
}>>;
|
|
177
181
|
};
|
|
178
182
|
}>;
|
package/dist/index.d.cts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.cts","names":[],"sources":["../src/types.ts","../src/components/CTContextBlock.tsx","../src/components/CTProvider.tsx","../src/components/LanguageSwitcher.tsx","../src/components/Trans.tsx","../src/hooks/useCt.ts","../src/hooks/useLanguage.ts","../src/hooks/useHotUpdates.ts","../src/interpolate.ts","../src/store.ts","../src/cache.ts"],"sourcesContent":[],"mappings":";;;;;KAAY,cAAA,GAAiB;KAEjB,oBAAA,GAAuB,eAAe;KAEtC,mBAAA,GAAsB;UAEjB,gBAAA;;EANL,eAAA,EAAc,MAAA;EAEd,kBAAA,EAAA,MAAoB,EAAA;EAEpB,YAAA,EAMG,oBANmB;EAEjB,SAAA,EAAA,OAAA;
|
|
1
|
+
{"version":3,"file":"index.d.cts","names":[],"sources":["../src/types.ts","../src/components/CTContextBlock.tsx","../src/components/CTProvider.tsx","../src/components/LanguageSwitcher.tsx","../src/components/Trans.tsx","../src/hooks/useCt.ts","../src/hooks/useLanguage.ts","../src/hooks/useHotUpdates.ts","../src/interpolate.ts","../src/store.ts","../src/cache.ts"],"sourcesContent":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -16,6 +16,7 @@ interface TranslationState {
|
|
|
16
16
|
isHydrated: boolean;
|
|
17
17
|
serverVersion: number | null;
|
|
18
18
|
lastVersionCheck: number | null;
|
|
19
|
+
cachedLanguages: string[];
|
|
19
20
|
}
|
|
20
21
|
interface TranslationActions {
|
|
21
22
|
setLanguage: (language: string) => void;
|
|
@@ -24,6 +25,7 @@ interface TranslationActions {
|
|
|
24
25
|
setLoading: (isLoading: boolean) => void;
|
|
25
26
|
setReady: (isReady: boolean) => void;
|
|
26
27
|
setServerVersion: (version: number) => void;
|
|
28
|
+
setCachedLanguages: (languages: string[]) => void;
|
|
27
29
|
}
|
|
28
30
|
type TranslationStore = TranslationState & TranslationActions;
|
|
29
31
|
interface CiaoManifest {
|
|
@@ -164,6 +166,7 @@ declare const useTranslationStore: zustand0.UseBoundStore<Omit<zustand0.StoreApi
|
|
|
164
166
|
setOptions: (options: Partial<zustand_middleware0.PersistOptions<TranslationStore, {
|
|
165
167
|
currentLanguage: string;
|
|
166
168
|
serverVersion: number | null;
|
|
169
|
+
cachedLanguages: string[];
|
|
167
170
|
}>>) => void;
|
|
168
171
|
clearStorage: () => void;
|
|
169
172
|
rehydrate: () => Promise<void> | void;
|
|
@@ -173,6 +176,7 @@ declare const useTranslationStore: zustand0.UseBoundStore<Omit<zustand0.StoreApi
|
|
|
173
176
|
getOptions: () => Partial<zustand_middleware0.PersistOptions<TranslationStore, {
|
|
174
177
|
currentLanguage: string;
|
|
175
178
|
serverVersion: number | null;
|
|
179
|
+
cachedLanguages: string[];
|
|
176
180
|
}>>;
|
|
177
181
|
};
|
|
178
182
|
}>;
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/types.ts","../src/components/CTContextBlock.tsx","../src/components/CTProvider.tsx","../src/components/LanguageSwitcher.tsx","../src/components/Trans.tsx","../src/hooks/useCt.ts","../src/hooks/useLanguage.ts","../src/hooks/useHotUpdates.ts","../src/interpolate.ts","../src/store.ts","../src/cache.ts"],"sourcesContent":[],"mappings":";;;;;KAAY,cAAA,GAAiB;KAEjB,oBAAA,GAAuB,eAAe;KAEtC,mBAAA,GAAsB;UAEjB,gBAAA;;EANL,eAAA,EAAc,MAAA;EAEd,kBAAA,EAAA,MAAoB,EAAA;EAEpB,YAAA,EAMG,oBANmB;EAEjB,SAAA,EAAA,OAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/types.ts","../src/components/CTContextBlock.tsx","../src/components/CTProvider.tsx","../src/components/LanguageSwitcher.tsx","../src/components/Trans.tsx","../src/hooks/useCt.ts","../src/hooks/useLanguage.ts","../src/hooks/useHotUpdates.ts","../src/interpolate.ts","../src/store.ts","../src/cache.ts"],"sourcesContent":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -253,6 +253,7 @@ const useTranslationStore = create()(persist((set) => ({
|
|
|
253
253
|
isHydrated: false,
|
|
254
254
|
serverVersion: null,
|
|
255
255
|
lastVersionCheck: null,
|
|
256
|
+
cachedLanguages: [],
|
|
256
257
|
setLanguage: (language) => {
|
|
257
258
|
set({
|
|
258
259
|
currentLanguage: language,
|
|
@@ -297,12 +298,16 @@ const useTranslationStore = create()(persist((set) => ({
|
|
|
297
298
|
serverVersion: version,
|
|
298
299
|
lastVersionCheck: Date.now()
|
|
299
300
|
});
|
|
301
|
+
},
|
|
302
|
+
setCachedLanguages: (languages) => {
|
|
303
|
+
set({ cachedLanguages: languages });
|
|
300
304
|
}
|
|
301
305
|
}), {
|
|
302
306
|
name: "ciao-tools-language",
|
|
303
307
|
partialize: (state) => ({
|
|
304
308
|
currentLanguage: state.currentLanguage,
|
|
305
|
-
serverVersion: state.serverVersion
|
|
309
|
+
serverVersion: state.serverVersion,
|
|
310
|
+
cachedLanguages: state.cachedLanguages
|
|
306
311
|
}),
|
|
307
312
|
onRehydrateStorage: () => (_, error) => {
|
|
308
313
|
if (!error && hydrationResolver) hydrationResolver();
|
|
@@ -341,7 +346,7 @@ async function fetchTranslations(url) {
|
|
|
341
346
|
function useHotUpdates(config, projectId) {
|
|
342
347
|
const isCheckingRef = useRef(false);
|
|
343
348
|
const hasCheckedOnMountRef = useRef(false);
|
|
344
|
-
const { serverVersion, setServerVersion, addLanguage } = useTranslationStore();
|
|
349
|
+
const { serverVersion, setServerVersion, addLanguage, cachedLanguages, setCachedLanguages } = useTranslationStore();
|
|
345
350
|
const checkForUpdates = useCallback(async () => {
|
|
346
351
|
if (!config || !projectId || isCheckingRef.current) return;
|
|
347
352
|
if (config.enabled !== true) return;
|
|
@@ -356,9 +361,11 @@ function useHotUpdates(config, projectId) {
|
|
|
356
361
|
console.log("[ciao-tools] Found latest.json, version:", manifest.version);
|
|
357
362
|
const isFirstCheck = serverVersion === null;
|
|
358
363
|
const hasNewVersion = serverVersion !== null && manifest.version > serverVersion;
|
|
359
|
-
|
|
364
|
+
const hasNoCache = cachedLanguages.length === 0;
|
|
365
|
+
if (isFirstCheck || hasNewVersion || hasNoCache) {
|
|
360
366
|
if (Object.keys(manifest.urls).length > 0) {
|
|
361
|
-
|
|
367
|
+
const reason = hasNewVersion ? "new version" : hasNoCache ? "no cached translations" : "first check";
|
|
368
|
+
console.log(`[ciao-tools] Fetching translations (${reason})...`);
|
|
362
369
|
await clearCache(projectId);
|
|
363
370
|
const updatedLanguages = [];
|
|
364
371
|
for (const [langCode, url] of Object.entries(manifest.urls)) try {
|
|
@@ -370,6 +377,7 @@ function useHotUpdates(config, projectId) {
|
|
|
370
377
|
console.error(`[ciao-tools] Failed to fetch ${langCode} translations:`, err);
|
|
371
378
|
}
|
|
372
379
|
if (updatedLanguages.length > 0) {
|
|
380
|
+
setCachedLanguages(updatedLanguages);
|
|
373
381
|
console.log("[ciao-tools] Updated translations for:", updatedLanguages);
|
|
374
382
|
if (hasNewVersion && config.onTranslationsUpdated) config.onTranslationsUpdated(updatedLanguages);
|
|
375
383
|
}
|
|
@@ -386,7 +394,9 @@ function useHotUpdates(config, projectId) {
|
|
|
386
394
|
projectId,
|
|
387
395
|
serverVersion,
|
|
388
396
|
setServerVersion,
|
|
389
|
-
addLanguage
|
|
397
|
+
addLanguage,
|
|
398
|
+
cachedLanguages,
|
|
399
|
+
setCachedLanguages
|
|
390
400
|
]);
|
|
391
401
|
useEffect(() => {
|
|
392
402
|
if (!config || !projectId) return;
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["dbPromise: Promise<IDBDatabase> | null","entry: CacheEntry","options: Intl.DateTimeFormatOptions","result: string","key: string","format: string | undefined","hydrationResolver: (() => void) | null","updatedLanguages: string[]","LANGUAGE_DATA: Record<\n\tstring,\n\t{ name: string; nativeName: string; flag: string }\n>","values: InterpolationValues | undefined","elements: ReactElement[]","result: ReactNode[]","match: RegExpExecArray | null","translated: string"],"sources":["../src/components/CTContextBlock.tsx","../src/cache.ts","../src/interpolate.ts","../src/store.ts","../src/hooks/useHotUpdates.ts","../src/components/CTProvider.tsx","../src/components/LanguageSwitcher.tsx","../src/hooks/useCt.ts","../src/components/Trans.tsx","../src/hooks/useLanguage.ts"],"sourcesContent":["import React from \"react\";\nimport type { CTContextBlockProps } from \"../types\";\n\nexport function CTContextBlock({ children }: CTContextBlockProps) {\n\treturn <>{children}</>;\n}\n","import type { TranslationMap } from \"./types\";\n\nconst DB_NAME = \"ciao-tools-translations\";\nconst DB_VERSION = 1;\nconst STORE_NAME = \"translations\";\n\ninterface CacheEntry {\n\tlanguage: string;\n\tprojectId: string;\n\tdata: TranslationMap;\n\turl: string;\n\tcachedAt: number;\n}\n\nlet dbPromise: Promise<IDBDatabase> | null = null;\n\nfunction openDB(): Promise<IDBDatabase> {\n\tif (dbPromise) return dbPromise;\n\n\tdbPromise = new Promise((resolve, reject) => {\n\t\tif (typeof indexedDB === \"undefined\") {\n\t\t\treject(new Error(\"IndexedDB not available\"));\n\t\t\treturn;\n\t\t}\n\n\t\tconst request = indexedDB.open(DB_NAME, DB_VERSION);\n\n\t\trequest.onerror = () => reject(request.error);\n\t\trequest.onsuccess = () => resolve(request.result);\n\n\t\trequest.onupgradeneeded = (event) => {\n\t\t\tconst db = (event.target as IDBOpenDBRequest).result;\n\t\t\tif (!db.objectStoreNames.contains(STORE_NAME)) {\n\t\t\t\tconst store = db.createObjectStore(STORE_NAME, { keyPath: \"url\" });\n\t\t\t\tstore.createIndex(\"language\", \"language\", { unique: false });\n\t\t\t\tstore.createIndex(\"projectId\", \"projectId\", { unique: false });\n\t\t\t}\n\t\t};\n\t});\n\n\treturn dbPromise;\n}\n\nexport async function getCachedTranslation(\n\turl: string,\n): Promise<TranslationMap | null> {\n\ttry {\n\t\tconst db = await openDB();\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tconst transaction = db.transaction(STORE_NAME, \"readonly\");\n\t\t\tconst store = transaction.objectStore(STORE_NAME);\n\t\t\tconst request = store.get(url);\n\n\t\t\trequest.onerror = () => reject(request.error);\n\t\t\trequest.onsuccess = () => {\n\t\t\t\tconst entry = request.result as CacheEntry | undefined;\n\t\t\t\tresolve(entry?.data ?? null);\n\t\t\t};\n\t\t});\n\t} catch {\n\t\treturn null;\n\t}\n}\n\nexport async function cacheTranslation(\n\turl: string,\n\tlanguage: string,\n\tprojectId: string,\n\tdata: TranslationMap,\n): Promise<void> {\n\ttry {\n\t\tconst db = await openDB();\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tconst transaction = db.transaction(STORE_NAME, \"readwrite\");\n\t\t\tconst store = transaction.objectStore(STORE_NAME);\n\n\t\t\tconst entry: CacheEntry = {\n\t\t\t\turl,\n\t\t\t\tlanguage,\n\t\t\t\tprojectId,\n\t\t\t\tdata,\n\t\t\t\tcachedAt: Date.now(),\n\t\t\t};\n\n\t\t\tconst request = store.put(entry);\n\t\t\trequest.onerror = () => reject(request.error);\n\t\t\trequest.onsuccess = () => resolve();\n\t\t});\n\t} catch {\n\t\t// Silently fail - caching is optional\n\t}\n}\n\nexport async function clearCache(projectId?: string): Promise<void> {\n\ttry {\n\t\tconst db = await openDB();\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tconst transaction = db.transaction(STORE_NAME, \"readwrite\");\n\t\t\tconst store = transaction.objectStore(STORE_NAME);\n\n\t\t\tif (projectId) {\n\t\t\t\tconst index = store.index(\"projectId\");\n\t\t\t\tconst request = index.openCursor(IDBKeyRange.only(projectId));\n\t\t\t\trequest.onsuccess = (event) => {\n\t\t\t\t\tconst cursor = (event.target as IDBRequest).result;\n\t\t\t\t\tif (cursor) {\n\t\t\t\t\t\tcursor.delete();\n\t\t\t\t\t\tcursor.continue();\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t\t\ttransaction.oncomplete = () => resolve();\n\t\t\t\ttransaction.onerror = () => reject(transaction.error);\n\t\t\t} else {\n\t\t\t\tconst request = store.clear();\n\t\t\t\trequest.onerror = () => reject(request.error);\n\t\t\t\trequest.onsuccess = () => resolve();\n\t\t\t}\n\t\t});\n\t} catch {\n\t\t// Silently fail\n\t}\n}\n\nexport async function getCacheStats(): Promise<{\n\tcount: number;\n\tlanguages: string[];\n}> {\n\ttry {\n\t\tconst db = await openDB();\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tconst transaction = db.transaction(STORE_NAME, \"readonly\");\n\t\t\tconst store = transaction.objectStore(STORE_NAME);\n\n\t\t\tconst countRequest = store.count();\n\t\t\tconst languages = new Set<string>();\n\n\t\t\tconst cursorRequest = store.openCursor();\n\t\t\tcursorRequest.onsuccess = (event) => {\n\t\t\t\tconst cursor = (event.target as IDBRequest).result;\n\t\t\t\tif (cursor) {\n\t\t\t\t\tlanguages.add((cursor.value as CacheEntry).language);\n\t\t\t\t\tcursor.continue();\n\t\t\t\t}\n\t\t\t};\n\n\t\t\ttransaction.oncomplete = () => {\n\t\t\t\tresolve({\n\t\t\t\t\tcount: countRequest.result,\n\t\t\t\t\tlanguages: Array.from(languages),\n\t\t\t\t});\n\t\t\t};\n\t\t\ttransaction.onerror = () => reject(transaction.error);\n\t\t});\n\t} catch {\n\t\treturn { count: 0, languages: [] };\n\t}\n}\n","export type InterpolationValues = Record<string, unknown>;\n\nconst numberFormatCache = new Map<string, Intl.NumberFormat>();\nconst dateFormatCache = new Map<string, Intl.DateTimeFormat>();\nconst pluralRulesCache = new Map<string, Intl.PluralRules>();\n\nexport function clearFormatterCache(): void {\n\tnumberFormatCache.clear();\n\tdateFormatCache.clear();\n\tpluralRulesCache.clear();\n}\n\nfunction getNumberFormatter(locale: string): Intl.NumberFormat {\n\tconst key = `number:${locale}`;\n\tif (!numberFormatCache.has(key)) {\n\t\tnumberFormatCache.set(\n\t\t\tkey,\n\t\t\tnew Intl.NumberFormat(locale, {\n\t\t\t\tmaximumFractionDigits: 20,\n\t\t\t}),\n\t\t);\n\t}\n\treturn numberFormatCache.get(key)!;\n}\n\nfunction getCurrencyFormatter(\n\tlocale: string,\n\tcurrency: string,\n): Intl.NumberFormat {\n\tconst key = `currency:${locale}:${currency}`;\n\tif (!numberFormatCache.has(key)) {\n\t\tnumberFormatCache.set(\n\t\t\tkey,\n\t\t\tnew Intl.NumberFormat(locale, {\n\t\t\t\tstyle: \"currency\",\n\t\t\t\tcurrency,\n\t\t\t}),\n\t\t);\n\t}\n\treturn numberFormatCache.get(key)!;\n}\n\nfunction getPercentFormatter(locale: string): Intl.NumberFormat {\n\tconst key = `percent:${locale}`;\n\tif (!numberFormatCache.has(key)) {\n\t\tnumberFormatCache.set(\n\t\t\tkey,\n\t\t\tnew Intl.NumberFormat(locale, {\n\t\t\t\tstyle: \"percent\",\n\t\t\t\tminimumFractionDigits: 0,\n\t\t\t\tmaximumFractionDigits: 2,\n\t\t\t}),\n\t\t);\n\t}\n\treturn numberFormatCache.get(key)!;\n}\n\nfunction getDateFormatter(\n\tlocale: string,\n\tstyle: \"short\" | \"medium\" | \"long\" | \"full\",\n): Intl.DateTimeFormat {\n\tconst key = `date:${locale}:${style}`;\n\tif (!dateFormatCache.has(key)) {\n\t\tconst options: Intl.DateTimeFormatOptions = {\n\t\t\tdateStyle: style,\n\t\t};\n\t\tdateFormatCache.set(key, new Intl.DateTimeFormat(locale, options));\n\t}\n\treturn dateFormatCache.get(key)!;\n}\n\nfunction getTimeFormatter(\n\tlocale: string,\n\tstyle: \"short\" | \"medium\" | \"long\" | \"full\",\n): Intl.DateTimeFormat {\n\tconst key = `time:${locale}:${style}`;\n\tif (!dateFormatCache.has(key)) {\n\t\tconst options: Intl.DateTimeFormatOptions = {\n\t\t\ttimeStyle: style,\n\t\t};\n\t\tdateFormatCache.set(key, new Intl.DateTimeFormat(locale, options));\n\t}\n\treturn dateFormatCache.get(key)!;\n}\n\nfunction getPluralRules(locale: string): Intl.PluralRules {\n\tif (!pluralRulesCache.has(locale)) {\n\t\tpluralRulesCache.set(locale, new Intl.PluralRules(locale));\n\t}\n\treturn pluralRulesCache.get(locale)!;\n}\n\nfunction formatValue(\n\tvalue: unknown,\n\tformat: string | undefined,\n\tlocale: string,\n): string {\n\tif (value === null || value === undefined) {\n\t\treturn \"\";\n\t}\n\n\tif (!format) {\n\t\treturn String(value);\n\t}\n\n\tconst parts = format.split(\":\");\n\tconst formatType = parts[0];\n\n\tswitch (formatType) {\n\t\tcase \"number\": {\n\t\t\tconst num = typeof value === \"number\" ? value : Number(value);\n\t\t\tif (Number.isNaN(num)) {\n\t\t\t\treturn String(value);\n\t\t\t}\n\t\t\treturn getNumberFormatter(locale).format(num);\n\t\t}\n\n\t\tcase \"currency\": {\n\t\t\tconst currency = parts[1];\n\t\t\tif (!currency) {\n\t\t\t\treturn String(value);\n\t\t\t}\n\t\t\tconst num = typeof value === \"number\" ? value : Number(value);\n\t\t\tif (Number.isNaN(num)) {\n\t\t\t\treturn String(value);\n\t\t\t}\n\t\t\treturn getCurrencyFormatter(locale, currency).format(num);\n\t\t}\n\n\t\tcase \"percent\": {\n\t\t\tconst num = typeof value === \"number\" ? value : Number(value);\n\t\t\tif (Number.isNaN(num)) {\n\t\t\t\treturn String(value);\n\t\t\t}\n\t\t\treturn getPercentFormatter(locale).format(num);\n\t\t}\n\n\t\tcase \"date\": {\n\t\t\tif (!(value instanceof Date)) {\n\t\t\t\treturn String(value);\n\t\t\t}\n\t\t\tconst style =\n\t\t\t\t(parts[1] as \"short\" | \"medium\" | \"long\" | \"full\") || \"medium\";\n\t\t\treturn getDateFormatter(locale, style).format(value);\n\t\t}\n\n\t\tcase \"time\": {\n\t\t\tif (!(value instanceof Date)) {\n\t\t\t\treturn String(value);\n\t\t\t}\n\t\t\tconst style =\n\t\t\t\t(parts[1] as \"short\" | \"medium\" | \"long\" | \"full\") || \"medium\";\n\t\t\treturn getTimeFormatter(locale, style).format(value);\n\t\t}\n\n\t\tcase \"plural\": {\n\t\t\tconst singular = parts[1];\n\t\t\tconst plural = parts[2];\n\t\t\tif (!singular || !plural) {\n\t\t\t\treturn String(value);\n\t\t\t}\n\t\t\tconst num = typeof value === \"number\" ? value : Number(value);\n\t\t\tconst rules = getPluralRules(locale);\n\t\t\tconst category = rules.select(num);\n\t\t\treturn category === \"one\" ? singular : plural;\n\t\t}\n\n\t\tdefault:\n\t\t\treturn String(value);\n\t}\n}\n\nexport function interpolate(\n\ttext: string,\n\tvalues: InterpolationValues | undefined,\n\tlocale: string,\n): string {\n\t// Temporarily replace escaped braces with placeholder characters\n\tconst escaped = text.replace(/\\{\\{/g, \"\\x00\").replace(/\\}\\}/g, \"\\x01\");\n\n\tlet result: string;\n\tif (!values || Object.keys(values).length === 0) {\n\t\tresult = escaped;\n\t} else {\n\t\tresult = escaped.replace(/\\{([^}]+)\\}/g, (match, placeholder) => {\n\t\t\tconst trimmed = placeholder.trim();\n\t\t\tconst colonIndex = trimmed.indexOf(\":\");\n\n\t\t\tlet key: string;\n\t\t\tlet format: string | undefined;\n\n\t\t\tif (colonIndex === -1) {\n\t\t\t\tkey = trimmed;\n\t\t\t\tformat = undefined;\n\t\t\t} else {\n\t\t\t\tkey = trimmed.substring(0, colonIndex);\n\t\t\t\tformat = trimmed.substring(colonIndex + 1);\n\t\t\t}\n\n\t\t\tif (!(key in values)) {\n\t\t\t\treturn match;\n\t\t\t}\n\n\t\t\tconst value = values[key];\n\t\t\treturn formatValue(value, format, locale);\n\t\t});\n\t}\n\n\t// Restore escaped braces\n\treturn result.replace(/\\x00/g, \"{\").replace(/\\x01/g, \"}\");\n}\n","import { create } from \"zustand\";\nimport { persist } from \"zustand/middleware\";\nimport { interpolate } from \"./interpolate\";\nimport type {\n\tInterpolationValues,\n\tLanguageTranslations,\n\tTranslationMap,\n\tTranslationStore,\n} from \"./types\";\n\nlet hydrationResolver: (() => void) | null = null;\nconst hydrationPromise = new Promise<void>((resolve) => {\n\thydrationResolver = resolve;\n});\n\nexport const useTranslationStore = create<TranslationStore>()(\n\tpersist(\n\t\t(set) => ({\n\t\t\tcurrentLanguage: \"en\",\n\t\t\tdefaultLanguage: \"en\",\n\t\t\tavailableLanguages: [\"en\"],\n\t\t\ttranslations: {},\n\t\t\tisLoading: false,\n\t\t\tisReady: false,\n\t\t\tisHydrated: false,\n\t\t\tserverVersion: null,\n\t\t\tlastVersionCheck: null,\n\n\t\t\tsetLanguage: (language: string) => {\n\t\t\t\tset({ currentLanguage: language, isReady: false });\n\t\t\t},\n\n\t\t\tloadTranslations: (translations: LanguageTranslations) => {\n\t\t\t\tset((state) => {\n\t\t\t\t\tconst languages = Object.keys(translations);\n\t\t\t\t\tconst availableLanguages = [\n\t\t\t\t\t\t...new Set([...state.availableLanguages, ...languages]),\n\t\t\t\t\t];\n\t\t\t\t\tconst merged = { ...state.translations };\n\t\t\t\t\tfor (const lang of languages) {\n\t\t\t\t\t\tmerged[lang] = { ...merged[lang], ...translations[lang] };\n\t\t\t\t\t}\n\t\t\t\t\treturn {\n\t\t\t\t\t\ttranslations: merged,\n\t\t\t\t\t\tavailableLanguages,\n\t\t\t\t\t};\n\t\t\t\t});\n\t\t\t},\n\n\t\t\taddLanguage: (language: string, translations: TranslationMap) => {\n\t\t\t\tset((state) => ({\n\t\t\t\t\ttranslations: {\n\t\t\t\t\t\t...state.translations,\n\t\t\t\t\t\t[language]: { ...state.translations[language], ...translations },\n\t\t\t\t\t},\n\t\t\t\t\tavailableLanguages: state.availableLanguages.includes(language)\n\t\t\t\t\t\t? state.availableLanguages\n\t\t\t\t\t\t: [...state.availableLanguages, language],\n\t\t\t\t}));\n\t\t\t},\n\n\t\t\tsetLoading: (loading: boolean) => {\n\t\t\t\tset({ isLoading: loading });\n\t\t\t},\n\n\t\t\tsetReady: (ready: boolean) => {\n\t\t\t\tset({ isReady: ready });\n\t\t\t},\n\n\t\t\tsetServerVersion: (version: number) => {\n\t\t\t\tset({ serverVersion: version, lastVersionCheck: Date.now() });\n\t\t\t},\n\t\t}),\n\t\t{\n\t\t\tname: \"ciao-tools-language\",\n\t\t\tpartialize: (state) => ({\n\t\t\t\tcurrentLanguage: state.currentLanguage,\n\t\t\t\tserverVersion: state.serverVersion,\n\t\t\t}),\n\t\t\tonRehydrateStorage: () => (_, error) => {\n\t\t\t\tif (!error && hydrationResolver) {\n\t\t\t\t\thydrationResolver();\n\t\t\t\t}\n\t\t\t},\n\t\t},\n\t),\n);\n\nhydrationPromise.then(() => {\n\tuseTranslationStore.setState({ isHydrated: true });\n});\n\nexport function getTranslation(\n\ttranslations: LanguageTranslations,\n\tlanguage: string,\n\ttext: string,\n\tvalues?: InterpolationValues,\n): string {\n\tconst translated = translations[language]?.[text] ?? text;\n\n\tif (!values || Object.keys(values).length === 0) {\n\t\treturn translated;\n\t}\n\n\treturn interpolate(translated, values, language);\n}\n","import { useCallback, useEffect, useRef } from \"react\";\nimport { clearCache, cacheTranslation } from \"../cache\";\nimport { useTranslationStore } from \"../store\";\nimport type { HotUpdateConfig, TranslationMap } from \"../types\";\n\nconst CDN_BASE_URL = \"https://t1.ciao-tools.com\";\n\ninterface LatestManifest {\n\tversion: number;\n\tupdatedAt: string;\n\turls: Record<string, string>;\n}\n\nasync function fetchLatestManifest(projectId: string): Promise<LatestManifest | null> {\n\tconst url = `${CDN_BASE_URL}/translations/${projectId}/latest.json`;\n\ttry {\n\t\tconst response = await fetch(url, { cache: \"no-cache\" });\n\t\tif (!response.ok) {\n\t\t\tif (response.status === 404) {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tthrow new Error(`Failed to fetch latest manifest: ${response.statusText}`);\n\t\t}\n\t\treturn response.json();\n\t} catch {\n\t\treturn null;\n\t}\n}\n\nasync function fetchTranslations(url: string): Promise<TranslationMap> {\n\tconst response = await fetch(url);\n\tif (!response.ok) {\n\t\tthrow new Error(`Failed to fetch translations: ${response.statusText}`);\n\t}\n\treturn response.json();\n}\n\nexport function useHotUpdates(\n\tconfig: HotUpdateConfig | undefined,\n\tprojectId: string | undefined,\n) {\n\tconst isCheckingRef = useRef(false);\n\tconst hasCheckedOnMountRef = useRef(false);\n\n\tconst { serverVersion, setServerVersion, addLanguage } = useTranslationStore();\n\n\tconst checkForUpdates = useCallback(async () => {\n\t\tif (!config || !projectId || isCheckingRef.current) return;\n\t\tif (config.enabled !== true) return;\n\n\t\tisCheckingRef.current = true;\n\n\t\ttry {\n\t\t\tconsole.log(\"[ciao-tools] Checking for hot updates...\");\n\t\t\tconst manifest = await fetchLatestManifest(projectId);\n\n\t\t\tif (!manifest) {\n\t\t\t\tconsole.log(\"[ciao-tools] No latest.json found (project may not have hot updates yet)\");\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconsole.log(\"[ciao-tools] Found latest.json, version:\", manifest.version);\n\n\t\t\tconst isFirstCheck = serverVersion === null;\n\t\t\tconst hasNewVersion = serverVersion !== null && manifest.version > serverVersion;\n\n\t\t\tif (isFirstCheck || hasNewVersion) {\n\t\t\t\tif (Object.keys(manifest.urls).length > 0) {\n\t\t\t\t\tconsole.log(\"[ciao-tools] Fetching updated translations...\");\n\t\t\t\t\tawait clearCache(projectId);\n\n\t\t\t\t\tconst updatedLanguages: string[] = [];\n\n\t\t\t\t\tfor (const [langCode, url] of Object.entries(manifest.urls)) {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tconst translations = await fetchTranslations(url);\n\t\t\t\t\t\t\taddLanguage(langCode, translations);\n\t\t\t\t\t\t\tawait cacheTranslation(url, langCode, projectId, translations);\n\t\t\t\t\t\t\tupdatedLanguages.push(langCode);\n\t\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\t\tconsole.error(`[ciao-tools] Failed to fetch ${langCode} translations:`, err);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif (updatedLanguages.length > 0) {\n\t\t\t\t\t\tconsole.log(\"[ciao-tools] Updated translations for:\", updatedLanguages);\n\t\t\t\t\t\tif (hasNewVersion && config.onTranslationsUpdated) {\n\t\t\t\t\t\t\tconfig.onTranslationsUpdated(updatedLanguages);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tconsole.log(\"[ciao-tools] Already up to date (version \" + manifest.version + \")\");\n\t\t\t}\n\n\t\t\tsetServerVersion(manifest.version);\n\t\t} catch (error) {\n\t\t\tconsole.error(\"[ciao-tools] Hot update check failed:\", error);\n\t\t} finally {\n\t\t\tisCheckingRef.current = false;\n\t\t}\n\t}, [config, projectId, serverVersion, setServerVersion, addLanguage]);\n\n\tuseEffect(() => {\n\t\tif (!config || !projectId) return;\n\t\tif (config.enabled !== true) return;\n\n\t\tif (!hasCheckedOnMountRef.current) {\n\t\t\thasCheckedOnMountRef.current = true;\n\t\t\tcheckForUpdates();\n\t\t}\n\n\t\tconst handleVisibilityChange = () => {\n\t\t\tif (document.visibilityState === \"visible\") {\n\t\t\t\tcheckForUpdates();\n\t\t\t}\n\t\t};\n\n\t\tdocument.addEventListener(\"visibilitychange\", handleVisibilityChange);\n\n\t\treturn () => {\n\t\t\tdocument.removeEventListener(\"visibilitychange\", handleVisibilityChange);\n\t\t};\n\t}, [config, projectId, checkForUpdates]);\n\n\treturn { checkForUpdates };\n}\n","import React, { useCallback, useEffect, useRef, type ReactNode } from \"react\";\nimport { getCachedTranslation, cacheTranslation } from \"../cache\";\nimport { useTranslationStore } from \"../store\";\nimport { useHotUpdates } from \"../hooks/useHotUpdates\";\nimport type { CiaoManifest, CTProviderProps, TranslationMap } from \"../types\";\n\nconst PRELOAD_DELAY_MS = 5000;\n\nasync function fetchTranslationsFromCDN(url: string): Promise<TranslationMap> {\n\tconst response = await fetch(url);\n\tif (!response.ok) {\n\t\tthrow new Error(`Failed to fetch translations: ${response.statusText}`);\n\t}\n\treturn response.json();\n}\n\nfunction detectBrowserLanguage(availableLanguages: string[]): string | null {\n\tif (typeof navigator === \"undefined\") return null;\n\n\tconst browserLangs = navigator.languages || [navigator.language];\n\n\tfor (const browserLang of browserLangs) {\n\t\tconst normalized = browserLang.toLowerCase();\n\t\tif (availableLanguages.includes(normalized)) {\n\t\t\treturn normalized;\n\t\t}\n\t\tconst langCode = normalized.split(\"-\")[0];\n\t\tif (availableLanguages.includes(langCode)) {\n\t\t\treturn langCode;\n\t\t}\n\t}\n\n\treturn null;\n}\n\nfunction getManifestUrlsHash(manifest: CiaoManifest | undefined): string {\n\tif (!manifest) return \"\";\n\treturn JSON.stringify(manifest.cdnUrls);\n}\n\nexport function CTProvider({\n\tchildren,\n\ttranslations,\n\tmanifest,\n\tdefaultLanguage = \"en\",\n\tavailableLanguages,\n\tonLanguageChange,\n\tdetectLanguage = true,\n\tblockUntilReady = true,\n\tfallback = null,\n\tpreloadLanguages = true,\n\tpreloadDelay = PRELOAD_DELAY_MS,\n\thotUpdates,\n}: CTProviderProps) {\n\tconst {\n\t\tloadTranslations,\n\t\tsetLanguage,\n\t\taddLanguage,\n\t\tsetLoading,\n\t\tsetReady,\n\t\tcurrentLanguage,\n\t\ttranslations: storeTranslations,\n\t\tisReady,\n\t\tisHydrated,\n\t} = useTranslationStore();\n\n\tconst manifestRef = useRef<CiaoManifest | undefined>(manifest);\n\tconst loadedUrlsRef = useRef<Map<string, string>>(new Map());\n\tconst previousManifestHashRef = useRef<string>(\"\");\n\tconst initializedRef = useRef(false);\n\tconst preloadTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n\tuseEffect(() => {\n\t\tmanifestRef.current = manifest;\n\n\t\tconst newHash = getManifestUrlsHash(manifest);\n\t\tconst oldHash = previousManifestHashRef.current;\n\n\t\tif (oldHash && newHash && oldHash !== newHash) {\n\t\t\tloadedUrlsRef.current.clear();\n\t\t\tuseTranslationStore.setState({ translations: {} });\n\t\t}\n\n\t\tpreviousManifestHashRef.current = newHash;\n\t}, [manifest]);\n\n\tuseEffect(() => {\n\t\tif (translations) {\n\t\t\tloadTranslations(translations);\n\t\t\tsetReady(true);\n\t\t}\n\t}, [translations, loadTranslations, setReady]);\n\n\tuseEffect(() => {\n\t\tif (!isHydrated) return;\n\t\tif (initializedRef.current) return;\n\t\tinitializedRef.current = true;\n\n\t\tconst store = useTranslationStore.getState();\n\t\tconst effectiveLanguages = manifest\n\t\t\t? [...manifest.languages]\n\t\t\t: availableLanguages || [];\n\n\t\tconst hasPersistedLanguage =\n\t\t\tstore.currentLanguage &&\n\t\t\tstore.currentLanguage !== \"en\" &&\n\t\t\teffectiveLanguages.includes(store.currentLanguage);\n\n\t\tif (hasPersistedLanguage) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (detectLanguage && effectiveLanguages.length > 0) {\n\t\t\tconst detected = detectBrowserLanguage(effectiveLanguages);\n\t\t\tif (detected) {\n\t\t\t\tsetLanguage(detected);\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\tif (defaultLanguage && defaultLanguage !== store.currentLanguage) {\n\t\t\tsetLanguage(defaultLanguage);\n\t\t}\n\t}, [\n\t\tmanifest,\n\t\tavailableLanguages,\n\t\tdefaultLanguage,\n\t\tdetectLanguage,\n\t\tsetLanguage,\n\t\tisHydrated,\n\t]);\n\n\tuseEffect(() => {\n\t\tconst effectiveLanguages = manifest\n\t\t\t? [...manifest.languages]\n\t\t\t: availableLanguages;\n\n\t\tif (effectiveLanguages) {\n\t\t\tconst store = useTranslationStore.getState();\n\t\t\tconst merged = [\n\t\t\t\t...new Set([...store.availableLanguages, ...effectiveLanguages]),\n\t\t\t];\n\t\t\tuseTranslationStore.setState({\n\t\t\t\tavailableLanguages: merged,\n\t\t\t\tdefaultLanguage,\n\t\t\t});\n\t\t}\n\t}, [availableLanguages, manifest, defaultLanguage]);\n\n\tconst loadLanguageFromCDN = useCallback(\n\t\tasync (language: string, isPreload = false): Promise<boolean> => {\n\t\t\tconst currentManifest = manifestRef.current;\n\t\t\tif (!currentManifest) {\n\t\t\t\tif (!isPreload) setReady(true);\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tconst cdnUrl = currentManifest.cdnUrls[language];\n\t\t\tif (!cdnUrl) {\n\t\t\t\tif (!isPreload) setReady(true);\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tconst loadedUrl = loadedUrlsRef.current.get(language);\n\t\t\tif (loadedUrl === cdnUrl) {\n\t\t\t\tif (!isPreload) setReady(true);\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\tif (!isPreload) {\n\t\t\t\tsetLoading(true);\n\t\t\t\tsetReady(false);\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tconst cached = await getCachedTranslation(cdnUrl);\n\t\t\t\tif (cached) {\n\t\t\t\t\taddLanguage(language, cached);\n\t\t\t\t\tloadedUrlsRef.current.set(language, cdnUrl);\n\t\t\t\t\tif (!isPreload) {\n\t\t\t\t\t\tsetReady(true);\n\t\t\t\t\t\tsetLoading(false);\n\t\t\t\t\t}\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\n\t\t\t\tconst translationData = await fetchTranslationsFromCDN(cdnUrl);\n\t\t\t\taddLanguage(language, translationData);\n\t\t\t\tloadedUrlsRef.current.set(language, cdnUrl);\n\n\t\t\t\tawait cacheTranslation(\n\t\t\t\t\tcdnUrl,\n\t\t\t\t\tlanguage,\n\t\t\t\t\tcurrentManifest.projectId,\n\t\t\t\t\ttranslationData,\n\t\t\t\t);\n\n\t\t\t\tif (!isPreload) setReady(true);\n\t\t\t\treturn true;\n\t\t\t} catch (error) {\n\t\t\t\tconsole.error(\n\t\t\t\t\t`[ciao-tools] Failed to load translations for ${language}:`,\n\t\t\t\t\terror,\n\t\t\t\t);\n\t\t\t\tif (!isPreload) setReady(true);\n\t\t\t\treturn false;\n\t\t\t} finally {\n\t\t\t\tif (!isPreload) setLoading(false);\n\t\t\t}\n\t\t},\n\t\t[addLanguage, setLoading, setReady],\n\t);\n\n\tuseEffect(() => {\n\t\tif (!isHydrated) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (currentLanguage === manifest?.sourceLanguage) {\n\t\t\tsetReady(true);\n\t\t\treturn;\n\t\t}\n\n\t\tif (manifest && currentLanguage) {\n\t\t\tloadLanguageFromCDN(currentLanguage, false);\n\t\t} else if (!manifest) {\n\t\t\tsetReady(true);\n\t\t}\n\t}, [manifest, currentLanguage, loadLanguageFromCDN, setReady, isHydrated]);\n\n\tuseEffect(() => {\n\t\tif (!preloadLanguages || !manifest) return;\n\n\t\tif (preloadTimeoutRef.current) {\n\t\t\tclearTimeout(preloadTimeoutRef.current);\n\t\t}\n\n\t\tpreloadTimeoutRef.current = setTimeout(async () => {\n\t\t\tconst languages = [...manifest.languages];\n\t\t\tfor (const language of languages) {\n\t\t\t\tif (language === manifest.sourceLanguage) continue;\n\t\t\t\tif (language === currentLanguage) continue;\n\n\t\t\t\tawait loadLanguageFromCDN(language, true);\n\t\t\t}\n\t\t}, preloadDelay);\n\n\t\treturn () => {\n\t\t\tif (preloadTimeoutRef.current) {\n\t\t\t\tclearTimeout(preloadTimeoutRef.current);\n\t\t\t}\n\t\t};\n\t}, [\n\t\tmanifest,\n\t\tcurrentLanguage,\n\t\tpreloadLanguages,\n\t\tpreloadDelay,\n\t\tloadLanguageFromCDN,\n\t]);\n\n\tuseEffect(() => {\n\t\tif (onLanguageChange) {\n\t\t\tonLanguageChange(currentLanguage);\n\t\t}\n\t}, [currentLanguage, onLanguageChange]);\n\n\tuseHotUpdates(hotUpdates, manifest?.projectId);\n\n\tif (blockUntilReady && (!isReady || !isHydrated)) {\n\t\treturn <>{fallback}</>;\n\t}\n\n\treturn <>{children}</>;\n}\n","import React, { createContext, useContext, useCallback, type ReactNode } from \"react\";\nimport { useTranslationStore } from \"../store\";\n\nexport const LANGUAGE_DATA: Record<\n\tstring,\n\t{ name: string; nativeName: string; flag: string }\n> = {\n\ten: { name: \"English\", nativeName: \"English\", flag: \"🇺🇸\" },\n\tes: { name: \"Spanish\", nativeName: \"Español\", flag: \"🇪🇸\" },\n\tfr: { name: \"French\", nativeName: \"Français\", flag: \"🇫🇷\" },\n\tde: { name: \"German\", nativeName: \"Deutsch\", flag: \"🇩🇪\" },\n\tit: { name: \"Italian\", nativeName: \"Italiano\", flag: \"🇮🇹\" },\n\tpt: { name: \"Portuguese\", nativeName: \"Português\", flag: \"🇵🇹\" },\n\tja: { name: \"Japanese\", nativeName: \"日本語\", flag: \"🇯🇵\" },\n\tko: { name: \"Korean\", nativeName: \"한국어\", flag: \"🇰🇷\" },\n\tzh: { name: \"Chinese\", nativeName: \"中文\", flag: \"🇨🇳\" },\n\tar: { name: \"Arabic\", nativeName: \"العربية\", flag: \"🇸🇦\" },\n\tru: { name: \"Russian\", nativeName: \"Русский\", flag: \"🇷🇺\" },\n\tnl: { name: \"Dutch\", nativeName: \"Nederlands\", flag: \"🇳🇱\" },\n\tpl: { name: \"Polish\", nativeName: \"Polski\", flag: \"🇵🇱\" },\n\tsv: { name: \"Swedish\", nativeName: \"Svenska\", flag: \"🇸🇪\" },\n\tda: { name: \"Danish\", nativeName: \"Dansk\", flag: \"🇩🇰\" },\n\tfi: { name: \"Finnish\", nativeName: \"Suomi\", flag: \"🇫🇮\" },\n\tno: { name: \"Norwegian\", nativeName: \"Norsk\", flag: \"🇳🇴\" },\n\ttr: { name: \"Turkish\", nativeName: \"Türkçe\", flag: \"🇹🇷\" },\n\tcs: { name: \"Czech\", nativeName: \"Čeština\", flag: \"🇨🇿\" },\n\tel: { name: \"Greek\", nativeName: \"Ελληνικά\", flag: \"🇬🇷\" },\n\the: { name: \"Hebrew\", nativeName: \"עברית\", flag: \"🇮🇱\" },\n\thu: { name: \"Hungarian\", nativeName: \"Magyar\", flag: \"🇭🇺\" },\n\tid: { name: \"Indonesian\", nativeName: \"Bahasa Indonesia\", flag: \"🇮🇩\" },\n\tth: { name: \"Thai\", nativeName: \"ไทย\", flag: \"🇹🇭\" },\n\tvi: { name: \"Vietnamese\", nativeName: \"Tiếng Việt\", flag: \"🇻🇳\" },\n\tuk: { name: \"Ukrainian\", nativeName: \"Українська\", flag: \"🇺🇦\" },\n\tro: { name: \"Romanian\", nativeName: \"Română\", flag: \"🇷🇴\" },\n\tbg: { name: \"Bulgarian\", nativeName: \"Български\", flag: \"🇧🇬\" },\n\tsk: { name: \"Slovak\", nativeName: \"Slovenčina\", flag: \"🇸🇰\" },\n\tlt: { name: \"Lithuanian\", nativeName: \"Lietuvių\", flag: \"🇱🇹\" },\n\tlv: { name: \"Latvian\", nativeName: \"Latviešu\", flag: \"🇱🇻\" },\n\tet: { name: \"Estonian\", nativeName: \"Eesti\", flag: \"🇪🇪\" },\n\tsl: { name: \"Slovenian\", nativeName: \"Slovenščina\", flag: \"🇸🇮\" },\n\tbs: { name: \"Bosnian\", nativeName: \"Bosanski\", flag: \"🇧🇦\" },\n\thr: { name: \"Croatian\", nativeName: \"Hrvatski\", flag: \"🇭🇷\" },\n\tsr: { name: \"Serbian\", nativeName: \"Српски\", flag: \"🇷🇸\" },\n\tkmr: { name: \"Kurdish\", nativeName: \"Kurdî\", flag: \"🇮🇶\" },\n\tfa: { name: \"Persian\", nativeName: \"فارسی\", flag: \"🇮🇷\" },\n\thi: { name: \"Hindi\", nativeName: \"हिन्दी\", flag: \"🇮🇳\" },\n\tbn: { name: \"Bengali\", nativeName: \"বাংলা\", flag: \"🇧🇩\" },\n\tms: { name: \"Malay\", nativeName: \"Bahasa Melayu\", flag: \"🇲🇾\" },\n};\n\nexport interface LanguageInfo {\n\tcode: string;\n\tname: string;\n\tnativeName: string;\n\tflag: string;\n}\n\nexport function getLanguageInfo(code: string): Omit<LanguageInfo, \"code\"> {\n\tconst normalized = code.toLowerCase();\n\treturn (\n\t\tLANGUAGE_DATA[normalized] ?? {\n\t\t\tname: code.toUpperCase(),\n\t\t\tnativeName: code.toUpperCase(),\n\t\t\tflag: \"🌐\",\n\t\t}\n\t);\n}\n\nexport function getFullLanguageInfo(code: string): LanguageInfo {\n\treturn {\n\t\tcode,\n\t\t...getLanguageInfo(code),\n\t};\n}\n\nexport type LanguageSwitcherDisplay =\n\t| \"flag\"\n\t| \"name\"\n\t| \"native\"\n\t| \"flag-name\"\n\t| \"flag-native\"\n\t| \"code\";\n\nexport function formatLanguageDisplay(\n\tcode: string,\n\tdisplay: LanguageSwitcherDisplay = \"flag-native\",\n): string {\n\tconst info = getLanguageInfo(code);\n\tswitch (display) {\n\t\tcase \"flag\":\n\t\t\treturn info.flag;\n\t\tcase \"name\":\n\t\t\treturn info.name;\n\t\tcase \"native\":\n\t\t\treturn info.nativeName;\n\t\tcase \"flag-name\":\n\t\t\treturn `${info.flag} ${info.name}`;\n\t\tcase \"flag-native\":\n\t\t\treturn `${info.flag} ${info.nativeName}`;\n\t\tcase \"code\":\n\t\t\treturn code.toUpperCase();\n\t\tdefault:\n\t\t\treturn `${info.flag} ${info.nativeName}`;\n\t}\n}\n\n// Simple default LanguageSwitcher (backward compatible)\nexport type LanguageSwitcherVariant = \"dropdown\" | \"buttons\" | \"minimal\";\n\nexport interface LanguageSwitcherProps {\n\tclassName?: string;\n\tvariant?: LanguageSwitcherVariant;\n\tdisplay?: LanguageSwitcherDisplay;\n\tonChange?: (language: string) => void;\n}\n\nexport default function LanguageSwitcher({\n\tclassName,\n\tvariant = \"dropdown\",\n\tdisplay = \"flag-native\",\n\tonChange,\n}: LanguageSwitcherProps) {\n\tconst { currentLanguage, availableLanguages, setLanguage } =\n\t\tuseTranslationStore();\n\n\tconst handleChange = (newLanguage: string) => {\n\t\tsetLanguage(newLanguage);\n\t\tonChange?.(newLanguage);\n\t};\n\n\tif (variant === \"buttons\") {\n\t\treturn (\n\t\t\t<div className={className} role=\"group\" aria-label=\"Language selection\">\n\t\t\t\t{availableLanguages.map((lang) => (\n\t\t\t\t\t<button\n\t\t\t\t\t\tkey={lang}\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tonClick={() => handleChange(lang)}\n\t\t\t\t\t\taria-pressed={currentLanguage === lang}\n\t\t\t\t\t\tdata-active={currentLanguage === lang}\n\t\t\t\t\t>\n\t\t\t\t\t\t{formatLanguageDisplay(lang, display)}\n\t\t\t\t\t</button>\n\t\t\t\t))}\n\t\t\t</div>\n\t\t);\n\t}\n\n\tif (variant === \"minimal\") {\n\t\treturn (\n\t\t\t<button\n\t\t\t\ttype=\"button\"\n\t\t\t\tclassName={className}\n\t\t\t\tonClick={() => {\n\t\t\t\t\tconst currentIndex = availableLanguages.indexOf(currentLanguage);\n\t\t\t\t\tconst nextIndex = (currentIndex + 1) % availableLanguages.length;\n\t\t\t\t\thandleChange(availableLanguages[nextIndex]);\n\t\t\t\t}}\n\t\t\t\taria-label={`Current language: ${getLanguageInfo(currentLanguage).name}. Click to change.`}\n\t\t\t>\n\t\t\t\t{formatLanguageDisplay(currentLanguage, display)}\n\t\t\t</button>\n\t\t);\n\t}\n\n\treturn (\n\t\t<select\n\t\t\tvalue={currentLanguage}\n\t\t\tonChange={(e) => handleChange(e.target.value)}\n\t\t\tclassName={className}\n\t\t\taria-label=\"Select language\"\n\t\t>\n\t\t\t{availableLanguages.map((lang) => (\n\t\t\t\t<option key={lang} value={lang}>\n\t\t\t\t\t{formatLanguageDisplay(lang, display)}\n\t\t\t\t</option>\n\t\t\t))}\n\t\t</select>\n\t);\n}\n","import { useCallback } from \"react\";\nimport { getTranslation, useTranslationStore } from \"../store\";\nimport type { CTFunction, InterpolationValues } from \"../types\";\n\nfunction isInterpolationValues(arg: unknown): arg is InterpolationValues {\n\treturn (\n\t\ttypeof arg === \"object\" &&\n\t\targ !== null &&\n\t\t!Array.isArray(arg) &&\n\t\t!(arg instanceof Date)\n\t);\n}\n\nexport function useCt(): CTFunction {\n\tconst { translations, currentLanguage } = useTranslationStore();\n\n\tconst ct = useCallback(\n\t\t(\n\t\t\ttext: string,\n\t\t\tcontextOrValues?: string | InterpolationValues,\n\t\t\tmaybeValues?: InterpolationValues,\n\t\t): string => {\n\t\t\tlet values: InterpolationValues | undefined;\n\n\t\t\tif (typeof contextOrValues === \"string\") {\n\t\t\t\tvalues = maybeValues;\n\t\t\t} else if (isInterpolationValues(contextOrValues)) {\n\t\t\t\tvalues = contextOrValues;\n\t\t\t}\n\n\t\t\treturn getTranslation(translations, currentLanguage, text, values);\n\t\t},\n\t\t[translations, currentLanguage],\n\t) as CTFunction;\n\n\treturn ct;\n}\n","import React, {\n\tChildren,\n\tcloneElement,\n\tisValidElement,\n\ttype ReactNode,\n\ttype ReactElement,\n} from \"react\";\nimport { useCt } from \"../hooks/useCt\";\nimport type { InterpolationValues } from \"../types\";\n\nexport interface TransProps {\n\tchildren: ReactNode;\n\tcontext?: string;\n\tvalues?: InterpolationValues;\n}\n\ninterface ParsedChild {\n\ttype: \"text\" | \"element\";\n\tcontent: string;\n\telement?: ReactElement;\n\tindex?: number;\n}\n\nfunction parseChildren(children: ReactNode): {\n\ttemplate: string;\n\telements: ReactElement[];\n} {\n\tconst elements: ReactElement[] = [];\n\tlet template = \"\";\n\n\tconst processNode = (node: ReactNode): string => {\n\t\tif (node === null || node === undefined) {\n\t\t\treturn \"\";\n\t\t}\n\n\t\tif (typeof node === \"string\") {\n\t\t\treturn node;\n\t\t}\n\n\t\tif (typeof node === \"number\") {\n\t\t\treturn String(node);\n\t\t}\n\n\t\tif (isValidElement(node)) {\n\t\t\tconst index = elements.length;\n\t\t\telements.push(node);\n\t\t\tconst innerContent = processNode(node.props.children);\n\t\t\treturn `<${index}>${innerContent}</${index}>`;\n\t\t}\n\n\t\tif (Array.isArray(node)) {\n\t\t\treturn node.map(processNode).join(\"\");\n\t\t}\n\n\t\treturn \"\";\n\t};\n\n\ttemplate = processNode(children);\n\treturn { template, elements };\n}\n\nfunction reconstructChildren(\n\ttranslated: string,\n\telements: ReactElement[],\n): ReactNode {\n\tif (elements.length === 0) {\n\t\treturn translated;\n\t}\n\n\tconst result: ReactNode[] = [];\n\tlet remaining = translated;\n\tlet keyCounter = 0;\n\n\tconst tagRegex = /<(\\d+)>(.*?)<\\/\\1>/gs;\n\n\tlet lastIndex = 0;\n\tlet match: RegExpExecArray | null;\n\n\t// Reset regex state\n\ttagRegex.lastIndex = 0;\n\n\twhile ((match = tagRegex.exec(translated)) !== null) {\n\t\t// Add text before the match\n\t\tif (match.index > lastIndex) {\n\t\t\tconst textBefore = translated.slice(lastIndex, match.index);\n\t\t\tif (textBefore) {\n\t\t\t\tresult.push(textBefore);\n\t\t\t}\n\t\t}\n\n\t\tconst elementIndex = parseInt(match[1], 10);\n\t\tconst innerContent = match[2];\n\t\tconst originalElement = elements[elementIndex];\n\n\t\tif (originalElement) {\n\t\t\t// Recursively process inner content in case of nested tags\n\t\t\tconst processedInner = reconstructChildren(innerContent, elements);\n\t\t\tconst cloned = cloneElement(originalElement, {\n\t\t\t\tkey: `trans-${keyCounter++}`,\n\t\t\t\tchildren: processedInner,\n\t\t\t});\n\t\t\tresult.push(cloned);\n\t\t}\n\n\t\tlastIndex = match.index + match[0].length;\n\t}\n\n\t// Add remaining text after last match\n\tif (lastIndex < translated.length) {\n\t\tresult.push(translated.slice(lastIndex));\n\t}\n\n\t// If no matches found, return the original string\n\tif (result.length === 0) {\n\t\treturn translated;\n\t}\n\n\treturn result.length === 1 ? result[0] : result;\n}\n\nexport function Trans({ children, context, values }: TransProps) {\n\tconst ct = useCt();\n\n\t// Parse children to extract template and elements\n\tconst { template, elements } = parseChildren(children);\n\n\t// Translate the template\n\tlet translated: string;\n\tif (context && values) {\n\t\ttranslated = ct(template, context, values);\n\t} else if (context) {\n\t\ttranslated = ct(template, context);\n\t} else if (values) {\n\t\ttranslated = ct(template, values);\n\t} else {\n\t\ttranslated = ct(template);\n\t}\n\n\t// Reconstruct with original elements\n\treturn <>{reconstructChildren(translated, elements)}</>;\n}\n","import { useCallback } from \"react\";\nimport { useTranslationStore } from \"../store\";\nimport {\n\tgetLanguageInfo,\n\tgetFullLanguageInfo,\n\tLANGUAGE_DATA,\n\ttype LanguageInfo,\n} from \"../components/LanguageSwitcher\";\n\nexport function useCurrentLanguage(): string {\n\treturn useTranslationStore((state) => state.currentLanguage);\n}\n\nexport function useSetLanguage(): (language: string) => void {\n\treturn useTranslationStore((state) => state.setLanguage);\n}\n\nexport function useAvailableLanguages(): string[] {\n\treturn useTranslationStore((state) => state.availableLanguages);\n}\n\nexport function useIsLoading(): boolean {\n\treturn useTranslationStore((state) => state.isLoading);\n}\n\nexport function useIsReady(): boolean {\n\treturn useTranslationStore((state) => state.isReady);\n}\n\nexport function useLanguageInfo(code?: string): LanguageInfo {\n\tconst currentLanguage = useTranslationStore((state) => state.currentLanguage);\n\tconst targetCode = code ?? currentLanguage;\n\treturn getFullLanguageInfo(targetCode);\n}\n\nexport function useAvailableLanguagesInfo(): LanguageInfo[] {\n\tconst availableLanguages = useTranslationStore(\n\t\t(state) => state.availableLanguages,\n\t);\n\treturn availableLanguages.map(getFullLanguageInfo);\n}\n\nexport function useLanguage() {\n\tconst currentLanguage = useTranslationStore((state) => state.currentLanguage);\n\tconst availableLanguages = useTranslationStore(\n\t\t(state) => state.availableLanguages,\n\t);\n\tconst setLanguage = useTranslationStore((state) => state.setLanguage);\n\tconst isLoading = useTranslationStore((state) => state.isLoading);\n\tconst isReady = useTranslationStore((state) => state.isReady);\n\n\tconst currentLanguageInfo = getFullLanguageInfo(currentLanguage);\n\tconst availableLanguagesInfo = availableLanguages.map(getFullLanguageInfo);\n\n\tconst cycleLanguage = useCallback(() => {\n\t\tconst currentIndex = availableLanguages.indexOf(currentLanguage);\n\t\tconst nextIndex = (currentIndex + 1) % availableLanguages.length;\n\t\tsetLanguage(availableLanguages[nextIndex]);\n\t}, [availableLanguages, currentLanguage, setLanguage]);\n\n\treturn {\n\t\tcurrentLanguage,\n\t\tcurrentLanguageInfo,\n\t\tavailableLanguages,\n\t\tavailableLanguagesInfo,\n\t\tsetLanguage,\n\t\tcycleLanguage,\n\t\tisLoading,\n\t\tisReady,\n\t};\n}\n\nexport {\n\tgetLanguageInfo,\n\tgetFullLanguageInfo,\n\tLANGUAGE_DATA,\n\ttype LanguageInfo,\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":["dbPromise: Promise<IDBDatabase> | null","entry: CacheEntry","options: Intl.DateTimeFormatOptions","result: string","key: string","format: string | undefined","hydrationResolver: (() => void) | null","updatedLanguages: string[]","LANGUAGE_DATA: Record<\n\tstring,\n\t{ name: string; nativeName: string; flag: string }\n>","values: InterpolationValues | undefined","elements: ReactElement[]","result: ReactNode[]","match: RegExpExecArray | null","translated: string"],"sources":["../src/components/CTContextBlock.tsx","../src/cache.ts","../src/interpolate.ts","../src/store.ts","../src/hooks/useHotUpdates.ts","../src/components/CTProvider.tsx","../src/components/LanguageSwitcher.tsx","../src/hooks/useCt.ts","../src/components/Trans.tsx","../src/hooks/useLanguage.ts"],"sourcesContent":["import React from \"react\";\nimport type { CTContextBlockProps } from \"../types\";\n\nexport function CTContextBlock({ children }: CTContextBlockProps) {\n\treturn <>{children}</>;\n}\n","import type { TranslationMap } from \"./types\";\n\nconst DB_NAME = \"ciao-tools-translations\";\nconst DB_VERSION = 1;\nconst STORE_NAME = \"translations\";\n\ninterface CacheEntry {\n\tlanguage: string;\n\tprojectId: string;\n\tdata: TranslationMap;\n\turl: string;\n\tcachedAt: number;\n}\n\nlet dbPromise: Promise<IDBDatabase> | null = null;\n\nfunction openDB(): Promise<IDBDatabase> {\n\tif (dbPromise) return dbPromise;\n\n\tdbPromise = new Promise((resolve, reject) => {\n\t\tif (typeof indexedDB === \"undefined\") {\n\t\t\treject(new Error(\"IndexedDB not available\"));\n\t\t\treturn;\n\t\t}\n\n\t\tconst request = indexedDB.open(DB_NAME, DB_VERSION);\n\n\t\trequest.onerror = () => reject(request.error);\n\t\trequest.onsuccess = () => resolve(request.result);\n\n\t\trequest.onupgradeneeded = (event) => {\n\t\t\tconst db = (event.target as IDBOpenDBRequest).result;\n\t\t\tif (!db.objectStoreNames.contains(STORE_NAME)) {\n\t\t\t\tconst store = db.createObjectStore(STORE_NAME, { keyPath: \"url\" });\n\t\t\t\tstore.createIndex(\"language\", \"language\", { unique: false });\n\t\t\t\tstore.createIndex(\"projectId\", \"projectId\", { unique: false });\n\t\t\t}\n\t\t};\n\t});\n\n\treturn dbPromise;\n}\n\nexport async function getCachedTranslation(\n\turl: string,\n): Promise<TranslationMap | null> {\n\ttry {\n\t\tconst db = await openDB();\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tconst transaction = db.transaction(STORE_NAME, \"readonly\");\n\t\t\tconst store = transaction.objectStore(STORE_NAME);\n\t\t\tconst request = store.get(url);\n\n\t\t\trequest.onerror = () => reject(request.error);\n\t\t\trequest.onsuccess = () => {\n\t\t\t\tconst entry = request.result as CacheEntry | undefined;\n\t\t\t\tresolve(entry?.data ?? null);\n\t\t\t};\n\t\t});\n\t} catch {\n\t\treturn null;\n\t}\n}\n\nexport async function cacheTranslation(\n\turl: string,\n\tlanguage: string,\n\tprojectId: string,\n\tdata: TranslationMap,\n): Promise<void> {\n\ttry {\n\t\tconst db = await openDB();\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tconst transaction = db.transaction(STORE_NAME, \"readwrite\");\n\t\t\tconst store = transaction.objectStore(STORE_NAME);\n\n\t\t\tconst entry: CacheEntry = {\n\t\t\t\turl,\n\t\t\t\tlanguage,\n\t\t\t\tprojectId,\n\t\t\t\tdata,\n\t\t\t\tcachedAt: Date.now(),\n\t\t\t};\n\n\t\t\tconst request = store.put(entry);\n\t\t\trequest.onerror = () => reject(request.error);\n\t\t\trequest.onsuccess = () => resolve();\n\t\t});\n\t} catch {\n\t\t// Silently fail - caching is optional\n\t}\n}\n\nexport async function clearCache(projectId?: string): Promise<void> {\n\ttry {\n\t\tconst db = await openDB();\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tconst transaction = db.transaction(STORE_NAME, \"readwrite\");\n\t\t\tconst store = transaction.objectStore(STORE_NAME);\n\n\t\t\tif (projectId) {\n\t\t\t\tconst index = store.index(\"projectId\");\n\t\t\t\tconst request = index.openCursor(IDBKeyRange.only(projectId));\n\t\t\t\trequest.onsuccess = (event) => {\n\t\t\t\t\tconst cursor = (event.target as IDBRequest).result;\n\t\t\t\t\tif (cursor) {\n\t\t\t\t\t\tcursor.delete();\n\t\t\t\t\t\tcursor.continue();\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t\t\ttransaction.oncomplete = () => resolve();\n\t\t\t\ttransaction.onerror = () => reject(transaction.error);\n\t\t\t} else {\n\t\t\t\tconst request = store.clear();\n\t\t\t\trequest.onerror = () => reject(request.error);\n\t\t\t\trequest.onsuccess = () => resolve();\n\t\t\t}\n\t\t});\n\t} catch {\n\t\t// Silently fail\n\t}\n}\n\nexport async function getCacheStats(): Promise<{\n\tcount: number;\n\tlanguages: string[];\n}> {\n\ttry {\n\t\tconst db = await openDB();\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tconst transaction = db.transaction(STORE_NAME, \"readonly\");\n\t\t\tconst store = transaction.objectStore(STORE_NAME);\n\n\t\t\tconst countRequest = store.count();\n\t\t\tconst languages = new Set<string>();\n\n\t\t\tconst cursorRequest = store.openCursor();\n\t\t\tcursorRequest.onsuccess = (event) => {\n\t\t\t\tconst cursor = (event.target as IDBRequest).result;\n\t\t\t\tif (cursor) {\n\t\t\t\t\tlanguages.add((cursor.value as CacheEntry).language);\n\t\t\t\t\tcursor.continue();\n\t\t\t\t}\n\t\t\t};\n\n\t\t\ttransaction.oncomplete = () => {\n\t\t\t\tresolve({\n\t\t\t\t\tcount: countRequest.result,\n\t\t\t\t\tlanguages: Array.from(languages),\n\t\t\t\t});\n\t\t\t};\n\t\t\ttransaction.onerror = () => reject(transaction.error);\n\t\t});\n\t} catch {\n\t\treturn { count: 0, languages: [] };\n\t}\n}\n","export type InterpolationValues = Record<string, unknown>;\n\nconst numberFormatCache = new Map<string, Intl.NumberFormat>();\nconst dateFormatCache = new Map<string, Intl.DateTimeFormat>();\nconst pluralRulesCache = new Map<string, Intl.PluralRules>();\n\nexport function clearFormatterCache(): void {\n\tnumberFormatCache.clear();\n\tdateFormatCache.clear();\n\tpluralRulesCache.clear();\n}\n\nfunction getNumberFormatter(locale: string): Intl.NumberFormat {\n\tconst key = `number:${locale}`;\n\tif (!numberFormatCache.has(key)) {\n\t\tnumberFormatCache.set(\n\t\t\tkey,\n\t\t\tnew Intl.NumberFormat(locale, {\n\t\t\t\tmaximumFractionDigits: 20,\n\t\t\t}),\n\t\t);\n\t}\n\treturn numberFormatCache.get(key)!;\n}\n\nfunction getCurrencyFormatter(\n\tlocale: string,\n\tcurrency: string,\n): Intl.NumberFormat {\n\tconst key = `currency:${locale}:${currency}`;\n\tif (!numberFormatCache.has(key)) {\n\t\tnumberFormatCache.set(\n\t\t\tkey,\n\t\t\tnew Intl.NumberFormat(locale, {\n\t\t\t\tstyle: \"currency\",\n\t\t\t\tcurrency,\n\t\t\t}),\n\t\t);\n\t}\n\treturn numberFormatCache.get(key)!;\n}\n\nfunction getPercentFormatter(locale: string): Intl.NumberFormat {\n\tconst key = `percent:${locale}`;\n\tif (!numberFormatCache.has(key)) {\n\t\tnumberFormatCache.set(\n\t\t\tkey,\n\t\t\tnew Intl.NumberFormat(locale, {\n\t\t\t\tstyle: \"percent\",\n\t\t\t\tminimumFractionDigits: 0,\n\t\t\t\tmaximumFractionDigits: 2,\n\t\t\t}),\n\t\t);\n\t}\n\treturn numberFormatCache.get(key)!;\n}\n\nfunction getDateFormatter(\n\tlocale: string,\n\tstyle: \"short\" | \"medium\" | \"long\" | \"full\",\n): Intl.DateTimeFormat {\n\tconst key = `date:${locale}:${style}`;\n\tif (!dateFormatCache.has(key)) {\n\t\tconst options: Intl.DateTimeFormatOptions = {\n\t\t\tdateStyle: style,\n\t\t};\n\t\tdateFormatCache.set(key, new Intl.DateTimeFormat(locale, options));\n\t}\n\treturn dateFormatCache.get(key)!;\n}\n\nfunction getTimeFormatter(\n\tlocale: string,\n\tstyle: \"short\" | \"medium\" | \"long\" | \"full\",\n): Intl.DateTimeFormat {\n\tconst key = `time:${locale}:${style}`;\n\tif (!dateFormatCache.has(key)) {\n\t\tconst options: Intl.DateTimeFormatOptions = {\n\t\t\ttimeStyle: style,\n\t\t};\n\t\tdateFormatCache.set(key, new Intl.DateTimeFormat(locale, options));\n\t}\n\treturn dateFormatCache.get(key)!;\n}\n\nfunction getPluralRules(locale: string): Intl.PluralRules {\n\tif (!pluralRulesCache.has(locale)) {\n\t\tpluralRulesCache.set(locale, new Intl.PluralRules(locale));\n\t}\n\treturn pluralRulesCache.get(locale)!;\n}\n\nfunction formatValue(\n\tvalue: unknown,\n\tformat: string | undefined,\n\tlocale: string,\n): string {\n\tif (value === null || value === undefined) {\n\t\treturn \"\";\n\t}\n\n\tif (!format) {\n\t\treturn String(value);\n\t}\n\n\tconst parts = format.split(\":\");\n\tconst formatType = parts[0];\n\n\tswitch (formatType) {\n\t\tcase \"number\": {\n\t\t\tconst num = typeof value === \"number\" ? value : Number(value);\n\t\t\tif (Number.isNaN(num)) {\n\t\t\t\treturn String(value);\n\t\t\t}\n\t\t\treturn getNumberFormatter(locale).format(num);\n\t\t}\n\n\t\tcase \"currency\": {\n\t\t\tconst currency = parts[1];\n\t\t\tif (!currency) {\n\t\t\t\treturn String(value);\n\t\t\t}\n\t\t\tconst num = typeof value === \"number\" ? value : Number(value);\n\t\t\tif (Number.isNaN(num)) {\n\t\t\t\treturn String(value);\n\t\t\t}\n\t\t\treturn getCurrencyFormatter(locale, currency).format(num);\n\t\t}\n\n\t\tcase \"percent\": {\n\t\t\tconst num = typeof value === \"number\" ? value : Number(value);\n\t\t\tif (Number.isNaN(num)) {\n\t\t\t\treturn String(value);\n\t\t\t}\n\t\t\treturn getPercentFormatter(locale).format(num);\n\t\t}\n\n\t\tcase \"date\": {\n\t\t\tif (!(value instanceof Date)) {\n\t\t\t\treturn String(value);\n\t\t\t}\n\t\t\tconst style =\n\t\t\t\t(parts[1] as \"short\" | \"medium\" | \"long\" | \"full\") || \"medium\";\n\t\t\treturn getDateFormatter(locale, style).format(value);\n\t\t}\n\n\t\tcase \"time\": {\n\t\t\tif (!(value instanceof Date)) {\n\t\t\t\treturn String(value);\n\t\t\t}\n\t\t\tconst style =\n\t\t\t\t(parts[1] as \"short\" | \"medium\" | \"long\" | \"full\") || \"medium\";\n\t\t\treturn getTimeFormatter(locale, style).format(value);\n\t\t}\n\n\t\tcase \"plural\": {\n\t\t\tconst singular = parts[1];\n\t\t\tconst plural = parts[2];\n\t\t\tif (!singular || !plural) {\n\t\t\t\treturn String(value);\n\t\t\t}\n\t\t\tconst num = typeof value === \"number\" ? value : Number(value);\n\t\t\tconst rules = getPluralRules(locale);\n\t\t\tconst category = rules.select(num);\n\t\t\treturn category === \"one\" ? singular : plural;\n\t\t}\n\n\t\tdefault:\n\t\t\treturn String(value);\n\t}\n}\n\nexport function interpolate(\n\ttext: string,\n\tvalues: InterpolationValues | undefined,\n\tlocale: string,\n): string {\n\t// Temporarily replace escaped braces with placeholder characters\n\tconst escaped = text.replace(/\\{\\{/g, \"\\x00\").replace(/\\}\\}/g, \"\\x01\");\n\n\tlet result: string;\n\tif (!values || Object.keys(values).length === 0) {\n\t\tresult = escaped;\n\t} else {\n\t\tresult = escaped.replace(/\\{([^}]+)\\}/g, (match, placeholder) => {\n\t\t\tconst trimmed = placeholder.trim();\n\t\t\tconst colonIndex = trimmed.indexOf(\":\");\n\n\t\t\tlet key: string;\n\t\t\tlet format: string | undefined;\n\n\t\t\tif (colonIndex === -1) {\n\t\t\t\tkey = trimmed;\n\t\t\t\tformat = undefined;\n\t\t\t} else {\n\t\t\t\tkey = trimmed.substring(0, colonIndex);\n\t\t\t\tformat = trimmed.substring(colonIndex + 1);\n\t\t\t}\n\n\t\t\tif (!(key in values)) {\n\t\t\t\treturn match;\n\t\t\t}\n\n\t\t\tconst value = values[key];\n\t\t\treturn formatValue(value, format, locale);\n\t\t});\n\t}\n\n\t// Restore escaped braces\n\treturn result.replace(/\\x00/g, \"{\").replace(/\\x01/g, \"}\");\n}\n","import { create } from \"zustand\";\nimport { persist } from \"zustand/middleware\";\nimport { interpolate } from \"./interpolate\";\nimport type {\n\tInterpolationValues,\n\tLanguageTranslations,\n\tTranslationMap,\n\tTranslationStore,\n} from \"./types\";\n\nlet hydrationResolver: (() => void) | null = null;\nconst hydrationPromise = new Promise<void>((resolve) => {\n\thydrationResolver = resolve;\n});\n\nexport const useTranslationStore = create<TranslationStore>()(\n\tpersist(\n\t\t(set) => ({\n\t\t\tcurrentLanguage: \"en\",\n\t\t\tdefaultLanguage: \"en\",\n\t\t\tavailableLanguages: [\"en\"],\n\t\t\ttranslations: {},\n\t\t\tisLoading: false,\n\t\t\tisReady: false,\n\t\t\tisHydrated: false,\n\t\t\tserverVersion: null,\n\t\t\tlastVersionCheck: null,\n\t\t\tcachedLanguages: [],\n\n\t\t\tsetLanguage: (language: string) => {\n\t\t\t\tset({ currentLanguage: language, isReady: false });\n\t\t\t},\n\n\t\t\tloadTranslations: (translations: LanguageTranslations) => {\n\t\t\t\tset((state) => {\n\t\t\t\t\tconst languages = Object.keys(translations);\n\t\t\t\t\tconst availableLanguages = [\n\t\t\t\t\t\t...new Set([...state.availableLanguages, ...languages]),\n\t\t\t\t\t];\n\t\t\t\t\tconst merged = { ...state.translations };\n\t\t\t\t\tfor (const lang of languages) {\n\t\t\t\t\t\tmerged[lang] = { ...merged[lang], ...translations[lang] };\n\t\t\t\t\t}\n\t\t\t\t\treturn {\n\t\t\t\t\t\ttranslations: merged,\n\t\t\t\t\t\tavailableLanguages,\n\t\t\t\t\t};\n\t\t\t\t});\n\t\t\t},\n\n\t\t\taddLanguage: (language: string, translations: TranslationMap) => {\n\t\t\t\tset((state) => ({\n\t\t\t\t\ttranslations: {\n\t\t\t\t\t\t...state.translations,\n\t\t\t\t\t\t[language]: { ...state.translations[language], ...translations },\n\t\t\t\t\t},\n\t\t\t\t\tavailableLanguages: state.availableLanguages.includes(language)\n\t\t\t\t\t\t? state.availableLanguages\n\t\t\t\t\t\t: [...state.availableLanguages, language],\n\t\t\t\t}));\n\t\t\t},\n\n\t\t\tsetLoading: (loading: boolean) => {\n\t\t\t\tset({ isLoading: loading });\n\t\t\t},\n\n\t\t\tsetReady: (ready: boolean) => {\n\t\t\t\tset({ isReady: ready });\n\t\t\t},\n\n\t\t\tsetServerVersion: (version: number) => {\n\t\t\t\tset({ serverVersion: version, lastVersionCheck: Date.now() });\n\t\t\t},\n\n\t\t\tsetCachedLanguages: (languages: string[]) => {\n\t\t\t\tset({ cachedLanguages: languages });\n\t\t\t},\n\t\t}),\n\t\t{\n\t\t\tname: \"ciao-tools-language\",\n\t\t\tpartialize: (state) => ({\n\t\t\t\tcurrentLanguage: state.currentLanguage,\n\t\t\t\tserverVersion: state.serverVersion,\n\t\t\t\tcachedLanguages: state.cachedLanguages,\n\t\t\t}),\n\t\t\tonRehydrateStorage: () => (_, error) => {\n\t\t\t\tif (!error && hydrationResolver) {\n\t\t\t\t\thydrationResolver();\n\t\t\t\t}\n\t\t\t},\n\t\t},\n\t),\n);\n\nhydrationPromise.then(() => {\n\tuseTranslationStore.setState({ isHydrated: true });\n});\n\nexport function getTranslation(\n\ttranslations: LanguageTranslations,\n\tlanguage: string,\n\ttext: string,\n\tvalues?: InterpolationValues,\n): string {\n\tconst translated = translations[language]?.[text] ?? text;\n\n\tif (!values || Object.keys(values).length === 0) {\n\t\treturn translated;\n\t}\n\n\treturn interpolate(translated, values, language);\n}\n","import { useCallback, useEffect, useRef } from \"react\";\nimport { clearCache, cacheTranslation } from \"../cache\";\nimport { useTranslationStore } from \"../store\";\nimport type { HotUpdateConfig, TranslationMap } from \"../types\";\n\nconst CDN_BASE_URL = \"https://t1.ciao-tools.com\";\n\ninterface LatestManifest {\n\tversion: number;\n\tupdatedAt: string;\n\turls: Record<string, string>;\n}\n\nasync function fetchLatestManifest(projectId: string): Promise<LatestManifest | null> {\n\tconst url = `${CDN_BASE_URL}/translations/${projectId}/latest.json`;\n\ttry {\n\t\tconst response = await fetch(url, { cache: \"no-cache\" });\n\t\tif (!response.ok) {\n\t\t\tif (response.status === 404) {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tthrow new Error(`Failed to fetch latest manifest: ${response.statusText}`);\n\t\t}\n\t\treturn response.json();\n\t} catch {\n\t\treturn null;\n\t}\n}\n\nasync function fetchTranslations(url: string): Promise<TranslationMap> {\n\tconst response = await fetch(url);\n\tif (!response.ok) {\n\t\tthrow new Error(`Failed to fetch translations: ${response.statusText}`);\n\t}\n\treturn response.json();\n}\n\nexport function useHotUpdates(\n\tconfig: HotUpdateConfig | undefined,\n\tprojectId: string | undefined,\n) {\n\tconst isCheckingRef = useRef(false);\n\tconst hasCheckedOnMountRef = useRef(false);\n\n\tconst { serverVersion, setServerVersion, addLanguage, cachedLanguages, setCachedLanguages } = useTranslationStore();\n\n\tconst checkForUpdates = useCallback(async () => {\n\t\tif (!config || !projectId || isCheckingRef.current) return;\n\t\tif (config.enabled !== true) return;\n\n\t\tisCheckingRef.current = true;\n\n\t\ttry {\n\t\t\tconsole.log(\"[ciao-tools] Checking for hot updates...\");\n\t\t\tconst manifest = await fetchLatestManifest(projectId);\n\n\t\t\tif (!manifest) {\n\t\t\t\tconsole.log(\"[ciao-tools] No latest.json found (project may not have hot updates yet)\");\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconsole.log(\"[ciao-tools] Found latest.json, version:\", manifest.version);\n\n\t\t\tconst isFirstCheck = serverVersion === null;\n\t\t\tconst hasNewVersion = serverVersion !== null && manifest.version > serverVersion;\n\t\t\tconst hasNoCache = cachedLanguages.length === 0;\n\n\t\t\tif (isFirstCheck || hasNewVersion || hasNoCache) {\n\t\t\t\tif (Object.keys(manifest.urls).length > 0) {\n\t\t\t\t\tconst reason = hasNewVersion ? \"new version\" : hasNoCache ? \"no cached translations\" : \"first check\";\n\t\t\t\t\tconsole.log(`[ciao-tools] Fetching translations (${reason})...`);\n\t\t\t\t\tawait clearCache(projectId);\n\n\t\t\t\t\tconst updatedLanguages: string[] = [];\n\n\t\t\t\t\tfor (const [langCode, url] of Object.entries(manifest.urls)) {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tconst translations = await fetchTranslations(url);\n\t\t\t\t\t\t\taddLanguage(langCode, translations);\n\t\t\t\t\t\t\tawait cacheTranslation(url, langCode, projectId, translations);\n\t\t\t\t\t\t\tupdatedLanguages.push(langCode);\n\t\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\t\tconsole.error(`[ciao-tools] Failed to fetch ${langCode} translations:`, err);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif (updatedLanguages.length > 0) {\n\t\t\t\t\t\tsetCachedLanguages(updatedLanguages);\n\t\t\t\t\t\tconsole.log(\"[ciao-tools] Updated translations for:\", updatedLanguages);\n\t\t\t\t\t\tif (hasNewVersion && config.onTranslationsUpdated) {\n\t\t\t\t\t\t\tconfig.onTranslationsUpdated(updatedLanguages);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tconsole.log(\"[ciao-tools] Already up to date (version \" + manifest.version + \")\");\n\t\t\t}\n\n\t\t\tsetServerVersion(manifest.version);\n\t\t} catch (error) {\n\t\t\tconsole.error(\"[ciao-tools] Hot update check failed:\", error);\n\t\t} finally {\n\t\t\tisCheckingRef.current = false;\n\t\t}\n\t}, [config, projectId, serverVersion, setServerVersion, addLanguage, cachedLanguages, setCachedLanguages]);\n\n\tuseEffect(() => {\n\t\tif (!config || !projectId) return;\n\t\tif (config.enabled !== true) return;\n\n\t\tif (!hasCheckedOnMountRef.current) {\n\t\t\thasCheckedOnMountRef.current = true;\n\t\t\tcheckForUpdates();\n\t\t}\n\n\t\tconst handleVisibilityChange = () => {\n\t\t\tif (document.visibilityState === \"visible\") {\n\t\t\t\tcheckForUpdates();\n\t\t\t}\n\t\t};\n\n\t\tdocument.addEventListener(\"visibilitychange\", handleVisibilityChange);\n\n\t\treturn () => {\n\t\t\tdocument.removeEventListener(\"visibilitychange\", handleVisibilityChange);\n\t\t};\n\t}, [config, projectId, checkForUpdates]);\n\n\treturn { checkForUpdates };\n}\n","import React, { useCallback, useEffect, useRef, type ReactNode } from \"react\";\nimport { getCachedTranslation, cacheTranslation } from \"../cache\";\nimport { useTranslationStore } from \"../store\";\nimport { useHotUpdates } from \"../hooks/useHotUpdates\";\nimport type { CiaoManifest, CTProviderProps, TranslationMap } from \"../types\";\n\nconst PRELOAD_DELAY_MS = 5000;\n\nasync function fetchTranslationsFromCDN(url: string): Promise<TranslationMap> {\n\tconst response = await fetch(url);\n\tif (!response.ok) {\n\t\tthrow new Error(`Failed to fetch translations: ${response.statusText}`);\n\t}\n\treturn response.json();\n}\n\nfunction detectBrowserLanguage(availableLanguages: string[]): string | null {\n\tif (typeof navigator === \"undefined\") return null;\n\n\tconst browserLangs = navigator.languages || [navigator.language];\n\n\tfor (const browserLang of browserLangs) {\n\t\tconst normalized = browserLang.toLowerCase();\n\t\tif (availableLanguages.includes(normalized)) {\n\t\t\treturn normalized;\n\t\t}\n\t\tconst langCode = normalized.split(\"-\")[0];\n\t\tif (availableLanguages.includes(langCode)) {\n\t\t\treturn langCode;\n\t\t}\n\t}\n\n\treturn null;\n}\n\nfunction getManifestUrlsHash(manifest: CiaoManifest | undefined): string {\n\tif (!manifest) return \"\";\n\treturn JSON.stringify(manifest.cdnUrls);\n}\n\nexport function CTProvider({\n\tchildren,\n\ttranslations,\n\tmanifest,\n\tdefaultLanguage = \"en\",\n\tavailableLanguages,\n\tonLanguageChange,\n\tdetectLanguage = true,\n\tblockUntilReady = true,\n\tfallback = null,\n\tpreloadLanguages = true,\n\tpreloadDelay = PRELOAD_DELAY_MS,\n\thotUpdates,\n}: CTProviderProps) {\n\tconst {\n\t\tloadTranslations,\n\t\tsetLanguage,\n\t\taddLanguage,\n\t\tsetLoading,\n\t\tsetReady,\n\t\tcurrentLanguage,\n\t\ttranslations: storeTranslations,\n\t\tisReady,\n\t\tisHydrated,\n\t} = useTranslationStore();\n\n\tconst manifestRef = useRef<CiaoManifest | undefined>(manifest);\n\tconst loadedUrlsRef = useRef<Map<string, string>>(new Map());\n\tconst previousManifestHashRef = useRef<string>(\"\");\n\tconst initializedRef = useRef(false);\n\tconst preloadTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n\tuseEffect(() => {\n\t\tmanifestRef.current = manifest;\n\n\t\tconst newHash = getManifestUrlsHash(manifest);\n\t\tconst oldHash = previousManifestHashRef.current;\n\n\t\tif (oldHash && newHash && oldHash !== newHash) {\n\t\t\tloadedUrlsRef.current.clear();\n\t\t\tuseTranslationStore.setState({ translations: {} });\n\t\t}\n\n\t\tpreviousManifestHashRef.current = newHash;\n\t}, [manifest]);\n\n\tuseEffect(() => {\n\t\tif (translations) {\n\t\t\tloadTranslations(translations);\n\t\t\tsetReady(true);\n\t\t}\n\t}, [translations, loadTranslations, setReady]);\n\n\tuseEffect(() => {\n\t\tif (!isHydrated) return;\n\t\tif (initializedRef.current) return;\n\t\tinitializedRef.current = true;\n\n\t\tconst store = useTranslationStore.getState();\n\t\tconst effectiveLanguages = manifest\n\t\t\t? [...manifest.languages]\n\t\t\t: availableLanguages || [];\n\n\t\tconst hasPersistedLanguage =\n\t\t\tstore.currentLanguage &&\n\t\t\tstore.currentLanguage !== \"en\" &&\n\t\t\teffectiveLanguages.includes(store.currentLanguage);\n\n\t\tif (hasPersistedLanguage) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (detectLanguage && effectiveLanguages.length > 0) {\n\t\t\tconst detected = detectBrowserLanguage(effectiveLanguages);\n\t\t\tif (detected) {\n\t\t\t\tsetLanguage(detected);\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\tif (defaultLanguage && defaultLanguage !== store.currentLanguage) {\n\t\t\tsetLanguage(defaultLanguage);\n\t\t}\n\t}, [\n\t\tmanifest,\n\t\tavailableLanguages,\n\t\tdefaultLanguage,\n\t\tdetectLanguage,\n\t\tsetLanguage,\n\t\tisHydrated,\n\t]);\n\n\tuseEffect(() => {\n\t\tconst effectiveLanguages = manifest\n\t\t\t? [...manifest.languages]\n\t\t\t: availableLanguages;\n\n\t\tif (effectiveLanguages) {\n\t\t\tconst store = useTranslationStore.getState();\n\t\t\tconst merged = [\n\t\t\t\t...new Set([...store.availableLanguages, ...effectiveLanguages]),\n\t\t\t];\n\t\t\tuseTranslationStore.setState({\n\t\t\t\tavailableLanguages: merged,\n\t\t\t\tdefaultLanguage,\n\t\t\t});\n\t\t}\n\t}, [availableLanguages, manifest, defaultLanguage]);\n\n\tconst loadLanguageFromCDN = useCallback(\n\t\tasync (language: string, isPreload = false): Promise<boolean> => {\n\t\t\tconst currentManifest = manifestRef.current;\n\t\t\tif (!currentManifest) {\n\t\t\t\tif (!isPreload) setReady(true);\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tconst cdnUrl = currentManifest.cdnUrls[language];\n\t\t\tif (!cdnUrl) {\n\t\t\t\tif (!isPreload) setReady(true);\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tconst loadedUrl = loadedUrlsRef.current.get(language);\n\t\t\tif (loadedUrl === cdnUrl) {\n\t\t\t\tif (!isPreload) setReady(true);\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\tif (!isPreload) {\n\t\t\t\tsetLoading(true);\n\t\t\t\tsetReady(false);\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tconst cached = await getCachedTranslation(cdnUrl);\n\t\t\t\tif (cached) {\n\t\t\t\t\taddLanguage(language, cached);\n\t\t\t\t\tloadedUrlsRef.current.set(language, cdnUrl);\n\t\t\t\t\tif (!isPreload) {\n\t\t\t\t\t\tsetReady(true);\n\t\t\t\t\t\tsetLoading(false);\n\t\t\t\t\t}\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\n\t\t\t\tconst translationData = await fetchTranslationsFromCDN(cdnUrl);\n\t\t\t\taddLanguage(language, translationData);\n\t\t\t\tloadedUrlsRef.current.set(language, cdnUrl);\n\n\t\t\t\tawait cacheTranslation(\n\t\t\t\t\tcdnUrl,\n\t\t\t\t\tlanguage,\n\t\t\t\t\tcurrentManifest.projectId,\n\t\t\t\t\ttranslationData,\n\t\t\t\t);\n\n\t\t\t\tif (!isPreload) setReady(true);\n\t\t\t\treturn true;\n\t\t\t} catch (error) {\n\t\t\t\tconsole.error(\n\t\t\t\t\t`[ciao-tools] Failed to load translations for ${language}:`,\n\t\t\t\t\terror,\n\t\t\t\t);\n\t\t\t\tif (!isPreload) setReady(true);\n\t\t\t\treturn false;\n\t\t\t} finally {\n\t\t\t\tif (!isPreload) setLoading(false);\n\t\t\t}\n\t\t},\n\t\t[addLanguage, setLoading, setReady],\n\t);\n\n\tuseEffect(() => {\n\t\tif (!isHydrated) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (currentLanguage === manifest?.sourceLanguage) {\n\t\t\tsetReady(true);\n\t\t\treturn;\n\t\t}\n\n\t\tif (manifest && currentLanguage) {\n\t\t\tloadLanguageFromCDN(currentLanguage, false);\n\t\t} else if (!manifest) {\n\t\t\tsetReady(true);\n\t\t}\n\t}, [manifest, currentLanguage, loadLanguageFromCDN, setReady, isHydrated]);\n\n\tuseEffect(() => {\n\t\tif (!preloadLanguages || !manifest) return;\n\n\t\tif (preloadTimeoutRef.current) {\n\t\t\tclearTimeout(preloadTimeoutRef.current);\n\t\t}\n\n\t\tpreloadTimeoutRef.current = setTimeout(async () => {\n\t\t\tconst languages = [...manifest.languages];\n\t\t\tfor (const language of languages) {\n\t\t\t\tif (language === manifest.sourceLanguage) continue;\n\t\t\t\tif (language === currentLanguage) continue;\n\n\t\t\t\tawait loadLanguageFromCDN(language, true);\n\t\t\t}\n\t\t}, preloadDelay);\n\n\t\treturn () => {\n\t\t\tif (preloadTimeoutRef.current) {\n\t\t\t\tclearTimeout(preloadTimeoutRef.current);\n\t\t\t}\n\t\t};\n\t}, [\n\t\tmanifest,\n\t\tcurrentLanguage,\n\t\tpreloadLanguages,\n\t\tpreloadDelay,\n\t\tloadLanguageFromCDN,\n\t]);\n\n\tuseEffect(() => {\n\t\tif (onLanguageChange) {\n\t\t\tonLanguageChange(currentLanguage);\n\t\t}\n\t}, [currentLanguage, onLanguageChange]);\n\n\tuseHotUpdates(hotUpdates, manifest?.projectId);\n\n\tif (blockUntilReady && (!isReady || !isHydrated)) {\n\t\treturn <>{fallback}</>;\n\t}\n\n\treturn <>{children}</>;\n}\n","import React, { createContext, useContext, useCallback, type ReactNode } from \"react\";\nimport { useTranslationStore } from \"../store\";\n\nexport const LANGUAGE_DATA: Record<\n\tstring,\n\t{ name: string; nativeName: string; flag: string }\n> = {\n\ten: { name: \"English\", nativeName: \"English\", flag: \"🇺🇸\" },\n\tes: { name: \"Spanish\", nativeName: \"Español\", flag: \"🇪🇸\" },\n\tfr: { name: \"French\", nativeName: \"Français\", flag: \"🇫🇷\" },\n\tde: { name: \"German\", nativeName: \"Deutsch\", flag: \"🇩🇪\" },\n\tit: { name: \"Italian\", nativeName: \"Italiano\", flag: \"🇮🇹\" },\n\tpt: { name: \"Portuguese\", nativeName: \"Português\", flag: \"🇵🇹\" },\n\tja: { name: \"Japanese\", nativeName: \"日本語\", flag: \"🇯🇵\" },\n\tko: { name: \"Korean\", nativeName: \"한국어\", flag: \"🇰🇷\" },\n\tzh: { name: \"Chinese\", nativeName: \"中文\", flag: \"🇨🇳\" },\n\tar: { name: \"Arabic\", nativeName: \"العربية\", flag: \"🇸🇦\" },\n\tru: { name: \"Russian\", nativeName: \"Русский\", flag: \"🇷🇺\" },\n\tnl: { name: \"Dutch\", nativeName: \"Nederlands\", flag: \"🇳🇱\" },\n\tpl: { name: \"Polish\", nativeName: \"Polski\", flag: \"🇵🇱\" },\n\tsv: { name: \"Swedish\", nativeName: \"Svenska\", flag: \"🇸🇪\" },\n\tda: { name: \"Danish\", nativeName: \"Dansk\", flag: \"🇩🇰\" },\n\tfi: { name: \"Finnish\", nativeName: \"Suomi\", flag: \"🇫🇮\" },\n\tno: { name: \"Norwegian\", nativeName: \"Norsk\", flag: \"🇳🇴\" },\n\ttr: { name: \"Turkish\", nativeName: \"Türkçe\", flag: \"🇹🇷\" },\n\tcs: { name: \"Czech\", nativeName: \"Čeština\", flag: \"🇨🇿\" },\n\tel: { name: \"Greek\", nativeName: \"Ελληνικά\", flag: \"🇬🇷\" },\n\the: { name: \"Hebrew\", nativeName: \"עברית\", flag: \"🇮🇱\" },\n\thu: { name: \"Hungarian\", nativeName: \"Magyar\", flag: \"🇭🇺\" },\n\tid: { name: \"Indonesian\", nativeName: \"Bahasa Indonesia\", flag: \"🇮🇩\" },\n\tth: { name: \"Thai\", nativeName: \"ไทย\", flag: \"🇹🇭\" },\n\tvi: { name: \"Vietnamese\", nativeName: \"Tiếng Việt\", flag: \"🇻🇳\" },\n\tuk: { name: \"Ukrainian\", nativeName: \"Українська\", flag: \"🇺🇦\" },\n\tro: { name: \"Romanian\", nativeName: \"Română\", flag: \"🇷🇴\" },\n\tbg: { name: \"Bulgarian\", nativeName: \"Български\", flag: \"🇧🇬\" },\n\tsk: { name: \"Slovak\", nativeName: \"Slovenčina\", flag: \"🇸🇰\" },\n\tlt: { name: \"Lithuanian\", nativeName: \"Lietuvių\", flag: \"🇱🇹\" },\n\tlv: { name: \"Latvian\", nativeName: \"Latviešu\", flag: \"🇱🇻\" },\n\tet: { name: \"Estonian\", nativeName: \"Eesti\", flag: \"🇪🇪\" },\n\tsl: { name: \"Slovenian\", nativeName: \"Slovenščina\", flag: \"🇸🇮\" },\n\tbs: { name: \"Bosnian\", nativeName: \"Bosanski\", flag: \"🇧🇦\" },\n\thr: { name: \"Croatian\", nativeName: \"Hrvatski\", flag: \"🇭🇷\" },\n\tsr: { name: \"Serbian\", nativeName: \"Српски\", flag: \"🇷🇸\" },\n\tkmr: { name: \"Kurdish\", nativeName: \"Kurdî\", flag: \"🇮🇶\" },\n\tfa: { name: \"Persian\", nativeName: \"فارسی\", flag: \"🇮🇷\" },\n\thi: { name: \"Hindi\", nativeName: \"हिन्दी\", flag: \"🇮🇳\" },\n\tbn: { name: \"Bengali\", nativeName: \"বাংলা\", flag: \"🇧🇩\" },\n\tms: { name: \"Malay\", nativeName: \"Bahasa Melayu\", flag: \"🇲🇾\" },\n};\n\nexport interface LanguageInfo {\n\tcode: string;\n\tname: string;\n\tnativeName: string;\n\tflag: string;\n}\n\nexport function getLanguageInfo(code: string): Omit<LanguageInfo, \"code\"> {\n\tconst normalized = code.toLowerCase();\n\treturn (\n\t\tLANGUAGE_DATA[normalized] ?? {\n\t\t\tname: code.toUpperCase(),\n\t\t\tnativeName: code.toUpperCase(),\n\t\t\tflag: \"🌐\",\n\t\t}\n\t);\n}\n\nexport function getFullLanguageInfo(code: string): LanguageInfo {\n\treturn {\n\t\tcode,\n\t\t...getLanguageInfo(code),\n\t};\n}\n\nexport type LanguageSwitcherDisplay =\n\t| \"flag\"\n\t| \"name\"\n\t| \"native\"\n\t| \"flag-name\"\n\t| \"flag-native\"\n\t| \"code\";\n\nexport function formatLanguageDisplay(\n\tcode: string,\n\tdisplay: LanguageSwitcherDisplay = \"flag-native\",\n): string {\n\tconst info = getLanguageInfo(code);\n\tswitch (display) {\n\t\tcase \"flag\":\n\t\t\treturn info.flag;\n\t\tcase \"name\":\n\t\t\treturn info.name;\n\t\tcase \"native\":\n\t\t\treturn info.nativeName;\n\t\tcase \"flag-name\":\n\t\t\treturn `${info.flag} ${info.name}`;\n\t\tcase \"flag-native\":\n\t\t\treturn `${info.flag} ${info.nativeName}`;\n\t\tcase \"code\":\n\t\t\treturn code.toUpperCase();\n\t\tdefault:\n\t\t\treturn `${info.flag} ${info.nativeName}`;\n\t}\n}\n\n// Simple default LanguageSwitcher (backward compatible)\nexport type LanguageSwitcherVariant = \"dropdown\" | \"buttons\" | \"minimal\";\n\nexport interface LanguageSwitcherProps {\n\tclassName?: string;\n\tvariant?: LanguageSwitcherVariant;\n\tdisplay?: LanguageSwitcherDisplay;\n\tonChange?: (language: string) => void;\n}\n\nexport default function LanguageSwitcher({\n\tclassName,\n\tvariant = \"dropdown\",\n\tdisplay = \"flag-native\",\n\tonChange,\n}: LanguageSwitcherProps) {\n\tconst { currentLanguage, availableLanguages, setLanguage } =\n\t\tuseTranslationStore();\n\n\tconst handleChange = (newLanguage: string) => {\n\t\tsetLanguage(newLanguage);\n\t\tonChange?.(newLanguage);\n\t};\n\n\tif (variant === \"buttons\") {\n\t\treturn (\n\t\t\t<div className={className} role=\"group\" aria-label=\"Language selection\">\n\t\t\t\t{availableLanguages.map((lang) => (\n\t\t\t\t\t<button\n\t\t\t\t\t\tkey={lang}\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tonClick={() => handleChange(lang)}\n\t\t\t\t\t\taria-pressed={currentLanguage === lang}\n\t\t\t\t\t\tdata-active={currentLanguage === lang}\n\t\t\t\t\t>\n\t\t\t\t\t\t{formatLanguageDisplay(lang, display)}\n\t\t\t\t\t</button>\n\t\t\t\t))}\n\t\t\t</div>\n\t\t);\n\t}\n\n\tif (variant === \"minimal\") {\n\t\treturn (\n\t\t\t<button\n\t\t\t\ttype=\"button\"\n\t\t\t\tclassName={className}\n\t\t\t\tonClick={() => {\n\t\t\t\t\tconst currentIndex = availableLanguages.indexOf(currentLanguage);\n\t\t\t\t\tconst nextIndex = (currentIndex + 1) % availableLanguages.length;\n\t\t\t\t\thandleChange(availableLanguages[nextIndex]);\n\t\t\t\t}}\n\t\t\t\taria-label={`Current language: ${getLanguageInfo(currentLanguage).name}. Click to change.`}\n\t\t\t>\n\t\t\t\t{formatLanguageDisplay(currentLanguage, display)}\n\t\t\t</button>\n\t\t);\n\t}\n\n\treturn (\n\t\t<select\n\t\t\tvalue={currentLanguage}\n\t\t\tonChange={(e) => handleChange(e.target.value)}\n\t\t\tclassName={className}\n\t\t\taria-label=\"Select language\"\n\t\t>\n\t\t\t{availableLanguages.map((lang) => (\n\t\t\t\t<option key={lang} value={lang}>\n\t\t\t\t\t{formatLanguageDisplay(lang, display)}\n\t\t\t\t</option>\n\t\t\t))}\n\t\t</select>\n\t);\n}\n","import { useCallback } from \"react\";\nimport { getTranslation, useTranslationStore } from \"../store\";\nimport type { CTFunction, InterpolationValues } from \"../types\";\n\nfunction isInterpolationValues(arg: unknown): arg is InterpolationValues {\n\treturn (\n\t\ttypeof arg === \"object\" &&\n\t\targ !== null &&\n\t\t!Array.isArray(arg) &&\n\t\t!(arg instanceof Date)\n\t);\n}\n\nexport function useCt(): CTFunction {\n\tconst { translations, currentLanguage } = useTranslationStore();\n\n\tconst ct = useCallback(\n\t\t(\n\t\t\ttext: string,\n\t\t\tcontextOrValues?: string | InterpolationValues,\n\t\t\tmaybeValues?: InterpolationValues,\n\t\t): string => {\n\t\t\tlet values: InterpolationValues | undefined;\n\n\t\t\tif (typeof contextOrValues === \"string\") {\n\t\t\t\tvalues = maybeValues;\n\t\t\t} else if (isInterpolationValues(contextOrValues)) {\n\t\t\t\tvalues = contextOrValues;\n\t\t\t}\n\n\t\t\treturn getTranslation(translations, currentLanguage, text, values);\n\t\t},\n\t\t[translations, currentLanguage],\n\t) as CTFunction;\n\n\treturn ct;\n}\n","import React, {\n\tChildren,\n\tcloneElement,\n\tisValidElement,\n\ttype ReactNode,\n\ttype ReactElement,\n} from \"react\";\nimport { useCt } from \"../hooks/useCt\";\nimport type { InterpolationValues } from \"../types\";\n\nexport interface TransProps {\n\tchildren: ReactNode;\n\tcontext?: string;\n\tvalues?: InterpolationValues;\n}\n\ninterface ParsedChild {\n\ttype: \"text\" | \"element\";\n\tcontent: string;\n\telement?: ReactElement;\n\tindex?: number;\n}\n\nfunction parseChildren(children: ReactNode): {\n\ttemplate: string;\n\telements: ReactElement[];\n} {\n\tconst elements: ReactElement[] = [];\n\tlet template = \"\";\n\n\tconst processNode = (node: ReactNode): string => {\n\t\tif (node === null || node === undefined) {\n\t\t\treturn \"\";\n\t\t}\n\n\t\tif (typeof node === \"string\") {\n\t\t\treturn node;\n\t\t}\n\n\t\tif (typeof node === \"number\") {\n\t\t\treturn String(node);\n\t\t}\n\n\t\tif (isValidElement(node)) {\n\t\t\tconst index = elements.length;\n\t\t\telements.push(node);\n\t\t\tconst innerContent = processNode(node.props.children);\n\t\t\treturn `<${index}>${innerContent}</${index}>`;\n\t\t}\n\n\t\tif (Array.isArray(node)) {\n\t\t\treturn node.map(processNode).join(\"\");\n\t\t}\n\n\t\treturn \"\";\n\t};\n\n\ttemplate = processNode(children);\n\treturn { template, elements };\n}\n\nfunction reconstructChildren(\n\ttranslated: string,\n\telements: ReactElement[],\n): ReactNode {\n\tif (elements.length === 0) {\n\t\treturn translated;\n\t}\n\n\tconst result: ReactNode[] = [];\n\tlet remaining = translated;\n\tlet keyCounter = 0;\n\n\tconst tagRegex = /<(\\d+)>(.*?)<\\/\\1>/gs;\n\n\tlet lastIndex = 0;\n\tlet match: RegExpExecArray | null;\n\n\t// Reset regex state\n\ttagRegex.lastIndex = 0;\n\n\twhile ((match = tagRegex.exec(translated)) !== null) {\n\t\t// Add text before the match\n\t\tif (match.index > lastIndex) {\n\t\t\tconst textBefore = translated.slice(lastIndex, match.index);\n\t\t\tif (textBefore) {\n\t\t\t\tresult.push(textBefore);\n\t\t\t}\n\t\t}\n\n\t\tconst elementIndex = parseInt(match[1], 10);\n\t\tconst innerContent = match[2];\n\t\tconst originalElement = elements[elementIndex];\n\n\t\tif (originalElement) {\n\t\t\t// Recursively process inner content in case of nested tags\n\t\t\tconst processedInner = reconstructChildren(innerContent, elements);\n\t\t\tconst cloned = cloneElement(originalElement, {\n\t\t\t\tkey: `trans-${keyCounter++}`,\n\t\t\t\tchildren: processedInner,\n\t\t\t});\n\t\t\tresult.push(cloned);\n\t\t}\n\n\t\tlastIndex = match.index + match[0].length;\n\t}\n\n\t// Add remaining text after last match\n\tif (lastIndex < translated.length) {\n\t\tresult.push(translated.slice(lastIndex));\n\t}\n\n\t// If no matches found, return the original string\n\tif (result.length === 0) {\n\t\treturn translated;\n\t}\n\n\treturn result.length === 1 ? result[0] : result;\n}\n\nexport function Trans({ children, context, values }: TransProps) {\n\tconst ct = useCt();\n\n\t// Parse children to extract template and elements\n\tconst { template, elements } = parseChildren(children);\n\n\t// Translate the template\n\tlet translated: string;\n\tif (context && values) {\n\t\ttranslated = ct(template, context, values);\n\t} else if (context) {\n\t\ttranslated = ct(template, context);\n\t} else if (values) {\n\t\ttranslated = ct(template, values);\n\t} else {\n\t\ttranslated = ct(template);\n\t}\n\n\t// Reconstruct with original elements\n\treturn <>{reconstructChildren(translated, elements)}</>;\n}\n","import { useCallback } from \"react\";\nimport { useTranslationStore } from \"../store\";\nimport {\n\tgetLanguageInfo,\n\tgetFullLanguageInfo,\n\tLANGUAGE_DATA,\n\ttype LanguageInfo,\n} from \"../components/LanguageSwitcher\";\n\nexport function useCurrentLanguage(): string {\n\treturn useTranslationStore((state) => state.currentLanguage);\n}\n\nexport function useSetLanguage(): (language: string) => void {\n\treturn useTranslationStore((state) => state.setLanguage);\n}\n\nexport function useAvailableLanguages(): string[] {\n\treturn useTranslationStore((state) => state.availableLanguages);\n}\n\nexport function useIsLoading(): boolean {\n\treturn useTranslationStore((state) => state.isLoading);\n}\n\nexport function useIsReady(): boolean {\n\treturn useTranslationStore((state) => state.isReady);\n}\n\nexport function useLanguageInfo(code?: string): LanguageInfo {\n\tconst currentLanguage = useTranslationStore((state) => state.currentLanguage);\n\tconst targetCode = code ?? currentLanguage;\n\treturn getFullLanguageInfo(targetCode);\n}\n\nexport function useAvailableLanguagesInfo(): LanguageInfo[] {\n\tconst availableLanguages = useTranslationStore(\n\t\t(state) => state.availableLanguages,\n\t);\n\treturn availableLanguages.map(getFullLanguageInfo);\n}\n\nexport function useLanguage() {\n\tconst currentLanguage = useTranslationStore((state) => state.currentLanguage);\n\tconst availableLanguages = useTranslationStore(\n\t\t(state) => state.availableLanguages,\n\t);\n\tconst setLanguage = useTranslationStore((state) => state.setLanguage);\n\tconst isLoading = useTranslationStore((state) => state.isLoading);\n\tconst isReady = useTranslationStore((state) => state.isReady);\n\n\tconst currentLanguageInfo = getFullLanguageInfo(currentLanguage);\n\tconst availableLanguagesInfo = availableLanguages.map(getFullLanguageInfo);\n\n\tconst cycleLanguage = useCallback(() => {\n\t\tconst currentIndex = availableLanguages.indexOf(currentLanguage);\n\t\tconst nextIndex = (currentIndex + 1) % availableLanguages.length;\n\t\tsetLanguage(availableLanguages[nextIndex]);\n\t}, [availableLanguages, currentLanguage, setLanguage]);\n\n\treturn {\n\t\tcurrentLanguage,\n\t\tcurrentLanguageInfo,\n\t\tavailableLanguages,\n\t\tavailableLanguagesInfo,\n\t\tsetLanguage,\n\t\tcycleLanguage,\n\t\tisLoading,\n\t\tisReady,\n\t};\n}\n\nexport {\n\tgetLanguageInfo,\n\tgetFullLanguageInfo,\n\tLANGUAGE_DATA,\n\ttype LanguageInfo,\n};\n"],"mappings":"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"}
|