open-notebook/frontend/src/lib/locales/ru-RU/index.ts
Luis Novo fb21f5e777
feat: add CI test workflow and improve i18n validation (#580)
- Add GitHub Actions workflow to run backend (pytest) and frontend
  (vitest) tests on PRs and pushes to main
- Replace hardcoded locale parity tests with dynamic discovery from
  the resources registry, so new languages are tested automatically
- Add unused key detection test that scans source files for i18n
  key references, with optional chaining normalization
- Remove 149 genuinely unused translation keys from all 7 locale files
- Add missing keys to it-IT (7) and ru-RU (5) with English fallback
2026-02-14 20:14:08 -03:00

916 lines
66 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

export const ruRU = {
common: {
search: "Поиск...",
create: "Создать",
new: "Новый",
cancel: "Отмена",
delete: "Удалить",
edit: "Редактировать",
theme: "Тема",
signOut: "Выйти",
noMatches: "Совпадений не найдено",
tryDifferentSearch: "Попробуйте другой поисковый запрос.",
light: "Светлая",
dark: "Тёмная",
system: "Системная",
loading: "Загрузка...",
note: "Заметка",
insight: "Инсайт",
newSource: "Новый источник",
newNotebook: "Новый блокнот",
newPodcast: "Новый подкаст",
language: "Язык",
english: "English",
chinese: "简体中文",
japanese: "日本語",
russian: "Русский",
source: "Источник",
notebook: "Блокнот",
podcast: "Подкаст",
quickActions: "Быстрые действия",
quickActionsDesc: "Навигация, поиск, запрос, тема",
appName: "Open Notebook",
add: "Добавить",
remove: "Удалить",
confirm: "Подтвердить",
warning: "Предупреждение",
error: "Ошибка",
success: "Успешно",
model: "Модель",
back: "Назад",
next: "Далее",
done: "Готово",
processing: "Обработка...",
creating: "Создание...",
linked: "Связано",
adding: "Добавление...",
addSelected: "Добавить выбранное",
customModel: "Своя модель",
failed: "не удалось",
current: "Текущий",
save: "Сохранить",
writeNote: "Написать заметку",
batchMode: "Пакетный режим",
optional: "Необязательно",
type: "Тип",
title: "Название",
created: "Создано {time}",
updated: "Обновлено {time}",
actions: "Действия",
noResults: "Нет результатов",
references: "Ссылки",
refreshPage: "Попробуйте обновить страницу",
refresh: "Обновить",
aiGenerated: "Сгенерировано ИИ",
human: "Человек",
unknown: "Неизвестно",
notes: "Заметки",
chat: "Чат",
deleteForever: "Удалить навсегда",
connectionError: "Ошибка подключения",
unableToConnect: "Не удаётся подключиться к API-серверу",
retryConnection: "Повторить подключение",
diagnosticInfo: "Диагностическая информация",
version: "Версия",
built: "Сборка",
apiUrl: "URL API",
frontendUrl: "URL фронтенда",
checkConsoleLogs: "Проверьте консоль браузера для подробных логов (ищите сообщения 🔧 [Config])",
yes: "Да",
no: "Нет",
saving: "Сохранение...",
description: "Описание",
saveToNote: "Сохранить в заметку",
copyToClipboard: "Копировать в буфер обмена",
close: "Закрыть",
insights: "Инсайты",
progress: "Прогресс",
deleting: "Удаление...",
created_label: "Создано",
updated_label: "Обновлено",
download: "Скачать",
saveChanges: "Сохранить изменения",
name: "Название",
default: "По умолчанию",
nameRequired: "Название обязательно",
modelConfiguration: "Настройка модели",
resetToDefault: "Сбросить по умолчанию",
reasoning: "Рассуждение",
searchTerms: "Поисковые запросы",
strategy: "Стратегия",
individualAnswers: "Отдельные ответы ({count})",
finalAnswer: "Итоговый ответ",
notebookLabel: "Блокнот: {name}",
itemNotFound: "Этот {type} не найден",
accessibility: {
transformationViews: "Представления трансформаций",
searchKB: "Спросить или найти в базе знаний",
enterQuestion: "Введите вопрос для базы знаний",
enterSearch: "Введите поисковый запрос",
searchKBBtn: "Поиск по базе знаний",
podcastViews: "Представления подкастов",
ytVideo: "Видео YouTube",
askResponse: "Ответ на запрос",
searchNotebooks: "Поиск блокнотов",
},
url: "URL",
errorDetails: "Детали ошибки",
editTransformation: "Редактировать трансформацию",
retry: "Повторить",
traditionalChinese: "繁體中文",
portuguese: "Português",
completed: "завершено",
saveSuccess: "Успешно сохранено",
contextModes: {
off: "Не включено в чат",
insights: "Только инсайты",
full: "Полное содержимое",
clickToCycle: "Нажмите для переключения",
},
clickToEdit: "Нажмите для редактирования",
},
apiErrors: {
notebookNotFound: "Блокнот не найден",
sourceNotFound: "Источник не найден",
transformationNotFound: "Трансформация не найдена",
fileUploadFailed: "Не удалось загрузить файл",
urlRequired: "URL обязателен для типа «ссылка»",
contentRequired: "Содержимое обязательно для типа «текст»",
invalidSourceType: "Недопустимый тип источника",
processingFailed: "Обработка не удалась",
failedToQueue: "Не удалось поставить в очередь обработки",
invalidSortBy: "Поле сортировки должно быть 'created' или 'updated'",
invalidSortOrder: "Порядок сортировки должен быть 'asc' или 'desc'",
accessDenied: "Доступ к файлу запрещён",
fileNotFoundOnServer: "Файл не найден на сервере",
searchFailed: "Поиск не удался",
askFailed: "Запрос не удался",
pleaseEnterQuestion: "Пожалуйста, введите вопрос",
pleaseConfigureModels: "Пожалуйста, настройте все необходимые модели",
failedToCreateSession: "Не удалось создать сессию",
failedToUpdateSession: "Не удалось обновить сессию",
failedToDeleteSession: "Не удалось удалить сессию",
failedToSendMessage: "Не удалось отправить сообщение",
unauthorized: "Неавторизованный доступ, проверьте пароль",
invalidPassword: "Неверный пароль",
embeddingModelRequired: "Для этой функции требуется модель эмбеддингов. Настройте её в разделе «Модели».",
strategyModelNotFound: "Модель стратегии не найдена",
answerModelNotFound: "Модель ответов не найдена",
finalAnswerModelNotFound: "Модель итогового ответа не найдена",
noAnswerGenerated: "Не удалось сгенерировать ответ",
genericError: "Произошла непредвиденная ошибка",
},
connectionErrors: {
apiTitle: "Не удаётся подключиться к API-серверу",
apiDesc: "API-сервер Open Notebook недоступен",
dbTitle: "Ошибка подключения к базе данных",
dbDesc: "API-сервер работает, но база данных недоступна",
troubleshooting: "Обычно это означает:",
apiUnreachable1: "API-сервер не запущен",
apiUnreachable2: "API-сервер работает по другому адресу",
apiUnreachable3: "Проблемы с сетевым подключением",
dbFailed1: "SurrealDB не запущен",
dbFailed2: "Неверные настройки подключения к базе данных",
dbFailed3: "Сетевые проблемы между API и базой данных",
quickFixes: "Быстрые решения:",
setApiUrl: "Установите переменную окружения API_URL:",
checkSurreal: "Проверьте, запущен ли SurrealDB:",
seeDocumentation: "Подробные инструкции по настройке см. в:",
docLink: "Документация Open Notebook",
showTechnical: "Показать техническую информацию",
attemptedUrl: "Использованный URL",
message: "Сообщение",
technicalDetails: "Технические детали",
stackTrace: "Стек вызовов",
retryLabel: "Повторить подключение",
retryHint: "Нажмите R или кнопку для повторной попытки",
dockerLabel: "Для Docker",
localDevLabel: "Для локальной разработки",
},
auth: {
loginTitle: "Open Notebook",
loginDesc: "Введите пароль для доступа к приложению",
passwordPlaceholder: "Пароль",
signingIn: "Вход...",
signIn: "Войти",
connectErrorHint: "Не удаётся подключиться к серверу. Проверьте, запущен ли API.",
},
navigation: {
collect: "Собрать",
process: "Обработать",
create: "Создать",
manage: "Управление",
sources: "Источники",
notebooks: "Блокноты",
askAndSearch: "Запрос и поиск",
podcasts: "Подкасты",
models: "Модели",
transformations: "Трансформации",
transformation: "Трансформация",
settings: "Настройки",
advanced: "Дополнительно",
nav: "Навигация",
language: "Переключить язык",
theme: "Тема",
ask: "Запрос",
},
notebooks: {
title: "Блокноты",
newNotebook: "Новый блокнот",
searchPlaceholder: "Поиск блокнотов...",
archived: "Архивные",
archive: "Архивировать",
unarchive: "Разархивировать",
deleteNotebook: "Удалить блокнот",
deleteNotebookDesc: "Вы уверены, что хотите удалить «{name}»? Это действие нельзя отменить.",
deleteNotebookLoading: "Загрузка предварительного просмотра удаления...",
deleteNotebookNotes: "Будет удалено заметок: {count}.",
deleteNotebookNoNotes: "Нет заметок для удаления.",
deleteNotebookExclusiveSources: "Источников только в этом блокноте: {count}.",
deleteNotebookSharedSources: "Источников, связанных с другими блокнотами (будут отвязаны): {count}.",
deleteNotebookNoSources: "В этом блокноте нет источников.",
deleteExclusiveSourcesLabel: "Удалить эксклюзивные источники",
keepExclusiveSourcesLabel: "Отвязать и сохранить",
activeNotebooks: "Активные блокноты",
archivedNotebooks: "Архивные блокноты",
notFound: "Блокнот не найден",
notFoundDesc: "Запрошенный блокнот не существует.",
updated: "Обновлено",
namePlaceholder: "Название блокнота",
addDescription: "Добавить описание...",
noNotesYet: "Пока нет заметок",
deleteNote: "Удалить заметку",
deleteNoteConfirm: "Вы уверены, что хотите удалить эту заметку? Это действие нельзя отменить.",
noteCreatedSuccess: "Заметка успешно создана",
failedToCreateNote: "Не удалось создать заметку",
noteUpdatedSuccess: "Заметка успешно обновлена",
failedToUpdateNote: "Не удалось обновить заметку",
noteDeletedSuccess: "Заметка успешно удалена",
failedToDeleteNote: "Не удалось удалить заметку",
createNew: "Создать новый блокнот",
createNewDesc: "Введите название и необязательное описание для начала.",
descPlaceholder: "Добавьте дополнительную информацию о блокноте...",
createSuccess: "Блокнот успешно создан",
updateSuccess: "Блокнот успешно обновлён",
deleteSuccess: "Блокнот успешно удалён",
},
sources: {
title: "Источники",
add: "Добавить источник",
addNew: "Добавить новый источник",
addExisting: "Добавить существующий источник",
delete: "Удалить источник",
statusPreparing: "Подготовка",
statusQueued: "В очереди",
statusProcessing: "Обработка",
statusCompleted: "Завершено",
statusFailed: "Ошибка",
statusPreparingDesc: "Подготовка к обработке",
statusQueuedDesc: "Ожидание обработки",
statusProcessingDesc: "Выполняется обработка",
statusCompletedDesc: "Успешно обработано",
statusFailedDesc: "Обработка не удалась",
failedToLoad: "Не удалось загрузить источники",
allSourcesDesc: "Просмотр всех источников. Вы можете добавлять новые или управлять существующими.",
allSources: "Все источники",
insights: "Инсайты",
yes: "Да",
no: "Нет",
loadingMore: "Загрузка...",
noSourcesYet: "Пока нет источников",
allSourcesDescShort: "Просмотр всех ваших источников.",
cannotSaveNoteNoNotebook: "Невозможно сохранить заметку: ID блокнота недоступен",
createFirstSource: "Добавьте первый источник, чтобы начать создание базы знаний.",
deleteSourceConfirm: "Вы уверены, что хотите удалить этот источник?",
deleteConfirm: "Вы уверены, что хотите удалить это?",
deleteConfirmWithTitle: "Вы уверены, что хотите удалить «{title}»?",
deleteSuccess: "Источник успешно удалён. Примечание: Чтобы удалить файл из хранилища, необходимо включить опцию «Удалить файл» в настройках.",
failedToDelete: "Не удалось удалить источник",
sourceQueued: "Источник в очереди",
sourceQueuedDesc: "Источник отправлен на фоновую обработку. Отслеживайте прогресс в списке источников.",
sourceAddedSuccess: "Источник успешно добавлен",
failedToAddSource: "Не удалось добавить источник",
sourceUpdatedSuccess: "Источник успешно обновлён",
failedToUpdateSource: "Не удалось обновить источник",
sourceDeletedSuccess: "Источник успешно удалён",
failedToDeleteSource: "Не удалось удалить источник",
fileUploadedSuccess: "Файл успешно загружен",
failedToUploadFile: "Не удалось загрузить файл",
sourceRequeued: "Повторная обработка в очереди",
sourceRequeuedDesc: "Источник поставлен в очередь на повторную обработку.",
failedToRetry: "Повтор не удался",
sourcesAddedToNotebook: "Добавлено источников в блокнот: {count}",
failedToAddSourcesToNotebook: "Не удалось добавить источники в блокнот",
partialAddSuccess: "Добавлено: {success}, не удалось: {failed}",
sourceRemovedFromNotebook: "Источник успешно удалён из блокнота",
failedToRemoveSourceFromNotebook: "Не удалось удалить источник из блокнота",
removeConfirm: "Вы уверены, что хотите удалить это из блокнота?",
checking: "Проверка...",
untitledSource: "Без названия",
maxItems: "макс. {count}",
insightsCount: "Инсайтов: {count}",
details: "Детали",
detailsTitle: "Детали источника",
content: "Содержимое",
metadata: "Метаданные",
type: {
link: "Ссылка",
file: "Файл",
text: "Текст",
},
id: "ID источника",
topics: "Темы",
embedded: "С эмбеддингом",
notEmbedded: "Без эмбеддинга",
embedContent: "Создать эмбеддинг",
embedding: "Создание эмбеддинга...",
alreadyEmbedded: "Эмбеддинг уже создан",
downloadFile: "Скачать файл",
fileUnavailable: "Файл недоступен",
preparing: "Подготовка...",
generateNewInsight: "Сгенерировать новый инсайт",
selectTransformation: "Выберите трансформацию...",
noInsightsYet: "Пока нет инсайтов",
createFirstInsight: "Создайте первый инсайт с помощью трансформации выше",
viewInsight: "Просмотреть инсайт",
deleteInsight: "Удалить инсайт",
deleteInsightConfirm: "Вы уверены, что хотите удалить этот инсайт? Это действие нельзя отменить.",
insightGenerationStarted: "Генерация инсайта запущена. Скоро он появится.",
editNote: "Редактировать заметку",
createNote: "Создать заметку",
addTitle: "Добавьте название...",
untitledNote: "Без названия",
writeNotePlaceholder: "Напишите содержимое заметки здесь...",
saveNote: "Сохранить заметку",
createNoteBtn: "Создать заметку",
createFirstNote: "Создайте первую заметку для записи идей и наблюдений.",
urlLabel: "URL(ы) *",
fileLabel: "Файл(ы) *",
textContentLabel: "Текстовое содержимое *",
enterUrlsPlaceholder: "Введите URL-адреса, по одному на строку\nhttps://example.com/article1\nhttps://example.com/article2",
batchUrlHint: "Вставьте несколько URL (по одному на строку) для пакетного импорта",
invalidUrlsDetected: "Обнаружены недопустимые URL:",
lineLabel: "Строка {line}",
fixInvalidUrls: "Исправьте или удалите недопустимые URL для продолжения",
selectMultipleFilesHint: "Выберите несколько файлов для пакетного импорта. Поддерживаются: Документы (PDF, DOC, DOCX, PPT, XLS, EPUB, TXT, MD), Медиа (MP4, MP3, WAV, M4A), Изображения (JPG, PNG), Архивы (ZIP)",
selectedFiles: "Выбранные файлы:",
textPlaceholder: "Вставьте или введите содержимое здесь...",
htmlDetected: "Обнаружено HTML-содержимое. После обработки оно будет преобразовано в Markdown.",
titlePlaceholder: "Дайте источнику понятное название",
batchTitlesAuto: "Названия будут автоматически сгенерированы для каждого источника.",
batchCommonSettings: "Одинаковые блокноты и трансформации будут применены ко всем элементам.",
urlsCount: "URL: {count}",
filesCount: "Файлов: {count}",
addSource: "Добавить источник",
notEmbeddedAlert: "Содержимое без эмбеддинга",
notEmbeddedDesc: "Для этого содержимого не создан эмбеддинг для векторного поиска. Эмбеддинг обеспечивает расширенные возможности поиска и лучшее обнаружение контента.",
openOnYoutube: "Открыть на YouTube",
urlCopied: "URL скопирован в буфер обмена",
viewSource: "Просмотреть источник",
noInsightSelected: "Инсайт не выбран",
sourceInsight: "Инсайт источника",
manageNotebooks: "Управление блокнотами",
manageNotebooksDesc: "Управление блокнотами, содержащими этот источник",
noNotebooksAvailable: "Нет доступных блокнотов",
loadFailed: "Не удалось загрузить детали источника",
removeFromNotebook: "Удалить из блокнота",
retryProcessing: "Повторить обработку",
deleteSource: "Удалить источник",
retry: "Повторить",
addExistingTitle: "Добавить существующие источники",
addExistingDesc: "Выберите существующие источники из всех блокнотов для добавления в текущий.",
searchPlaceholder: "Поиск источников по названию или URL...",
noNotebooksFound: "Блокноты не найдены.",
showingFirst100: "Показаны первые 100 источников. Используйте поиск для конкретных результатов.",
selectedCount: "Выбрано источников: {count}",
added: "Добавлено {date}",
addUrl: "Добавить URL",
uploadFile: "Загрузить файл",
enterText: "Ввести текст",
processDescription: "Содержимое будет обработано и проанализировано ИИ.",
processingFiles: "Обработка файлов...",
titleRequired: "Для текстового содержимого требуется название",
titleGenerated: "Если оставить пустым, название будет сгенерировано из содержимого",
batchCount: "{count} {type} будет обработано",
enableEmbedding: "Включить эмбеддинг для поиска",
embeddingDesc: "Позволяет находить этот источник в векторном поиске и запросах ИИ",
embeddingAlways: "Эмбеддинг включён автоматически",
embeddingAlwaysDesc: "В ваших настройках включено автоматическое создание эмбеддинга для векторного поиска.",
embeddingNever: "Эмбеддинг отключён",
embeddingNeverDesc: "В ваших настройках отключено создание эмбеддинга. Векторный поиск будет недоступен для этого источника.",
changeInSettings: "Вы можете изменить это в Настройках",
notFound: "Источник не найден",
noContent: "Содержимое недоступно",
insightsDesc: "Инсайты, сгенерированные анализом модели",
uploadedFile: "Загруженный файл",
fileUnavailableDesc: "Этот файл временно недоступен из-за проблем с хранилищем.",
batchSuccess: "Успешно создано источников: {count}",
batchFailed: "Не удалось создать все источники: {count}",
batchPartial: "Успешно: {success}, не удалось: {failed}",
submittingSource: "Отправка источника на обработку...",
processingBatchSources: "Обработка источников: {count}. Это может занять некоторое время.",
processingSource: "Источник обрабатывается. Это может занять некоторое время.",
maxFilesAllowed: "Максимальное количество файлов в пакете: {count}",
},
chat: {
sessions: "Сессии",
sessionTitlePlaceholder: "Введите название...",
noSessions: "Пока нет сессий чата",
deleteSession: "Удалить сессию",
deleteSessionDesc: "Вы уверены, что хотите удалить эту сессию чата? Это действие нельзя отменить.",
sendPlaceholder: "Задайте вопрос о ваших источниках...",
sessionsTitle: "Сессии чата",
chatWith: "Чат с {name}",
startConversation: "Начните разговор об этом {type}",
askQuestions: "Задавайте вопросы, чтобы лучше понять содержимое",
pressToSend: "Нажмите {key} для отправки",
model: "Модель",
createToStart: "Создайте сессию для начала.",
chatWithNotebook: "Чат с блокнотом",
unableToLoadChat: "Не удалось загрузить чат",
noDescription: "Без описания",
startByCreating: "Начните с создания первого блокнота для организации исследований.",
messagesCount: "Сообщений: {count}",
sessionCreated: "Сессия чата создана",
sessionUpdated: "Сессия обновлена",
sessionDeleted: "Сессия удалена",
},
searchPage: {
askAndSearch: "Запрос и поиск",
chooseAMode: "Выберите режим",
askBeta: "Запрос (бета)",
search: "Поиск",
askYourKb: "Спросите базу знаний (бета)",
askYourKbDesc: "LLM ответит на ваш запрос на основе документов в базе знаний.",
question: "Вопрос",
enterQuestionPlaceholder: "Введите ваш вопрос...",
pressToSubmit: "Нажмите Cmd/Ctrl+Enter для отправки",
noEmbeddingModel: "Вы не можете использовать эту функцию, потому что не выбрана модель эмбеддинга. Настройте её на странице «Модели».",
usingCustomModels: "Используются пользовательские модели",
usingDefaultModels: "Используются модели по умолчанию",
advanced: "Расширенные",
strategy: "Стратегия",
answer: "Ответ",
final: "Итоговый",
ask: "Спросить",
processing: "Обработка...",
saveToNotebooks: "Сохранить в блокноты",
searchDesc: "Поиск в базе знаний по ключевым словам или концепциям",
enterSearchPlaceholder: "Введите поисковый запрос...",
pressToSearch: "Нажмите Enter для поиска",
searchType: "Тип поиска",
vectorSearchWarning: "Векторный поиск требует модель эмбеддинга. Доступен только текстовый поиск.",
textSearch: "Текстовый поиск",
vectorSearch: "Векторный поиск",
searchIn: "Искать в",
searchSources: "Искать в источниках",
searchNotes: "Искать в заметках",
resultsFound: "Найдено результатов: {count}",
matches: "Совпадения ({count})",
noResultsFor: "Нет результатов для «{query}»",
notSet: "Не задано",
saveToNotebook: "Сохранить в блокнот",
saveSuccess: "Успешно сохранено в блокнот",
saveError: "Не удалось сохранить в блокнот",
selectNotebook: "Выберите блокнот",
searchAndAsk: "Поиск и запрос",
searchResultsFor: "Результаты поиска для «{query}»",
askAbout: "Спросить о «{query}»",
orSearchKb: "Или выполнить поиск по базе знаний",
saving: "Сохранение...",
advancedModelTitle: "Расширенный выбор моделей",
advancedModelDesc: "Выберите конкретные модели для каждого этапа процесса запроса",
strategyModel: "Модель стратегии",
answerModel: "Модель ответа",
finalAnswerModel: "Модель итогового ответа",
selectStrategyPlaceholder: "Выберите модель стратегии",
selectAnswerPlaceholder: "Выберите модель ответа",
selectFinalPlaceholder: "Выберите модель итогового ответа",
saveChanges: "Сохранить изменения",
processingQuestion: "Обработка вашего вопроса...",
},
podcasts: {
generateEpisode: "Сгенерировать эпизод подкаста",
generateEpisodeDesc: "Выберите контент для включения и настройте параметры эпизода перед генерацией.",
content: "Контент",
contentDesc: "Выберите блокноты, источники и заметки для этого эпизода.",
itemsSelected: "Выбрано элементов: {count}",
tokens: "Токенов: {count}",
chars: "Символов: {count}",
loadingNotebooks: "Загрузка блокнотов...",
noNotebooksFoundInPodcasts: "Блокноты не найдены. Создайте блокнот и добавьте контент перед генерацией подкаста.",
noContentSelected: "Контент не выбран",
summary: "Краткое содержание",
fullContent: "Полное содержимое",
untitledSource: "Без названия",
untitledNote: "Без названия",
episodeSettings: "Настройки эпизода",
episodeProfile: "Профиль эпизода",
episodeProfilePlaceholder: "Выберите профиль эпизода",
episodeName: "Название эпизода",
episodeNamePlaceholder: "напр., ИИ и будущее работы",
additionalInstructions: "Дополнительные инструкции",
instructionsPlaceholder: "Любые дополнительные указания для брифинга эпизода...",
generating: "Генерация...",
generate: "Сгенерировать",
hostPlaceholder: "Ведущий {number}",
profileRequired: "Требуется профиль эпизода",
profileRequiredDesc: "Выберите профиль эпизода перед генерацией подкаста.",
nameRequired: "Требуется название эпизода",
nameRequiredDesc: "Укажите название эпизода.",
addContext: "Добавить контекст",
addContextDesc: "Выберите хотя бы один источник или заметку для включения в эпизод.",
generationFailed: "Генерация подкаста не удалась",
speakerProfile: "Профиль говорящего",
usesSpeakerProfile: "Использует профиль говорящего",
sources: "Источники",
notes: "Заметки",
noSources: "В этом блокноте нет доступных источников.",
noNotes: "В этом блокноте нет доступных заметок.",
selectMode: "Выберите режим",
buildContextFailed: "Не удалось построить контекст. Проверьте выбранные элементы.",
podcastTaskStarted: "Задача подкаста запущена",
loadingProfiles: "Загрузка профилей эпизодов...",
noProfilesFound: "Профили эпизодов не найдены. Создайте профиль перед генерацией подкаста.",
listTitle: "Подкасты",
listDesc: "Отслеживайте сгенерированные эпизоды и управляйте шаблонами.",
chooseAView: "Выберите представление",
episodesTab: "Эпизоды",
templatesTab: "Шаблоны",
overviewTitle: "Обзор эпизодов",
overviewDesc: "Отслеживайте задачи генерации подкастов и просматривайте готовые материалы.",
generateBtn: "Сгенерировать подкаст",
total: "Всего",
processingLabel: "В обработке",
completedLabel: "Завершено",
failedLabel: "Ошибка",
pendingLabel: "Ожидание",
loadErrorTitle: "Не удалось загрузить эпизоды",
loadErrorDesc: "Не удалось получить последние эпизоды подкастов. Попробуйте позже.",
loadingEpisodes: "Загрузка эпизодов…",
noEpisodesYet: "Пока нет эпизодов подкастов. Сгенерируйте первый из интерфейса чата блокнота или источника.",
statusRunningTitle: "В процессе",
statusRunningDesc: "Эпизоды, для которых активно генерируются материалы.",
statusPendingTitle: "В очереди / Ожидание",
statusPendingDesc: "Отправленные эпизоды, ожидающие начала обработки.",
statusCompletedTitle: "Завершённые эпизоды",
statusCompletedDesc: "Готовы к просмотру, загрузке или публикации.",
statusFailedTitle: "Неудачные эпизоды",
statusFailedDesc: "Эпизоды с ошибками во время генерации.",
templatesWorkspaceTitle: "Рабочее пространство шаблонов",
templatesWorkspaceDesc: "Создавайте переиспользуемые конфигурации эпизодов и говорящих для быстрого производства подкастов.",
howTemplatesPowerTitle: "Как шаблоны ускоряют генерацию подкастов",
howTemplatesPowerDesc: "Шаблоны разделяют процесс на два переиспользуемых компонента. Комбинируйте их при генерации нового эпизода.",
episodeProfilesSetFormat: "Профили эпизодов задают формат",
episodeProfilesList1: "Определяют количество сегментов и структуру повествования",
episodeProfilesList2: "Выбирают языковые модели для брифинга, планирования и написания сценария",
episodeProfilesList3: "Хранят стандартные брифинги для единообразного стиля эпизодов",
speakerProfilesBringVoices: "Профили говорящих оживляют голоса",
speakerProfilesList1: "Выбирают провайдера и модель озвучивания",
speakerProfilesList2: "Фиксируют личность, биографию и заметки о произношении для каждого говорящего",
speakerProfilesList3: "Переиспользуют одни и те же голоса ведущих или гостей в разных форматах эпизодов",
recommendedWorkflow: "Рекомендуемый рабочий процесс",
workflowStep1: "Создайте профили говорящих для каждого нужного голоса",
workflowStep2: "Создайте профили эпизодов со ссылками на говорящих по имени",
workflowStep3: "Генерируйте подкасты, выбирая подходящий профиль эпизода",
workflowHint: "Профили эпизодов ссылаются на профили говорящих по имени, поэтому начинайте с говорящих, чтобы избежать пропущенных назначений голосов.",
failedToLoadTemplates: "Не удалось загрузить данные шаблонов",
failedToLoadTemplatesDesc: "Убедитесь, что API работает, и попробуйте снова. Некоторые разделы могут быть неполными.",
loadingTemplates: "Загрузка шаблонов…",
speakerProfilesTitle: "Профили говорящих",
speakerProfilesDesc: "Настройте голоса и личности для генерируемых эпизодов.",
createSpeaker: "Создать говорящего",
noSpeakerProfiles: "Пока нет профилей говорящих. Создайте один, чтобы шаблоны эпизодов стали доступны.",
noDescription: "Описание не указано.",
usedByCount_one: "Используется в 1 эпизоде",
usedByCount_other: "Используется в {count} эпизодах",
usedByCount: "Используется в {count} эпизодах",
unused: "Не используется",
voiceId: "ID голоса",
backstory: "Биография",
personality: "Личность",
edit: "Редактировать",
duplicate: "Дублировать",
deleteSpeakerProfileTitle: "Удалить профиль говорящего?",
deleteSpeakerProfileDesc: "Удаление «{name}» нельзя отменить.",
deleteSpeakerDisabledHint: "Сначала удалите этого говорящего из профилей эпизодов.",
deleting: "Удаление…",
episodeProfilesTitle: "Профили эпизодов",
episodeProfilesDesc: "Определите переиспользуемые настройки генерации для ваших шоу.",
createProfile: "Создать профиль",
createSpeakerFirst: "Сначала создайте профиль говорящего перед добавлением профиля эпизода.",
noEpisodeProfiles: "Пока нет профилей эпизодов. Создайте один для запуска генерации подкастов.",
speakerCreated: "Говорящий создан",
speakerCreatedDesc: "Говорящий «{name}» успешно добавлен.",
failedToCreateSpeaker: "Не удалось создать профиль говорящего",
speakerUpdated: "Говорящий обновлён",
speakerUpdatedDesc: "Говорящий «{name}» успешно обновлён.",
failedToUpdateSpeaker: "Не удалось обновить профиль говорящего",
speakerDeleted: "Говорящий удалён",
speakerDeletedDesc: "Говорящий «{name}» успешно удалён.",
failedToDeleteSpeaker: "Не удалось удалить профиль говорящего",
speakerDuplicated: "Говорящий дублирован",
speakerDuplicatedDesc: "Говорящий «{name}» успешно дублирован.",
failedToDuplicateSpeaker: "Не удалось дублировать профиль говорящего",
generationStarted: "Генерация запущена",
generationStartedDesc: "Генерация подкаста поставлена в очередь.",
failedToStartGeneration: "Не удалось запустить генерацию",
tryAgainMoment: "Попробуйте ещё раз через некоторое время.",
deleteProfileTitle: "Удалить профиль?",
deleteProfileDesc: "Это удалит «{name}». Существующие эпизоды сохранят свои данные, но новые больше не смогут использовать эту конфигурацию.",
profileCreated: "Профиль создан",
profileCreatedDesc: "Профиль эпизода «{name}» успешно создан.",
failedToCreateProfile: "Не удалось создать профиль",
profileUpdated: "Профиль обновлён",
profileUpdatedDesc: "Профиль эпизода «{name}» успешно обновлён.",
failedToUpdateProfile: "Не удалось обновить профиль",
profileDeleted: "Профиль удалён",
profileDeletedDesc: "Профиль эпизода «{name}» успешно удалён.",
failedToDeleteProfile: "Не удалось удалить профиль",
failedToDeleteProfileDesc: "Не удалось удалить профиль эпизода.",
profileDuplicated: "Профиль дублирован",
profileDuplicatedDesc: "Профиль эпизода «{name}» успешно дублирован.",
failedToDuplicateProfile: "Не удалось дублировать профиль",
episodeDeleted: "Эпизод удалён",
episodeDeletedDesc: "Эпизод успешно удалён.",
failedToDeleteEpisode: "Не удалось удалить эпизод",
failedToDeleteSpeakerDesc: "Не удалось удалить профиль говорящего.",
outlineModel: "Модель плана",
transcriptModel: "Модель транскрипта",
segments: "Сегменты",
defaultBriefingTitle: "Брифинг по умолчанию",
created: "Создано {time}",
details: "Детали",
summaryTab: "Краткое",
outlineTab: "План",
transcriptTab: "Транскрипт",
briefing: "Брифинг",
noOutline: "План недоступен.",
noTranscript: "Транскрипт недоступен.",
deleteEpisodeTitle: "Удалить эпизод?",
deleteEpisodeDesc: "Это навсегда удалит «{name}» и его аудиофайл.",
audioUnavailable: "Аудио недоступно",
segment: "Сегмент",
speaker: "Говорящий",
profile: "Профиль",
link: "Ссылка",
file: "Файл",
embedded: "С эмбеддингом",
notEmbedded: "Без эмбеддинга",
noSpeakerProfilesAvailable: "Нет доступных профилей говорящих",
noLanguageModelsAvailable: "Нет доступных языковых моделей",
editEpisodeProfile: "Редактировать профиль эпизода",
createEpisodeProfile: "Создать профиль эпизода",
episodeProfileFormDesc: "Определите, как должны генерироваться эпизоды и какую конфигурацию говорящих использовать по умолчанию.",
noSpeakerProfilesDesc: "Создайте профиль говорящего перед настройкой профиля эпизода.",
noLanguageModelsDesc: "Добавьте языковые модели в разделе «Модели» для настройки генерации плана и транскрипта.",
profileName: "Название профиля",
profileNamePlaceholder: "напр., Техническая дискуссия",
descriptionPlaceholder: "Краткое описание, когда использовать этот профиль",
speakerConfig: "Конфигурация говорящих",
selectSpeakerProfile: "Выберите профиль говорящего",
outlineGeneration: "Генерация плана",
transcriptGeneration: "Генерация транскрипта",
defaultBriefingPlaceholder: "Опишите структуру, тон и цели для этого формата эпизода",
editSpeakerProfile: "Редактировать профиль говорящего",
createSpeakerProfile: "Создать профиль говорящего",
speakerProfileFormDesc: "Настройте параметры озвучивания и определите до четырёх говорящих.",
noTtsModelsAvailable: "Нет доступных моделей озвучивания",
noTtsModelsDesc: "Добавьте TTS-модели в разделе «Модели» перед созданием профиля говорящего.",
speakers: "Говорящие",
speakersDesc: "Настройте от одного до четырёх голосов для этого профиля.",
addSpeaker: "Добавить говорящего",
speakerNumber: "Говорящий {number}",
backstoryPlaceholder: "Краткая биография или контекст для говорящего",
personalityPlaceholder: "Опишите стиль и тон",
outlineProviderRequired: "Требуется провайдер плана",
outlineModelRequired: "Требуется модель плана",
transcriptProviderRequired: "Требуется провайдер транскрипта",
transcriptModelRequired: "Требуется модель транскрипта",
defaultBriefingRequired: "Требуется брифинг по умолчанию",
segmentsInteger: "Должно быть целым числом",
segmentsMin: "Минимум 3 сегмента",
segmentsMax: "Максимум 20 сегментов",
voiceIdRequired: "Требуется ID голоса",
backstoryRequired: "Требуется биография",
personalityRequired: "Требуется описание личности",
speakerCountMin: "Требуется минимум один говорящий",
speakerCountMax: "Можно настроить до 4 говорящих",
delete: "Удалить",
failedToDelete: "Не удалось удалить подкаст",
},
settings: {
contentProcessing: "Обработка контента",
contentProcessingDesc: "Настройте обработку документов и URL",
docEngine: "Движок обработки документов",
docEnginePlaceholder: "Выберите движок обработки документов",
urlEngine: "Движок обработки URL",
urlEnginePlaceholder: "Выберите движок обработки URL",
autoRecommended: "Авто (рекомендуется)",
simple: "Простой",
docling: "Docling",
helpMeChoose: "Помогите выбрать",
docHelp: "· Docling немного медленнее, но точнее, особенно для документов с таблицами и изображениями. · Simple извлекает содержимое без форматирования. · Авто (рекомендуется) попробует Docling и переключится на Simple при необходимости.",
firecrawl: "Firecrawl",
jina: "Jina",
urlHelp: "· Firecrawl — платный сервис (есть бесплатный уровень), очень мощный. · Jina тоже хороший вариант с бесплатным уровнем. · Simple использует базовое HTTP-извлечение и пропустит контент на JavaScript-сайтах. · Авто (рекомендуется) попробует Firecrawl, затем Jina, затем Simple.",
embeddingAndSearch: "Эмбеддинг и поиск",
embeddingAndSearchDesc: "Настройте параметры поиска и эмбеддинга",
defaultEmbeddingOption: "Опция эмбеддинга по умолчанию",
embeddingOptionPlaceholder: "Выберите опцию эмбеддинга",
ask: "Спрашивать",
always: "Всегда",
never: "Никогда",
embeddingHelp: "Эмбеддинг контента упрощает поиск для вас и ИИ-агентов. Если вы используете локальную модель эмбеддинга (например, Ollama), можно не беспокоиться о стоимости и создавать эмбеддинг для всего.",
fileManagement: "Управление файлами",
fileManagementDesc: "Настройте обработку и хранение файлов",
autoDeleteFiles: "Автоудаление файлов",
autoDeletePlaceholder: "Выберите опцию автоудаления",
filesHelp: "После загрузки и обработки файлы больше не нужны. Большинству пользователей следует разрешить Open Notebook автоматически удалять загруженные файлы из папки загрузок.",
loadFailed: "Не удалось загрузить настройки",
},
advanced: {
title: "Дополнительные инструменты",
desc: "Расширенные инструменты и утилиты для опытных пользователей",
systemInfo: "Информация о системе",
rebuildEmbeddings: "Пересоздать эмбеддинги",
rebuildEmbeddingsDesc: "Пересоздать индекс векторного поиска для всех источников",
currentVersion: "Текущая версия",
latestVersion: "Последняя версия",
status: "Статус",
updateAvailable: "Доступна версия {version}",
updateAvailableDesc: "Доступна новая версия Open Notebook.",
upToDate: "Актуальная версия",
unknown: "Неизвестно",
viewOnGithub: "Посмотреть на GitHub",
updateCheckFailed: "Не удалось проверить обновления. GitHub может быть недоступен.",
rebuild: {
mode: "Режим пересоздания",
existing: "Существующие",
all: "Все",
existingDesc: "Пересоздать эмбеддинги только для элементов с существующими эмбеддингами (быстрее, для смены модели)",
allDesc: "Пересоздать существующие + создать эмбеддинги для элементов без них (медленнее, полный охват)",
include: "Включить в пересоздание",
selectOneError: "Выберите хотя бы один тип элементов для пересоздания",
starting: "Запуск пересоздания...",
startBtn: "🚀 Начать пересоздание",
queued: "В очереди",
running: "Отправка задач...",
completed: "Задачи отправлены!",
failed: "Ошибка",
leavePageHint: "Вы можете покинуть эту страницу — процесс выполняется в фоне",
startNew: "Начать новое пересоздание",
itemsProcessed: "Отправлено задач: {processed}/{total} ({percent}%)",
failedItems: "Не удалось отправить задач: {count}",
time: "Время",
whenToRebuild: "Когда нужно пересоздавать эмбеддинги?",
whenToRebuildAns: "При смене модели, обновлении версии, исправлении повреждений или после массового импорта.",
howLong: "Сколько времени занимает пересоздание?",
howLongAns: "Время зависит от количества элементов, скорости модели и лимитов API. Локальные модели обычно очень быстрые.",
isSafe: "Безопасно ли пересоздавать во время работы с приложением?",
isSafeAns: "Да, пересоздание безопасно! Оно не удаляет контент, только заменяет эмбеддинги, и корректно обрабатывает ошибки.",
},
},
transformations: {
title: "Трансформации",
desc: "Трансформации — это промпты, которые LLM использует для обработки источника и извлечения инсайтов, резюме и т.д.",
workspace: "Выберите рабочее пространство",
playground: "Песочница",
defaultPrompt: "Промпт трансформации по умолчанию",
defaultPromptDesc: "Этот текст будет добавлен ко всем промптам трансформаций",
defaultPromptPlaceholder: "Введите инструкции трансформации по умолчанию...",
listTitle: "Пользовательские трансформации",
createNew: "Создать новую",
inputLabel: "Входной текст",
inputPlaceholder: "Введите текст для трансформации...",
outputLabel: "Результат",
runTest: "Запустить трансформацию",
running: "Выполнение...",
selectToStart: "Выберите трансформацию для начала",
name: "Название",
namePlaceholder: "Уникальный идентификатор, напр. key_topics",
titlePlaceholder: "Отображаемое название, по умолчанию совпадает с именем",
promptPlaceholder: "Напишите промпт для этой трансформации...",
descriptionPlaceholder: "Опишите, что делает эта трансформация.",
suggestDefault: "Предлагать по умолчанию для новых источников",
promptHint: "Промпты должны учитывать содержимое источника. Вы можете попросить модель резюмировать, извлечь инсайты или создать структурированный вывод, например таблицы.",
createSuccess: "Трансформация успешно создана",
updateSuccess: "Трансформация успешно обновлена",
deleteSuccess: "Трансформация успешно удалена",
noTransformations: "Пока нет трансформаций",
createOne: "Создайте трансформацию для начала",
selectModel: "Выберите модель",
deleteConfirm: "Вы уверены, что хотите удалить эту трансформацию?",
model: "Модель",
systemPrompt: "Системный промпт",
overrideModelDesc: "Переопределить модель по умолчанию для этой сессии чата. Оставьте пустым для использования системной модели.",
sessionUseReplacement: "Эта сессия будет использовать {name} вместо модели по умолчанию.",
systemDefault: "Системная по умолчанию",
},
models: {
embedding: "Модели эмбеддинга",
tts: "Озвучивание (TTS)",
stt: "Распознавание речи (STT)",
provider: "Провайдер",
apiKey: "API-ключ",
deleteSuccess: "Модель успешно удалена",
saveSuccess: "Модель успешно сохранена",
noModels: "Нет моделей",
discoverModels: "Обнаружение моделей",
noModelsFound: "Модели от этого провайдера не найдены",
modelType: "Тип модели",
modelTypeHint: "Выберите тип для добавляемых моделей. Если нужны разные типы, добавляйте их отдельными партиями.",
deleteModel: "Удалить модель",
defaultAssignments: "Назначение моделей по умолчанию",
defaultAssignmentsDesc: "Настройте, какие модели использовать для различных задач в Open Notebook",
missingRequiredModels: "Отсутствуют необходимые модели: {models}. Open Notebook может работать некорректно без них.",
selectModelPlaceholder: "Выберите модель",
requiredModelPlaceholder: "⚠️ Обязательно — выберите модель",
chatModelLabel: "Модель чата",
chatModelDesc: "Используется для чат-разговоров",
transformationModelLabel: "Модель трансформаций",
transformationModelDesc: "Используется для резюме, инсайтов и трансформаций",
toolsModelLabel: "Модель инструментов",
toolsModelDesc: "Используется для вызова функций — рекомендуется OpenAI или Anthropic",
largeContextModelLabel: "Модель для большого контекста",
largeContextModelDesc: "Используется для обработки больших документов — рекомендуется Gemini",
embeddingModelLabel: "Модель эмбеддинга",
embeddingModelDesc: "Используется для семантического поиска и векторных эмбеддингов",
ttsModelLabel: "Модель озвучивания",
ttsModelDesc: "Используется для генерации подкастов",
sttModelLabel: "Модель распознавания речи",
sttModelDesc: "Используется для транскрибации аудио",
selectProviderPlaceholder: "Выберите провайдера",
providerRequired: "Требуется провайдер",
modelRequired: "Требуется модель",
embeddingChangeTitle: "Изменение модели эмбеддинга",
embeddingChangeConfirm: "Вы собираетесь изменить модель эмбеддинга с {from} на {to}.",
rebuildRequired: "Важно: Требуется пересоздание",
rebuildReason: "Изменение модели эмбеддинга требует пересоздания всех существующих эмбеддингов для сохранения согласованности. Без пересоздания поиск может возвращать некорректные или неполные результаты.",
whatHappensNext: "Что произойдёт далее:",
step1: "Модель эмбеддинга по умолчанию будет обновлена",
step2: "Существующие эмбеддинги останутся неизменными до пересоздания",
step3: "Новый контент будет использовать новую модель эмбеддинга",
step4: "Вам следует пересоздать эмбеддинги как можно скорее",
proceedToRebuildPrompt: "Хотите перейти на страницу «Дополнительно», чтобы начать пересоздание сейчас?",
changeModelOnly: "Только изменить модель",
changeAndRebuild: "Изменить и перейти к пересозданию",
autoAssign: "Автоназначение по умолчанию",
autoAssigning: "Назначение...",
autoAssignSuccess: "{count} моделей по умолчанию автоматически назначено",
autoAssignNoModels: "Нет доступных моделей для назначения. Сначала синхронизируйте модели.",
autoAssignAlreadySet: "Все модели по умолчанию уже настроены",
testModel: "Тестировать модель",
testModelSuccess: "Тест модели пройден",
testModelFailed: "Тест модели не пройден",
searchOrAddModel: "Поиск или введите имя модели...",
addCustomModel: "Добавить \"{name}\"",
},
apiKeys: {
title: "Настройте ИИ с помощью собственных API-ключей",
description: "Храните API-ключи в базе данных для безопасного подключения провайдеров ИИ в Open Notebook.",
encryptionRequired: "Ключ шифрования не настроен",
encryptionRequiredDescription: "Установите переменную окружения OPEN_NOTEBOOK_ENCRYPTION_KEY в любую секретную строку для хранения API-ключей в базе данных.",
configured: "Настроено",
notConfigured: "Не настроено",
migrationAvailable: "Обнаружены переменные окружения",
migrationDescription: "{count} API-ключ(ей) настроено через переменные окружения и может быть перенесено в базу данных для удобного управления.",
migrateToDatabase: "Перенести в базу данных",
migrating: "Перенос...",
migrationSuccess: "{count} API-ключ(ей) успешно перенесено",
migrationErrors: "{count} ключ(ей) не удалось перенести",
migrationNothingToMigrate: "Все ключи уже находятся в базе данных",
learnMore: "Узнайте, как настроить API-ключи →",
testConnection: "Проверить подключение",
testSuccess: "Подключение успешно",
testFailed: "Проверка подключения не удалась",
syncModels: "Синхронизировать модели",
syncSuccess: "Обнаружено {discovered} моделей, добавлено {new} новых",
syncNoNew: "Обнаружено {count} моделей, все уже зарегистрированы",
syncFailed: "Не удалось синхронизировать модели",
getApiKey: "Получить API-ключ",
vertexProject: "ID проекта GCP",
vertexLocation: "Регион",
vertexCredentials: "Путь к JSON сервисного аккаунта",
addConfig: "Добавить конфигурацию",
editConfig: "Редактировать конфигурацию",
deleteConfig: "Удалить конфигурацию",
configName: "Название конфигурации",
configNameHint: "Описательное название для этой конфигурации (например, «Продакшн», «Разработка»)",
baseUrl: "Базовый URL",
baseUrlOverrideHint: "Изменяйте только если нужно переопределить стандартную конечную точку API провайдера.",
deleteConfigConfirm: "Вы уверены, что хотите удалить «{name}»? Это действие необратимо.",
configSaveSuccess: "Конфигурация успешно сохранена",
configUpdateSuccess: "Конфигурация успешно обновлена",
configDeleteSuccess: "Конфигурация успешно удалена",
apiKeyEditHint: "Оставьте пустым, чтобы сохранить текущий API-ключ",
},
setupBanner: {
encryptionRequired: "Ключ шифрования не настроен",
encryptionRequiredDescription: "Установите переменную окружения OPEN_NOTEBOOK_ENCRYPTION_KEY для безопасного хранения учётных данных.",
migrationAvailable: "Доступна миграция API-ключей",
migrationDescription: "{count} провайдер(ов) имеют API-ключи, заданные через переменные окружения. Перенесите их в базу данных для удобного управления.",
goToSettings: "Перейти к настройкам",
viewDocs: "Документация",
},
}