538 lines
24 KiB
TypeScript
538 lines
24 KiB
TypeScript
/**
|
||
* Flat string dictionary for ru/en. Keys use dot notation but are just
|
||
* strings — no nesting overhead.
|
||
*
|
||
* Interpolation: `{name}` placeholders are replaced via `useT()` helper.
|
||
*
|
||
* Pluralization: keys ending in `.one`/`.few`/`.many` (ru) or
|
||
* `.one`/`.other` (en) are picked by `tn()` helper based on count.
|
||
*/
|
||
|
||
export type Dict = Record<string, string>
|
||
|
||
export const ru: Dict = {
|
||
// Sidebar / nav
|
||
'nav.today': 'Сегодня',
|
||
'nav.exercises': 'Упражнения',
|
||
'nav.games': 'Игры',
|
||
'nav.challenges': 'Челленджи',
|
||
'nav.settings': 'Настройки',
|
||
'sidebar.slogan': 'Двигайся осознанно',
|
||
'sidebar.status_tracking': 'Активность отслеживается',
|
||
'titlebar.menu_aria': 'Меню',
|
||
'titlebar.minimize_aria': 'Свернуть',
|
||
'titlebar.maximize_aria': 'Развернуть',
|
||
'titlebar.restore_aria': 'Восстановить размер',
|
||
'titlebar.tray_aria': 'В трей',
|
||
'titlebar.close_aria': 'Закрыть',
|
||
'titlebar.app_title': 'Exercise Reminder',
|
||
|
||
// Common buttons / actions
|
||
'btn.add': 'Добавить',
|
||
'btn.new': 'Новый',
|
||
'btn.cancel': 'Отмена',
|
||
'btn.save': 'Сохранить',
|
||
'btn.done': 'Готово',
|
||
'btn.start': 'Старт',
|
||
'btn.pause': 'Пауза',
|
||
'btn.refresh': 'Обновить',
|
||
'btn.edit': 'Редактировать',
|
||
'btn.delete': 'Удалить',
|
||
'btn.snooze_min': 'Отложить {n} мин',
|
||
'btn.skip': 'Пропустить',
|
||
'btn.close': 'Закрыть',
|
||
'btn.later': 'Позже',
|
||
'btn.connect': 'Подключить',
|
||
'btn.disconnect': 'Отключить',
|
||
'btn.check': 'Проверить',
|
||
'btn.download': 'Скачать',
|
||
'btn.restart': 'Перезапустить',
|
||
'btn.retry': 'Повторить',
|
||
|
||
// Dashboard
|
||
'dashboard.kicker': 'Тренировка дня',
|
||
'dashboard.title': 'Сегодня',
|
||
'dashboard.stat.active': 'Активных',
|
||
'dashboard.stat.active.of': 'из {total}',
|
||
'dashboard.stat.today_done': 'Сегодня',
|
||
'dashboard.stat.today_done.subtitle': 'повторов за день',
|
||
'dashboard.stat.streak': 'Стрик',
|
||
'dashboard.stat.streak.subtitle': '{n} дн. подряд',
|
||
'dashboard.stat.next': 'До следующего',
|
||
'dashboard.stat.next.now': 'Сейчас',
|
||
'dashboard.stat.next.subtitle_paused': 'на паузе',
|
||
'dashboard.stat.next.subtitle_running': 'отсчёт идёт',
|
||
'dashboard.stat.tracking': 'Трекинг матчей',
|
||
'dashboard.stat.tracking.on': 'On',
|
||
'dashboard.stat.tracking.off': 'Off',
|
||
'dashboard.stat.tracking.subtitle_on': 'в реальном времени',
|
||
'dashboard.stat.tracking.subtitle_off': 'выключен',
|
||
'dashboard.paused.title': 'Напоминания на паузе',
|
||
'dashboard.paused.hint': 'Возобнови, чтобы продолжить отсчёт',
|
||
'dashboard.empty.title': 'Программа пуста',
|
||
'dashboard.empty.hint': 'Добавь первое упражнение, чтобы начать',
|
||
|
||
// Exercises
|
||
'exercises.kicker': 'Программа',
|
||
'exercises.title': 'Упражнения',
|
||
'exercises.section.active': 'Активные · {n}',
|
||
'exercises.section.disabled': 'Выключенные · {n}',
|
||
'exercises.row.meta': '{reps} раз · {interval}',
|
||
'exercises.empty': 'Программа пуста — добавь первое упражнение',
|
||
|
||
// Exercise editor
|
||
'editor.exercise.title.new': 'Новое упражнение',
|
||
'editor.exercise.title.edit': 'Редактировать',
|
||
'editor.exercise.preview.placeholder': 'Без названия',
|
||
'editor.exercise.preview.meta': '{reps} раз · каждые {min} мин',
|
||
'editor.field.name': 'Название',
|
||
'editor.field.name.placeholder': 'Приседания',
|
||
'editor.field.reps': 'Повторений',
|
||
'editor.field.interval_min': 'Интервал (мин)',
|
||
'editor.field.icon': 'Иконка',
|
||
|
||
// Challenges
|
||
'challenges.kicker': 'Правила за матч',
|
||
'challenges.title': 'Челленджи',
|
||
'challenges.subtitle': 'Повторов = {formula}',
|
||
'challenges.subtitle.formula': 'статистика × коэффициент',
|
||
'challenges.warning.no_games':
|
||
'Челленджи срабатывают после матча. Подключи игру во вкладке «Игры».',
|
||
'challenges.section.all': 'Все · {n}',
|
||
'challenges.empty':
|
||
'Челленджей пока нет. Привяжи упражнение к статистике матча.',
|
||
|
||
// Challenge editor
|
||
'editor.challenge.title.new': 'Новый челлендж',
|
||
'editor.challenge.title.edit': 'Редактировать',
|
||
'editor.field.challenge_name': 'Название',
|
||
'editor.field.challenge_name.placeholder': 'За смерти — приседания',
|
||
'editor.field.game': 'Игра',
|
||
'editor.field.stat': 'Статистика',
|
||
'editor.field.multiplier': 'Коэффициент',
|
||
'editor.field.exercise_name': 'Упражнение',
|
||
'editor.field.exercise_name.placeholder': 'Приседания',
|
||
'editor.challenge.preview.kicker': 'Превью · 5 событий',
|
||
'editor.challenge.preview.fallback': 'повторов',
|
||
|
||
// Games
|
||
'games.kicker': 'Трекинг матчей',
|
||
'games.title': 'Игры',
|
||
'games.subtitle': 'Подключи игру — челленджи сработают сразу после матча',
|
||
'games.subtitle.live': '{n} live',
|
||
'games.section.supported': 'Поддерживаемые',
|
||
'games.scanning': 'Сканируем установленные игры…',
|
||
'games.queued.body':
|
||
'Steam запущен. Параметр {opt} пропишется автоматически при следующем закрытии Steam.',
|
||
'games.no_user.body':
|
||
'В Steam нет залогиненного аккаунта (нет папки userdata). Запусти Steam один раз и нажми «Установить интеграцию».',
|
||
'games.not_installed.hint': 'Установи игру в Steam и нажми «Обновить»',
|
||
'games.dev.toggle': 'dev · симулировать конец матча',
|
||
'games.badge.live': 'Live',
|
||
'games.badge.ready': 'Готово',
|
||
'games.badge.queued': 'В очереди',
|
||
'games.badge.installed': 'Установлена',
|
||
'games.badge.not_found': 'Не найдена',
|
||
|
||
// Settings
|
||
'settings.kicker': 'Конфигурация',
|
||
'settings.title': 'Настройки',
|
||
'settings.section.reminders': 'Напоминания',
|
||
'settings.section.quiet': 'Тихие часы',
|
||
'settings.section.window': 'Окно и трей',
|
||
'settings.section.appearance': 'Внешний вид',
|
||
'settings.section.language': 'Язык',
|
||
'settings.section.updates': 'Обновления',
|
||
'settings.section.data': 'Данные',
|
||
'settings.data.export.label': 'Экспортировать всё',
|
||
'settings.data.export.hint':
|
||
'Сохрани резервную копию упражнений, истории, челленджей и настроек в JSON-файл.',
|
||
'settings.data.export.btn': 'Сохранить',
|
||
'settings.data.export.ok': 'Сохранено в {path}',
|
||
'settings.data.export.err': 'Не удалось сохранить',
|
||
'settings.data.import.label': 'Восстановить из файла',
|
||
'settings.data.import.hint':
|
||
'Загрузить ранее сохранённую копию. Текущие данные будут перезаписаны.',
|
||
'settings.data.import.btn': 'Восстановить',
|
||
'settings.data.import.confirm':
|
||
'Все текущие упражнения, история и настройки будут заменены содержимым файла. Продолжить?',
|
||
'settings.data.import.ok': 'Восстановлено',
|
||
'settings.data.import.err': 'Файл не подошёл — это не наша резервная копия?',
|
||
'settings.notification_mode.label': 'Режим уведомления',
|
||
'settings.notification_mode.hint': 'Как должно выглядеть напоминание',
|
||
'settings.notification_mode.modal': 'Окно поверх всех',
|
||
'settings.notification_mode.toast': 'Системное уведомление',
|
||
'settings.notification_mode.both': 'Окно и уведомление',
|
||
'settings.sound.label': 'Звук уведомления',
|
||
'settings.sound.hint': 'Короткий сигнал при срабатывании',
|
||
'settings.voice.label': 'Голосовая подсказка',
|
||
'settings.voice.hint':
|
||
'Диктор произносит название упражнения и количество — полезно когда фокус на коде.',
|
||
'settings.snooze.label': '«Отложить» на',
|
||
'settings.snooze.hint': 'Сколько минут добавлять при отложении',
|
||
'settings.snooze.1': '1 минута',
|
||
'settings.snooze.5': '5 минут',
|
||
'settings.snooze.10': '10 минут',
|
||
'settings.snooze.15': '15 минут',
|
||
'settings.snooze.30': '30 минут',
|
||
'settings.quiet.enabled.label': 'Тихие часы',
|
||
'settings.quiet.enabled.hint': 'Не показывать напоминания в указанные часы',
|
||
'settings.quiet.times.label': 'С и до',
|
||
'settings.quiet.times.hint': 'Если до раньше — окно переходит через полночь',
|
||
'settings.quiet.days.label': 'Дни недели',
|
||
'settings.quiet.days.hint': 'Тихие часы действуют в выбранные дни',
|
||
'settings.tray.label': 'Сворачивать в трей',
|
||
'settings.tray.hint': 'При закрытии остаётся работать в фоне',
|
||
'settings.autostart.label': 'Запускать с Windows',
|
||
'settings.autostart.hint': 'Открывать при входе в систему',
|
||
'settings.start_minimized.label': 'Запускать свёрнутым',
|
||
'settings.start_minimized.hint': 'При автозапуске открывать сразу в трее',
|
||
'settings.theme.label': 'Тема',
|
||
'settings.theme.hint': 'Светлая / тёмная / как в системе',
|
||
'settings.theme.system': 'Как в системе',
|
||
'settings.theme.light': 'Светлая',
|
||
'settings.theme.dark': 'Тёмная',
|
||
'settings.language.label': 'Язык интерфейса',
|
||
'settings.language.hint': 'Применяется сразу',
|
||
'settings.language.ru': 'Русский',
|
||
'settings.language.en': 'English',
|
||
'settings.loading': 'Загрузка…',
|
||
|
||
// Updater
|
||
'updater.unsupported': 'Auto-update недоступен',
|
||
'updater.unsupported.reason_dev': 'Auto-update недоступен в dev-режиме',
|
||
'updater.checking': 'Проверяем обновления…',
|
||
'updater.up_to_date': 'Последняя версия',
|
||
'updater.up_to_date.subtitle': 'Текущая: v{v}',
|
||
'updater.up_to_date.subtitle_checked': 'Текущая: v{v} · проверено {when}',
|
||
'updater.last_checked': 'проверено {when}',
|
||
'updater.checked.just_now': 'только что',
|
||
'updater.checked.minutes_ago': '{n} мин назад',
|
||
'updater.checked.hours_ago': '{n} ч назад',
|
||
'updater.available.title': 'Доступна v{v}',
|
||
'updater.downloading.title': 'Загружаем обновление',
|
||
'updater.downloading.subtitle': '{got} / {total} МБ · {speed} МБ/с',
|
||
'updater.downloading.hint': 'Можно закрыть это окно — скачивание продолжится в фоне.',
|
||
'updater.downloaded.title': 'Готово · v{v}',
|
||
'updater.downloaded.subtitle': 'Нажми «Рестарт» — приложение моментально откроется в новой версии.',
|
||
'updater.error.title': 'Ошибка проверки',
|
||
'updater.idle.title': 'Проверить обновления',
|
||
'updater.idle.subtitle': 'Авто-проверка раз в час',
|
||
|
||
// Reminder window
|
||
'reminder.kicker': 'Время тренировки',
|
||
'reminder.subkicker': 'Двигайся',
|
||
'reminder.reps': 'раз',
|
||
'reminder.next_in': 'Следующее через {interval}',
|
||
'reminder.partial': 'Засчитаем {actual} из {planned}',
|
||
'reminder.aria.decrement': 'Уменьшить количество повторов',
|
||
'reminder.aria.increment': 'Увеличить количество повторов',
|
||
|
||
// Weekday short labels (Mon..Sun). Used by Settings days-of-week picker,
|
||
// HistoryHeatmap row axis, and Dashboard date headers. Index 0 = Sunday
|
||
// to match Date.getDay()'s convention so callers can use the value
|
||
// directly without re-mapping.
|
||
'weekday.short.0': 'Вс',
|
||
'weekday.short.1': 'Пн',
|
||
'weekday.short.2': 'Вт',
|
||
'weekday.short.3': 'Ср',
|
||
'weekday.short.4': 'Чт',
|
||
'weekday.short.5': 'Пт',
|
||
'weekday.short.6': 'Сб',
|
||
|
||
// History heatmap
|
||
'heatmap.title': 'Активность за 12 недель',
|
||
'heatmap.legend.less': 'Меньше',
|
||
'heatmap.legend.more': 'Больше',
|
||
'heatmap.tooltip.reps_one': '{n} повтор',
|
||
'heatmap.tooltip.reps_few': '{n} повтора',
|
||
'heatmap.tooltip.reps_many': '{n} повторов',
|
||
|
||
// Sidebar
|
||
'sidebar.aria.nav': 'Главная навигация',
|
||
'exercise.aria.toggle': 'Переключить упражнение «{name}»',
|
||
'reminder.btn.done': 'Готово',
|
||
'match.title.won': 'Победа',
|
||
'match.title.lost': 'Поражение',
|
||
'match.title.draw': 'Матч завершён',
|
||
'match.summary.minutes_count': '{n} мин',
|
||
'match.summary.challenges_one': '{n} челлендж',
|
||
'match.summary.challenges_few': '{n} челленджа',
|
||
'match.summary.challenges_many': '{n} челленджей',
|
||
'match.summary.all_done': 'всё готово',
|
||
'match.summary.remaining': '{n} осталось',
|
||
'match.total': 'Всего',
|
||
'match.total_reps_suffix': 'повторов',
|
||
|
||
// Format helpers
|
||
'fmt.now': 'сейчас',
|
||
'fmt.h': 'ч',
|
||
'fmt.m': 'мин',
|
||
'fmt.h_short': 'ч',
|
||
'fmt.m_short': 'м',
|
||
'fmt.s_short': 'с',
|
||
'fmt.paused': 'на паузе',
|
||
'fmt.through': 'Через'
|
||
}
|
||
|
||
export const en: Dict = {
|
||
// Sidebar / nav
|
||
'nav.today': 'Today',
|
||
'nav.exercises': 'Exercises',
|
||
'nav.games': 'Games',
|
||
'nav.challenges': 'Challenges',
|
||
'nav.settings': 'Settings',
|
||
'sidebar.slogan': 'Move with intention',
|
||
'sidebar.status_tracking': 'Activity tracking is on',
|
||
'titlebar.menu_aria': 'Menu',
|
||
'titlebar.minimize_aria': 'Minimize',
|
||
'titlebar.maximize_aria': 'Maximize',
|
||
'titlebar.restore_aria': 'Restore size',
|
||
'titlebar.tray_aria': 'To tray',
|
||
'titlebar.close_aria': 'Close',
|
||
'titlebar.app_title': 'Exercise Reminder',
|
||
|
||
// Common buttons
|
||
'btn.add': 'Add',
|
||
'btn.new': 'New',
|
||
'btn.cancel': 'Cancel',
|
||
'btn.save': 'Save',
|
||
'btn.done': 'Done',
|
||
'btn.start': 'Start',
|
||
'btn.pause': 'Pause',
|
||
'btn.refresh': 'Refresh',
|
||
'btn.edit': 'Edit',
|
||
'btn.delete': 'Delete',
|
||
'btn.snooze_min': 'Snooze {n}m',
|
||
'btn.skip': 'Skip',
|
||
'btn.close': 'Close',
|
||
'btn.later': 'Later',
|
||
'btn.connect': 'Connect',
|
||
'btn.disconnect': 'Disconnect',
|
||
'btn.check': 'Check',
|
||
'btn.download': 'Download',
|
||
'btn.restart': 'Restart',
|
||
'btn.retry': 'Retry',
|
||
|
||
// Dashboard
|
||
'dashboard.kicker': 'Daily training',
|
||
'dashboard.title': 'Today',
|
||
'dashboard.stat.active': 'Active',
|
||
'dashboard.stat.active.of': 'of {total}',
|
||
'dashboard.stat.today_done': 'Today',
|
||
'dashboard.stat.today_done.subtitle': 'reps logged',
|
||
'dashboard.stat.streak': 'Streak',
|
||
'dashboard.stat.streak.subtitle': '{n} days in a row',
|
||
'dashboard.stat.next': 'Next in',
|
||
'dashboard.stat.next.now': 'Now',
|
||
'dashboard.stat.next.subtitle_paused': 'paused',
|
||
'dashboard.stat.next.subtitle_running': 'counting down',
|
||
'dashboard.stat.tracking': 'Match tracking',
|
||
'dashboard.stat.tracking.on': 'On',
|
||
'dashboard.stat.tracking.off': 'Off',
|
||
'dashboard.stat.tracking.subtitle_on': 'real-time',
|
||
'dashboard.stat.tracking.subtitle_off': 'disabled',
|
||
'dashboard.paused.title': 'Reminders paused',
|
||
'dashboard.paused.hint': 'Resume to continue countdown',
|
||
'dashboard.empty.title': 'Program is empty',
|
||
'dashboard.empty.hint': 'Add your first exercise to start',
|
||
|
||
// Exercises
|
||
'exercises.kicker': 'Program',
|
||
'exercises.title': 'Exercises',
|
||
'exercises.section.active': 'Active · {n}',
|
||
'exercises.section.disabled': 'Disabled · {n}',
|
||
'exercises.row.meta': '{reps} reps · {interval}',
|
||
'exercises.empty': 'Program is empty — add your first exercise',
|
||
|
||
// Exercise editor
|
||
'editor.exercise.title.new': 'New exercise',
|
||
'editor.exercise.title.edit': 'Edit',
|
||
'editor.exercise.preview.placeholder': 'Untitled',
|
||
'editor.exercise.preview.meta': '{reps} reps · every {min} min',
|
||
'editor.field.name': 'Name',
|
||
'editor.field.name.placeholder': 'Squats',
|
||
'editor.field.reps': 'Reps',
|
||
'editor.field.interval_min': 'Interval (min)',
|
||
'editor.field.icon': 'Icon',
|
||
|
||
// Challenges
|
||
'challenges.kicker': 'Per-match rules',
|
||
'challenges.title': 'Challenges',
|
||
'challenges.subtitle': 'Reps = {formula}',
|
||
'challenges.subtitle.formula': 'stat × multiplier',
|
||
'challenges.warning.no_games':
|
||
'Challenges trigger after a match. Connect a game in the Games tab.',
|
||
'challenges.section.all': 'All · {n}',
|
||
'challenges.empty':
|
||
'No challenges yet. Tie an exercise to a match statistic.',
|
||
|
||
// Challenge editor
|
||
'editor.challenge.title.new': 'New challenge',
|
||
'editor.challenge.title.edit': 'Edit',
|
||
'editor.field.challenge_name': 'Name',
|
||
'editor.field.challenge_name.placeholder': 'Squats per death',
|
||
'editor.field.game': 'Game',
|
||
'editor.field.stat': 'Statistic',
|
||
'editor.field.multiplier': 'Multiplier',
|
||
'editor.field.exercise_name': 'Exercise',
|
||
'editor.field.exercise_name.placeholder': 'Squats',
|
||
'editor.challenge.preview.kicker': 'Preview · 5 events',
|
||
'editor.challenge.preview.fallback': 'reps',
|
||
|
||
// Games
|
||
'games.kicker': 'Match tracking',
|
||
'games.title': 'Games',
|
||
'games.subtitle': 'Connect a game — challenges fire right after the match',
|
||
'games.subtitle.live': '{n} live',
|
||
'games.section.supported': 'Supported',
|
||
'games.scanning': 'Scanning installed games…',
|
||
'games.queued.body':
|
||
'Steam is running. The {opt} option will be added automatically next time Steam closes.',
|
||
'games.no_user.body':
|
||
'No logged-in Steam account (no userdata folder). Launch Steam once, then click “Connect”.',
|
||
'games.not_installed.hint': 'Install the game in Steam and click Refresh',
|
||
'games.dev.toggle': 'dev · simulate match end',
|
||
'games.badge.live': 'Live',
|
||
'games.badge.ready': 'Ready',
|
||
'games.badge.queued': 'Queued',
|
||
'games.badge.installed': 'Installed',
|
||
'games.badge.not_found': 'Not found',
|
||
|
||
// Settings
|
||
'settings.kicker': 'Configuration',
|
||
'settings.title': 'Settings',
|
||
'settings.section.reminders': 'Reminders',
|
||
'settings.section.quiet': 'Quiet hours',
|
||
'settings.section.window': 'Window & tray',
|
||
'settings.section.appearance': 'Appearance',
|
||
'settings.section.language': 'Language',
|
||
'settings.section.updates': 'Updates',
|
||
'settings.section.data': 'Data',
|
||
'settings.data.export.label': 'Export everything',
|
||
'settings.data.export.hint':
|
||
'Save a backup of exercises, history, challenges and settings to a JSON file.',
|
||
'settings.data.export.btn': 'Save',
|
||
'settings.data.export.ok': 'Saved to {path}',
|
||
'settings.data.export.err': 'Could not save',
|
||
'settings.data.import.label': 'Restore from file',
|
||
'settings.data.import.hint':
|
||
'Load a previously saved backup. Current data will be overwritten.',
|
||
'settings.data.import.btn': 'Restore',
|
||
'settings.data.import.confirm':
|
||
'All current exercises, history and settings will be replaced with the file contents. Continue?',
|
||
'settings.data.import.ok': 'Restored',
|
||
'settings.data.import.err': "Couldn't read the file — not our backup?",
|
||
'settings.notification_mode.label': 'Notification mode',
|
||
'settings.notification_mode.hint': 'How a reminder appears',
|
||
'settings.notification_mode.modal': 'Window on top',
|
||
'settings.notification_mode.toast': 'System notification',
|
||
'settings.notification_mode.both': 'Window and notification',
|
||
'settings.sound.label': 'Notification sound',
|
||
'settings.sound.hint': 'Short beep on trigger',
|
||
'settings.voice.label': 'Voice prompt',
|
||
'settings.voice.hint':
|
||
'Speaks the exercise name and count — useful when your eyes are on the code.',
|
||
'settings.snooze.label': '“Snooze” for',
|
||
'settings.snooze.hint': 'How many minutes to postpone',
|
||
'settings.snooze.1': '1 minute',
|
||
'settings.snooze.5': '5 minutes',
|
||
'settings.snooze.10': '10 minutes',
|
||
'settings.snooze.15': '15 minutes',
|
||
'settings.snooze.30': '30 minutes',
|
||
'settings.quiet.enabled.label': 'Quiet hours',
|
||
'settings.quiet.enabled.hint': 'Suppress reminders during the chosen window',
|
||
'settings.quiet.times.label': 'From and to',
|
||
'settings.quiet.times.hint': 'If `to` is earlier, the window wraps midnight',
|
||
'settings.quiet.days.label': 'Days of week',
|
||
'settings.quiet.days.hint': 'Quiet hours apply on the selected days',
|
||
'settings.tray.label': 'Minimize to tray',
|
||
'settings.tray.hint': 'Keep running in background when closed',
|
||
'settings.autostart.label': 'Start with Windows',
|
||
'settings.autostart.hint': 'Open at system login',
|
||
'settings.start_minimized.label': 'Start minimized',
|
||
'settings.start_minimized.hint': 'On autostart open straight to tray',
|
||
'settings.theme.label': 'Theme',
|
||
'settings.theme.hint': 'Light / dark / follow system',
|
||
'settings.theme.system': 'System',
|
||
'settings.theme.light': 'Light',
|
||
'settings.theme.dark': 'Dark',
|
||
'settings.language.label': 'Interface language',
|
||
'settings.language.hint': 'Applied immediately',
|
||
'settings.language.ru': 'Русский',
|
||
'settings.language.en': 'English',
|
||
'settings.loading': 'Loading…',
|
||
|
||
// Updater
|
||
'updater.unsupported': 'Auto-update unavailable',
|
||
'updater.unsupported.reason_dev': 'Auto-update is disabled in dev mode',
|
||
'updater.checking': 'Checking for updates…',
|
||
'updater.up_to_date': 'Up to date',
|
||
'updater.up_to_date.subtitle': 'Current: v{v}',
|
||
'updater.up_to_date.subtitle_checked': 'Current: v{v} · checked {when}',
|
||
'updater.last_checked': 'checked {when}',
|
||
'updater.checked.just_now': 'just now',
|
||
'updater.checked.minutes_ago': '{n}m ago',
|
||
'updater.checked.hours_ago': '{n}h ago',
|
||
'updater.available.title': 'v{v} available',
|
||
'updater.downloading.title': 'Downloading update',
|
||
'updater.downloading.subtitle': '{got} / {total} MB · {speed} MB/s',
|
||
'updater.downloading.hint': 'You can close this window — download continues in the background.',
|
||
'updater.downloaded.title': 'Ready · v{v}',
|
||
'updater.downloaded.subtitle': 'Click Restart — the app will reopen instantly in the new version.',
|
||
'updater.error.title': 'Check failed',
|
||
'updater.idle.title': 'Check for updates',
|
||
'updater.idle.subtitle': 'Auto-check every hour',
|
||
|
||
// Reminder window
|
||
'reminder.kicker': 'Workout time',
|
||
'reminder.subkicker': 'Move',
|
||
'reminder.reps': 'reps',
|
||
'reminder.next_in': 'Next in {interval}',
|
||
'reminder.partial': "We'll log {actual} of {planned}",
|
||
'reminder.aria.decrement': 'Decrease rep count',
|
||
'reminder.aria.increment': 'Increase rep count',
|
||
|
||
// Weekday short labels (Mon..Sun). Index 0 = Sunday.
|
||
'weekday.short.0': 'Sun',
|
||
'weekday.short.1': 'Mon',
|
||
'weekday.short.2': 'Tue',
|
||
'weekday.short.3': 'Wed',
|
||
'weekday.short.4': 'Thu',
|
||
'weekday.short.5': 'Fri',
|
||
'weekday.short.6': 'Sat',
|
||
|
||
// History heatmap
|
||
'heatmap.title': 'Activity, last 12 weeks',
|
||
'heatmap.legend.less': 'Less',
|
||
'heatmap.legend.more': 'More',
|
||
'heatmap.tooltip.reps_one': '{n} rep',
|
||
'heatmap.tooltip.reps_many': '{n} reps',
|
||
|
||
// Sidebar
|
||
'sidebar.aria.nav': 'Main navigation',
|
||
'exercise.aria.toggle': 'Toggle exercise "{name}"',
|
||
'reminder.btn.done': 'Done',
|
||
'match.title.won': 'Victory',
|
||
'match.title.lost': 'Defeat',
|
||
'match.title.draw': 'Match finished',
|
||
'match.summary.minutes_count': '{n} min',
|
||
'match.summary.challenges_one': '{n} challenge',
|
||
'match.summary.challenges_few': '{n} challenges',
|
||
'match.summary.challenges_many': '{n} challenges',
|
||
'match.summary.all_done': 'all done',
|
||
'match.summary.remaining': '{n} left',
|
||
'match.total': 'Total',
|
||
'match.total_reps_suffix': 'reps',
|
||
|
||
// Format helpers
|
||
'fmt.now': 'now',
|
||
'fmt.h': 'h',
|
||
'fmt.m': 'min',
|
||
'fmt.h_short': 'h',
|
||
'fmt.m_short': 'm',
|
||
'fmt.s_short': 's',
|
||
'fmt.paused': 'paused',
|
||
'fmt.through': 'In'
|
||
}
|