453ddc5e94
- plain Svelte 5 + TS + Vite (no SvelteKit); CSS-token design system (Telegram-ready), hash router, IndexedDB session - pure libs: domain model, premium/value maps ported from solver, board replay, placement state machine, i18n en/ru - in-memory mock transport + seed data; pnpm start runs lobby->active game->board with no backend - board: pointer-drag + tap placement, MakeMove (popup / 1s-hold commit), two-state zoom, blank chooser, exchange, hint, word-check, chat - Playwright smoke (mock) green; svelte-check clean; mock bundle ~37 KB gzip
38 lines
1.2 KiB
TypeScript
38 lines
1.2 KiB
TypeScript
// Pure i18n catalog + lookup (no runes) so any module can import the types and
|
|
// translate without depending on the reactive layer.
|
|
|
|
import { en, type MessageKey } from './en';
|
|
import { ru } from './ru';
|
|
|
|
export type Locale = 'en' | 'ru';
|
|
export type { MessageKey };
|
|
|
|
export const catalogs: Record<Locale, Record<MessageKey, string>> = { en, ru };
|
|
|
|
export function translate(
|
|
locale: Locale,
|
|
key: MessageKey,
|
|
params?: Record<string, string | number>,
|
|
): string {
|
|
const dict = catalogs[locale] ?? en;
|
|
let s: string = dict[key] ?? en[key] ?? key;
|
|
if (params) {
|
|
for (const [k, v] of Object.entries(params)) {
|
|
s = s.replaceAll(`{${k}}`, String(v));
|
|
}
|
|
}
|
|
return s;
|
|
}
|
|
|
|
/** errorKey maps a gateway result/edge code to a message key, falling back to generic. */
|
|
export function errorKey(code: string): MessageKey {
|
|
const key = `error.${code}` as MessageKey;
|
|
return key in en ? key : 'error.generic';
|
|
}
|
|
|
|
/** localeFrom picks a supported locale from a free-form hint (e.g. 'ru-RU' -> 'ru'). */
|
|
export function localeFrom(hint: string | undefined | null, fallback: Locale = 'en'): Locale {
|
|
const l = (hint ?? '').slice(0, 2).toLowerCase();
|
|
return l === 'ru' ? 'ru' : l === 'en' ? 'en' : fallback;
|
|
}
|