@goodandready/dsh-russian-lang 0.1.0
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/LICENSE +21 -0
- package/README.md +64 -0
- package/cordis.patch.yml +8 -0
- package/lib/client.js +1901 -0
- package/lib/index.js +20 -0
- package/package.json +60 -0
- package/ru/01-core-small.json +97 -0
- package/ru/02-conversation.json +172 -0
- package/ru/03-models-workspace.json +160 -0
- package/ru/04-preset-cordis.json +108 -0
- package/ru/05-plugins-subagent.json +117 -0
- package/ru/06-rest.json +140 -0
- package/ru-plugins/01-token-dashboard.json +83 -0
- package/ru-plugins/02-subscriptions.json +40 -0
- package/ru-plugins/03-dshmarket.json +258 -0
- package/ru-plugins/04-context-doctor.json +27 -0
- package/ru-plugins/05-plugins-store.json +81 -0
- package/ru-plugins/06-im-hub.json +97 -0
- package/ru-plugins/07-better-sidebar.json +242 -0
- package/ru-plugins/08-task-board.json +126 -0
- package/ru-plugins/09-dshmarket-1.13.json +46 -0
package/lib/client.js
ADDED
|
@@ -0,0 +1,1901 @@
|
|
|
1
|
+
// dsh-russian-lang — браузерная половина. ФАЙЛ СГЕНЕРИРОВАН, правьте ru/*.json
|
|
2
|
+
// и ru-plugins/*.json и запускайте build.py.
|
|
3
|
+
//
|
|
4
|
+
// Плагин докладывает русский словарь в чужие namespace'ы: реестр локалей это
|
|
5
|
+
// разрешает — register(ns, locale, dict) конфликтует только если пара
|
|
6
|
+
// (namespace, язык) уже занята, а "ru" не занимает никто.
|
|
7
|
+
//
|
|
8
|
+
// Ядро без русского: список языков (LOCALES) зашит в @deepseek-ai/dsh-client-locale,
|
|
9
|
+
// из него родная строка Language строит меню и setLocale() берёт валидацию.
|
|
10
|
+
// Список живёт в snapshot локаль-runtime — плагин расширяет snapshot пунктом
|
|
11
|
+
// "Русский", и родной селектор показывает его третьей позицией. Файлы ядра не
|
|
12
|
+
// правятся; если ядро когда-нибудь узнает "ru" само, расширение не происходит.
|
|
13
|
+
window.__ModuleLoader__.load({
|
|
14
|
+
id: '@goodandready/dsh-russian-lang',
|
|
15
|
+
factory: (require) => {
|
|
16
|
+
var module = { exports: {} }
|
|
17
|
+
|
|
18
|
+
/** namespace -> { ключ: перевод } */
|
|
19
|
+
const RU = {
|
|
20
|
+
"betterSidebar": {
|
|
21
|
+
"addPluginsBrowseMore": "Ещё плагины на GitHub (тема: dsh-better-sidebar)",
|
|
22
|
+
"addPluginsEmpty": "Подборки пока нет — опубликуйте свой плагин под темой на GitHub",
|
|
23
|
+
"addPluginsRecommended": "Рекомендуемые плагины",
|
|
24
|
+
"addPluginsTabCard": "Добавить плагины вкладок",
|
|
25
|
+
"addPluginsTabCardDesc": "Зарегистрировать новую страницу панели",
|
|
26
|
+
"addPluginsTabDesc": "Страницы панели (вкладки) расширяются плагинами. Плагины регистрируются через сервис ctx.betterSidebar; кнопка «Установить» копирует команду — вставьте её в терминал на машине с профилем DSH и выполните.",
|
|
27
|
+
"addPluginsViewerCard": "Добавить плагины предпросмотра",
|
|
28
|
+
"addPluginsViewerCardDesc": "Зарегистрировать просмотр нового типа файлов",
|
|
29
|
+
"addPluginsViewerDesc": "Просмотрщики файлов расширяются плагинами. Плагины регистрируются через сервис ctx.betterSidebar; кнопка «Установить» копирует команду — вставьте её в терминал на машине с профилем DSH и выполните.",
|
|
30
|
+
"addToConversation": "Добавить в диалог",
|
|
31
|
+
"binary": "Двоичный файл, предпросмотр недоступен",
|
|
32
|
+
"binaryNoPreview": "Этот тип файлов нельзя показать",
|
|
33
|
+
"branch": "Ветка",
|
|
34
|
+
"brokenSymlink": "Битая ссылка",
|
|
35
|
+
"browser": "Браузер",
|
|
36
|
+
"browserBack": "Назад",
|
|
37
|
+
"browserBlockedLoopback": "Заблокировано: локальные и внутренние адреса здесь открывать нельзя",
|
|
38
|
+
"browserBlockedScheme": "Заблокировано: разрешены только адреса http и https",
|
|
39
|
+
"browserEmbedAnyway": "Всё равно загрузить",
|
|
40
|
+
"browserEmbedBlocked": "{host} запрещает встраивание",
|
|
41
|
+
"browserEmbedBlockedDesc": "Сайт запрещает показывать себя внутри других страниц (X-Frame-Options / frame-ancestors), поэтому в панели он не откроется. Откройте его в обычном браузере.",
|
|
42
|
+
"browserForward": "Вперёд",
|
|
43
|
+
"browserGo": "Перейти",
|
|
44
|
+
"browserInvalid": "Неверный адрес",
|
|
45
|
+
"browserNoSandboxWarning": "Песочница выключена: страница работает с полными правами интерфейса (включить обратно можно в настройках)",
|
|
46
|
+
"browserOpenExternal": "Открыть в браузере",
|
|
47
|
+
"browserPlaceholder": "Введите адрес, например example.com",
|
|
48
|
+
"browserStart": "Введите адрес, чтобы начать (режим песочницы)",
|
|
49
|
+
"cancel": "Отмена",
|
|
50
|
+
"changes": "Изменения",
|
|
51
|
+
"checkoutError": "Переключить ветку не удалось",
|
|
52
|
+
"cherryPickCommit": "Перенести коммит",
|
|
53
|
+
"cherryPickDesc": "Применить изменения «{subject}» к текущей ветке.",
|
|
54
|
+
"cherryPickTitle": "Перенос коммита",
|
|
55
|
+
"close": "Закрыть",
|
|
56
|
+
"collapse": "Свернуть панель",
|
|
57
|
+
"collapseBottomPanel": "Свернуть нижнюю панель",
|
|
58
|
+
"commit": "Закоммитить",
|
|
59
|
+
"commitError": "Коммит не удался",
|
|
60
|
+
"commitPlaceholder": "Сообщение коммита (Ctrl+Enter)",
|
|
61
|
+
"copied": "Скопировано",
|
|
62
|
+
"copy": "Копировать",
|
|
63
|
+
"copyAbsolute": "Копировать абсолютный путь",
|
|
64
|
+
"copyFullHash": "Копировать полный хеш",
|
|
65
|
+
"copyInstall": "Копировать команду установки",
|
|
66
|
+
"copyRelative": "Копировать относительный путь",
|
|
67
|
+
"copyShortHash": "Копировать короткий хеш",
|
|
68
|
+
"copySubject": "Копировать заголовок",
|
|
69
|
+
"diffAdded": "Добавлено",
|
|
70
|
+
"diffBinary": "Двоичный",
|
|
71
|
+
"diffCollapse": "Свернуть",
|
|
72
|
+
"diffDeleted": "Удалено",
|
|
73
|
+
"diffEmpty": "Текстовых изменений нет",
|
|
74
|
+
"diffExpand": "Показать ещё строк: {count}",
|
|
75
|
+
"diffLoadError": "Не удалось загрузить различия",
|
|
76
|
+
"diffRenamed": "Переименовано",
|
|
77
|
+
"discard": "Отменить изменения",
|
|
78
|
+
"discardDesc": "Изменения «{path}» в рабочем дереве будут отброшены без возможности вернуть.",
|
|
79
|
+
"discardTitle": "Отмена изменений",
|
|
80
|
+
"disconnected": "Терминал отключился, переподключаемся…",
|
|
81
|
+
"download": "Скачать",
|
|
82
|
+
"downloadToView": "Скачать, чтобы посмотреть",
|
|
83
|
+
"edit": "Изменить",
|
|
84
|
+
"editor": "Редактор",
|
|
85
|
+
"editorEmptyHint": "Выберите файл в дереве или введите путь выше, чтобы открыть предпросмотр",
|
|
86
|
+
"editorExplorer": "Как открывать файлы",
|
|
87
|
+
"editorExplorerDesc": "Управляет поведением при открытии файлов",
|
|
88
|
+
"editorExplorerMerged": "В одном окне",
|
|
89
|
+
"editorExplorerMergedDesc": "Файлы сменяются в том же окне; новые окна открываются с деревом",
|
|
90
|
+
"editorExplorerSplit": "Раздельно",
|
|
91
|
+
"editorExplorerSplitDesc": "Окно без пути — это отдельный проводник (только дерево); каждый файл открывается своим окном (дерево пристыковано и по умолчанию закрыто)",
|
|
92
|
+
"editorPathPlaceholder": "Путь к файлу (от папки сессии или абсолютный), Enter — открыть",
|
|
93
|
+
"editorSearchNoResults": "Подходящих файлов нет",
|
|
94
|
+
"editorSearchPlaceholder": "Поиск файлов по имени…",
|
|
95
|
+
"editorSearchTruncated": "Слишком много совпадений — показана часть",
|
|
96
|
+
"editorTreeToggle": "Дерево файлов",
|
|
97
|
+
"error": "Не удалось загрузить",
|
|
98
|
+
"exited": "Процесс терминала завершился",
|
|
99
|
+
"expand": "Развернуть панель",
|
|
100
|
+
"expandBottomPanel": "Развернуть нижнюю панель",
|
|
101
|
+
"explorer": "Проводник",
|
|
102
|
+
"files": "Файлы",
|
|
103
|
+
"git": "Контроль версий",
|
|
104
|
+
"gitDetail": "Посмотреть изменения",
|
|
105
|
+
"hiddenFiles": "Скрытые файлы",
|
|
106
|
+
"history": "История",
|
|
107
|
+
"historyLoadError": "Не удалось догрузить историю",
|
|
108
|
+
"htmlNoSandboxWarning": "Песочница выключена: этот HTML работает с полными правами интерфейса (включить обратно можно в настройках)",
|
|
109
|
+
"jobDurationHours": "{hours} ч {minutes} мин",
|
|
110
|
+
"jobDurationMinutes": "{minutes} мин {seconds} с",
|
|
111
|
+
"jobDurationSeconds": "{seconds} с",
|
|
112
|
+
"jobHideOutput": "Скрыть вывод",
|
|
113
|
+
"jobKill": "Прервать",
|
|
114
|
+
"jobKillConfirm": "Нажмите ещё раз для подтверждения",
|
|
115
|
+
"jobKillError": "Прервать не удалось",
|
|
116
|
+
"jobNoOutput": "Вывода пока нет",
|
|
117
|
+
"jobNotReadYet": "Ждём, пока модель прочитает эту задачу; вывод появится здесь после вызова job_output",
|
|
118
|
+
"jobOutputError": "Не удалось прочитать вывод",
|
|
119
|
+
"jobOutputTruncated": "Вывод обрезан",
|
|
120
|
+
"jobStatusCompleted": "Завершена",
|
|
121
|
+
"jobStatusFailed": "Ошибка",
|
|
122
|
+
"jobStatusKilled": "Прервана",
|
|
123
|
+
"jobStatusRunning": "Выполняется",
|
|
124
|
+
"jobStatusStopping": "Останавливается",
|
|
125
|
+
"jobViewOutput": "Посмотреть вывод",
|
|
126
|
+
"jobs": "Фоновые задачи",
|
|
127
|
+
"jobsCount": "фоновых задач: {count}",
|
|
128
|
+
"jobsCountRunning": "фоновых задач: {count} · выполняется: {running}",
|
|
129
|
+
"loadMore": "Показать ещё",
|
|
130
|
+
"loading": "Загрузка…",
|
|
131
|
+
"newFile": "Новый файл",
|
|
132
|
+
"newTab": "Новая вкладка",
|
|
133
|
+
"newTerminal": "Новый терминал",
|
|
134
|
+
"noChanges": "Изменений нет",
|
|
135
|
+
"noSession": "Выберите диалог, чтобы пользоваться панелью",
|
|
136
|
+
"notRepo": "Эта папка не является репозиторием git",
|
|
137
|
+
"openEditor": "Открыть редактор",
|
|
138
|
+
"openExplorer": "Проводник",
|
|
139
|
+
"openFileNewTab": "Открыть в новой вкладке",
|
|
140
|
+
"openFileSide": "Открыть сбоку",
|
|
141
|
+
"openGit": "Панель git",
|
|
142
|
+
"openPlugin": "Открыть",
|
|
143
|
+
"openSubagent": "Задачи",
|
|
144
|
+
"parent": "Родительская папка",
|
|
145
|
+
"pluginGitRemotesDesc": "Вкладка Git Remotes: ветка, upstream, отставание и опережение, fetch (с необязательным prune), pull только ff-only и push после подтверждения во вкладке. Не заменяет встроенную вкладку git со стадированием и коммитами, не предлагает force-push и не даёт модели инструмент автопуша",
|
|
146
|
+
"pluginNotLoaded": "Плагин не загружен, вкладка недоступна:",
|
|
147
|
+
"pluginOfficeDesc": "Предпросмотр офисных файлов (.docx / .xlsx / .pptx) в редакторе better-sidebar; тяжёлые библиотеки рендеринга держатся вне основного бандла",
|
|
148
|
+
"pluginSentinelDesc": "Пробуждение агента по условию: датчики файлов, процессов, портов, http, команд и вебхуков будят спящие сессии, когда условие сработало; добавляет вкладку Sentinel с общей таблицей наблюдений",
|
|
149
|
+
"pluginSidebarQaDesc": "Выделил и спросил: выделите текст в диалоге, задайте вопрос в правой панели — откроется отдельная сессия-уточнение в той же рабочей папке; быстрая модель без рассуждений сжимает основной контекст и подставляет его вместе с цитатой, не прерывая основной диалог. Уточнения вкладываются, продолжаются и уходят в архив",
|
|
150
|
+
"pluginVideoPreviewDesc": "Просмотр видео (.mp4/.webm/.mov/.mkv/.avi и других) прямо в редакторе better-sidebar через отдельный маршрут /video с поддержкой HTTP Range (206) — перемотка работает, ограничение mediaLimit в 20 МБ не действует",
|
|
151
|
+
"preview": "Предпросмотр",
|
|
152
|
+
"produced": "Создано",
|
|
153
|
+
"producedOpen": "Открыть в панели",
|
|
154
|
+
"referenceFile": "@файл",
|
|
155
|
+
"refresh": "Обновить",
|
|
156
|
+
"retry": "Повторить",
|
|
157
|
+
"revertCommit": "Откатить коммит",
|
|
158
|
+
"revertDesc": "Создать в текущей ветке новый коммит, отменяющий «{subject}».",
|
|
159
|
+
"revertTitle": "Откат коммита",
|
|
160
|
+
"sandboxRestore": "Вернуть песочницу",
|
|
161
|
+
"sandboxStatusOn": "Песочница включена · страницы не видят данные интерфейса и локальные файлы; входы и сторонние куки могут не работать",
|
|
162
|
+
"sandboxUnlock": "Временно отключить (небезопасно)",
|
|
163
|
+
"save": "Сохранить",
|
|
164
|
+
"saveFailed": "Сохранить не удалось",
|
|
165
|
+
"saved": "Сохранено",
|
|
166
|
+
"settingsBottomTerminalDesc": "При первом разворачивании нижней панели в сессии открывать в ней новый терминал (ограничение на число терминалов сохраняется; по умолчанию включено)",
|
|
167
|
+
"settingsBottomTerminalTitle": "Открывать терминал при первом разворачивании нижней панели",
|
|
168
|
+
"settingsBrowserHttpDesc": "Если включено, клик по внешней http-ссылке в диалоге или интерфейсе открывает панель (страницы плагинов с urlTarget имеют приоритет); Ctrl/Cmd+клик всегда в обход",
|
|
169
|
+
"settingsBrowserHttpTitle": "Открывать http-страницы в панели",
|
|
170
|
+
"settingsBrowserHttpsDesc": "Если включено, клик по внешней https-ссылке открывает панель. По умолчанию выключено: большинство https-сайтов запрещают встраивание, поэтому системный браузер удобнее",
|
|
171
|
+
"settingsBrowserHttpsTitle": "Открывать https-страницы в панели",
|
|
172
|
+
"settingsBrowserLinksDesc": "Если включено, клик по внешней ссылке открывает панель, а не новое окно; http и https управляются отдельными переключателями ниже; Ctrl/Cmd+клик всегда в обход",
|
|
173
|
+
"settingsBrowserLinksTitle": "Открывать внешние ссылки из диалога в панели",
|
|
174
|
+
"settingsBrowserSandboxDesc": "С выключенной песочницей любой открытый сайт работает в том же origin, что и интерфейс: он может читать данные сессии и действовать от вашего имени. Включайте только для полностью доверенных сайтов",
|
|
175
|
+
"settingsBrowserSandboxTitle": "Отключить песочницу браузера (небезопасно)",
|
|
176
|
+
"settingsConflict": "Настройку изменили в другом окне — повторите",
|
|
177
|
+
"settingsDone": "Готово",
|
|
178
|
+
"settingsFontFamilyDesc": "Своя гарнитура терминала (CSS-стек вида \"JetBrains Mono\", monospace; пусто — моноширинный шрифт темы)",
|
|
179
|
+
"settingsFontFamilyPlaceholder": "\"JetBrains Mono\", monospace",
|
|
180
|
+
"settingsFontFamilyTitle": "Шрифт терминала",
|
|
181
|
+
"settingsFontSizeDesc": "Размер шрифта терминала в пикселях (9–32, по умолчанию 13)",
|
|
182
|
+
"settingsFontSizeSuffix": "px",
|
|
183
|
+
"settingsFontSizeTitle": "Размер шрифта терминала",
|
|
184
|
+
"settingsGeneralTitle": "Общие",
|
|
185
|
+
"settingsHtmlDefaultUnsafeDesc": "Если включено, каждый новый предпросмотр HTML открывается без песочницы (тот же origin, что и интерфейс — доступны файлы сессии и внутренние API); вернуть песочницу можно одним нажатием в строке состояния",
|
|
186
|
+
"settingsHtmlDefaultUnsafeTitle": "Открывать предпросмотр HTML без песочницы (небезопасно)",
|
|
187
|
+
"settingsHtmlSandboxDesc": "С выключенной песочницей просматриваемый HTML работает в том же origin, что и интерфейс: он может читать файлы сессии, локальное хранилище и вызывать внутренние API. Включайте только для полностью доверенных файлов",
|
|
188
|
+
"settingsHtmlSandboxTitle": "Отключить песочницу предпросмотра HTML (небезопасно)",
|
|
189
|
+
"settingsIntro": "Что показывает боковая панель и как она себя ведёт",
|
|
190
|
+
"settingsJobsDesc": "Разворачивать панель и открывать страницу задач при появлении новой фоновой задачи в текущем диалоге (срабатывает на каждую); выключите, чтобы открывать вручную",
|
|
191
|
+
"settingsJobsTitle": "Открывать страницу задач при новой фоновой задаче",
|
|
192
|
+
"settingsNav": "Боковая панель",
|
|
193
|
+
"settingsOpenDesc": "Разворачивать панель для совсем новых диалогов; у существующих сохраняется своя раскладка",
|
|
194
|
+
"settingsOpenPathDesc": "Открывать файловые ссылки из диалога (строки инструментов, созданные файлы, упоминания) в редакторе панели, а не в системном приложении",
|
|
195
|
+
"settingsOpenPathTitle": "Открывать файлы из диалога в панели",
|
|
196
|
+
"settingsOpenTitle": "Разворачивать для новых диалогов",
|
|
197
|
+
"settingsPopup": "Настройки функции",
|
|
198
|
+
"settingsPopupDesc": "Параметры для «{feature}»",
|
|
199
|
+
"settingsSaveFailed": "Не удалось сохранить",
|
|
200
|
+
"settingsSubagentDesc": "Разворачивать панель и открывать страницу задач, когда в диалоге появляется субагент; выключите, чтобы открывать вручную",
|
|
201
|
+
"settingsSubagentTitle": "Открывать страницу задач при появлении субагента",
|
|
202
|
+
"settingsTabsTitle": "Содержимое панели",
|
|
203
|
+
"settingsTitleBarDesc": "Оставлять место под системный заголовок окна Windows справа сверху, чтобы кнопки и содержимое панели располагались ниже, а не под ним",
|
|
204
|
+
"settingsTitleBarStripDesc": "Высота полосы заголовка: на сколько пикселей опускаются кнопки и содержимое панели (0–120, по умолчанию 40)",
|
|
205
|
+
"settingsTitleBarStripTitle": "Смещение",
|
|
206
|
+
"settingsTitleBarTitle": "Режим совместимости с заголовком окна",
|
|
207
|
+
"settingsToolsDesc": "Если включено, модель может создавать терминалы в панели и работать в них через восемь инструментов terminal_* (по умолчанию выключено)",
|
|
208
|
+
"settingsToolsTitle": "Дать модели инструменты терминала",
|
|
209
|
+
"settingsViewerCatchAll": "На всё остальное: любой файл",
|
|
210
|
+
"settingsViewersTitle": "Просмотрщики файлов",
|
|
211
|
+
"settingsWidthDesc": "Какую долю ширины окна занимает панель в новых диалогах (20–60)",
|
|
212
|
+
"settingsWidthSuffix": "%",
|
|
213
|
+
"settingsWidthTitle": "Ширина по умолчанию",
|
|
214
|
+
"splitDown": "Разделить вниз",
|
|
215
|
+
"splitLeft": "Разделить влево",
|
|
216
|
+
"splitRight": "Разделить вправо",
|
|
217
|
+
"splitUp": "Разделить вверх",
|
|
218
|
+
"stage": "В индекс",
|
|
219
|
+
"stageAll": "Всё в индекс",
|
|
220
|
+
"staged": "В индексе",
|
|
221
|
+
"subagent": "Задачи",
|
|
222
|
+
"subagentCount": "субагентов: {count}",
|
|
223
|
+
"subagentCountRunning": "субагентов: {count} · работает: {running}",
|
|
224
|
+
"subagentDiagCorrupt": "Повреждён",
|
|
225
|
+
"subagentDiagUnavailable": "Недоступен",
|
|
226
|
+
"subagentDiagUnsupported": "Не поддерживается",
|
|
227
|
+
"subagentEmpty": "Субагентов нет",
|
|
228
|
+
"subagentEmptyDesc": "Здесь появятся субагенты, запущенные основным агентом",
|
|
229
|
+
"subagentInactive": "Простаивает",
|
|
230
|
+
"subagentMainAgent": "Основной агент",
|
|
231
|
+
"subagentModeContinuable": "С продолжением",
|
|
232
|
+
"subagentModeOneShot": "Разовый",
|
|
233
|
+
"subagentRunning": "Работает",
|
|
234
|
+
"subagentThinking": "Думает…",
|
|
235
|
+
"terminal": "Терминал",
|
|
236
|
+
"terminalConnectFailed": "Терминал не смог подключиться несколько раз подряд",
|
|
237
|
+
"terminalDepsFailed": "Не удалось загрузить зависимость терминала node-pty",
|
|
238
|
+
"terminalDepsHint": "Выполните команду ниже в терминале на машине с DSH, чтобы починить, и повторите (версия node-pty должна совпадать с версией ядра DSH):",
|
|
239
|
+
"terminalDepsProfile": " (определён профиль: {profile})",
|
|
240
|
+
"terminalError": "Не удалось подключиться к терминалу",
|
|
241
|
+
"terminalLimit": "Достигнут предел терминалов (3)",
|
|
242
|
+
"terminalRetry": "Повторить",
|
|
243
|
+
"timeHoursAgo": "{n} ч назад",
|
|
244
|
+
"timeJustNow": "только что",
|
|
245
|
+
"timeMinutesAgo": "{n} мин назад",
|
|
246
|
+
"timeYesterday": "вчера",
|
|
247
|
+
"truncation": "Файл слишком большой — показаны первые 512 КБ",
|
|
248
|
+
"unsaved": "Не сохранено",
|
|
249
|
+
"unstage": "Из индекса",
|
|
250
|
+
"unstageAll": "Всё из индекса",
|
|
251
|
+
"unstaged": "Вне индекса",
|
|
252
|
+
"viewCommitDiff": "Посмотреть изменения коммита",
|
|
253
|
+
"viewerBinary": "Скачивание файла",
|
|
254
|
+
"viewerCode": "Код",
|
|
255
|
+
"viewerHtml": "HTML",
|
|
256
|
+
"viewerImage": "Изображение",
|
|
257
|
+
"viewerMarkdown": "Markdown",
|
|
258
|
+
"viewerPdf": "PDF"
|
|
259
|
+
},
|
|
260
|
+
"command": {
|
|
261
|
+
"listbox.aria": "Совпадения /{command}",
|
|
262
|
+
"notice.imagesUnsupported": "/{command} не принимает вложения-изображения — сначала удалите их",
|
|
263
|
+
"overlay.aria": "Параметры /{command}",
|
|
264
|
+
"search.aria": "Фильтр параметров",
|
|
265
|
+
"search.placeholder": "Поиск…",
|
|
266
|
+
"status.applying": "Применение…",
|
|
267
|
+
"status.empty": "Нет параметров",
|
|
268
|
+
"status.loading": "Загрузка параметров…"
|
|
269
|
+
},
|
|
270
|
+
"common": {
|
|
271
|
+
"back": "Назад",
|
|
272
|
+
"cancel": "Отмена",
|
|
273
|
+
"close": "Закрыть",
|
|
274
|
+
"collapse": "Свернуть",
|
|
275
|
+
"copied": "Скопировано",
|
|
276
|
+
"copy": "Копировать",
|
|
277
|
+
"delete": "Удалить",
|
|
278
|
+
"edit": "Изменить",
|
|
279
|
+
"expand": "Развернуть",
|
|
280
|
+
"load.failed": "Не удалось загрузить",
|
|
281
|
+
"loading": "Загрузка…",
|
|
282
|
+
"more": "Ещё",
|
|
283
|
+
"next": "Дальше",
|
|
284
|
+
"none": "Нет",
|
|
285
|
+
"ok": "ОК",
|
|
286
|
+
"previous": "Назад",
|
|
287
|
+
"retry": "Повторить",
|
|
288
|
+
"save": "Сохранить",
|
|
289
|
+
"search": "Поиск",
|
|
290
|
+
"skip": "Пропустить",
|
|
291
|
+
"submit": "Отправить",
|
|
292
|
+
"submitting": "Отправка…",
|
|
293
|
+
"truncated": "Обрезано",
|
|
294
|
+
"unknown": "Неизвестно"
|
|
295
|
+
},
|
|
296
|
+
"context-doctor": {
|
|
297
|
+
"cd.attention": "Стоит посмотреть",
|
|
298
|
+
"cd.catalog": "{n} скиллов",
|
|
299
|
+
"cd.empty": "Данных пока нет",
|
|
300
|
+
"cd.error": "Проверка не удалась",
|
|
301
|
+
"cd.files": "файлов",
|
|
302
|
+
"cd.guideline": "из 50k",
|
|
303
|
+
"cd.healthy": "В норме",
|
|
304
|
+
"cd.healthyHint": "Контекст расходуется экономно и укладывается в рекомендованный бюджет.",
|
|
305
|
+
"cd.hint": "Открыть аудит контекста",
|
|
306
|
+
"cd.instructions": "Цепочка инструкций",
|
|
307
|
+
"cd.loading": "Проверка…",
|
|
308
|
+
"cd.mcp": "Инструменты MCP",
|
|
309
|
+
"cd.mcpTools": "{n} инструментов",
|
|
310
|
+
"cd.refresh": "Обновить",
|
|
311
|
+
"cd.residentTokens": "Проверка бюджета контекста",
|
|
312
|
+
"cd.review": "Стоит посмотреть",
|
|
313
|
+
"cd.reviewHint": "Некоторые части контекста стоит пересмотреть, пока они не стали дорогими.",
|
|
314
|
+
"cd.skills": "Каталог скиллов",
|
|
315
|
+
"cd.suggestions": "{n} рекомендаций",
|
|
316
|
+
"cd.title": "Аудит контекста",
|
|
317
|
+
"cd.tools": "Схемы инструментов",
|
|
318
|
+
"cd.toolsCount": "инструментов",
|
|
319
|
+
"cd.updated": "Обновлено"
|
|
320
|
+
},
|
|
321
|
+
"conversation": {
|
|
322
|
+
"access.confirm.acknowledge": "Я понимаю риски и хочу продолжить",
|
|
323
|
+
"access.confirm.cancel": "Отмена",
|
|
324
|
+
"access.confirm.description": "Полный доступ убирает часть подтверждений и позволяет агенту действовать напрямую, включая чувствительные операции, изменение файлов и внешние команды. Включайте, только если доверяете текущей задаче.",
|
|
325
|
+
"access.confirm.enable": "Включить полный доступ",
|
|
326
|
+
"access.confirm.title": "Включить полный доступ?",
|
|
327
|
+
"approval.allowOnce": "Разрешить один раз",
|
|
328
|
+
"approval.detail.aria": "Подробности запроса",
|
|
329
|
+
"approval.escalation": "Инструмент {toolName} просит повышенных прав",
|
|
330
|
+
"approval.reject": "Отклонить",
|
|
331
|
+
"approval.waiting": "Ожидание подтверждения",
|
|
332
|
+
"ask.answered": "{answered}/{total} отвечено",
|
|
333
|
+
"ask.cancelled": "отменено",
|
|
334
|
+
"ask.interrupted": "прервано",
|
|
335
|
+
"ask.rowTitle": "Вопрос",
|
|
336
|
+
"ask.waiting": "ожидание",
|
|
337
|
+
"bash.failed": "Ошибка",
|
|
338
|
+
"bash.running": "Выполняется",
|
|
339
|
+
"bash.stopped": "Остановлено",
|
|
340
|
+
"chat.loadError": "Не удалось загрузить историю: {message} ({code})",
|
|
341
|
+
"chat.loadOlder": "Загрузить раньше",
|
|
342
|
+
"chat.loadingHistory": "Загрузка истории…",
|
|
343
|
+
"chat.toBottom": "Вниз",
|
|
344
|
+
"clock.md": "{d}.{m}",
|
|
345
|
+
"clock.ymd": "{d}.{m}.{y}",
|
|
346
|
+
"command.done": "Готово",
|
|
347
|
+
"command.failed": "Команда не выполнена",
|
|
348
|
+
"command.imagesUnsupported": "/{command} не принимает вложения-изображения — сначала удалите их",
|
|
349
|
+
"command.running": "Выполняется…",
|
|
350
|
+
"command.title": "Команда",
|
|
351
|
+
"context.aria": "{percent} контекста занято",
|
|
352
|
+
"context.messages": "Сообщения",
|
|
353
|
+
"context.system": "Системный промпт",
|
|
354
|
+
"context.tools": "Инструменты",
|
|
355
|
+
"context.used": "контекста занято",
|
|
356
|
+
"details.close": "Закрыть подробности",
|
|
357
|
+
"details.empty": "Выберите строку инструмента в переписке, чтобы увидеть подробности",
|
|
358
|
+
"details.input": "Вход",
|
|
359
|
+
"details.notInWindow": "Этот вызов вне текущего окна",
|
|
360
|
+
"details.output": "Выход",
|
|
361
|
+
"details.running": "Выполняется…",
|
|
362
|
+
"details.title": "Подробности",
|
|
363
|
+
"duration.minutes": "{minutes} мин {seconds} с",
|
|
364
|
+
"duration.seconds": "{seconds} с",
|
|
365
|
+
"fileOpen.folderTitle": "Не удалось открыть папку",
|
|
366
|
+
"fileOpen.folderUnknown": "Не удалось открыть эту папку",
|
|
367
|
+
"fileOpen.title": "Не удалось открыть файл",
|
|
368
|
+
"fileOpen.unknown": "Не удалось открыть этот файл",
|
|
369
|
+
"hero.chooseWorkspace": "Выбрать рабочую папку",
|
|
370
|
+
"hero.headline": "Навстречу неизвестному",
|
|
371
|
+
"hero.preview": "Предпросмотр",
|
|
372
|
+
"hint.goal": "опишите цель длительной задачи",
|
|
373
|
+
"hint.goal.active": "цель активна — изменить / пауза / продолжить / снять",
|
|
374
|
+
"image.closePreview": "Закрыть просмотр оригинала",
|
|
375
|
+
"image.dimensionTooLarge": "Стороны изображения не больше {size}px — уменьшите его и попробуйте снова",
|
|
376
|
+
"image.dropBlocked": "Сейчас картинки добавить нельзя",
|
|
377
|
+
"image.dropDesc": "До {count} изображений, каждое до {size}",
|
|
378
|
+
"image.dropTitle": "Перетащите изображения сюда",
|
|
379
|
+
"image.fileTooLarge": "Каждое изображение должно быть меньше {size}",
|
|
380
|
+
"image.label": "Изображение",
|
|
381
|
+
"image.loadFailed": "Изображение не загрузилось, нажмите для повтора",
|
|
382
|
+
"image.loading": "Загрузка изображения…",
|
|
383
|
+
"image.modelUnsupported": "Текущая модель не принимает изображения; выберите подходящую",
|
|
384
|
+
"image.openOriginal": "Открыть оригинал",
|
|
385
|
+
"image.openOriginalLabel": "{label}, нажмите, чтобы открыть оригинал",
|
|
386
|
+
"image.original": "Оригинал",
|
|
387
|
+
"image.pending": "Изображения к отправке",
|
|
388
|
+
"image.preview": "Просмотр оригинала",
|
|
389
|
+
"image.remove": "Убрать изображение {name}",
|
|
390
|
+
"image.scrollLeft": "Прокрутить изображения влево",
|
|
391
|
+
"image.scrollRight": "Прокрутить изображения вправо",
|
|
392
|
+
"image.sendFailed": "Не удалось отправить изображения ({reason}); добавьте заново и повторите",
|
|
393
|
+
"image.serviceUnavailable": "Служба загрузки изображений недоступна",
|
|
394
|
+
"image.subagentUnsupported": "Сессии субагентов пока не поддерживают изображения",
|
|
395
|
+
"image.tooMany": "В одно сообщение помещается до {count} изображений",
|
|
396
|
+
"image.tooManyPixels": "Слишком большое разрешение; сожмите изображение и повторите",
|
|
397
|
+
"image.totalTooLarge": "Изображения весят больше {size}; уберите часть и повторите",
|
|
398
|
+
"image.unsupportedType": "Поддерживаются только PNG, JPG, WebP и GIF",
|
|
399
|
+
"input.accessMode": "Режим доступа, сейчас: {name}",
|
|
400
|
+
"input.commands": "Команды",
|
|
401
|
+
"input.send": "Отправить сообщение",
|
|
402
|
+
"input.stop": "Остановить генерацию",
|
|
403
|
+
"json.truncated": "… обрезано, всего символов: {total}",
|
|
404
|
+
"message.branch": "Ответвить новый диалог",
|
|
405
|
+
"message.branchUnavailable": "Доступно только на последнем сообщении завершённого хода",
|
|
406
|
+
"message.compaction": "Контекст сжат",
|
|
407
|
+
"message.compaction.completed": "Сжато элементов истории: {items} (~{tokens} токенов)",
|
|
408
|
+
"message.compaction.expand": "Показать итог сжатия",
|
|
409
|
+
"message.compaction.running": "Сжатие контекста…",
|
|
410
|
+
"message.compaction.unavailable": "Итог сжатия недоступен",
|
|
411
|
+
"message.context.catalog.more": "… ещё {count}",
|
|
412
|
+
"message.context.catalog.replaced": "Каталог заменён",
|
|
413
|
+
"message.context.instructions.added": "добавлено",
|
|
414
|
+
"message.context.instructions.loaded": "загружено",
|
|
415
|
+
"message.context.instructions.removed": "удалено",
|
|
416
|
+
"message.context.instructions.updated": "обновлено",
|
|
417
|
+
"message.context.recall.counts": "{retained} оставлено · {omitted} пропущено",
|
|
418
|
+
"message.context.recall.truncated": "обрезано",
|
|
419
|
+
"message.context.relay.from": "Из сессии {session}",
|
|
420
|
+
"message.context.snapshot.supersedes": "Заменяет прежние снимки",
|
|
421
|
+
"message.contextInjection": "Инъекция контекста",
|
|
422
|
+
"message.contextRecall": "Напоминание из сессии",
|
|
423
|
+
"message.extraBlock": "Дополнительный блок",
|
|
424
|
+
"message.maxTokens": "Достигнут лимит выходных токенов",
|
|
425
|
+
"message.maxTokens.hint": "Ответ обрезан; написанное ранее сохранено в переписке. Отправьте «продолжай», чтобы модель дописала.",
|
|
426
|
+
"message.ranFor": "Заняло {duration}",
|
|
427
|
+
"message.referenceSeparator": ", ",
|
|
428
|
+
"message.referenceSummary": "Упомянутая сессия · {labels}",
|
|
429
|
+
"message.retry.active": "Повтор запроса к модели",
|
|
430
|
+
"message.retry.cancelled": "Повтор запроса отменён",
|
|
431
|
+
"message.retry.delay": "Задержка перед повтором: ",
|
|
432
|
+
"message.retry.failure": "Причина сбоя: ",
|
|
433
|
+
"message.retry.scheduled": "Ожидание повтора запроса",
|
|
434
|
+
"message.retry.started": "Запрос к модели повторён",
|
|
435
|
+
"message.retry.status": "{label} ({retry}/{maximum}) · {seconds} с",
|
|
436
|
+
"message.stopped": "Остановлено",
|
|
437
|
+
"message.tokensPerSecond": "{tps} ток/с",
|
|
438
|
+
"message.ttft": "Первый токен {seconds} с",
|
|
439
|
+
"message.turnError": "Ход не удался",
|
|
440
|
+
"message.unknownBlock": "Неизвестный блок содержимого",
|
|
441
|
+
"message.unknownSurface": "Неизвестное событие: {type}",
|
|
442
|
+
"placeholder.default": "Напишите агенту",
|
|
443
|
+
"placeholder.hero": "Опишите, что хотите сделать",
|
|
444
|
+
"placeholder.parentOffline": "Родительская сессия офлайн: отправка недоступна, но остановить выполнение можно",
|
|
445
|
+
"placeholder.steerQueue": "Cmd/Ctrl+Enter направит все сообщения из очереди",
|
|
446
|
+
"placeholder.unavailable": "Сессия недоступна",
|
|
447
|
+
"placeholder.workspace": "Выберите рабочую папку, чтобы начать",
|
|
448
|
+
"queue.cancelEdit": "Отменить правку",
|
|
449
|
+
"queue.count": "Сообщений в очереди: {n}",
|
|
450
|
+
"queue.edit": "Изменить сообщение в очереди",
|
|
451
|
+
"queue.edit.unsupported": "Содержит не только текст; правка пока не поддерживается",
|
|
452
|
+
"queue.editFailed": "Не удалось изменить: сообщение, возможно, уже отправляется.",
|
|
453
|
+
"queue.remove": "Убрать из очереди",
|
|
454
|
+
"queue.removeFailed": "Не удалось убрать: сообщение, возможно, уже отправляется.",
|
|
455
|
+
"queue.save": "Сохранить сообщение",
|
|
456
|
+
"queue.steer": "Направить сообщение",
|
|
457
|
+
"queue.steer.unavailable": "Направлять можно только пока агент работает",
|
|
458
|
+
"queue.steerFailed": "Не удалось направить. Попробуйте ещё раз.",
|
|
459
|
+
"row.failed": "Ошибка",
|
|
460
|
+
"row.running": "Выполняется",
|
|
461
|
+
"row.stopped": "Остановлено",
|
|
462
|
+
"session.hierarchy": "Иерархия сессий",
|
|
463
|
+
"settings.enter.description": "Только когда агент занят; Cmd/Ctrl+Enter даёт другое поведение",
|
|
464
|
+
"settings.enter.queue": "В очередь",
|
|
465
|
+
"settings.enter.steer": "Направить",
|
|
466
|
+
"settings.enter.title": "Enter, когда агент занят",
|
|
467
|
+
"stats.cacheHit": "Попаданий в кэш {percent}%",
|
|
468
|
+
"stats.counts": "ходов: {turns} · шагов: {steps}",
|
|
469
|
+
"stats.llm": "Модель {duration}",
|
|
470
|
+
"stats.tokens": "Вход {input} ток · выход {output} ток",
|
|
471
|
+
"stats.tokensPerSecond": "{throughput} ток/с",
|
|
472
|
+
"stats.toolCall": "Инструменты {duration}",
|
|
473
|
+
"stats.ttftAverage": "Первый токен в среднем {duration}",
|
|
474
|
+
"terminal.collapseAria": "Свернуть вывод",
|
|
475
|
+
"terminal.done": "Готово",
|
|
476
|
+
"terminal.exitCode": "код возврата {code}",
|
|
477
|
+
"terminal.expandAria": "Показать оставшиеся строки вывода: {n}",
|
|
478
|
+
"terminal.expandRest": "… ещё строк: {n}",
|
|
479
|
+
"terminal.failed": "Ошибка",
|
|
480
|
+
"terminal.noOutput": "Вывода нет",
|
|
481
|
+
"terminal.running": "Выполняется",
|
|
482
|
+
"terminal.signal": "сигнал {signal}",
|
|
483
|
+
"todo.completed": "{done}/{total} выполнено",
|
|
484
|
+
"todo.progress.active": "{active} в работе",
|
|
485
|
+
"todo.progress.done": "{done} выполнено",
|
|
486
|
+
"todo.progress.pending": "{pending} в очереди",
|
|
487
|
+
"todo.rowTitle": "Обновить список задач",
|
|
488
|
+
"todo.title": "Задачи",
|
|
489
|
+
"view.chat": "Чат"
|
|
490
|
+
},
|
|
491
|
+
"cordis": {
|
|
492
|
+
"a11y.defining": "Определение плагина",
|
|
493
|
+
"a11y.failed": "Определить не удалось",
|
|
494
|
+
"a11y.stopped": "Определение прервано",
|
|
495
|
+
"action.approve": "Разрешить",
|
|
496
|
+
"action.approveOnce": "Разрешить только эту версию",
|
|
497
|
+
"action.approvePlugin": "Разрешить будущие версии этого плагина",
|
|
498
|
+
"action.decline": "Отклонить",
|
|
499
|
+
"action.remove": "Удалить",
|
|
500
|
+
"action.retry": "Повторить",
|
|
501
|
+
"action.rollback": "Откатить",
|
|
502
|
+
"action.run": "Запустить",
|
|
503
|
+
"action.stop": "Остановить",
|
|
504
|
+
"body.clientCode": "Клиент",
|
|
505
|
+
"body.copied": "Скопировано",
|
|
506
|
+
"body.copy": "Копировать",
|
|
507
|
+
"body.hostCode": "Хост",
|
|
508
|
+
"body.output": "Результат",
|
|
509
|
+
"body.source": "Исходник плагина",
|
|
510
|
+
"panel.approvals.aria": "Подтверждения Cordis",
|
|
511
|
+
"panel.current": "Текущая: {packageId}",
|
|
512
|
+
"panel.empty": "Плагинов пока нет",
|
|
513
|
+
"panel.group.current": "Эта сессия",
|
|
514
|
+
"panel.group.others": "Другие сессии",
|
|
515
|
+
"panel.hint": "Управление запуском — в панели Cordis над настройками",
|
|
516
|
+
"panel.loading": "Чтение…",
|
|
517
|
+
"panel.next": "Следующая: {packageId}",
|
|
518
|
+
"panel.plugins.aria": "Плагины Cordis",
|
|
519
|
+
"panel.readFailed": "Не удалось прочитать список плагинов: {message}",
|
|
520
|
+
"panel.runningCount": "работает: {count}",
|
|
521
|
+
"panel.title": "Плагины Cordis",
|
|
522
|
+
"panel.trigger": "Плагин Cordis",
|
|
523
|
+
"panel.version": "Версия",
|
|
524
|
+
"purpose.missing": "(назначение не указано)",
|
|
525
|
+
"render.failedAbdicated": "Отрисовка в {slot} не удалась, вернули стандартный интерфейс:",
|
|
526
|
+
"render.failedHeld": "Отрисовка в {slot} не удалась:",
|
|
527
|
+
"row.defineTitle": "Зарегистрировать плагин Cordis",
|
|
528
|
+
"row.removeTitle": "Удалить плагин Cordis",
|
|
529
|
+
"row.runTitle": "Запустить плагин Cordis",
|
|
530
|
+
"row.stopTitle": "Остановить плагин Cordis",
|
|
531
|
+
"row.updateTitle": "Обновить плагин Cordis",
|
|
532
|
+
"run.removed": "Этого пакета больше нет",
|
|
533
|
+
"run.superseded": "Ниже есть более свежая карточка запуска",
|
|
534
|
+
"status.awaitingApproval": "Ждёт подтверждения",
|
|
535
|
+
"status.clientPending": "Клиент готов к активации",
|
|
536
|
+
"status.failed": "Запуск не удался",
|
|
537
|
+
"status.idle": "Готов",
|
|
538
|
+
"status.removed": "Удалён",
|
|
539
|
+
"status.running": "Работает",
|
|
540
|
+
"status.superseded": "Есть более свежий запуск"
|
|
541
|
+
},
|
|
542
|
+
"deliverables": {
|
|
543
|
+
"produced.label": "Создано",
|
|
544
|
+
"produced.more": "+ {count} файлов",
|
|
545
|
+
"produced.moreOne": "+ 1 файл",
|
|
546
|
+
"produced.open": "Открыть {name}",
|
|
547
|
+
"produced.showInFolder": "Показать в папке"
|
|
548
|
+
},
|
|
549
|
+
"directory-browser": {
|
|
550
|
+
"browser.cancel": "Отмена",
|
|
551
|
+
"browser.create": "Создать",
|
|
552
|
+
"browser.createIn": "Новая папка в «{name}»",
|
|
553
|
+
"browser.editPath": "Изменить путь",
|
|
554
|
+
"browser.folderName": "Имя папки",
|
|
555
|
+
"browser.home": "Домашняя папка",
|
|
556
|
+
"browser.loading": "Загрузка…",
|
|
557
|
+
"browser.newFolder": "Новая папка",
|
|
558
|
+
"browser.open": "Открыть",
|
|
559
|
+
"browser.showHidden": "Показывать скрытые файлы",
|
|
560
|
+
"browser.title": "Выбор рабочей папки",
|
|
561
|
+
"browser.truncated": "Слишком много папок; показано только начало.",
|
|
562
|
+
"browser.untitledFolder": "Без имени"
|
|
563
|
+
},
|
|
564
|
+
"dsh-market": {
|
|
565
|
+
"actWhy": "Почему не активен?",
|
|
566
|
+
"aiFix": "Починить с агентом",
|
|
567
|
+
"aiFixConservative": "Действуй осторожно: чини только явные ошибки из списка выше (падения при запуске, дубли записей, подтверждённые расхождения зависимостей). Предупреждения и записи к сведению (например, неподтверждённые диапазоны peer-зависимостей) трогай, только если они связаны с явной ошибкой. Не делай лишних обновлений и перестановок; объясняй каждое изменение и жди подтверждения.",
|
|
568
|
+
"aiFixCopied": "Промпт скопирован — вставьте его в новый диалог и отправьте, когда будете готовы",
|
|
569
|
+
"aiFixFail": "Буфер обмена недоступен — скопируйте диагностику ниже вручную",
|
|
570
|
+
"aiFixHint": "Передать диагностику новой сессии агента (скопировано в буфер; отправлять или нет — решаете вы)",
|
|
571
|
+
"aiFixIntro": "Помоги починить проблемы с плагинами DeepSeek Harness (профиль: {0}). Диагностика показала:",
|
|
572
|
+
"aiFixScope": "Можно менять порядок в dsh.profile.bundles, включать и выключать плагины, править cordis.patch.yml. Учти: официальные бандлы трогать нельзя; прежде чем что-то менять, изложи план.",
|
|
573
|
+
"all": "Все",
|
|
574
|
+
"alreadyInstalled": "✓ Установлен",
|
|
575
|
+
"approveBuilds": "Разрешить сборочные скрипты и повторить",
|
|
576
|
+
"autoBackup": "Резервная копия раз в сутки (при открытии маркета)",
|
|
577
|
+
"backTop": "Наверх",
|
|
578
|
+
"backupDone": "Копия загружена",
|
|
579
|
+
"backupDownload": "Выгрузить копию",
|
|
580
|
+
"backupHint": "Включает список плагинов и настройки профиля, но не node_modules. Восстановление ставит плагины заново по списку.",
|
|
581
|
+
"backupImport": "Импортировать и посмотреть",
|
|
582
|
+
"backupLocal": "Локальный файл",
|
|
583
|
+
"backupWorking": "Выполняется…",
|
|
584
|
+
"buildsSkipped": "Этому плагину нужны сборочные скрипты; по умолчанию они заблокированы ради безопасности. Разрешите их и переустановите:",
|
|
585
|
+
"busyWait": "Уже выполняется другая операция — дождитесь её окончания (установка, обновление и удаление идут по одной)",
|
|
586
|
+
"cancel": "Отмена",
|
|
587
|
+
"cancelOp": "Отменить",
|
|
588
|
+
"cancelled": "Отменено",
|
|
589
|
+
"cancelling": "Отмена…",
|
|
590
|
+
"catConflict": "Конфликты",
|
|
591
|
+
"catDeps": "Зависимости",
|
|
592
|
+
"catOrder": "Порядок",
|
|
593
|
+
"catsLess": "Свернуть",
|
|
594
|
+
"catsMore": "Ещё",
|
|
595
|
+
"checkBundles": "Порядок загрузки плагинов",
|
|
596
|
+
"checkBundlesEmpty": "Слои плагинов не объявлены",
|
|
597
|
+
"checkCommunity": "сообщество",
|
|
598
|
+
"checkDir": "каталог",
|
|
599
|
+
"checkDuplicates": "Повторяющиеся записи плагинов",
|
|
600
|
+
"checkDuplicatesEmpty": "Повторов нет",
|
|
601
|
+
"checkEntries": "записей (идентификаторы загрузчика)",
|
|
602
|
+
"checkErrors": "Ошибки",
|
|
603
|
+
"checkErrorsEmpty": "Ошибок нет",
|
|
604
|
+
"checkHoisted": "поднят",
|
|
605
|
+
"checkIssues": "Найдены проблемы",
|
|
606
|
+
"checkLoadFail": "Не удалось загрузить диагностику: ",
|
|
607
|
+
"checkLoading": "Анализ профиля…",
|
|
608
|
+
"checkMultiEmpty": "Пакетов ядра в нескольких версиях нет",
|
|
609
|
+
"checkMultiVersion": "Пакеты ядра в нескольких версиях",
|
|
610
|
+
"checkOfficial": "официальный",
|
|
611
|
+
"checkOrderTip": "порядок загрузки бандла сообщества конфликтует с объявленными правилами before/after",
|
|
612
|
+
"checkOrphans": "Неверные записи конфига",
|
|
613
|
+
"checkOrphansEmpty": "Неверных записей нет",
|
|
614
|
+
"checkOverridden": "переопределяет",
|
|
615
|
+
"checkOverrides": "Переопределения",
|
|
616
|
+
"checkOverridesEmpty": "Переопределений нет",
|
|
617
|
+
"checkPatch": "файл патча",
|
|
618
|
+
"checkPeerEmpty": "Расхождений версий зависимостей нет",
|
|
619
|
+
"checkPeerInfo": "{0} записей к сведению (не подтверждено)",
|
|
620
|
+
"checkPeerMismatches": "Расхождения версий зависимостей",
|
|
621
|
+
"checkPeerOverview": "расхождений: {0} · к сведению: {1}",
|
|
622
|
+
"checkProfile": "профиль",
|
|
623
|
+
"checkRange": "объявленный диапазон",
|
|
624
|
+
"checkRefresh": "Проверить заново",
|
|
625
|
+
"checkResolved": "разрешённая версия",
|
|
626
|
+
"checkSatisfied": "удовлетворено",
|
|
627
|
+
"checkSource": "источник",
|
|
628
|
+
"checkUnknown": "неизвестно",
|
|
629
|
+
"checkUnsatisfied": "не удовлетворено",
|
|
630
|
+
"checkWarnings": "Предупреждения",
|
|
631
|
+
"checkWarningsEmpty": "Предупреждений нет",
|
|
632
|
+
"cmdDetails": "Команда установки",
|
|
633
|
+
"confirm": "Подтвердить",
|
|
634
|
+
"confirmRemove": "Подтверждаете?",
|
|
635
|
+
"confirmTitle": "Установка",
|
|
636
|
+
"confirmWarn": "Плагины — сторонний код сообщества. Устанавливая, вы доверяете этому источнику; сборочные скрипты по умолчанию заблокированы.",
|
|
637
|
+
"credsWarning": "Внимание: в копию попадают настройки профиля и файлы, где могут лежать секреты (config.toml, .env и подобные). Локальная выгрузка ничего не вырезает, поэтому выгружайте на WebDAV, которому доверяете.",
|
|
638
|
+
"deprecatedBadge": "Устарел",
|
|
639
|
+
"deprecatedWarn": "Каталог помечает этот плагин как устаревший; новым пользователям ставить его не советуют.",
|
|
640
|
+
"diagExplain": "Что это",
|
|
641
|
+
"diagExplainText": "Эта страница ищет плагины, конфликтующие друг с другом, несовпадения версий зависимостей и неверный порядок загрузки. Термины:",
|
|
642
|
+
"diagOkAll": "Всё в порядке: конфликтов, проблем с зависимостями и порядком не найдено",
|
|
643
|
+
"diagTermBundle": "бандл — один пакет плагина, применяется по порядку",
|
|
644
|
+
"diagTermEntry": "запись — то, что плагин добавляет в работающую композицию",
|
|
645
|
+
"diagTermOrder": "порядок загрузки — очерёдность активации; более поздний может перекрыть более ранний",
|
|
646
|
+
"diagTermOrphan": "неверная запись — конфиг ссылается на то, чего нет",
|
|
647
|
+
"diagTermPeer": "peer-зависимость — пакет, который плагин ждёт от хоста",
|
|
648
|
+
"diagTermShadow": "перекрытие — старая копия из плагина закрывает более новую хостовую",
|
|
649
|
+
"disable": "Выключить",
|
|
650
|
+
"disabledState": "Выключен",
|
|
651
|
+
"dismiss": "Скрыть",
|
|
652
|
+
"dismissNotice": "Скрыть это уведомление",
|
|
653
|
+
"duplicateNames": "Плагины с одинаковыми именами (к сведению, это не конфликт)",
|
|
654
|
+
"empty": "Подходящих плагинов нет",
|
|
655
|
+
"enable": "Включить",
|
|
656
|
+
"envFix": "Настроить автоматически",
|
|
657
|
+
"envFixFail": "Автоматическая настройка не удалась — выгрузите журнал и пришлите нам файл",
|
|
658
|
+
"envFixing": "Настройка…",
|
|
659
|
+
"envMissing": "Перед установкой плагинов нужен один небольшой компонент",
|
|
660
|
+
"exportLog": "Выгрузить журнал",
|
|
661
|
+
"exportLogFail": "Не удалось выгрузить журнал",
|
|
662
|
+
"exportedLog": "Журнал выгружен: dsh-market-log.txt — приложите его к обращению",
|
|
663
|
+
"exportingLog": "Выгрузка…",
|
|
664
|
+
"filter": "Фильтр",
|
|
665
|
+
"filterDir": "Порядок",
|
|
666
|
+
"filterSort": "Поле сортировки",
|
|
667
|
+
"filterTime": "Вышло за",
|
|
668
|
+
"firstPage": "В начало",
|
|
669
|
+
"gist": "GitHub Gist",
|
|
670
|
+
"gistCreated": "Выгружено:",
|
|
671
|
+
"gistErrAuth": "GitHub не авторизовал: токен неверный или истёк, либо gh CLI не залогинен",
|
|
672
|
+
"gistErrInvalid": "Содержимое Gist повреждено или формат копии не поддерживается",
|
|
673
|
+
"gistErrNetwork": "GitHub недоступен — проверьте сеть или прокси",
|
|
674
|
+
"gistErrNoId": "Для обновления нужен идентификатор Gist — заполните поле или переключитесь на «Создать»",
|
|
675
|
+
"gistErrNotFound": "Gist не найден — проверьте идентификатор или ссылку",
|
|
676
|
+
"gistErrRateLimit": "Достигнут лимит GitHub, либо у токена нет права gist",
|
|
677
|
+
"gistErrTimeout": "GitHub не ответил вовремя — проверьте сеть и повторите",
|
|
678
|
+
"gistExport": "Выгрузить в Gist…",
|
|
679
|
+
"gistExportDone": "Выгружено в Gist",
|
|
680
|
+
"gistExportGo": "Выгрузить",
|
|
681
|
+
"gistExportHint": "Отмечено всё — полная копия вместе с настройками; если снять любую галочку, выгрузятся только выбранные плагины, а настройки — по отдельному флажку.",
|
|
682
|
+
"gistExportSelect": "Выберите плагины для выгрузки",
|
|
683
|
+
"gistId": "Идентификатор или ссылка на Gist (при выгрузке оставьте пустым, чтобы создать новый приватный)",
|
|
684
|
+
"gistImport": "Загрузить из Gist",
|
|
685
|
+
"gistIncludeConfig": "Включить файлы настроек (в них могут быть секреты)",
|
|
686
|
+
"gistModeCreate": "Создать новый приватный Gist",
|
|
687
|
+
"gistModeUpdate": "Обновить Gist из поля",
|
|
688
|
+
"gistNoPlugins": "В этом профиле нечего выгружать",
|
|
689
|
+
"gistNote": "В отличие от локальной выгрузки (архив на этой машине), Gist нужен для переноса между машинами: выгрузите в приватный Gist и загрузите на другом компьютере под тем же аккаунтом. Токен живёт только в памяти этой вкладки и никогда не пишется в браузерное хранилище; если залогинен gh CLI или задан DSH_GITHUB_TOKEN, вводить его не нужно. Gist приватный, до 1 МБ на файл.",
|
|
690
|
+
"gistSelectAll": "Выбрать все",
|
|
691
|
+
"gistSelectNone": "Снять выбор",
|
|
692
|
+
"gistSpecLocal": "локально",
|
|
693
|
+
"gistSrcEnv": "переменная DSH_GITHUB_TOKEN",
|
|
694
|
+
"gistSrcGh": "gh CLI",
|
|
695
|
+
"gistSrcToken": "введён вручную",
|
|
696
|
+
"gistToken": "Токен GitHub (только в памяти вкладки — после обновления страницы введите заново; оставьте пустым, чтобы использовать серверный DSH_GITHUB_TOKEN или залогиненный gh CLI)",
|
|
697
|
+
"gistVerify": "Проверить связь",
|
|
698
|
+
"gistVerifySource": "Проверено — источник токена: {0}",
|
|
699
|
+
"gotIt": "Понятно",
|
|
700
|
+
"groupAdd": "Добавить плагин",
|
|
701
|
+
"groupAddEmpty": "Все установленные плагины уже в этой группе",
|
|
702
|
+
"groupAddTheme": "Добавить тему",
|
|
703
|
+
"groupAssign": "Назначить",
|
|
704
|
+
"groupConfirmDelete": "Удалить группу?",
|
|
705
|
+
"groupCreate": "Создать",
|
|
706
|
+
"groupDelete": "Удалить группу",
|
|
707
|
+
"groupEmpty": "Пока пусто",
|
|
708
|
+
"groupMixed": "Включена частично",
|
|
709
|
+
"groupNamePh": "Название группы",
|
|
710
|
+
"groupNew": "Новая группа",
|
|
711
|
+
"groupRemove": "Убрать",
|
|
712
|
+
"groupRename": "Переименовать",
|
|
713
|
+
"hostDependencyMore": "ещё находок пропущено: {0}",
|
|
714
|
+
"hostDependencyWarning": "Плагин перечисляет в зависимостях известные общие пакеты хоста DSH. Это может перекрыть хостовую версию; проверка смотрит только манифест и не подтверждает, что в рантайме появился дубль:",
|
|
715
|
+
"hotBanner": "плагины готовы — обновите страницу, чтобы ими пользоваться",
|
|
716
|
+
"install": "Установить",
|
|
717
|
+
"installFail": "Установить не удалось",
|
|
718
|
+
"installReplacement": "Установить замену",
|
|
719
|
+
"installedBadge": "✓ Установлен",
|
|
720
|
+
"installedEmpty": "Плагинов сообщества пока нет — загляните во вкладку «Обзор»",
|
|
721
|
+
"installing": "Установка…",
|
|
722
|
+
"lastPage": "В конец",
|
|
723
|
+
"linkedDev": "подключён как разработка",
|
|
724
|
+
"loadFail": "Не удалось загрузить каталог плагинов, попробуйте позже",
|
|
725
|
+
"loading": "Загрузка каталога…",
|
|
726
|
+
"localOnly": "Адрес WebDAV и учётные данные остаются только в этом браузере.",
|
|
727
|
+
"marketNoToggle": "Сам маркет выключить нельзя",
|
|
728
|
+
"marketUpdate": "Доступно обновление маркета — обновить",
|
|
729
|
+
"nav": "Маркет плагинов",
|
|
730
|
+
"nextPage": "Дальше",
|
|
731
|
+
"noGroups": "Групп пока нет — создайте",
|
|
732
|
+
"notInstalled": "Не установлен",
|
|
733
|
+
"orderAlreadyOptimal": "Текущий порядок уже удовлетворяет всем правилам и зависимостям — переставлять нечего",
|
|
734
|
+
"orderApplied": "✓ Применено — перезапустите, чтобы вступило в силу",
|
|
735
|
+
"orderApply": "Применить порядок",
|
|
736
|
+
"orderAutoSort": "Отсортировать автоматически",
|
|
737
|
+
"orderConflicts": "конфликты before/after в текущем порядке",
|
|
738
|
+
"orderDiffHint": "Этот порядок изменит композицию: переопределений {0}, потерянных записей {1}, дублей {2}",
|
|
739
|
+
"orderDown": "↓",
|
|
740
|
+
"orderDrag": "Перетащите, чтобы изменить порядок",
|
|
741
|
+
"orderDragHint": "Тяните ⠿, чтобы переставить; «Применить порядок» сохранит",
|
|
742
|
+
"orderReset": "Сбросить черновик",
|
|
743
|
+
"orderSection": "Порядок загрузки",
|
|
744
|
+
"orderSuggestApply": "Применить предложенный порядок",
|
|
745
|
+
"orderSuggestHint": "Предложенный порядок (отсортирован по правилам before/after):",
|
|
746
|
+
"orderTrialFail": "Статическая проверка композиции не прошла: {0}",
|
|
747
|
+
"orderUp": "↑",
|
|
748
|
+
"orphanIdRequired": "нет идентификатора",
|
|
749
|
+
"orphanInsertNotArray": "неверный формат",
|
|
750
|
+
"orphanInsertTargetMissing": "цель не найдена",
|
|
751
|
+
"orphanInsertTargetNotGroup": "цель не является группой",
|
|
752
|
+
"orphanNameMismatch": "имя не совпадает",
|
|
753
|
+
"orphanPatchTargetMissing": "цель не найдена",
|
|
754
|
+
"orphanReasonOther": "другое",
|
|
755
|
+
"packagesDone": "обработано пакетов: {0}",
|
|
756
|
+
"pageInfo": "Страница {0} из {1}",
|
|
757
|
+
"partialNote": "Отменено — часть изменений уже применена",
|
|
758
|
+
"patchDisabled": "Выключен патчем",
|
|
759
|
+
"patchForced": "Включён патчем",
|
|
760
|
+
"perPage": "На странице",
|
|
761
|
+
"phaseBuilding": "Сборочные скрипты",
|
|
762
|
+
"phaseDownloading": "Загрузка",
|
|
763
|
+
"phaseLinking": "Связывание",
|
|
764
|
+
"phaseResolving": "Разрешение зависимостей",
|
|
765
|
+
"prevPage": "Назад",
|
|
766
|
+
"progressHint": "Первая установка скачивает и разрешает зависимости — крупные плагины занимают 1–3 минуты",
|
|
767
|
+
"published": "выпущен",
|
|
768
|
+
"readme": "README",
|
|
769
|
+
"refresh": "Обновить",
|
|
770
|
+
"refreshBanner": "изменения применены — обновите страницу, чтобы их увидеть",
|
|
771
|
+
"replacementHint": "Каталог предлагает",
|
|
772
|
+
"restartBanner": "изменения внесены — перезапустите DeepSeek Harness",
|
|
773
|
+
"restartFail": "Перезапустить не удалось",
|
|
774
|
+
"restartHint": "Как перезапустить: остановите текущий процесс dsh и запустите его снова (например, dsh web)",
|
|
775
|
+
"restartNow": "Перезапустить",
|
|
776
|
+
"restartTimeout": "Не дождались запуска DeepSeek Harness",
|
|
777
|
+
"restarting": "Перезапуск…",
|
|
778
|
+
"restoreConfirm": "Восстановление перезапишет настройки этого профиля и переустановит плагины. Продолжить?",
|
|
779
|
+
"restoreDone": "Восстановление завершено — перезапустите DeepSeek Harness",
|
|
780
|
+
"restoreMissing": "Плагинов из копии не установлено: {0}",
|
|
781
|
+
"restorePartial": "Восстановление продолжилось, но эти плагины установить не удалось:",
|
|
782
|
+
"restorePreviewDone": "Копия загружена. Проверьте вкладку «Установленные» и запускайте восстановление.",
|
|
783
|
+
"restoreStart": "Начать восстановление",
|
|
784
|
+
"searchPh": "Поиск плагинов: уведомления, терминал, память…",
|
|
785
|
+
"setCardDesc": "Версия маркета, обновление и удаление.",
|
|
786
|
+
"setSelfCancel": "Отмена",
|
|
787
|
+
"setSelfConfirm": "Удалить маркет плагинов? Поставить его заново можно будет только из командной строки.",
|
|
788
|
+
"setSelfFailed": "Операция не удалась",
|
|
789
|
+
"setSelfPurge": "Заодно стереть данные маркета",
|
|
790
|
+
"setSelfPurgeOff": "Данные маркета сохранятся. Учтите: плагины, которые он выключил, останутся выключенными, а интерфейса, чтобы вернуть их, после удаления не будет.",
|
|
791
|
+
"setSelfPurgeOn": "Будут удалены: список выключенных плагинов, свои группы и строки выключения, которые маркет записал в патч профиля, — выключенные им плагины снова заработают. Паролей и токенов это не касается: маркет их на диск не пишет.",
|
|
792
|
+
"setSelfRemove": "Удалить маркет плагинов",
|
|
793
|
+
"setSelfRemoveConfirm": "Удалить",
|
|
794
|
+
"setSelfRemoveHint": "Удаляет маркет из этого профиля. Остальные плагины не трогаются.",
|
|
795
|
+
"setSelfRemoved": "Удалён",
|
|
796
|
+
"setSelfRemovedHint": "Перезапустите DeepSeek Harness, чтобы завершить.",
|
|
797
|
+
"setSelfRestartAfter": "Перезапустить DeepSeek Harness сразу после удаления",
|
|
798
|
+
"setSelfRestartingHint": "Перезапуск DeepSeek Harness…",
|
|
799
|
+
"setSelfUpToDate": "Обновлений нет",
|
|
800
|
+
"setSelfUpdate": "Обновить",
|
|
801
|
+
"setSelfUpdateHint": "Обновление скачает новую версию; она заработает после перезапуска.",
|
|
802
|
+
"setSelfUpdateReady": "Доступна новая версия:",
|
|
803
|
+
"setSelfUpdatedHint": "Скачано. Перезапустите DeepSeek Harness, чтобы обновление вступило в силу: страница обновляется сразу, серверная половина — нет.",
|
|
804
|
+
"setSelfWorking": "Удаление…",
|
|
805
|
+
"sortAdded": "Дата выпуска",
|
|
806
|
+
"sortAsc": "По возрастанию",
|
|
807
|
+
"sortDesc": "По убыванию",
|
|
808
|
+
"sortNewest": "Сначала новые",
|
|
809
|
+
"sortOldest": "Сначала старые",
|
|
810
|
+
"sortStars": "Звёзды",
|
|
811
|
+
"stateBroken": "Установлен, но не прошёл проверку",
|
|
812
|
+
"stateDisabled": "Выключен",
|
|
813
|
+
"stateInert": "Установлен, но не является плагином слоя профиля",
|
|
814
|
+
"stateLive": "Работает (загружен на лету)",
|
|
815
|
+
"stateRestart": "Установлен — перезапустите, чтобы применить",
|
|
816
|
+
"subtitle": "Плагины сообщества для DeepSeek Harness",
|
|
817
|
+
"tabBackup": "Копия и восстановление",
|
|
818
|
+
"tabDiagnostics": "Диагностика",
|
|
819
|
+
"tabDiscover": "Обзор",
|
|
820
|
+
"tabGroups": "Группы",
|
|
821
|
+
"tabInstalled": "Установленные",
|
|
822
|
+
"tabList": "Список",
|
|
823
|
+
"tabThemes": "Темы",
|
|
824
|
+
"terminalWarn": "Похоже, это плагин для терминала: в веб-профиле он может ничего не делать или даже сломать запуск DeepSeek Harness. Прочитайте его README и ставьте в тот профиль, для которого он написан.",
|
|
825
|
+
"themeActive": "Активна",
|
|
826
|
+
"themeApply": "Применить",
|
|
827
|
+
"themeDeactivate": "Отключить",
|
|
828
|
+
"themeEmpty": "Других тем в каталоге пока нет — следите за обновлениями",
|
|
829
|
+
"timeAll": "Всё время",
|
|
830
|
+
"timeDay": "Сутки",
|
|
831
|
+
"timeMonth": "30 дней",
|
|
832
|
+
"timeQuarter": "90 дней",
|
|
833
|
+
"timeWeek": "7 дней",
|
|
834
|
+
"timeYear": "Год",
|
|
835
|
+
"toastReady": "установлен и работает",
|
|
836
|
+
"toastTheme": "теперь активна. Переключить можно в «Настройки → Маркет плагинов → Темы»",
|
|
837
|
+
"toggleFail": "Переключить не удалось",
|
|
838
|
+
"ungrouped": "Без группы",
|
|
839
|
+
"uninstall": "Удалить",
|
|
840
|
+
"uninstallConfirmDesc": "Плагин будет удалён из текущего профиля.",
|
|
841
|
+
"uninstalling": "Удаление…",
|
|
842
|
+
"upToDate": "Обновлений нет",
|
|
843
|
+
"update": "Обновить",
|
|
844
|
+
"updateAll": "Обновить все",
|
|
845
|
+
"updateFail": "Обновить не удалось",
|
|
846
|
+
"updateNow": "Обновить сейчас",
|
|
847
|
+
"updated": "✓ Обновлён — перезапустите, чтобы применить",
|
|
848
|
+
"updatedLive": "✓ Обновлён — работает",
|
|
849
|
+
"updating": "Обновление…",
|
|
850
|
+
"versionHint": "Версия маркета плагинов — указывайте её при обращении",
|
|
851
|
+
"viewReplacement": "Посмотреть замену",
|
|
852
|
+
"viewSource": "Исходник",
|
|
853
|
+
"webdav": "WebDAV",
|
|
854
|
+
"webdavNote": "Адрес WebDAV и имя пользователя остаются только в этом браузере; пароль хранится на сервере и вводится заново каждую сессию.",
|
|
855
|
+
"webdavPassword": "Пароль (необязательно)",
|
|
856
|
+
"webdavPreset": "Готовая настройка провайдера",
|
|
857
|
+
"webdavRestore": "Восстановить с WebDAV",
|
|
858
|
+
"webdavUpload": "Выгрузить копию",
|
|
859
|
+
"webdavUrl": "Адрес файла копии",
|
|
860
|
+
"webdavUser": "Имя пользователя (необязательно)"
|
|
861
|
+
},
|
|
862
|
+
"feedback": {
|
|
863
|
+
"action.dislike": "Плохой ответ",
|
|
864
|
+
"action.dislikeActive": "Убрать оценку",
|
|
865
|
+
"action.like": "Хороший ответ",
|
|
866
|
+
"action.likeActive": "Убрать оценку",
|
|
867
|
+
"error.conflict": "Эту оценку изменили в другом месте; показано актуальное состояние",
|
|
868
|
+
"error.generic": "Не удалось сохранить оценку",
|
|
869
|
+
"error.load": "Не удалось загрузить оценку",
|
|
870
|
+
"note.aria": "Комментарий к оценке",
|
|
871
|
+
"note.cancel": "Отмена",
|
|
872
|
+
"note.dialog": "Отзыв",
|
|
873
|
+
"note.open": "Добавить комментарий",
|
|
874
|
+
"note.placeholder": "Что получилось хорошо, а что нет? (необязательно)",
|
|
875
|
+
"note.save": "Сохранить"
|
|
876
|
+
},
|
|
877
|
+
"goal": {
|
|
878
|
+
"action.cancel": "Отменить правку",
|
|
879
|
+
"action.clear": "Снять цель",
|
|
880
|
+
"action.edit": "Изменить цель",
|
|
881
|
+
"action.pause": "Приостановить цель",
|
|
882
|
+
"action.resume": "Продолжить цель",
|
|
883
|
+
"action.save": "Сохранить цель",
|
|
884
|
+
"commandInput.aria": "Ввод команды",
|
|
885
|
+
"objective.aria": "Формулировка цели",
|
|
886
|
+
"phase.active": "Цель в работе",
|
|
887
|
+
"phase.blocked": "Цель заблокирована",
|
|
888
|
+
"phase.paused": "Цель на паузе"
|
|
889
|
+
},
|
|
890
|
+
"im-hub": {
|
|
891
|
+
"f.agentCwd": "Рабочая папка",
|
|
892
|
+
"f.agentCwdHint": "Папка для сессий агента; пусто — папка процесса dsh.",
|
|
893
|
+
"f.agentMaxMessageLength": "Длина сообщения",
|
|
894
|
+
"f.agentMaxMessageLengthHint": "Максимум символов в исходящем сообщении; длинные ответы разбиваются.",
|
|
895
|
+
"f.agentModel": "Модель",
|
|
896
|
+
"f.agentModelHint": "Переопределить модель; пусто — как задано в установке.",
|
|
897
|
+
"f.agentProvider": "Провайдер",
|
|
898
|
+
"f.agentProviderHint": "Переопределить провайдера модели; пусто — как задано в установке.",
|
|
899
|
+
"f.allowedUserIdsHint": "Идентификаторы через запятую; пусто — доступ всем (для боевой работы не советуем).",
|
|
900
|
+
"f.configured": "Задано",
|
|
901
|
+
"f.enabled": "Включено",
|
|
902
|
+
"f.enabledHint": "Общий выключатель всего IM-шлюза.",
|
|
903
|
+
"f.feishuAllowedUserIds": "Разрешённые open id",
|
|
904
|
+
"f.feishuAppId": "App id",
|
|
905
|
+
"f.feishuAppIdHint": "App id приложения Feishu (cli_…).",
|
|
906
|
+
"f.feishuAppSecret": "App secret",
|
|
907
|
+
"f.feishuEnabled": "Включено",
|
|
908
|
+
"f.feishuEnabledHint": "Включить адаптер Feishu по постоянному WebSocket-соединению (публичный адрес не нужен).",
|
|
909
|
+
"f.httpHost": "Адрес привязки",
|
|
910
|
+
"f.httpHostHint": "Адрес, на котором слушают HTTP-серверы в режиме вебхуков.",
|
|
911
|
+
"f.httpPort": "Порт привязки",
|
|
912
|
+
"f.httpPortHint": "Порт, на котором слушают HTTP-серверы в режиме вебхуков.",
|
|
913
|
+
"f.inherit": "Наследовать",
|
|
914
|
+
"f.larkAllowedUserIds": "Разрешённые open id",
|
|
915
|
+
"f.larkAppId": "App id",
|
|
916
|
+
"f.larkAppSecret": "App secret",
|
|
917
|
+
"f.larkEnabled": "Включено",
|
|
918
|
+
"f.larkEnabledHint": "Включить международный адаптер Lark (open.larksuite.com).",
|
|
919
|
+
"f.mockEnabled": "Включено",
|
|
920
|
+
"f.mockEnabledHint": "Адаптер только для тестов: локальный HTTP-эндпоинт без учётных данных платформы.",
|
|
921
|
+
"f.mockPort": "Порт",
|
|
922
|
+
"f.mockPortHint": "Фиксированный HTTP-порт тестового эндпоинта (0 — любой свободный).",
|
|
923
|
+
"f.notConfigured": "Не задано",
|
|
924
|
+
"f.off": "Выкл",
|
|
925
|
+
"f.on": "Вкл",
|
|
926
|
+
"f.secretHint": "Хранится на сервере и больше не показывается. Оставьте пустым, чтобы сохранить текущее значение.",
|
|
927
|
+
"f.telegramAllowedUserIds": "Разрешённые id пользователей",
|
|
928
|
+
"f.telegramEnabled": "Включено",
|
|
929
|
+
"f.telegramEnabledHint": "Включить адаптер Telegram Bot API с опросом обновлений.",
|
|
930
|
+
"f.telegramToken": "Токен бота",
|
|
931
|
+
"f.telegramTokenHint": "Токен от @BotFather (123456:ABC-DEF…).",
|
|
932
|
+
"f.wecomAgentId": "Agent id",
|
|
933
|
+
"f.wecomAgentIdHint": "Agent id приложения WeCom.",
|
|
934
|
+
"f.wecomAllowedUserIds": "Разрешённые id пользователей",
|
|
935
|
+
"f.wecomCorpId": "Corp id",
|
|
936
|
+
"f.wecomCorpIdHint": "Идентификатор организации из консоли WeCom.",
|
|
937
|
+
"f.wecomCorpSecret": "App secret",
|
|
938
|
+
"f.wecomEnabled": "Включено",
|
|
939
|
+
"f.wecomEnabledHint": "Включить адаптер WeCom с обратным вызовом (нужен публичный адрес).",
|
|
940
|
+
"f.wecomEncodingAesKey": "EncodingAESKey",
|
|
941
|
+
"f.wecomToken": "Токен обратного вызова",
|
|
942
|
+
"g.agent": "Агент",
|
|
943
|
+
"g.feishu": "Feishu (Китай)",
|
|
944
|
+
"g.general": "Общие",
|
|
945
|
+
"g.http": "HTTP (режим вебхуков)",
|
|
946
|
+
"g.lark": "Lark (международный)",
|
|
947
|
+
"g.mock": "Тестовый адаптер",
|
|
948
|
+
"g.telegram": "Telegram",
|
|
949
|
+
"g.wecom": "WeCom (WeChat Work)",
|
|
950
|
+
"p.agentCwd": "Например: /home/user/projects/my-agent (пусто — папка DSH)",
|
|
951
|
+
"p.agentMaxMessageLength": "Например: 4000",
|
|
952
|
+
"p.agentModel": "Например: deepseek-v4-flash (пусто — по умолчанию)",
|
|
953
|
+
"p.agentProvider": "Например: volcengine (пусто — по умолчанию)",
|
|
954
|
+
"p.feishuAllowedUserIds": "Например: ou_xxxxxxxxxxxxx",
|
|
955
|
+
"p.feishuAppId": "Например: cli_xxxxxxxxxxxxx",
|
|
956
|
+
"p.feishuAppSecret": "App Secret приложения Feishu",
|
|
957
|
+
"p.httpHost": "Например: 0.0.0.0",
|
|
958
|
+
"p.httpPort": "Например: 8080",
|
|
959
|
+
"p.larkAllowedUserIds": "Например: ou_xxxxxxxxxxxxx",
|
|
960
|
+
"p.larkAppId": "Например: cli_xxxxxxxxxxxxx",
|
|
961
|
+
"p.larkAppSecret": "App Secret приложения Lark",
|
|
962
|
+
"p.mockPort": "Например: 9099 (0 — автоматически)",
|
|
963
|
+
"p.telegramAllowedUserIds": "Например: 123456789, 987654321",
|
|
964
|
+
"p.telegramToken": "Например: 123456789:AA...",
|
|
965
|
+
"p.wecomAgentId": "Например: 1000002",
|
|
966
|
+
"p.wecomAllowedUserIds": "Например: ivanov, petrov",
|
|
967
|
+
"p.wecomCorpId": "Например: wwxxxxxxxxxxxxxx",
|
|
968
|
+
"p.wecomCorpSecret": "Secret приложения WeCom",
|
|
969
|
+
"p.wecomEncodingAesKey": "EncodingAESKey из 43 символов",
|
|
970
|
+
"p.wecomToken": "Токен адреса обратного вызова",
|
|
971
|
+
"settings.collapse": "Свернуть",
|
|
972
|
+
"settings.description": "Подключает агентов dsh к Feishu (Lark), WeCom и Telegram. Каждый чат получает свою сессию агента.",
|
|
973
|
+
"settings.discard": "Отменить",
|
|
974
|
+
"settings.expand": "Развернуть",
|
|
975
|
+
"settings.invalidNumber": "Введите корректное число",
|
|
976
|
+
"settings.overridden": "Переопределено",
|
|
977
|
+
"settings.readOnly": "Установка доступна только для чтения: настройки из интерфейса не меняются.",
|
|
978
|
+
"settings.reset": "Сбросить",
|
|
979
|
+
"settings.save": "Сохранить",
|
|
980
|
+
"settings.saveFailed": "Сохранить не удалось",
|
|
981
|
+
"settings.saving": "Сохранение…",
|
|
982
|
+
"settings.title": "IM-шлюз (dsh-im-hub)",
|
|
983
|
+
"settings.unsaved": "Есть несохранённые изменения"
|
|
984
|
+
},
|
|
985
|
+
"job": {
|
|
986
|
+
"count.idle.one": "{count} фоновая задача",
|
|
987
|
+
"count.idle.other": "{count} фоновых задач",
|
|
988
|
+
"count.live.one": "{count} фоновая задача выполняется",
|
|
989
|
+
"count.live.other": "{count} фоновых задач выполняется",
|
|
990
|
+
"duration.hours": "{hours} ч {minutes} мин",
|
|
991
|
+
"duration.minutes": "{minutes} мин {seconds} с",
|
|
992
|
+
"duration.seconds": "{seconds} с",
|
|
993
|
+
"duration.title.done": "Заняло {duration}",
|
|
994
|
+
"duration.title.live": "Выполняется {duration}",
|
|
995
|
+
"list.aria": "Фоновые задачи",
|
|
996
|
+
"status.completed": "завершена",
|
|
997
|
+
"status.failed": "ошибка",
|
|
998
|
+
"status.killed": "отменена",
|
|
999
|
+
"status.running": "выполняется",
|
|
1000
|
+
"status.stopping": "останавливается"
|
|
1001
|
+
},
|
|
1002
|
+
"model": {
|
|
1003
|
+
"action.reload": "Обновить",
|
|
1004
|
+
"blocked.composer": "Эта модель недоступна — выберите другую, чтобы продолжить",
|
|
1005
|
+
"command.description": "Выбрать модель для этого диалога",
|
|
1006
|
+
"effort.providerDefault": "По умолчанию",
|
|
1007
|
+
"empty.efforts": "У этой модели нет уровней рассуждения.",
|
|
1008
|
+
"empty.models": "Доступных моделей нет.",
|
|
1009
|
+
"error.action": "Операция с моделью не удалась: {message}",
|
|
1010
|
+
"menu.aria": "Модель и уровень рассуждения",
|
|
1011
|
+
"menu.effort": "Уровень рассуждений",
|
|
1012
|
+
"menu.model": "Модель",
|
|
1013
|
+
"option.loadError": "Каталог не загрузился: {message}",
|
|
1014
|
+
"status.loading": "Обновление списка моделей…",
|
|
1015
|
+
"trigger.aria": "Выбор модели, сейчас {model}",
|
|
1016
|
+
"trigger.ariaEffort": "Выбор модели, сейчас {model}, уровень рассуждения {effort}",
|
|
1017
|
+
"trigger.fallback": "Выбрать модель",
|
|
1018
|
+
"trigger.selectAria": "Выбрать модель",
|
|
1019
|
+
"warning.groupLoad": "{name} не загрузился: {message}"
|
|
1020
|
+
},
|
|
1021
|
+
"permission.access": {
|
|
1022
|
+
"confirm.acknowledge": "Я понимаю риски и хочу продолжить",
|
|
1023
|
+
"confirm.cancel": "Отмена",
|
|
1024
|
+
"confirm.description": "Полный доступ убирает часть подтверждений и позволяет агенту действовать напрямую, включая чувствительные операции, изменение файлов и внешние команды. Включайте, только если доверяете текущей задаче.",
|
|
1025
|
+
"confirm.enable": "Включить полный доступ",
|
|
1026
|
+
"confirm.title": "Включить полный доступ?"
|
|
1027
|
+
},
|
|
1028
|
+
"pin": {
|
|
1029
|
+
"action.pin": "Закрепить",
|
|
1030
|
+
"action.unpin": "Открепить"
|
|
1031
|
+
},
|
|
1032
|
+
"plan": {
|
|
1033
|
+
"chip.off.aria": "Режим плана выключен, нажмите, чтобы включить",
|
|
1034
|
+
"chip.off.title": "Режим плана выключен — нажмите, чтобы включить (/plan)",
|
|
1035
|
+
"chip.on.aria": "Режим плана включён, нажмите, чтобы выключить",
|
|
1036
|
+
"chip.on.title": "Режим плана включён — нажмите, чтобы выключить (/plan off)"
|
|
1037
|
+
},
|
|
1038
|
+
"plugin-store": {
|
|
1039
|
+
"dialog.close": "Закрыть магазин плагинов",
|
|
1040
|
+
"header.open": "Открыть магазин плагинов",
|
|
1041
|
+
"header.title": "Магазин плагинов DSH",
|
|
1042
|
+
"settings.tab": "Магазин плагинов",
|
|
1043
|
+
"store.analyzeFailed": "Передать разбор агенту не удалось",
|
|
1044
|
+
"store.analyzeHint": "Отправить эту ошибку в новую сессию агента для разбора.",
|
|
1045
|
+
"store.analyzeSent": "Отправлено агенту",
|
|
1046
|
+
"store.analyzeWithAgent": "Попросить агента разобраться",
|
|
1047
|
+
"store.analyzing": "Создаём сессию агента…",
|
|
1048
|
+
"store.cancel": "Отмена",
|
|
1049
|
+
"store.category": "Категория",
|
|
1050
|
+
"store.categoryAll": "Все категории",
|
|
1051
|
+
"store.confirmInstall": "Установить плагин",
|
|
1052
|
+
"store.confirmRemove": "Удалить плагин",
|
|
1053
|
+
"store.confirmUpdate": "Обновить плагин",
|
|
1054
|
+
"store.copied": "Ссылка для установки скопирована",
|
|
1055
|
+
"store.copyInstall": "Скопировать ссылку для установки",
|
|
1056
|
+
"store.disclaimer": "Наличие в каталоге не подтверждает работоспособность, совместимость, безопасность или качество.",
|
|
1057
|
+
"store.done": "Готово",
|
|
1058
|
+
"store.empty": "Под эти фильтры ничего не подходит",
|
|
1059
|
+
"store.install": "Установить",
|
|
1060
|
+
"store.installFailed": "Установить не удалось",
|
|
1061
|
+
"store.installSuccess": "Установлено. Перезапустите DSH Web, чтобы плагин заработал.",
|
|
1062
|
+
"store.installed": "Установлен",
|
|
1063
|
+
"store.installedLoadFailed": "Список установленных плагинов недоступен",
|
|
1064
|
+
"store.installedOnly": "Только установленные",
|
|
1065
|
+
"store.installing": "Установка…",
|
|
1066
|
+
"store.loadFailed": "Не удалось загрузить каталог",
|
|
1067
|
+
"store.loadMore": "Показать ещё",
|
|
1068
|
+
"store.loading": "Загрузка каталога плагинов…",
|
|
1069
|
+
"store.openDetails": "Открыть карточку в магазине",
|
|
1070
|
+
"store.refresh": "Обновить каталог",
|
|
1071
|
+
"store.refreshFailed": "Каталог не обновился; показаны последние успешные данные",
|
|
1072
|
+
"store.remove": "Удалить плагин",
|
|
1073
|
+
"store.removeDetail": "Меняется только зависимость текущего профиля. Чтобы удаление вступило в силу, перезапустите DSH Web.",
|
|
1074
|
+
"store.removeFailed": "Удалить не удалось",
|
|
1075
|
+
"store.removeLead": "Плагин будет удалён из текущего профиля DSH Web.",
|
|
1076
|
+
"store.removeSuccess": "Удалено. Перезапустите DSH Web, чтобы изменение вступило в силу.",
|
|
1077
|
+
"store.removeTitle": "Удаление плагина",
|
|
1078
|
+
"store.removing": "Удаление…",
|
|
1079
|
+
"store.results": "{visible} из {total} проектов",
|
|
1080
|
+
"store.retry": "Повторить",
|
|
1081
|
+
"store.riskAcknowledge": "Я понимаю риск и хочу установить этот сторонний плагин",
|
|
1082
|
+
"store.riskDetail": "Присутствие в каталоге не является проверкой безопасности, совместимости или качества. Установленный код выполняется с правами процесса DSH, а чтобы он заработал, DSH Web нужно перезапустить.",
|
|
1083
|
+
"store.riskLead": "В текущий профиль DSH Web будет установлен код из стороннего репозитория.",
|
|
1084
|
+
"store.riskTitle": "Подтверждение риска стороннего плагина",
|
|
1085
|
+
"store.search": "Поиск по названию, автору, описанию или теме",
|
|
1086
|
+
"store.sort": "Сортировка",
|
|
1087
|
+
"store.sortName": "Название",
|
|
1088
|
+
"store.sortRecommended": "Рекомендуемые",
|
|
1089
|
+
"store.sortStars": "Звёзды",
|
|
1090
|
+
"store.sortUpdated": "Недавно обновлённые",
|
|
1091
|
+
"store.stars": "звёзд: {count}",
|
|
1092
|
+
"store.topicListed": "Указана тема",
|
|
1093
|
+
"store.update": "Обновить",
|
|
1094
|
+
"store.updateAvailable": "Есть обновление",
|
|
1095
|
+
"store.updateRiskDetail": "Обновление заменит версию плагина в этом профиле. Чтобы оно вступило в силу, перезапустите DSH Web.",
|
|
1096
|
+
"store.updateRiskLead": "В текущий профиль DSH Web будет установлена более новая ревизия стороннего репозитория.",
|
|
1097
|
+
"store.updateRiskTitle": "Подтверждение обновления стороннего плагина",
|
|
1098
|
+
"store.updateSuccess": "Обновлено. Перезапустите DSH Web, чтобы плагин заработал.",
|
|
1099
|
+
"store.updated": "Каталог обновлён {date}",
|
|
1100
|
+
"store.updating": "Обновление…",
|
|
1101
|
+
"store.validation.check-failed": "Проверка структуры не пройдена",
|
|
1102
|
+
"store.validation.check-pending": "Проверка структуры в очереди",
|
|
1103
|
+
"store.validation.check-running": "Идёт проверка структуры",
|
|
1104
|
+
"store.validation.expired": "Нужна повторная проверка",
|
|
1105
|
+
"store.validation.inconclusive": "Требует рассмотрения",
|
|
1106
|
+
"store.validation.not-applicable": "Вне проверки плагинов",
|
|
1107
|
+
"store.validation.recorded": "Есть запись о проверке",
|
|
1108
|
+
"store.validation.sandbox-failed": "Проверка в песочнице не пройдена",
|
|
1109
|
+
"store.validation.sandbox-pending": "Проверка в песочнице в очереди",
|
|
1110
|
+
"store.validation.sandbox-running": "Идёт проверка в песочнице",
|
|
1111
|
+
"store.validation.security-review": "Проверка безопасности",
|
|
1112
|
+
"store.validation.unrecognized": "Требует опознания",
|
|
1113
|
+
"store.validation.verified": "Проверен",
|
|
1114
|
+
"store.verified": "Проверен",
|
|
1115
|
+
"store.verifiedOnly": "Только проверенные"
|
|
1116
|
+
},
|
|
1117
|
+
"question": {
|
|
1118
|
+
"action.next": "Дальше",
|
|
1119
|
+
"action.skip": "Пропустить вопрос",
|
|
1120
|
+
"custom.placeholder": "Впишите свой ответ",
|
|
1121
|
+
"error.incomplete": "Сначала ответьте на этот вопрос.",
|
|
1122
|
+
"error.unanswered": "Выберите вариант или впишите свой ответ.",
|
|
1123
|
+
"nav.cancel": "Закрыть все вопросы",
|
|
1124
|
+
"nav.maximize": "Развернуть карточку вопроса",
|
|
1125
|
+
"nav.minimize": "Свернуть карточку вопроса",
|
|
1126
|
+
"nav.next": "Следующий вопрос",
|
|
1127
|
+
"nav.prev": "Предыдущий вопрос",
|
|
1128
|
+
"option.recommended": "Рекомендуем",
|
|
1129
|
+
"plan.approve": "Утвердить",
|
|
1130
|
+
"plan.decline": "Отклонить",
|
|
1131
|
+
"plan.discuss": "Обсудить",
|
|
1132
|
+
"plan.header": "Проверка плана"
|
|
1133
|
+
},
|
|
1134
|
+
"reference": {
|
|
1135
|
+
"candidate.file": "Файл",
|
|
1136
|
+
"candidate.folder": "Папка",
|
|
1137
|
+
"candidate.noCwd": "(нет cwd)",
|
|
1138
|
+
"candidate.session": "Сессия",
|
|
1139
|
+
"section.files": "Файлы и папки",
|
|
1140
|
+
"section.sessions": "Диалоги сессий"
|
|
1141
|
+
},
|
|
1142
|
+
"session-log-download": {
|
|
1143
|
+
"dialog.close": "Закрыть",
|
|
1144
|
+
"dialog.commandFailed": "Не удалось запустить экспорт сессии.",
|
|
1145
|
+
"dialog.errorTitle": "Экспорт сессии не удался",
|
|
1146
|
+
"dialog.preparingDescription": "Готовится ZIP с этой сессией, её подсессиями и вложениями.",
|
|
1147
|
+
"dialog.preparingTitle": "Экспорт сессии",
|
|
1148
|
+
"dialog.successDescription": "Браузер загружает ZIP с сессией.",
|
|
1149
|
+
"dialog.successTitle": "Загрузка сессии началась"
|
|
1150
|
+
},
|
|
1151
|
+
"settings": {
|
|
1152
|
+
"close": "Закрыть",
|
|
1153
|
+
"general.nav": "Общие",
|
|
1154
|
+
"openDocument": "Открыть файл настроек",
|
|
1155
|
+
"openDocument.error": "Не удалось открыть файл настроек",
|
|
1156
|
+
"title": "Настройки",
|
|
1157
|
+
"trigger": "Настройки"
|
|
1158
|
+
},
|
|
1159
|
+
"settings.agentPreset": {
|
|
1160
|
+
"brokenBadge": "Не загрузился",
|
|
1161
|
+
"brokenNoCopy": "Пресет, который не загрузился, скопировать нельзя",
|
|
1162
|
+
"builtIn": "Встроенный",
|
|
1163
|
+
"builtInGroup": "Встроенные",
|
|
1164
|
+
"cancel": "Отмена",
|
|
1165
|
+
"close": "Закрыть",
|
|
1166
|
+
"composition": "Композиция (agent.cordis.yml)",
|
|
1167
|
+
"copyIntro": "Пресет копируется целиком на этой машине. Идентификатор станет именем каталога и позже не меняется; всё остальное правится в файлах самого пресета.",
|
|
1168
|
+
"copyOf": "Скопирован с",
|
|
1169
|
+
"copyTitle": "Скопировать пресет",
|
|
1170
|
+
"create": "Создать",
|
|
1171
|
+
"creating": "Создание…",
|
|
1172
|
+
"creatorDraft": "Набросать свой пресет в режиме «Конструктор»",
|
|
1173
|
+
"customGroup": "Свои",
|
|
1174
|
+
"delete": "Удалить",
|
|
1175
|
+
"deleteConfirm": "Удалить",
|
|
1176
|
+
"deleteDescription": "Каталог пресета будет удалён. Уже запущенные на нём сессии продолжат работать, но выбрать его для новых нельзя.",
|
|
1177
|
+
"deleteTitle": "Удалить этот пресет?",
|
|
1178
|
+
"deleting": "Удаление…",
|
|
1179
|
+
"description": "Действует на сессии, запущенные с этого момента. Работающие сессии остаются на своём пресете.",
|
|
1180
|
+
"displayName": "Название",
|
|
1181
|
+
"displayNamePlaceholder": "Показывается в списке; по умолчанию — идентификатор",
|
|
1182
|
+
"duplicate": "Скопировать",
|
|
1183
|
+
"duplicateUnavailable": "В этой установке нет каталога пресетов с правом записи",
|
|
1184
|
+
"error": "Не удалось загрузить пресеты агента.",
|
|
1185
|
+
"headerHint": "Пресет агента, на котором идёт сессия; зафиксирован при запуске",
|
|
1186
|
+
"idInvalid": "Строчные буквы, цифры и дефисы, начиная с буквы или цифры.",
|
|
1187
|
+
"idRequired": "Задайте пресету идентификатор.",
|
|
1188
|
+
"idTaken": "Пресет с таким идентификатором уже есть.",
|
|
1189
|
+
"inUse": "Используется",
|
|
1190
|
+
"loading": "Загрузка пресетов…",
|
|
1191
|
+
"nav": "Пресеты агента",
|
|
1192
|
+
"noDescription": "Без описания.",
|
|
1193
|
+
"openLocation": "Открыть папку",
|
|
1194
|
+
"presetCodeDescription": "Всё, что умеет обычный режим, но инструменты отдаются через Code Mode SDK: модель собирает многошаговые операции в одну программу на TypeScript.",
|
|
1195
|
+
"presetCodeName": "Режим кода",
|
|
1196
|
+
"presetCordisDescription": "Для создания своих пресетов: всё из обычного режима плюс инспекция рантайма, опыты с плагинами и подсказки по авторству пресетов.",
|
|
1197
|
+
"presetCordisName": "Конструктор",
|
|
1198
|
+
"presetId": "Идентификатор",
|
|
1199
|
+
"presetIdPlaceholder": "my-agent",
|
|
1200
|
+
"presetMinimalDescription": "Агент из двух инструментов: постоянный bash и str_replace_editor.",
|
|
1201
|
+
"presetMinimalName": "Минимальный режим",
|
|
1202
|
+
"presetStandardDescription": "Полноценный кодинг-агент: правка файлов, консоль, поиск по файлам и в вебе, скиллы, планирование, цели, субагенты и воркфлоу.",
|
|
1203
|
+
"presetStandardName": "Обычный режим",
|
|
1204
|
+
"retry": "Повторить",
|
|
1205
|
+
"revealedPathLabel": "Файлы пресета:",
|
|
1206
|
+
"seatHint": "Пресет агента для сессии, которую вы собираетесь запустить",
|
|
1207
|
+
"sectionIntro": "Пресет — это состав плагинов, на котором работает агент сессии: его инструменты, промпт и возможности. Скопируйте готовый и допилите под себя или попросите агента набросать свой в режиме «Конструктор».",
|
|
1208
|
+
"setDefault": "Сделать основным",
|
|
1209
|
+
"showLocation": "Показать расположение",
|
|
1210
|
+
"title": "Пресет агента",
|
|
1211
|
+
"userTrust": "Свой",
|
|
1212
|
+
"view": "Посмотреть"
|
|
1213
|
+
},
|
|
1214
|
+
"settings.locale": {
|
|
1215
|
+
"language.title": "Язык"
|
|
1216
|
+
},
|
|
1217
|
+
"settings.models": {
|
|
1218
|
+
"add": "Добавить провайдера",
|
|
1219
|
+
"addModel": "Добавить модель",
|
|
1220
|
+
"advancedHint": "Остальные поля живут в settings.yaml — правьте этот раздел напрямую.",
|
|
1221
|
+
"apply": "Применить",
|
|
1222
|
+
"applying": "Применение…",
|
|
1223
|
+
"baseUrl": "Базовый URL",
|
|
1224
|
+
"baseUrlDefault": "По умолчанию у провайдера",
|
|
1225
|
+
"cancel": "Отмена",
|
|
1226
|
+
"close": "Закрыть",
|
|
1227
|
+
"conflict": "Пока карточка была открыта, настройки изменил кто-то ещё. Закройте и откройте заново, чтобы править актуальные значения.",
|
|
1228
|
+
"contextWindow": "Окно контекста",
|
|
1229
|
+
"contextWindowPlaceholder": "Как у провайдера по умолчанию",
|
|
1230
|
+
"create": "Создать провайдера",
|
|
1231
|
+
"creating": "Создание…",
|
|
1232
|
+
"credentialConfigured": "API-ключ задан",
|
|
1233
|
+
"credentialMissing": "API-ключ не задан",
|
|
1234
|
+
"customAdd": "Добавить своего провайдера",
|
|
1235
|
+
"customApi": "Протокол API",
|
|
1236
|
+
"customApiUnset": "Не выбран",
|
|
1237
|
+
"customDisplayName": "Отображаемое имя",
|
|
1238
|
+
"customNeedsBaseUrl": "Своему провайдеру нужен базовый URL.",
|
|
1239
|
+
"customNeedsModels": "Своему провайдеру нужна хотя бы одна модель.",
|
|
1240
|
+
"customRoute": "Идентификатор провайдера",
|
|
1241
|
+
"customRouteHint": "Идентификатор в нижнем регистре, начинается с буквы. По нему провайдер адресуется в запросах, и так же называется его ключ.",
|
|
1242
|
+
"customRouteInvalid": "Начните со строчной буквы, дальше строчные буквы, цифры и дефисы.",
|
|
1243
|
+
"customRouteTaken": "Такой идентификатор уже занят другим провайдером.",
|
|
1244
|
+
"customTag": "Свой",
|
|
1245
|
+
"customTitle": "Свой провайдер",
|
|
1246
|
+
"customized": "Настройки изменены",
|
|
1247
|
+
"deleteConfirm": "Удалить {provider}",
|
|
1248
|
+
"deleteDescription": "Удаление {provider} убирает его настройки. Ключ, которым он пользовался, хранится отдельно и останется.",
|
|
1249
|
+
"deleteDescriptionWithCredential": "Удаление {provider} убирает его настройки и сохранённый API-ключ.",
|
|
1250
|
+
"deleteTitle": "Удалить {provider}?",
|
|
1251
|
+
"deleting": "Удаление {provider}…",
|
|
1252
|
+
"edit": "Изменить",
|
|
1253
|
+
"editProvider": "Изменить {provider}",
|
|
1254
|
+
"fetchAdopt": "Добавить выбранные",
|
|
1255
|
+
"fetchDescription": "Вот модели, доступные у этого провайдера. Отметьте те, что нужно добавить.",
|
|
1256
|
+
"fetchDeselectAll": "Снять выбор",
|
|
1257
|
+
"fetchEmpty": "Провайдер не вернул ни одной модели. Добавьте их вручную.",
|
|
1258
|
+
"fetchModels": "Запросить список моделей",
|
|
1259
|
+
"fetchNeedsBaseUrl": "Сначала укажите базовый URL, потом запрашивайте.",
|
|
1260
|
+
"fetchSelectAll": "Выбрать все",
|
|
1261
|
+
"fetchTitle": "Выберите модели",
|
|
1262
|
+
"fetching": "Запрос к провайдеру…",
|
|
1263
|
+
"intro": "Введите свои API-ключи, чтобы пользоваться моделями этих провайдеров.",
|
|
1264
|
+
"keyBlank": "Введите API-ключ или оставьте поле пустым, чтобы сохранить прежний.",
|
|
1265
|
+
"keyBlankNew": "Введите API-ключ или оставьте поле пустым, если провайдер авторизуется иначе.",
|
|
1266
|
+
"keyEnvLocked": "Задан переменной окружения (только чтение)",
|
|
1267
|
+
"keyIllegalCharacters": "Ключ в недопустимом формате. Проверьте его.",
|
|
1268
|
+
"keyInput": "API-ключ",
|
|
1269
|
+
"keyPlaceholder": "Введите API-ключ",
|
|
1270
|
+
"keyPlaceholderNative": "Введите API-ключ или оставьте пустым для авторизации из окружения",
|
|
1271
|
+
"keyRequired": "Чтобы продолжить, введите API-ключ.",
|
|
1272
|
+
"keyStored": "Задан — введите новое значение, чтобы заменить",
|
|
1273
|
+
"loadFailed": "Не удалось загрузить список провайдеров",
|
|
1274
|
+
"maxTokens": "Максимум выходных токенов",
|
|
1275
|
+
"maxTokensPlaceholder": "Как у провайдера по умолчанию",
|
|
1276
|
+
"model": "Модель",
|
|
1277
|
+
"modelAdvanced": "Ёмкости",
|
|
1278
|
+
"modelCapacityInvalid": "Ёмкость задаётся числом, можно с суффиксом K или M.",
|
|
1279
|
+
"modelContextInvalid": "Окно контекста — положительное число, например 131072, 256K или 1M.",
|
|
1280
|
+
"modelContextWindow": "Окно контекста",
|
|
1281
|
+
"modelDuplicate": "Каждый идентификатор модели встречается один раз.",
|
|
1282
|
+
"modelId": "Идентификатор модели",
|
|
1283
|
+
"modelIdDuplicate": "Идентификатор модели должен быть уникальным.",
|
|
1284
|
+
"modelIdRequired": "Нужен идентификатор модели.",
|
|
1285
|
+
"modelMaxTokens": "Максимум выходных токенов",
|
|
1286
|
+
"modelMaxTokensInvalid": "Максимум выходных токенов — положительное число, например 8192, 64K или 1M.",
|
|
1287
|
+
"modelName": "Отображаемое имя",
|
|
1288
|
+
"modelNameInvalid": "Отображаемое имя не может быть пустым.",
|
|
1289
|
+
"modelNamePlaceholder": "Пусто — возьмётся идентификатор модели",
|
|
1290
|
+
"models": "Модели",
|
|
1291
|
+
"modelsCustomized": "Каталог моделей изменён",
|
|
1292
|
+
"modelsEmpty": "В выборе моделей не будет ничего. Неуказанные идентификаторы всё равно можно отправлять напрямую.",
|
|
1293
|
+
"modelsInherited": "По умолчанию, как в адаптере",
|
|
1294
|
+
"nav": "Модели",
|
|
1295
|
+
"onboardingDescription": "Настройте официального провайдера DeepSeek, чтобы начать.",
|
|
1296
|
+
"onboardingLater": "Настроить позже",
|
|
1297
|
+
"onboardingSave": "Сохранить и продолжить",
|
|
1298
|
+
"onboardingSaving": "Сохранение…",
|
|
1299
|
+
"onboardingTitle": "Добавьте API-ключ, чтобы начать",
|
|
1300
|
+
"provider": "Провайдер",
|
|
1301
|
+
"readOnly": "В этой установке файл настроек доступен только для чтения.",
|
|
1302
|
+
"remove": "Удалить",
|
|
1303
|
+
"removeModel": "Удалить модель",
|
|
1304
|
+
"removeProvider": "Удалить {provider}",
|
|
1305
|
+
"resetModels": "Вернуть значения по умолчанию",
|
|
1306
|
+
"retry": "Повторить",
|
|
1307
|
+
"savedProvider": "{provider} сохранён.",
|
|
1308
|
+
"title": "Модели",
|
|
1309
|
+
"welcomeError": "Не удалось сохранить подтверждение. Попробуйте ещё раз."
|
|
1310
|
+
},
|
|
1311
|
+
"settings.permission": {
|
|
1312
|
+
"confirm.acknowledge": "Я понимаю риски и хочу продолжить",
|
|
1313
|
+
"confirm.cancel": "Отмена",
|
|
1314
|
+
"confirm.description": "Полный доступ позволяет новым сессиям реже спрашивать подтверждение и действовать напрямую, включая чувствительные операции, изменение файлов и внешние команды. Включайте, только если доверяете будущим задачам.",
|
|
1315
|
+
"confirm.enable": "Включить полный доступ",
|
|
1316
|
+
"confirm.title": "Включить полный доступ?",
|
|
1317
|
+
"description": "Режим разрешений по умолчанию для новых сессий",
|
|
1318
|
+
"loading": "Загрузка",
|
|
1319
|
+
"title": "Разрешения",
|
|
1320
|
+
"unavailable": "Недоступно"
|
|
1321
|
+
},
|
|
1322
|
+
"settings.pluginInventory": {
|
|
1323
|
+
"active": "Подключён",
|
|
1324
|
+
"catalog": "Список плагинов",
|
|
1325
|
+
"configuration": "Настройки",
|
|
1326
|
+
"cordis": "Состояние Cordis",
|
|
1327
|
+
"disabledTag": "Выключен",
|
|
1328
|
+
"empty": "Плагинов нет.",
|
|
1329
|
+
"emptySearch": "Подходящих плагинов нет.",
|
|
1330
|
+
"enabledTag": "Включён",
|
|
1331
|
+
"error": "Плагины временно недоступны.",
|
|
1332
|
+
"failed": "Не удалось подключить",
|
|
1333
|
+
"loading": "Чтение плагинов…",
|
|
1334
|
+
"loadingPhase": "Загрузка",
|
|
1335
|
+
"pending": "Ожидает зависимости",
|
|
1336
|
+
"retry": "Повторить",
|
|
1337
|
+
"search": "Поиск плагинов",
|
|
1338
|
+
"tab": "Список плагинов",
|
|
1339
|
+
"unloading": "Выгружается",
|
|
1340
|
+
"unobserved": "Не подключён"
|
|
1341
|
+
},
|
|
1342
|
+
"settings.plugins": {
|
|
1343
|
+
"agentLoopDescription": "Как агент раздаёт вызовы инструментов.",
|
|
1344
|
+
"agentLoopMaxParallel": "Параллельных вызовов",
|
|
1345
|
+
"agentLoopMaxParallelHint": "Сколько безопасных для параллели вызовов идёт одновременно в пределах шага.",
|
|
1346
|
+
"agentLoopTitle": "Цикл агента",
|
|
1347
|
+
"bashDescription": "Ограничения для каждой команды, которую запускает агент.",
|
|
1348
|
+
"bashMaxOutputBytes": "Предел вывода на поток (байт)",
|
|
1349
|
+
"bashMaxOutputBytesHint": "Всё сверх предела уходит во временный файл, а не теряется.",
|
|
1350
|
+
"bashTimeoutMs": "Таймаут команды (мс)",
|
|
1351
|
+
"bashTimeoutMsHint": "Сколько команда может выполняться до принудительного завершения.",
|
|
1352
|
+
"bashTitle": "Консоль",
|
|
1353
|
+
"collapse": "Скрыть настройки",
|
|
1354
|
+
"configurableTab": "Настройки плагинов",
|
|
1355
|
+
"discard": "Отменить",
|
|
1356
|
+
"empty": "В этой установке настройки плагинов не выведены.",
|
|
1357
|
+
"expand": "Показать настройки",
|
|
1358
|
+
"intro": "Настройка и просмотр плагинов, установленных в этой сборке.",
|
|
1359
|
+
"invalidNumber": "Введите число или оставьте пустым, чтобы взять значение по умолчанию.",
|
|
1360
|
+
"nav": "Плагины",
|
|
1361
|
+
"overridden": "Переопределено",
|
|
1362
|
+
"readOnly": "В этой установке настройки доступны только для чтения.",
|
|
1363
|
+
"reset": "Вернуть по умолчанию",
|
|
1364
|
+
"save": "Сохранить",
|
|
1365
|
+
"saveFailed": "Установка не приняла эти значения; они оставлены, чтобы вы их поправили.",
|
|
1366
|
+
"saving": "Сохранение…",
|
|
1367
|
+
"tabs": "Разделы плагинов",
|
|
1368
|
+
"title": "Плагины",
|
|
1369
|
+
"unsaved": "Не сохранено",
|
|
1370
|
+
"webSearchApiKey": "API-ключ",
|
|
1371
|
+
"webSearchApiKeyHint": "Хранится вне файла настроек. Оставьте пустым, чтобы сохранить текущий ключ.",
|
|
1372
|
+
"webSearchApiKeySet": "Ключ задан.",
|
|
1373
|
+
"webSearchApiKeyUnset": "Ключ не задан; без него поиск недоступен.",
|
|
1374
|
+
"webSearchBaseUrl": "Адрес сервиса",
|
|
1375
|
+
"webSearchBaseUrlHint": "Оставьте пустым, чтобы взять адрес провайдера по умолчанию.",
|
|
1376
|
+
"webSearchDescription": "Поисковый провайдер DeepSeek.",
|
|
1377
|
+
"webSearchMaxUses": "Максимум поисков на запрос",
|
|
1378
|
+
"webSearchMaxUsesHint": "Сколько раз в рамках одного запроса можно искать, прежде чем придётся отвечать.",
|
|
1379
|
+
"webSearchTitle": "Поиск в вебе"
|
|
1380
|
+
},
|
|
1381
|
+
"settings.subscriptions": {
|
|
1382
|
+
"cancel": "Отмена",
|
|
1383
|
+
"checking": "Проверка…",
|
|
1384
|
+
"generating": "Генерация изображения…",
|
|
1385
|
+
"image": "изображение",
|
|
1386
|
+
"imageClose": "Закрыть",
|
|
1387
|
+
"imageLoadFailed": "Повторить",
|
|
1388
|
+
"imageLoading": "Загрузка…",
|
|
1389
|
+
"imagePreview": "Просмотр изображения",
|
|
1390
|
+
"intro": "Вход и выход из провайдеров по подписке. Вход открывает страницу авторизации в новой вкладке; без браузера можно вставить адрес обратного вызова или код.",
|
|
1391
|
+
"loggedIn": "Выполнен вход",
|
|
1392
|
+
"loggedInAccount": "Вход выполнен как {account}",
|
|
1393
|
+
"loggedInAccountExpires": "Вход выполнен как {account} · истекает {date}",
|
|
1394
|
+
"loggedInExpires": "Вход выполнен · истекает {date}",
|
|
1395
|
+
"login": "Войти",
|
|
1396
|
+
"loginInProgress": "Идёт вход…",
|
|
1397
|
+
"loginMissingUrl": "ответ на вход пришёл без authorizeUrl",
|
|
1398
|
+
"logout": "Выйти",
|
|
1399
|
+
"logoutConfirm": "Выйти из {provider}?",
|
|
1400
|
+
"manualPlaceholder": "Вставьте адрес обратного вызова или код",
|
|
1401
|
+
"manualSummary": "Не работает вход через браузер? Вставьте адрес обратного вызова или код",
|
|
1402
|
+
"nav": "Подписки",
|
|
1403
|
+
"notLoggedIn": "Вход не выполнен",
|
|
1404
|
+
"submit": "Отправить",
|
|
1405
|
+
"unavailable": "Нет связи; состояние подписок не загрузить.",
|
|
1406
|
+
"usageEmpty": "Окна расхода не переданы.",
|
|
1407
|
+
"usageError": "Не удалось получить расход: {message}",
|
|
1408
|
+
"usageLoading": "Загрузка расхода…",
|
|
1409
|
+
"usagePlan": "Тариф: {plan}",
|
|
1410
|
+
"usageRefresh": "Обновить",
|
|
1411
|
+
"usageResets": "сбрасывается {date}",
|
|
1412
|
+
"usageSession": "Окно 5 часов",
|
|
1413
|
+
"usageTitle": "Расход",
|
|
1414
|
+
"usageWeekly": "За неделю",
|
|
1415
|
+
"usageWindow": "Окно",
|
|
1416
|
+
"viewImage": "Посмотреть изображение",
|
|
1417
|
+
"viewImageNamed": "Посмотреть {name}"
|
|
1418
|
+
},
|
|
1419
|
+
"settings.theme": {
|
|
1420
|
+
"appearance.dark": "Тёмная",
|
|
1421
|
+
"appearance.light": "Светлая",
|
|
1422
|
+
"appearance.system": "Как в системе",
|
|
1423
|
+
"appearance.title": "Оформление"
|
|
1424
|
+
},
|
|
1425
|
+
"sidebar": {
|
|
1426
|
+
"session.new": "Новая сессия",
|
|
1427
|
+
"session.new.label": "Новая сессия",
|
|
1428
|
+
"toggle.collapse": "Свернуть панель",
|
|
1429
|
+
"toggle.open": "Открыть панель"
|
|
1430
|
+
},
|
|
1431
|
+
"skill": {
|
|
1432
|
+
"menu.userOnly": "только вручную",
|
|
1433
|
+
"row.failed": "Не удалось загрузить скилл",
|
|
1434
|
+
"row.instructions": "Инструкции",
|
|
1435
|
+
"row.running": "Загрузка скилла",
|
|
1436
|
+
"row.stopped": "Загрузка скилла остановлена"
|
|
1437
|
+
},
|
|
1438
|
+
"slash.menu": {
|
|
1439
|
+
"command": "Команды",
|
|
1440
|
+
"loading": "Загрузка…",
|
|
1441
|
+
"skill": "Скиллы",
|
|
1442
|
+
"subagent": "Субагенты",
|
|
1443
|
+
"suggestions.aria": "Подсказки по вводу"
|
|
1444
|
+
},
|
|
1445
|
+
"subagent": {
|
|
1446
|
+
"activity.inactive": "не работает",
|
|
1447
|
+
"activity.running": "работает",
|
|
1448
|
+
"branch.collapse": "Свернуть потомков {label}",
|
|
1449
|
+
"branch.expand": "Развернуть потомков {label}",
|
|
1450
|
+
"count.running.one": "{count} субагент работает",
|
|
1451
|
+
"count.running.other": "{count} субагентов работает",
|
|
1452
|
+
"count.total.one": "{count} субагент",
|
|
1453
|
+
"count.total.other": "{count} субагентов",
|
|
1454
|
+
"diagnostic.corrupt": "запись сессии повреждена",
|
|
1455
|
+
"diagnostic.unavailable": "запись сессии временно недоступна",
|
|
1456
|
+
"diagnostic.unsupported": "неподдерживаемая версия записи субагента",
|
|
1457
|
+
"duration.days": "{days} дн",
|
|
1458
|
+
"duration.daysHours": "{days} дн {hours} ч",
|
|
1459
|
+
"duration.exactDays": "{days} дн {hours} ч {minutes} мин {seconds} с",
|
|
1460
|
+
"duration.exactTitle": "Всего активного времени: {duration}",
|
|
1461
|
+
"duration.hours": "{hours} ч {minutes} мин {seconds} с",
|
|
1462
|
+
"duration.minutes": "{minutes} мин {seconds} с",
|
|
1463
|
+
"duration.months": "~{months} мес",
|
|
1464
|
+
"duration.monthsDays": "~{months} мес {days} дн",
|
|
1465
|
+
"duration.seconds": "{seconds} с",
|
|
1466
|
+
"duration.years": "~{years} г",
|
|
1467
|
+
"duration.yearsMonths": "~{years} г {months} мес",
|
|
1468
|
+
"load.error": "Не удалось загрузить субагентов",
|
|
1469
|
+
"loading.aria": "Загрузка субагентов",
|
|
1470
|
+
"loading.label": "Загрузка субагентов…",
|
|
1471
|
+
"mode.continuable": "с продолжением",
|
|
1472
|
+
"mode.oneShot": "разовый",
|
|
1473
|
+
"readonly.body": "Родительская сессия офлайн; откройте её заново, чтобы продолжить переписку.",
|
|
1474
|
+
"readonly.oneShot.body": "Разовые задачи не принимают продолжения; здесь можно изучить полную запись выполнения.",
|
|
1475
|
+
"readonly.oneShot.title": "Запись разового субагента",
|
|
1476
|
+
"readonly.title": "Пока этот субагент доступен только для чтения",
|
|
1477
|
+
"retry": "Повторить",
|
|
1478
|
+
"switcher.aria": "Переключить субагента: {title}",
|
|
1479
|
+
"tree.aria": "Сессии субагентов"
|
|
1480
|
+
},
|
|
1481
|
+
"task-board": {
|
|
1482
|
+
"archive.empty": "В архиве пусто",
|
|
1483
|
+
"board.archive": "Архив",
|
|
1484
|
+
"board.archiveView": "Архив ({count})",
|
|
1485
|
+
"board.backToBoard": "К доске",
|
|
1486
|
+
"board.close": "В чат",
|
|
1487
|
+
"board.created": "Создана",
|
|
1488
|
+
"board.empty": "В этой колонке задач нет",
|
|
1489
|
+
"board.filterAll": "Все",
|
|
1490
|
+
"board.hostError": "Действие на хосте не удалось: {error}",
|
|
1491
|
+
"board.hostMeta": "Часовой пояс хоста {timeZone} · ревизия {revision}",
|
|
1492
|
+
"board.new": "Новая задача",
|
|
1493
|
+
"board.pending": "Отправка",
|
|
1494
|
+
"board.retryHost": "Переподключиться к хосту",
|
|
1495
|
+
"board.runs": "запусков",
|
|
1496
|
+
"board.search": "Фильтр задач…",
|
|
1497
|
+
"board.status": "Статус",
|
|
1498
|
+
"board.status.backlog": "Бэклог",
|
|
1499
|
+
"board.status.done": "Готово",
|
|
1500
|
+
"board.status.failed": "Ошибка",
|
|
1501
|
+
"board.status.running": "В работе",
|
|
1502
|
+
"board.status.todo": "К выполнению",
|
|
1503
|
+
"board.title": "Доска задач",
|
|
1504
|
+
"board.updated": "Обновлена",
|
|
1505
|
+
"card.scheduled": "по расписанию",
|
|
1506
|
+
"delete.cancel": "Отмена",
|
|
1507
|
+
"delete.confirm": "Удалить «{name}»? Отменить это будет нельзя.",
|
|
1508
|
+
"delete.ok": "Удалить",
|
|
1509
|
+
"delete.title": "Удаление задачи",
|
|
1510
|
+
"detail.archive": "В архив",
|
|
1511
|
+
"detail.archivedAt": "В архиве · {time}",
|
|
1512
|
+
"detail.close": "Закрыть",
|
|
1513
|
+
"detail.delete": "Удалить",
|
|
1514
|
+
"detail.description": "Описание",
|
|
1515
|
+
"detail.execution": "История запусков",
|
|
1516
|
+
"detail.executionEnded": "Завершён",
|
|
1517
|
+
"detail.executionSettings": "Параметры запуска",
|
|
1518
|
+
"detail.executionStarted": "Начат",
|
|
1519
|
+
"detail.noExecution": "Ещё не запускалась",
|
|
1520
|
+
"detail.noSession": "Сессии нет",
|
|
1521
|
+
"detail.prompt": "Промпт запуска",
|
|
1522
|
+
"detail.rerun": "Запустить снова",
|
|
1523
|
+
"detail.restore": "Вернуть из архива",
|
|
1524
|
+
"detail.result.cancelled": "Отменён",
|
|
1525
|
+
"detail.result.failed": "Ошибка",
|
|
1526
|
+
"detail.result.running": "Выполняется",
|
|
1527
|
+
"detail.result.succeeded": "Успешно",
|
|
1528
|
+
"detail.run": "Запустить",
|
|
1529
|
+
"detail.schedule": "Запуски по расписанию",
|
|
1530
|
+
"detail.schedule.cron": "Выражение cron",
|
|
1531
|
+
"detail.schedule.dueSoon": "Скоро",
|
|
1532
|
+
"detail.schedule.enable": "Включить запуски по расписанию",
|
|
1533
|
+
"detail.schedule.invalid": "Неверное выражение cron",
|
|
1534
|
+
"detail.schedule.lastTriggered": "Последний запуск",
|
|
1535
|
+
"detail.schedule.nextRun": "Следующий запуск",
|
|
1536
|
+
"detail.schedule.notScheduled": "Расписания пока нет",
|
|
1537
|
+
"detail.schedule.preset.daily9": "Каждый день в 09:00",
|
|
1538
|
+
"detail.schedule.preset.hourly": "Каждый час",
|
|
1539
|
+
"detail.schedule.preset.tenMin": "Каждые 10 минут",
|
|
1540
|
+
"detail.schedule.preset.weeklyMon9": "По понедельникам в 09:00",
|
|
1541
|
+
"detail.schedule.presets": "Готовые варианты",
|
|
1542
|
+
"detail.title": "Задача",
|
|
1543
|
+
"detail.viewSession": "Открыть сессию",
|
|
1544
|
+
"entry.label": "Доска задач",
|
|
1545
|
+
"exec.error.noWorkspace": "Нет рабочей папки, в которой можно выполнить задачу",
|
|
1546
|
+
"exec.error.promptRejected": "Промпт отклонён",
|
|
1547
|
+
"exec.hint": "Применяется при запуске задачи: рабочая папка определяет, где появится сессия выполнения; режим задаёт пресет агента; разрешение выставляется командой /permission. Пусто — как по умолчанию в рантайме.",
|
|
1548
|
+
"exec.mode.brokenSuffix": " (недоступен)",
|
|
1549
|
+
"exec.mode.default": "Как в установке",
|
|
1550
|
+
"exec.mode.defaultSuffix": " (по умолчанию)",
|
|
1551
|
+
"exec.mode.removed": " (удалён)",
|
|
1552
|
+
"exec.permission.danger-full-access": "Полный доступ",
|
|
1553
|
+
"exec.permission.default": "Как в сессии",
|
|
1554
|
+
"exec.permission.read-only": "Только чтение",
|
|
1555
|
+
"exec.permission.workspace-write": "Запись в рабочую папку",
|
|
1556
|
+
"exec.workspace.recent": "Последняя (по умолчанию)",
|
|
1557
|
+
"new.cancel": "Отмена",
|
|
1558
|
+
"new.description": "Описание",
|
|
1559
|
+
"new.descriptionPlaceholder": "Контекст, границы, критерии приёмки (необязательно)",
|
|
1560
|
+
"new.mode": "Режим",
|
|
1561
|
+
"new.permission": "Разрешения",
|
|
1562
|
+
"new.prompt": "Промпт запуска",
|
|
1563
|
+
"new.promptPlaceholder": "Полная инструкция агенту (если пусто, возьмётся заголовок)",
|
|
1564
|
+
"new.required": "Нужен заголовок",
|
|
1565
|
+
"new.submit": "Создать",
|
|
1566
|
+
"new.title": "Заголовок",
|
|
1567
|
+
"new.titlePlaceholder": "Что нужно сделать, одной строкой",
|
|
1568
|
+
"new.workspace": "Рабочая папка",
|
|
1569
|
+
"run.failed": "Запуск не удался: {error}",
|
|
1570
|
+
"settings.announceToAgent": "Сообщать агентам о доске задач",
|
|
1571
|
+
"settings.announceToAgentHint": "Включено: в системный промпт каждого агента добавляется упоминание доски. Выключено: агенты узнают о ней, только если вы скажете сами.",
|
|
1572
|
+
"settings.collapse": "Скрыть настройки",
|
|
1573
|
+
"settings.description": "Настройка доски задач на хосте, упоминания в промпте и защиты от засыпания, пока есть незавершённая работа.",
|
|
1574
|
+
"settings.discard": "Отменить",
|
|
1575
|
+
"settings.enabled": "Включить доску задач",
|
|
1576
|
+
"settings.enabledHint": "Когда выключено, пункт в панели и сама доска скрыты.",
|
|
1577
|
+
"settings.expand": "Показать настройки",
|
|
1578
|
+
"settings.inherit": "Наследовать",
|
|
1579
|
+
"settings.invalidNumber": "Введите число или оставьте пустым, чтобы взять значение по умолчанию.",
|
|
1580
|
+
"settings.notExposed": "Эта версия DSH не выводит namespace настроек плагина на страницу конфигурации, поэтому форма недоступна. Правьте ~/.dsh/settings.yaml напрямую или добавьте namespace в список WEB_SETTINGS_NAMESPACES у dsh-host-apiproxy и перезапустите.",
|
|
1581
|
+
"settings.off": "Выкл",
|
|
1582
|
+
"settings.on": "Вкл",
|
|
1583
|
+
"settings.overridden": "Переопределено",
|
|
1584
|
+
"settings.powerBoundary": "Батарея будет расходоваться быстрее. Закрытие крышки, ручной уход в сон, гибернация, выключение, действия при низком заряде и корпоративные политики под гарантию не попадают; уже спящий компьютер не разбудят.",
|
|
1585
|
+
"settings.powerError": "Последняя ошибка защиты от засыпания: {error}",
|
|
1586
|
+
"settings.powerStatus": "Платформа: {platform}; защита: {phase}; работающих сессий: {running}; включённых расписаний: {schedules}",
|
|
1587
|
+
"settings.powerUnknown": "неизвестно",
|
|
1588
|
+
"settings.preventIdleSleep": "Не давать системе засыпать",
|
|
1589
|
+
"settings.preventIdleSleepHint": "По умолчанию выключено. Когда включено, хост не даёт системе уйти в сон, пока работает хоть одна сессия DSH, включено расписание или состояние сессий ещё неизвестно. Экран при этом может гаснуть.",
|
|
1590
|
+
"settings.readOnly": "В этой установке настройки доступны только для чтения.",
|
|
1591
|
+
"settings.reset": "Вернуть по умолчанию",
|
|
1592
|
+
"settings.save": "Сохранить",
|
|
1593
|
+
"settings.saveFailed": "Установка не приняла эти значения; они оставлены, чтобы вы их поправили.",
|
|
1594
|
+
"settings.saving": "Сохранение…",
|
|
1595
|
+
"settings.title": "Доска задач",
|
|
1596
|
+
"settings.unsaved": "Не сохранено",
|
|
1597
|
+
"status.move.backlog": "В бэклог",
|
|
1598
|
+
"status.move.todo": "К выполнению",
|
|
1599
|
+
"time.justNow": "только что"
|
|
1600
|
+
},
|
|
1601
|
+
"trajectory": {
|
|
1602
|
+
"toolbar.actualTime": "Реальное время",
|
|
1603
|
+
"toolbar.aria": "Панель траектории",
|
|
1604
|
+
"toolbar.calls": "Вызовы",
|
|
1605
|
+
"toolbar.collapseCalls": "Свернуть вызовы",
|
|
1606
|
+
"toolbar.collapseTurns": "Свернуть ходы",
|
|
1607
|
+
"toolbar.duration": "Длительность",
|
|
1608
|
+
"toolbar.expandCalls": "Развернуть вызовы",
|
|
1609
|
+
"toolbar.expandTurns": "Развернуть ходы",
|
|
1610
|
+
"toolbar.search": "Поиск по траектории",
|
|
1611
|
+
"toolbar.searchPlaceholder": "Поиск",
|
|
1612
|
+
"toolbar.turns": "Ходы",
|
|
1613
|
+
"toolbar.useActualDuration": "По реальной длительности",
|
|
1614
|
+
"toolbar.useEqualWidth": "Операции равной ширины",
|
|
1615
|
+
"view.trajectory": "Траектория"
|
|
1616
|
+
},
|
|
1617
|
+
"usageDashboard": {
|
|
1618
|
+
"buckets.cacheRead": "Чтение кэша",
|
|
1619
|
+
"buckets.cacheWrite": "Запись в кэш",
|
|
1620
|
+
"buckets.caption": "Четыре непересекающиеся корзины тарификации · всего {total} ток",
|
|
1621
|
+
"buckets.output": "Выход",
|
|
1622
|
+
"buckets.title": "Состав токенов",
|
|
1623
|
+
"buckets.uncachedInput": "Вход мимо кэша",
|
|
1624
|
+
"composition.caption": "Оценка по эвристике, не по счёту; в сумму занятости не сойдётся",
|
|
1625
|
+
"composition.messages": "Сообщения",
|
|
1626
|
+
"composition.system": "Системный промпт",
|
|
1627
|
+
"composition.title": "Состав контекста",
|
|
1628
|
+
"composition.tools": "Схемы инструментов",
|
|
1629
|
+
"efficiency.llm": "Время модели",
|
|
1630
|
+
"efficiency.steps": "Шаги",
|
|
1631
|
+
"efficiency.stepsValue": "{steps}",
|
|
1632
|
+
"efficiency.throughput": "Скорость выдачи",
|
|
1633
|
+
"efficiency.title": "Эффективность запросов",
|
|
1634
|
+
"efficiency.tool": "Время инструментов",
|
|
1635
|
+
"efficiency.ttft": "Первый токен, среднее",
|
|
1636
|
+
"efficiency.ttftOver": "шагов: {steps}",
|
|
1637
|
+
"efficiency.turns": "Ходы",
|
|
1638
|
+
"efficiency.turnsValue": "{turns}",
|
|
1639
|
+
"empty.usage": "Расхода токенов пока нет",
|
|
1640
|
+
"empty.usageHint": "Цифры появятся, когда сессия сделает первый запрос к модели.",
|
|
1641
|
+
"overview.billedInput": "Оплаченный вход",
|
|
1642
|
+
"overview.billedInputSub": "мимо кэша {uncached} · из кэша {cached}",
|
|
1643
|
+
"overview.cacheHit": "Попадания в кэш",
|
|
1644
|
+
"overview.cacheHitSub": "прочитано {read} из {total} ток",
|
|
1645
|
+
"overview.context": "Контекст занят",
|
|
1646
|
+
"overview.contextSub": "{used} из {window} ток",
|
|
1647
|
+
"overview.contextUnknown": "Размер окна модели неизвестен",
|
|
1648
|
+
"overview.output": "Выход",
|
|
1649
|
+
"overview.outputSub": "всего {total} ток",
|
|
1650
|
+
"scope.aria": "Охват статистики",
|
|
1651
|
+
"scope.session": "Эта сессия",
|
|
1652
|
+
"scope.sessions": "Все сессии",
|
|
1653
|
+
"sessions.currentTag": "Текущая",
|
|
1654
|
+
"sessions.detail.noData": "Данные по этой сессии загружаются или их нет",
|
|
1655
|
+
"sessions.detail.title": "Подробности сессии",
|
|
1656
|
+
"sessions.empty": "Расход по сессиям не записан",
|
|
1657
|
+
"sessions.inactive": "Простаивает",
|
|
1658
|
+
"sessions.running": "Работает",
|
|
1659
|
+
"sessions.selectHint": "Выберите строку, чтобы посмотреть сессию",
|
|
1660
|
+
"sessions.subagentTag": "Субагент",
|
|
1661
|
+
"sessions.summary.input": "Оплаченный вход, всего",
|
|
1662
|
+
"sessions.summary.output": "Выход, всего",
|
|
1663
|
+
"sessions.summary.sessions": "Сессий с расходом",
|
|
1664
|
+
"sessions.summary.sessionsValue": "{count}",
|
|
1665
|
+
"sessions.summary.totalValue": "всего сессий: {count}",
|
|
1666
|
+
"sessions.summary.turns": "Ходов всего",
|
|
1667
|
+
"sessions.summary.turnsValue": "{turns}",
|
|
1668
|
+
"sessions.table.cacheHit": "Попаданий в кэш",
|
|
1669
|
+
"sessions.table.input": "Оплаченный вход",
|
|
1670
|
+
"sessions.table.output": "Выход",
|
|
1671
|
+
"sessions.table.session": "Сессия",
|
|
1672
|
+
"sessions.table.status": "Состояние",
|
|
1673
|
+
"sessions.table.turns": "Ходы",
|
|
1674
|
+
"sessions.table.updated": "Изменена",
|
|
1675
|
+
"steps.cacheRead": "Кэш Ч",
|
|
1676
|
+
"steps.cacheWrite": "Кэш З",
|
|
1677
|
+
"steps.caption": "Только загруженное окно, новые сверху; итог считает то же окно",
|
|
1678
|
+
"steps.done": "Готово",
|
|
1679
|
+
"steps.empty": "В загруженном окне шагов нет",
|
|
1680
|
+
"steps.input": "Вход",
|
|
1681
|
+
"steps.interrupted": "Прервано",
|
|
1682
|
+
"steps.model": "Модель",
|
|
1683
|
+
"steps.output": "Выход",
|
|
1684
|
+
"steps.reasoning": "Рассуждения",
|
|
1685
|
+
"steps.sortBy": "Сортировать по «{column}»",
|
|
1686
|
+
"steps.status": "Состояние",
|
|
1687
|
+
"steps.title": "Подробности по шагам",
|
|
1688
|
+
"steps.tps": "ток/с",
|
|
1689
|
+
"steps.ttft": "Первый токен",
|
|
1690
|
+
"steps.turn": "Ход.шаг",
|
|
1691
|
+
"steps.windowTotal": "Итог по окну",
|
|
1692
|
+
"time.daysAgo": "{n} дн назад",
|
|
1693
|
+
"time.hoursAgo": "{n} ч назад",
|
|
1694
|
+
"time.justNow": "только что",
|
|
1695
|
+
"time.minutesAgo": "{n} мин назад",
|
|
1696
|
+
"view.usage": "Статистика"
|
|
1697
|
+
},
|
|
1698
|
+
"workflowRun": {
|
|
1699
|
+
"member.empty": "Пустое имя участника",
|
|
1700
|
+
"member.open": "Открыть {name}",
|
|
1701
|
+
"phase.empty": "Пустое имя фазы",
|
|
1702
|
+
"phase.unassigned": "Вне фаз",
|
|
1703
|
+
"run.empty": "Ни один участник не запущен",
|
|
1704
|
+
"run.members.one": "{count} участник",
|
|
1705
|
+
"run.members.other": "{count} участников",
|
|
1706
|
+
"run.title": "{name}",
|
|
1707
|
+
"status.cancelled": "Отменено",
|
|
1708
|
+
"status.completed": "Завершено",
|
|
1709
|
+
"status.failed": "Ошибка",
|
|
1710
|
+
"status.interrupted": "Прервано",
|
|
1711
|
+
"status.running": "Работает",
|
|
1712
|
+
"statusCount.cancelled": "Отменено: {count}",
|
|
1713
|
+
"statusCount.completed": "Завершено: {count}",
|
|
1714
|
+
"statusCount.failed": "Ошибок: {count}",
|
|
1715
|
+
"statusCount.interrupted": "Прервано: {count}",
|
|
1716
|
+
"statusCount.running": "Работает: {count}"
|
|
1717
|
+
},
|
|
1718
|
+
"workspace": {
|
|
1719
|
+
"actions.newSession.aria": "Новая сессия в {name}",
|
|
1720
|
+
"actions.session.aria": "Действия с сессией {name}",
|
|
1721
|
+
"actions.workspace.aria": "Действия с рабочей папкой {name}",
|
|
1722
|
+
"conflict.named": "Рабочая папка «{name}» уже есть.",
|
|
1723
|
+
"date.ymd": "{d}.{m}.{y}",
|
|
1724
|
+
"delete.desc": "Уберёт «{name}» из списка рабочих папок. Сама папка и журналы сессий останутся, а её сессии переедут в «Без папки».",
|
|
1725
|
+
"delete.pending": "Удаление рабочей папки…",
|
|
1726
|
+
"delete.workspace": "Удалить рабочую папку",
|
|
1727
|
+
"empty.noMatches": "Ничего не найдено",
|
|
1728
|
+
"empty.none": "Сессий пока нет",
|
|
1729
|
+
"field.sessionName": "Название сессии",
|
|
1730
|
+
"field.workspaceName": "Название рабочей папки",
|
|
1731
|
+
"folderError.retry": "Выбрать снова",
|
|
1732
|
+
"folderError.title": "Не удалось открыть папку",
|
|
1733
|
+
"group.ungrouped": "Без папки",
|
|
1734
|
+
"groupBy.flat": "Одним списком",
|
|
1735
|
+
"groupBy.label": "Группировать",
|
|
1736
|
+
"groupBy.workspace": "По рабочим папкам",
|
|
1737
|
+
"hover.copied": "Скопировано",
|
|
1738
|
+
"hover.created": "Создано {time}",
|
|
1739
|
+
"menu.addWorkspace": "Добавить рабочую папку…",
|
|
1740
|
+
"menu.archiveSession": "Убрать сессию в архив",
|
|
1741
|
+
"menu.fork": "Ответвить сессию",
|
|
1742
|
+
"orderBy.label": "Сортировать",
|
|
1743
|
+
"orderBy.manual": "Вручную",
|
|
1744
|
+
"orderBy.updated": "По изменению",
|
|
1745
|
+
"picker.loading": "Загрузка рабочих папок…",
|
|
1746
|
+
"rename": "Переименовать",
|
|
1747
|
+
"rename.session.title": "Переименовать сессию",
|
|
1748
|
+
"rename.workspace.title": "Переименовать рабочую папку",
|
|
1749
|
+
"search.clear": "Очистить поиск",
|
|
1750
|
+
"search.hasMore": "Показаны первые {n} результатов. Уточните запрос.",
|
|
1751
|
+
"search.noMatches": "Подходящих сессий нет",
|
|
1752
|
+
"search.pending": "Поиск по истории сессий…",
|
|
1753
|
+
"search.placeholder": "Поиск по сессиям...",
|
|
1754
|
+
"search.results.aria": "Результаты поиска",
|
|
1755
|
+
"search.sessions.aria": "Поиск сессий",
|
|
1756
|
+
"search.unavailable": "Поиск по содержимому временно недоступен. Показаны совпадения по названию.",
|
|
1757
|
+
"section.sessions": "Сессии",
|
|
1758
|
+
"section.workspaces": "Рабочие папки",
|
|
1759
|
+
"session.new": "Новая сессия",
|
|
1760
|
+
"sessions.collapse": "Показать меньше",
|
|
1761
|
+
"sessions.count.one": "{n} сессия",
|
|
1762
|
+
"sessions.count.other": "{n} сессий",
|
|
1763
|
+
"sessions.expand": "Показать ещё {n}",
|
|
1764
|
+
"status.completed": "Завершено",
|
|
1765
|
+
"status.idle": "Простаивает",
|
|
1766
|
+
"status.planReview": "План ждёт проверки",
|
|
1767
|
+
"status.running": "Работает",
|
|
1768
|
+
"status.subagentsRunning.one": "{n} субагент работает",
|
|
1769
|
+
"status.subagentsRunning.other": "{n} субагентов работает",
|
|
1770
|
+
"status.waitingAnswer": "Ждёт ответа",
|
|
1771
|
+
"status.waitingApproval": "Ждёт подтверждения",
|
|
1772
|
+
"time.ago": "{t} назад",
|
|
1773
|
+
"time.days": "{n} дн",
|
|
1774
|
+
"time.hours": "{n} ч",
|
|
1775
|
+
"time.minutes": "{n} мин",
|
|
1776
|
+
"time.months": "{n} мес",
|
|
1777
|
+
"time.now": "только что",
|
|
1778
|
+
"time.years": "{n} г",
|
|
1779
|
+
"viewOptions.label": "Параметры отображения",
|
|
1780
|
+
"workspace.add": "Добавить рабочую папку"
|
|
1781
|
+
}
|
|
1782
|
+
}
|
|
1783
|
+
|
|
1784
|
+
const SETTINGS_NS_NAME = 'russian-lang'
|
|
1785
|
+
|
|
1786
|
+
function apply(ctx) {
|
|
1787
|
+
const runtime = ctx.locale
|
|
1788
|
+
const scope = ctx.settingsScope.bind({ namespace: SETTINGS_NS_NAME })
|
|
1789
|
+
|
|
1790
|
+
// 1. Словари: каждый namespace — свой эффект, словарь снимается вместе с
|
|
1791
|
+
// плагином. Если namespace уже несёт ru (плагин локализовался сам) —
|
|
1792
|
+
// не конфликтуем.
|
|
1793
|
+
for (const ns of Object.keys(RU)) {
|
|
1794
|
+
ctx.effect(() => {
|
|
1795
|
+
try { return ctx.locale.register(ns, 'ru', RU[ns]) }
|
|
1796
|
+
catch (err) { return () => {} }
|
|
1797
|
+
}, 'dsh-russian-lang: ' + ns)
|
|
1798
|
+
}
|
|
1799
|
+
|
|
1800
|
+
// 2. <html lang>: в таблице DOCUMENT_LANGUAGE ядра нет "ru", без нас там
|
|
1801
|
+
// окажется undefined после переключения.
|
|
1802
|
+
const syncLang = () => {
|
|
1803
|
+
try {
|
|
1804
|
+
if (typeof document !== 'undefined' && document.documentElement
|
|
1805
|
+
&& runtime.getLocale().active === 'ru') {
|
|
1806
|
+
document.documentElement.lang = 'ru'
|
|
1807
|
+
}
|
|
1808
|
+
} catch (err) { /* ignore */ }
|
|
1809
|
+
}
|
|
1810
|
+
|
|
1811
|
+
const native = runtime.getLocale().locales.some((l) => l.id === 'ru')
|
|
1812
|
+
|
|
1813
|
+
if (!native) {
|
|
1814
|
+
// Ядро не знает ru: добавляем его в snapshot runtime. Родная строка
|
|
1815
|
+
// Language берёт меню из snapshot.locales, setLocale() по нему же
|
|
1816
|
+
// валидирует выбор — «Русский» появляется в родном списке.
|
|
1817
|
+
const s0 = runtime.getLocale()
|
|
1818
|
+
runtime.snapshot = Object.freeze({
|
|
1819
|
+
active: s0.active,
|
|
1820
|
+
locales: s0.locales.concat([{ id: 'ru', label: 'Русский' }]),
|
|
1821
|
+
revision: s0.revision + 1
|
|
1822
|
+
})
|
|
1823
|
+
ctx.emit('locale/change', runtime.snapshot)
|
|
1824
|
+
syncLang()
|
|
1825
|
+
|
|
1826
|
+
// Хост-схема namespace "locale" знает только zh/en, запись preference
|
|
1827
|
+
// "ru" он отклонит. Перехватываем её: выбор сохраняется нашим флагом
|
|
1828
|
+
// russian-lang.enabled, остальные языки пишутся штатно.
|
|
1829
|
+
//
|
|
1830
|
+
// Кроме того, adopt() в ядре при каждом обновлении настроек возвращает
|
|
1831
|
+
// активный язык к сохранённому preference (или языку браузера): он
|
|
1832
|
+
// читает scope через getSnapshot. Пока активен русский, докладываем в
|
|
1833
|
+
// снимок preference "ru", иначе любой settings-запись вернёт en.
|
|
1834
|
+
const realHost = runtime.host
|
|
1835
|
+
if (realHost) {
|
|
1836
|
+
const origGetSnapshot = realHost.getSnapshot.bind(realHost)
|
|
1837
|
+
const patchedGetSnapshot = () => {
|
|
1838
|
+
const s = origGetSnapshot()
|
|
1839
|
+
try {
|
|
1840
|
+
if (runtime.getLocale().active === 'ru') {
|
|
1841
|
+
return Object.assign({}, s, {
|
|
1842
|
+
value: Object.assign({}, s && s.value ? s.value : {}, { preference: 'ru' })
|
|
1843
|
+
})
|
|
1844
|
+
}
|
|
1845
|
+
} catch (err) { /* ignore */ }
|
|
1846
|
+
return s
|
|
1847
|
+
}
|
|
1848
|
+
realHost.getSnapshot = patchedGetSnapshot
|
|
1849
|
+
runtime.host = {
|
|
1850
|
+
getSnapshot: patchedGetSnapshot,
|
|
1851
|
+
subscribe: (fn) => realHost.subscribe(fn),
|
|
1852
|
+
set: (field, value) => {
|
|
1853
|
+
if (field === 'preference' && value === 'ru') return Promise.resolve()
|
|
1854
|
+
return realHost.set(field, value)
|
|
1855
|
+
},
|
|
1856
|
+
unset: (field) => realHost.unset ? realHost.unset(field) : Promise.resolve()
|
|
1857
|
+
}
|
|
1858
|
+
}
|
|
1859
|
+
}
|
|
1860
|
+
|
|
1861
|
+
// 3. Флаг russianLang.enabled всегда повторяет активный язык: выбор
|
|
1862
|
+
// английского или китайского в родном меню выключает русский и наоборот.
|
|
1863
|
+
const syncFlag = () => {
|
|
1864
|
+
try {
|
|
1865
|
+
const wantRu = runtime.getLocale().active === 'ru'
|
|
1866
|
+
const value = scope.getSnapshot().value || {}
|
|
1867
|
+
if (!!value.enabled !== wantRu) scope.set('enabled', wantRu)
|
|
1868
|
+
} catch (err) { /* снимок ещё не готов */ }
|
|
1869
|
+
}
|
|
1870
|
+
ctx.effect(() => {
|
|
1871
|
+
try { return runtime.subscribe(syncFlag) }
|
|
1872
|
+
catch (err) { return undefined }
|
|
1873
|
+
}, 'dsh-russian-lang: sync-flag')
|
|
1874
|
+
|
|
1875
|
+
// 4. Старт: сохранённый флаг включает русский.
|
|
1876
|
+
const activate = () => {
|
|
1877
|
+
try {
|
|
1878
|
+
if (runtime.getLocale().active === 'ru') return
|
|
1879
|
+
if (native) runtime.setLocale('ru')
|
|
1880
|
+
else runtime.publish('ru', true)
|
|
1881
|
+
} catch (err) { console.warn('dsh-russian-lang: activate failed', err) }
|
|
1882
|
+
}
|
|
1883
|
+
let booted = false
|
|
1884
|
+
const tryBoot = () => {
|
|
1885
|
+
if (booted) return
|
|
1886
|
+
try {
|
|
1887
|
+
const value = scope.getSnapshot().value
|
|
1888
|
+
if (value && value.enabled === true) { booted = true; activate() }
|
|
1889
|
+
} catch (err) { /* ignore */ }
|
|
1890
|
+
}
|
|
1891
|
+
ctx.effect(() => scope.subscribe(tryBoot), 'dsh-russian-lang: boot')
|
|
1892
|
+
tryBoot()
|
|
1893
|
+
|
|
1894
|
+
ctx.effect(() => runtime.subscribe(syncLang), 'dsh-russian-lang: html-lang')
|
|
1895
|
+
syncLang()
|
|
1896
|
+
}
|
|
1897
|
+
|
|
1898
|
+
module.exports = { apply, inject: ['locale', 'connection', 'remote', 'settingsScope'] }
|
|
1899
|
+
return module.exports
|
|
1900
|
+
},
|
|
1901
|
+
})
|