精简版第四轮补裁(P4): 页面层摘除 + Xray更新端点下线 + 本机核心监管下线

页面层(用户真机截图发现前两轮漏裁):
- 设置: 摘除 Telegram机器人/邮件菜单与页面, 及页内残留入口(通知页/外部流量/LDAP/2FA设置页)
- Xray配置: 摘除负载均衡/DNS/高级配置菜单与页面; 基础配置(出站+路由)完好
- 总览: 摘除 Xray更新弹窗(VersionModal+GeodataSection)全部入口, 版本号改为静态展示
- 13个locale同步摘除461个已删功能专属翻译键(逐键核查前后端引用为零; i18n-dead-keys测试全绿)

Xray更新后端(经调查确认仅服务本机bin/xray, 与agent下发/订阅无关):
- 删除 getXrayVersion/installXray/updateGeofile 路由与handler(访问返回404)
- 删除 ServerService 对应实现与校验和函数; 同步api-docs/monitor白名单/openapi

本机核心监管下线(设计: 主控永不运行本机xray, 入站全在agent):
- XrayService.RestartXray 降级为no-op(一次性Warning说明日志); StopXray无进程时幂等返回
- web.go 摘除启动拉起本机核心/CheckXrayRunning看门狗(1s)/ApplyPendingRestart cron(30s)/XrayTrafficJob/CheckClientIpJob 注册
- ApplyPendingRestart 降级为消费即清, 其测试更新为新语义
- XrayMetricsService.Sample 短路: 不再每2s探本机/debug/vars, 状态优雅置为不可用
- 配置生成(纯JSON)/agent链路/订阅/入站CRUD未动; 状态读数优雅归零(stop/Unknown)

注: TestGetXrayConfig_EnabledClientsStillEmitted 在基线945b3a5同样失败(既有问题, 非本轮引入)
This commit is contained in:
Muse
2026-10-20 14:58:05 +00:00
parent 945b3a56a2
commit 4828f946b1
56 changed files with 149 additions and 11458 deletions
+4 -466
View File
@@ -67,16 +67,12 @@
"success": "Успішно",
"lastOnline": "Був(ла) онлайн",
"lastSubFetch": "Останнє отримання підписки",
"getVersion": "Отримати версію",
"install": "Встановити",
"clients": "Клієнти",
"usage": "Використання",
"twoFactorCode": "Код",
"remained": "Залишилося",
"security": "Беспека",
"emptyDnsDesc": "Немає доданих DNS-серверів.",
"emptyFakeDnsDesc": "Немає доданих Fake DNS-серверів.",
"emptyBalancersDesc": "Немає доданих балансувальників.",
"somethingWentWrong": "Щось пішло не так",
"subscription": {
"title": "Інформація про підписку",
@@ -86,7 +82,6 @@
"uploaded": "Відвантажено",
"expiry": "Термін дії",
"totalQuota": "Загальна квота",
"individualLinks": "Окремі посилання",
"active": "Активна",
"inactive": "Неактивна",
"unlimited": "Безліміт",
@@ -136,9 +131,6 @@
"xrayStatus": "Xray",
"stopXray": "Стоп",
"restartXray": "Перезапуск",
"xraySwitch": "Версія",
"xrayUpdates": "Оновлення Xray",
"xraySwitchClickDesk": "Вибирайте уважно, оскільки старіші версії можуть бути несумісними з поточними конфігураціями.",
"updatePanel": "Оновити панель",
"panelUpdateDesc": "Це оновить 3X-UI до останнього релізу та перезапустить сервіс панелі.",
"currentPanelVersion": "Поточна версія панелі",
@@ -200,9 +192,6 @@
"download": "Завантажити",
"sent": "Відправлено",
"received": "Отримано",
"xraySwitchVersionDialog": "Ви дійсно хочете змінити версію Xray?",
"xraySwitchVersionDialogDesc": "Це змінить версію Xray на #version#.",
"xraySwitchVersionPopover": "Xray успішно оновлено",
"panelUpdateDialog": "Ви дійсно хочете оновити панель?",
"panelUpdateDialogDesc": "Це оновить 3X-UI до #version# та перезапустить сервіс панелі.",
"panelUpdateStartedPopover": "Розпочато оновлення панелі",
@@ -210,24 +199,6 @@
"panelUpdateFailedDesc": "Оновлення не завершилося успішно. Перевірте журнали сервера або виконайте 'x-ui update' у командному рядку.",
"panelUpdateUnknownTitle": "Не вдалося підтвердити завершення оновлення",
"panelUpdateUnknownDesc": "Панель не повідомила результат вчасно. Перезавантажте сторінку, щоб перевірити поточну версію, або перевірте журнали сервера.",
"geofileUpdateDialog": "Ви дійсно хочете оновити геофайл?",
"geofileUpdateDialogDesc": "Це оновить файл #filename#.",
"geofilesUpdateDialogDesc": "Це оновить усі геофайли.",
"geofilesUpdateAll": "Оновити все",
"geofileUpdatePopover": "Геофайл успішно оновлено",
"geodataTitle": "Автооновлення Geodata",
"geodataHint": "Xray завантажує ці файли за розкладом і перезавантажує їх без перезапуску. URL мають бути HTTPS. Файл має вже існувати в теці bin, щоб Xray міг його оновлювати.",
"geodataCron": "Розклад (cron)",
"geodataOutbound": "Завантажувати через outbound (необов’язково)",
"geodataFile": "Ім’я файлу",
"geodataAddFile": "Додати файл",
"geodataSaveRestart": "Зберегти та перезапустити Xray",
"geodataConfirmTitle": "Зберегти налаштування geodata?",
"geodataConfirmContent": "Шаблон конфігурації Xray буде оновлено, а Xray перезапущено.",
"geodataInvalidUrl": "Для кожного файлу потрібен HTTPS URL.",
"geodataInvalidFile": "Ім’я файлу має бути простим, напр. geosite_custom.dat (без шляхів).",
"geodataInvalidCron": "Cron має містити 5 полів, напр. 0 4 * * *",
"geodataEmpty": "Файли не налаштовано. У правилах маршрутизації файли вказуються як ext:geosite_custom.dat:category.",
"dontRefresh": "Інсталяція триває, будь ласка, не оновлюйте цю сторінку",
"logs": "Логи",
"accessLogs": "Логи доступу",
@@ -1082,7 +1053,6 @@
"warnDefaultBasePath": "Базовий шлях за замовчуванням \"/\" широко відомий — змініть його на випадковий.",
"warnDefaultSubPath": "Шлях підписки за замовчуванням \"/sub/\" широко відомий — змініть його.",
"warnDefaultJsonPath": "JSON-шлях підписки за замовчуванням \"/json/\" широко відомий — змініть його.",
"TGBotSettings": "Telegram-бот",
"panelListeningIP": "Слухати IP",
"panelListeningIPDesc": "IP-адреса для веб-панелі. (залиште порожнім, щоб слухати всі IP-адреси)",
"panelListeningDomain": "Домен прослуховування",
@@ -1107,43 +1077,12 @@
"currentPassword": "Поточний пароль",
"newUsername": "Нове ім'я користувача",
"newPassword": "Новий пароль",
"telegramBotEnable": "Увімкнути Telegram Bot",
"telegramBotEnableDesc": "Вмикає бота Telegram.",
"telegramToken": "Telegram-токен",
"telegramTokenDesc": "Токен бота Telegram, отриманий від '{'@'}BotFather'.",
"telegramProxy": "SOCKS-проксі",
"telegramProxyDesc": "Вмикає проксі-сервер SOCKS5 для підключення до Telegram. (відкоригуйте параметри відповідно до посібника)",
"telegramAPIServer": "Telegram API сервер",
"telegramAPIServerDesc": "Сервер Telegram API для використання. Залиште поле порожнім, щоб використовувати сервер за умовчанням.",
"telegramChatId": "Ідентифікатор чату адміністратора",
"telegramChatIdDesc": "Ідентифікатори чату адміністратора Telegram. (розділені комами) (отримайте тут {'@'}userinfobot) або (використовуйте команду '/id' у боті)",
"telegramNotifyTime": "Час сповіщення",
"telegramNotifyTimeDesc": "Як часто бот Telegram надсилає періодичні звіти. Виберіть готовий інтервал або «Власний», щоб ввести вираз crontab.",
"notifyTime": {
"every": "@every — повторювати з інтервалом",
"hourly": "@hourly — щогодини",
"daily": "@daily — щодня о 00:00",
"weekly": "@weekly — щотижня",
"monthly": "@monthly — щомісяця",
"custom": "Власний (crontab)",
"seconds": "Секунди",
"minutes": "Хвилини",
"hours": "Години",
"interval": "Інтервал",
"unit": "Одиниця"
},
"tgNotifyBackup": "Резервне копіювання бази даних",
"tgNotifyBackupDesc": "Надіслати файл резервної копії бази даних зі звітом.",
"tgNotifyLogin": "Сповіщення про вхід",
"tgNotifyLoginDesc": "Отримувати сповіщення про ім'я користувача, IP-адресу та час щоразу, коли хтось намагається увійти у вашу веб-панель.",
"sessionMaxAge": "Тривалість сеансу",
"sessionMaxAgeDesc": "Тривалість, протягом якої ви можете залишатися в системі. (одиниця: хвилина)",
"expireTimeDiff": "Повідомлення про дату закінчення",
"expireTimeDiffDesc": "Отримувати сповіщення про термін дії при досягненні цього порогу. (одиниця: день)",
"trafficDiff": "Повідомлення про обмеження трафіку",
"trafficDiffDesc": "Отримувати сповіщення про обмеження трафіку при досягненні цього порогу. (одиниця: ГБ)",
"tgNotifyCpu": "Сповіщення про завантаження ЦП",
"tgNotifyCpuDesc": "Отримувати сповіщення, якщо навантаження ЦП перевищує це порогове значення. (одиниця: %)",
"timeZone": "Часовий пояс",
"timeZoneDesc": "Заплановані завдання виконуватимуться на основі цього часового поясу.",
"subSettings": "Підписка",
@@ -1208,10 +1147,6 @@
"subEncryptDesc": "Повернений вміст послуги підписки матиме кодування Base64.",
"subURI": "URI зворотного проксі",
"subURIDesc": "Повна базова URL-адреса (scheme://домен[:порт]/шлях/) для посилання підписки та QR-коду, використовується замість Домену/Порту прослуховування. Вкажіть це, якщо підписка доступна через зворотний проксі або на іншому домені/порту, ніж вказано вище.",
"externalTrafficInformEnable": "Інформація про зовнішній трафік",
"externalTrafficInformEnableDesc": "Повідомляти зовнішній API про кожне оновлення трафіку.",
"externalTrafficInformURI": "Інформаційний URI зовнішнього трафіку",
"externalTrafficInformURIDesc": "Оновлення трафіку надсилаються на цей URI.",
"restartXrayOnClientDisable": "Перезапускати Xray після авто-вимкнення",
"restartXrayOnClientDisableDesc": "Коли клієнт автоматично вимикається через закінчення терміну дії або ліміт трафіку, перезапускати Xray.",
"fragment": "Фрагментація",
@@ -1221,38 +1156,6 @@
"noisesSett": "Налаштування Noises",
"trustedProxyCidrs": "Довірені CIDR проксі",
"trustedProxyCidrsDesc": "IP/CIDR через кому, яким дозволено встановлювати заголовки forwarded host, proto та client IP.",
"ldap": {
"enable": "Увімкнути LDAP-синхронізацію",
"host": "LDAP-хост",
"port": "Порт LDAP",
"useTls": "Використовувати TLS (LDAPS)",
"skipTlsVerify": "Пропустити перевірку сертифіката TLS",
"skipTlsVerifyDesc": "Небезпечно — вимикає перевірку сертифіката сервера. Використовуйте лише з внутрішніми/ненадійними CA.",
"bindDn": "Bind DN",
"passwordConfigured": "Налаштовано; залиште порожнім для збереження поточного паролю.",
"passwordUnconfigured": "Не налаштовано.",
"passwordPlaceholder": "Налаштовано — введіть нове значення для заміни",
"baseDn": "Base DN",
"userFilter": "Фільтр користувача",
"userAttr": "Атрибут користувача (username/email)",
"vlessField": "Атрибут VLESS-flag",
"flagField": "Загальний атрибут flag (опц.)",
"flagFieldDesc": "Якщо задано, перевизначає VLESS flag — напр. shadowInactive.",
"truthyValues": "Truthy-значення",
"truthyValuesDesc": "Через кому; за замовч.: true,1,yes,on",
"invertFlag": "Інвертувати flag",
"invertFlagDesc": "Увімкніть, коли атрибут означає «вимкнено» (напр. shadowInactive).",
"syncSchedule": "Розклад синхронізації",
"syncScheduleDesc": "Рядок типу cron, напр. @every 1m",
"inboundTags": "Теги вхідних",
"inboundTagsDesc": "Вхідні, на яких LDAP-синхронізація може авто-створювати або авто-видаляти клієнтів.",
"noInbounds": "Вхідних не знайдено. Спочатку створіть один у Вхідних.",
"autoCreate": "Авто-створення клієнтів",
"autoDelete": "Авто-видалення клієнтів",
"defaultTotalGb": "Обсяг за замовч. (ГБ)",
"defaultExpiryDays": "Термін за замовч. (дні)",
"defaultIpLimit": "Ліміт IP за замовч."
},
"subFormats": {
"finalMask": "Final Mask",
"finalMaskDesc": "Додає TCP/UDP-маски finalmask Xray і параметри QUIC до кожного створеного профілю Xray JSON. Потрібен застосунок із підтримкою підписок Xray JSON і нова версія ядра Xray.",
@@ -1276,31 +1179,15 @@
"muxSett": "Налаштування Mux",
"direct": "Пряме підключення",
"directDesc": "Безпосередньо встановлює з’єднання з доменами або діапазонами IP певної країни.",
"notifications": "Сповіщення",
"certs": "Сертифікати",
"externalTraffic": "Зовнішній трафік",
"dateAndTime": "Дата та час",
"proxyAndServer": "Проксі та сервер",
"intervals": "Інтервали",
"information": "Інформація",
"profile": "Профіль",
"language": "Мова",
"telegramBotLanguage": "Мова Telegram-бота",
"security": {
"admin": "Облікові дані адміністратора",
"twoFactor": "Двофакторна аутентифікація",
"twoFactorEnable": "Увімкнути 2FA",
"twoFactorEnableDesc": "Додає додатковий рівень аутентифікації для підвищення безпеки.",
"twoFactorModalSetTitle": "Увімкнути двофакторну аутентифікацію",
"twoFactorModalDeleteTitle": "Вимкнути двофакторну аутентифікацію",
"twoFactorModalSteps": "Щоб налаштувати двофакторну аутентифікацію, виконайте кілька кроків:",
"twoFactorModalFirstStep": "1. Відскануйте цей QR-код у програмі для аутентифікації або скопіюйте токен біля QR-коду та вставте його в програму",
"twoFactorModalSecondStep": "2. Введіть код з програми",
"twoFactorModalRemoveStep": "Введіть код з програми, щоб вимкнути двофакторну аутентифікацію.",
"twoFactorModalChangeCredentialsTitle": "Змінити облікові дані",
"twoFactorModalChangeCredentialsStep": "Введіть код з додатку, щоб змінити облікові дані адміністратора.",
"twoFactorModalSetSuccess": "Двофакторна аутентифікація була успішно встановлена",
"twoFactorModalDeleteSuccess": "Двофакторна аутентифікація була успішно видалена",
"twoFactorModalError": "Невірний код",
"show": "Показати",
"hide": "Сховати",
@@ -1323,36 +1210,6 @@
"getOutboundTrafficError": "Помилка отримання вихідного трафіку",
"resetOutboundTrafficError": "Помилка скидання вихідного трафіку"
},
"smtpSettings": "Налаштування SMTP",
"smtpEnable": "Увімкнути сповіщення електронною поштою",
"smtpEnableDesc": "Увімкнути сповіщення електронною поштою через SMTP",
"smtpHost": "Хост SMTP",
"smtpHostDesc": "Ім'я хоста сервера SMTP (наприклад, smtp.gmail.com)",
"smtpPort": "Порт SMTP",
"smtpPortDesc": "Порт сервера SMTP (типово: 587)",
"smtpUsername": "Ім'я користувача SMTP",
"smtpUsernameDesc": "Ім'я користувача для автентифікації SMTP",
"smtpFrom": "Адреса відправника (From)",
"smtpFromDesc": "Адреса в заголовку From листа. Залиште порожнім, щоб використати ім'я користувача.",
"smtpFromName": "Ім'я відправника (From)",
"smtpFromNameDesc": "Необов'язкове відображуване ім'я перед адресою в заголовку From.",
"smtpPassword": "Пароль SMTP",
"smtpPasswordDesc": "Пароль для автентифікації SMTP",
"smtpTo": "Отримувачі",
"smtpToDesc": "Адреси електронної пошти отримувачів, розділені комами",
"emailSettings": "Електронна пошта",
"emailNotifications": "Сповіщення",
"smtpEventBusNotify": "Сповіщення про події електронною поштою",
"smtpEventBusNotifyDesc": "Виберіть, які події спричиняють сповіщення електронною поштою",
"tgEventBusNotify": "Сповіщення про події в Telegram",
"tgEventBusNotifyDesc": "Виберіть, які події спричиняють сповіщення в Telegram",
"testSmtp": "Надіслати тестовий лист",
"testTgBot": "Надіслати тестове повідомлення",
"eventGroupOutbound": "Вихідні з'єднання",
"eventGroupXray": "Ядро Xray",
"eventGroupSystem": "Система",
"eventGroupSecurity": "Безпека",
"eventGroupNode": "Вузли",
"eventOutboundDown": "Недоступне",
"eventOutboundUp": "Доступне",
"eventXrayCrash": "Збій",
@@ -1360,36 +1217,7 @@
"eventNodeUp": "Доступний",
"eventCPUHigh": "Високе навантаження на CPU (%)",
"requestFailed": "Запит не вдалося виконати",
"smtpEncryption": "Шифрування",
"smtpEncryptionDesc": "Метод шифрування з'єднання SMTP",
"smtpEncryptionNone": "Немає (відкритий текст)",
"smtpEncryptionStartTLS": "STARTTLS",
"smtpEncryptionTLS": "TLS (неявне)",
"smtpStageConnect": "З'єднання",
"smtpStageAuth": "Автентифікація",
"smtpStageSend": "Надсилання",
"smtpTestSuccess": "Тестовий лист успішно надіслано",
"smtpHostNotConfigured": "Хост SMTP не налаштовано",
"smtpNoRecipients": "Отримувачів не налаштовано",
"smtpFromNotConfigured": "Адресу відправника SMTP не налаштовано",
"eventLoginAttempt": "Спроба входу",
"telegramTokenConfigured": "Налаштовано; залиште порожнім, щоб зберегти поточний токен.",
"telegramTokenPlaceholder": "Налаштовано — введіть новий токен для заміни",
"smtpPasswordConfigured": "Налаштовано; залиште порожнім, щоб зберегти поточний пароль.",
"smtpPasswordPlaceholder": "Налаштовано — введіть новий пароль для заміни",
"smtpNotInitialized": "SMTP не ініціалізовано",
"tgBotNotEnabled": "Бот Telegram не увімкнено",
"tgTestFailed": "Тест Telegram не вдався",
"tgTestSuccess": "Тестове повідомлення надіслано в Telegram",
"tgBotNotRunning": "Бот Telegram не запущено",
"smtpErrorAuth": "Помилка автентифікації — перевірте ім'я користувача та пароль",
"smtpErrorStarttls": "Сервер вимагає STARTTLS — змініть тип шифрування",
"smtpErrorTls": "Сервер вимагає TLS — змініть тип шифрування",
"smtpErrorRefused": "У з'єднанні відмовлено — перевірте хост і порт",
"smtpErrorTimeout": "Час очікування з'єднання вичерпано — хост недоступний",
"smtpErrorRelay": "Сервер відхиляє надсилання з цієї адреси",
"smtpErrorEof": "З'єднання закрито сервером",
"smtpErrorUnknown": "Помилка SMTP: {{ .Error }}",
"eventMemoryHigh": "Високе використання пам'яті (%)",
"remarkTemplate": "Шаблон примітки",
"remarkTemplateDesc": "Якщо задано, це замінює модель примітки для кожного посилання підписки — напишіть власний формат із токенами змінних (використовуйте кнопку для їх вставлення). Залиште порожнім, щоб використовувати модель вище.",
@@ -1475,8 +1303,6 @@
"directdomains": "Прямі домени",
"ipv4Routing": "Маршрутизація IPv4",
"ipv4RoutingDesc": "Ці параметри спрямовуватимуть трафік на основі певного призначення через IPv4.",
"Template": "Шаблон розширеної конфігурації Xray",
"TemplateDesc": "Остаточний конфігураційний файл Xray буде створено на основі цього шаблону.",
"FreedomStrategy": "Стратегія протоколу свободи",
"FreedomStrategyDesc": "Установити стратегію виведення для мережі в протоколі свободи.",
"FreedomHappyEyeballs": "Freedom Happy Eyeballs (IPv4/IPv6)",
@@ -1492,11 +1318,6 @@
"Balancers": "Балансери",
"balancerTagRequired": "Тег обов'язковий",
"balancerSelectorRequired": "Виберіть принаймні один вихідний",
"balancerLive": "Поточна ціль",
"balancerOverride": "Примусова ціль",
"balancerOverridePh": "Авто (стратегія)",
"balancerLiveRefresh": "Оновити стан балансувальника",
"balancerNotRunning": "Цей балансувальник неактивний у запущеному Xray — збережіть зміни або спочатку запустіть Xray",
"routeTester": "Тест маршруту",
"routeTesterDesc": "Запитайте запущений Xray, через який вихідний буде оброблено з'єднання. Реальний трафік не надсилається — рішення надходить безпосередньо від живого рушія маршрутизації.",
"routeTesterDest": "Домен або IP",
@@ -1516,7 +1337,6 @@
"metricsListen": "Точка доступу метрик",
"metricsListenDesc": "Надає метрики Xray у стилі Prometheus за цією адресою:порт (наприклад, 127.0.0.1:11111). Залиште порожнім, щоб вимкнути. Прив'яжіть до localhost і використовуйте зворотний проксі — доступ без автентифікації.",
"metricsTag": "Тег метрик",
"completeTemplate": "Усі",
"logLevel": "Рівень журналу",
"logLevelDesc": "Рівень журналу для журналів помилок із зазначенням інформації, яку потрібно записати.",
"accessLog": "Журнал доступу",
@@ -1544,7 +1364,6 @@
"source": "Джерело",
"dest": "Пункт призначення",
"inbound": "Вхідний",
"balancer": "Балансувальник",
"useComma": "Елементи, розділені комами"
},
"routing": {
@@ -1725,32 +1544,7 @@
"alreadyAdded": "Цей сервер уже в списку вихідних. Щоб оновити ключ, натисніть {reset}.",
"provisionFailed": "Не вдалося створити вихідний PIA. Спробуйте ще раз."
},
"tabBalancerSettings": "Налаштування балансувальника",
"tabObservatory": "Обсерваторія",
"observatory": {
"autoManaged": "Спостерігачі керуються автоматично на основі ваших балансувальників. Нижче можна налаштувати, як вони опитують; відстежувані вихідні слідують за селекторами балансувальника.",
"emptyHint": "Немає активного спостерігача з’єднань. Його буде додано автоматично під час створення балансувальника Least Ping або Least Load — чи Random / Round-robin із fallback — щоб балансувальники зі спостерігачем могли перевіряти стан вихідних перед вибором цілі.",
"mixedLegacy": "Ця конфігурація містить і Observatory, і Burst Observatory. Xray використовує одного глобального спостерігача, тому такий застарілий змішаний стан не підтримується; збереження балансувальників нормалізує його до одного спостерігача.",
"subjectSelector": "Відстежувані вихідні",
"subjectSelectorDesc": "Теги вихідних, які опитує цей спостерігач. Керується автоматично на основі ваших балансувальників.",
"probeURL": "URL проби",
"probeURLDesc": "URL, що запитується для вимірювання кожного вихідного. Має повертати HTTP 204.",
"probeInterval": "Інтервал проби",
"probeIntervalDesc": "Як часто опитувати кожен вихідний, напр. 30s, 1m, 2h45m.",
"enableConcurrency": "Паралельні проби",
"enableConcurrencyDesc": "Опитувати всі відстежувані вихідні одночасно, а не по одному. Швидше, але помітніше в мережі.",
"destination": "Призначення проби",
"destinationDesc": "URL, що запитується для вимірювання кожного вихідного. Має повертати HTTP 204.",
"connectivity": "Перевірка з’єднання",
"connectivityDesc": "Необов’язковий URL перевірки локальної мережі, використовується лише після збою призначення. Залиште порожнім, щоб пропустити.",
"interval": "Інтервал проби",
"intervalDesc": "Середній час між пробами для кожного вихідного, напр. 1m. Мінімум 10s.",
"timeout": "Тайм-аут проби",
"timeoutDesc": "Скільки чекати на пробу, перш ніж вважати її невдалою, напр. 5s.",
"sampling": "Розмір вибірки",
"samplingDesc": "Скільки останніх результатів проб зберігається для оцінювання кожного вихідного.",
"httpMethod": "Метод HTTP",
"httpMethodDesc": "Метод HTTP, що використовується для проб.",
"deleteAlsoObservatory": "Це останній балансувальник, що використовує Observatory, тож його теж буде видалено.",
"deleteAlsoBurst": "Це останній балансувальник, що використовує Burst Observatory, тож його теж буде видалено."
},
@@ -1762,25 +1556,7 @@
},
"balancer": {
"balancerStrategy": "Стратегія",
"tag": "Тег",
"tagDuplicate": "Тег уже використовується іншим балансувальником",
"tagPlaceholder": "унікальний тег балансувальника",
"selector": "Селектор",
"fallback": "Fallback",
"cycleTooltip": "Цикл: {path} → (назад до {start})",
"expected": "Очікуване",
"expectedPlaceholder": "оптимальна кількість вузлів",
"maxRtt": "Макс. RTT",
"tolerance": "Допуск",
"baselines": "Baselines",
"costs": "Costs",
"costMatch": "Шаблон тегу",
"costValue": "Вага",
"costRegexp": "Збіг за регулярним виразом",
"balancerDeleteInUse": "Неможливо видалити цей балансувач — він використовується як резервний для: {names}",
"balancerFallbackCycle": "Неможливо призначити цей балансувач резервним — це створить циклічну залежність.",
"balancerFallbackInfo": "Трафік буде маршрутизовано через: Балансувач → Loopback → Сервер → Цільовий балансувач → Вихідне зʼєднання. Це додає додатковий хоп через сервер, що може спричинити невеликі затримки.",
"fallbackBalancerHint": "Оберіть інший балансувач як резервний",
"reservedPrefix": "Префікс _bl_ зарезервовано для внутрішніх loopback-об'єктів балансувальника"
},
"wireguard": {
@@ -1883,55 +1659,8 @@
"usage": "Використання",
"addOutbound": "Додати вихідний"
},
"dns": {
"enable": "Увімкнути DNS",
"enableDesc": "Увімкнути вбудований DNS-сервер",
"tag": "Мітка вхідного DNS",
"tagDesc": "Ця мітка буде доступна як вхідна мітка в правилах маршрутизації.",
"clientIp": "IP клієнта",
"clientIpDesc": "Використовується для повідомлення серверу про вказане місцезнаходження IP під час DNS-запитів",
"disableCache": "Вимкнути кеш",
"disableCacheDesc": "Вимкнути кешування DNS",
"disableFallback": "Вимкнути резервний DNS",
"disableFallbackDesc": "Вимкнути резервні DNS-запити",
"disableFallbackIfMatch": "Вимкнути резервний DNS при збігу",
"disableFallbackIfMatchDesc": "Вимкнути резервні DNS-запити при збігу списку доменів DNS-сервера",
"enableParallelQuery": "Увімкнути паралельні запити",
"enableParallelQueryDesc": "Увімкнути паралельні DNS-запити до кількох серверів для швидшого вирішення",
"strategy": "Стратегія запиту",
"strategyDesc": "Загальна стратегія вирішення доменних імен",
"add": "Додати сервер",
"edit": "Редагувати сервер",
"domains": "Домени",
"expectIPs": "Очікувані IP",
"unexpectIPs": "Неочікувані IP",
"useSystemHosts": "Використовувати системні Hosts",
"useSystemHostsDesc": "Використовувати файл hosts з встановленої системи",
"serveStale": "Видавати застарілі",
"serveStaleDesc": "Повертати застарілі результати з кешу під час фонового оновлення",
"serveExpiredTTL": "TTL застарілих",
"serveExpiredTTLDesc": "Термін дії (секунди) застарілих записів кешу; 0 = ніколи",
"timeoutMs": "Тайм-аут (мс)",
"skipFallback": "Пропустити Fallback",
"finalQuery": "Фінальний запит",
"hosts": "Hosts",
"hostsAdd": "Додати Host",
"hostsEmpty": "Host не визначено",
"hostsDomain": "Домен (напр. domain:example.com)",
"hostsValues": "IP або домен — введіть і натисніть Enter",
"usePreset": "Використати шаблон",
"dnsPresetTitle": "Шаблони DNS",
"dnsPresetFamily": "Сімейний",
"clearAll": "Видалити всі",
"clearAllTitle": "Видалити всі DNS-сервери?",
"clearAllConfirm": "Усі DNS-сервери буде видалено зі списку. Дію не можна скасувати.",
"dnsLeakWarning": "DNS може витікати через localhost, звичайний UDP/TCP, локальний режим DoH/DoQ, fallback-запити або EDNS client IP. Для приватності використовуйте маршрутизований DoH, фіксацію hosts і вимикайте fallback."
},
"fakedns": {
"add": "Додати підроблений DNS",
"ipPool": "Підмережа IP-пулу",
"poolSize": "Розмір пулу"
},
"dns": {},
"fakedns": {},
"defaultOutbound": "Вихідний за замовчуванням",
"defaultOutboundDesc": "Трафік без збігу з правилами маршрутизації йде через цей вихідний (перший у списку)."
},
@@ -2055,198 +1784,7 @@
}
},
"tgbot": {
"keyboardClosed": "❌ Клавіатуру закрито!",
"noResult": "❗ Немає результату!",
"noQuery": "❌ Запит не знайдено! Будь ласка, використовуйте команду ще раз!",
"wentWrong": "❌ Щось пішло не так!",
"noIpRecord": "❗ Немає запису IP!",
"noInbounds": "❗ Вхідні не знайдені!",
"unlimited": "♾ Необмежено (Скинути)",
"add": "Додати",
"month": "Місяць",
"months": "Місяці",
"days": "Дні",
"hours": "Години",
"minutes": "Хвилини",
"unknown": "Невідомо",
"inbounds": "Вхідні",
"clients": "Клієнти",
"offline": "🔴 Не в мережі",
"online": "🟢 У мережі",
"commands": {
"unknown": "❗ Невідома команда.",
"pleaseChoose": "👇 Будь ласка, виберіть:\r\n",
"help": "🤖 Ласкаво просимо до цього бота! Він розроблений, щоб надавати певні дані з веб-панелі та дозволяє вносити зміни за потреби.\r\n\r\n",
"start": "👋 Привіт <i>{{ .Firstname }}</i>.\r\n",
"welcome": "🤖 Ласкаво просимо до <b>{{ .Hostname }}</b> бота керування.\r\n",
"status": "✅ Бот в порядку!",
"usage": "❗ Введіть текст для пошуку!",
"getID": "🆔 Ваш ідентифікатор: <code>{{ .ID }}</code>",
"helpAdminCommands": "Для перезапуску Xray Core:\r\n<code>/restart</code>\r\n\r\nДля пошуку електронної пошти клієнта:\r\n<code>/usage [Електронна пошта]</code>\r\n\r\nДля пошуку вхідних (зі статистикою клієнта):\r\n<code>/inbound [Примітка]</code>\r\n\r\nID чату Telegram:\r\n<code>/id</code>",
"helpClientCommands": "Для пошуку статистики використовуйте наступну команду:\r\n<code>/usage [Електронна пошта]</code>\r\n\r\nID чату Telegram:\r\n<code>/id</code>",
"restartUsage": "\r\n\r\n<code>/restart</code>",
"restartSuccess": "✅ Операція успішна!",
"restartFailed": "❗ Помилка в операції.\r\n\r\n<code>Помилка: {{ .Error }}</code>.",
"xrayNotRunning": "❗ Xray Core не запущений.",
"startDesc": "Показати головне меню",
"helpDesc": "Довідка по боту",
"statusDesc": "Перевірити статус бота",
"idDesc": "Показати ваш Telegram ID",
"usageDesc": "Показати трафік клієнта: /usage email",
"inboundDesc": "Пошук вхідних: /inbound назва (адмін)",
"restartDesc": "Перезапустити ядро Xray (адмін)",
"clearallDesc": "Скинути трафік усіх клієнтів (адмін)"
},
"messages": {
"cpuThreshold": "Навантаження ЦП {{ .Percent }}% перевищує порогове значення {{ .Threshold }}%",
"selectUserFailed": "❌ Помилка під час вибору користувача!",
"userSaved": "✅ Користувача Telegram збережено.",
"loginSuccess": "✅ Успішно ввійшли в панель\r\n",
"loginFailed": "❗️ Помилка входу в панель.\r\n",
"report": "🕰 Заплановані звіти: {{ .RunTime }}\r\n",
"datetime": "⏰ Дата й час: {{ .DateTime }}\r\n",
"hostname": "💻 Хост: {{ .Hostname }}\r\n",
"version": "🚀 3X-UI Версія: {{ .Version }}\r\n",
"xrayVersion": "📡 Xray Версія: {{ .XrayVersion }}\r\n",
"ipv6": "🌐 IPv6: {{ .IPv6 }}\r\n",
"ipv4": "🌐 IPv4: {{ .IPv4 }}\r\n",
"ip": "🌐 IP: {{ .IP }}\r\n",
"ips": "🔢 IP:\r\n{{ .IPs }}\r\n",
"serverUpTime": "⏳ Час роботи: {{ .UpTime }} {{ .Unit }}\r\n",
"serverLoad": "📈 Завантаження системи: {{ .Load1 }}, {{ .Load2 }}, {{ .Load3 }}\r\n",
"serverMemory": "📋 RAM: {{ .Current }}/{{ .Total }}\r\n",
"tcpCount": "🔹 TCP: {{ .Count }}\r\n",
"udpCount": "🔸 UDP: {{ .Count }}\r\n",
"traffic": "🚦 Трафік: {{ .Total }} (↑{{ .Upload }},↓{{ .Download }})\r\n",
"xrayStatus": "ℹ️ Статус: {{ .State }}\r\n",
"username": "👤 Ім'я користувача: {{ .Username }}\r\n",
"reason": "❗️ Причина: {{ .Reason }}\r\n",
"time": "⏰ Час: {{ .Time }}\r\n",
"inbound": "📍 Вхідний: {{ .Remark }}\r\n",
"port": "🔌 Порт: {{ .Port }}\r\n",
"expire": "📅 Дата закінчення: {{ .Time }}\r\n",
"expireIn": "📅 Термін дії: {{ .Time }}\r\n",
"active": "💡 Активний: {{ .Enable }}\r\n",
"enabled": "🚨 Увімкнено: {{ .Enable }}\r\n",
"online": "🌐 Стан підключення: {{ .Status }}\r\n",
"lastOnline": "🔙 Був(ла) онлайн: {{ .Time }}\r\n",
"email": "📧 Email: {{ .Email }}\r\n",
"upload": "🔼 Завантаження: ↑{{ .Upload }}\r\n",
"download": "🔽 Завантаження: ↓{{ .Download }}\r\n",
"total": "📊 Усього: ↑↓{{ .UpDown }} / {{ .Total }}\r\n",
"TGUser": "👤 Користувач Telegram: {{ .TelegramID }}\r\n",
"exhaustedCount": "🚨 Вичерпано кількість {{ .Type }} count:\r\n",
"onlinesCount": "🌐 Онлайн-клієнти: {{ .Count }}\r\n",
"disabled": "🛑 Вимкнено: {{ .Disabled }}\r\n",
"depleteSoon": "🔜 Скоро вичерпається: {{ .Deplete }}\r\n\r\n",
"backupTime": "🗄 Час резервного копіювання: {{ .Time }}\r\n",
"refreshedOn": "\r\n📋🔄 Оновлено: {{ .Time }}\r\n\r\n",
"yes": "✅ Так",
"no": "❌ Ні",
"received_email": "📧📥 Електронна пошта оновлена.",
"received_comment": "💬📥 Коментар оновлено.",
"email_prompt": "📧 Стандартний email: {{ .ClientEmail }}\n\nВведіть ваш email.",
"comment_prompt": "💬 Стандартний коментар: {{ .ClientComment }}\n\nВведіть ваш коментар.",
"cancel": "❌ Процес скасовано! \n\nВи можете знову розпочати, використовуючи /start у будь-який час. 🔄",
"error_add_client": "⚠️ Помилка:\n\n {{ .error }}",
"using_default_value": "Гаразд, залишу значення за замовчуванням. 😊",
"incorrect_input": "Ваш ввід невірний.\nФрази повинні бути без пробілів.\nПравильний приклад: aaaaaa\nНеправильний приклад: aaa aaa 🚫",
"AreYouSure": "Ви впевнені? 🤔",
"SuccessResetTraffic": "📧 Електронна пошта: {{ .ClientEmail }}\n🏁 Результат: ✅ Успішно",
"FailedResetTraffic": "📧 Електронна пошта: {{ .ClientEmail }}\n🏁 Результат: ❌ Невдача \n\n🛠️ Помилка: [ {{ .ErrorMessage }} ]",
"FinishProcess": "🔚 Процес скидання трафіку завершено для всіх клієнтів.",
"eventOutboundDown": "Вихідне з'єднання {{ .Tag }} НЕДОСТУПНЕ",
"eventOutboundUp": "Вихідне з'єднання {{ .Tag }} ДОСТУПНЕ",
"eventErrorDetail": "Помилка: {{ .Error }}",
"eventDelayDetail": "Затримка: {{ .Delay }} мс",
"eventXrayCrash": "Стався збій Xray",
"eventXrayCrashError": "Помилка: {{ .Error }}",
"eventNodeDown": "Вузол {{ .Name }} НЕДОСТУПНИЙ",
"eventNodeUp": "Вузол {{ .Name }} ДОСТУПНИЙ",
"eventLoginFallback": "Невдала спроба входу з {{ .Source }}",
"memoryThreshold": "Використання пам'яті {{ .Percent }}% перевищує порогове значення {{ .Threshold }}%"
},
"buttons": {
"closeKeyboard": "❌ Закрити клавіатуру",
"cancel": "❌ Скасувати",
"cancelReset": "❌ Скасувати скидання",
"cancelIpLimit": "❌ Скасувати обмеження IP",
"confirmResetTraffic": "✅ Підтвердити скидання трафіку?",
"confirmClearIps": "✅ Підтвердити очищення IP-адрес?",
"confirmRemoveTGUser": "✅ Підтвердити видалення користувача Telegram?",
"confirmToggle": "✅ Підтвердити ввімкнути/вимкнути користувача?",
"dbBackup": "Отримати резервну копію БД",
"serverUsage": "Використання сервера",
"getInbounds": "Отримати вхідні",
"depleteSoon": "Скоро вичерпати",
"clientUsage": "Отримати використання",
"onlines": "Онлайн-клієнти",
"commands": "Команди",
"refresh": "🔄 Оновити",
"clearIPs": "❌ Очистити IP-адреси",
"removeTGUser": "❌ Видалити користувача Telegram",
"selectTGUser": "👤 Виберіть користувача Telegram",
"selectOneTGUser": "👤 Виберіть користувача Telegram:",
"resetTraffic": "📈 Скинути трафік",
"resetExpire": "📅 Змінити термін дії",
"ipLog": "🔢 IP журнал",
"ipLimit": "🔢 IP Ліміт",
"setTGUser": "👤 Встановити користувача Telegram",
"toggle": "🔘 Увімкнути / Вимкнути",
"custom": "🔢 Своє",
"confirmNumber": "✅ Підтвердити: {{ .Num }}",
"confirmNumberAdd": "✅ Підтвердити додавання: {{ .Num }}",
"limitTraffic": "🚧 Ліміт трафіку",
"getBanLogs": "Отримати журнали заборон",
"allClients": "Всі Клієнти",
"addClient": "Додати клієнта",
"submitDisable": "Надіслати як вимкнено ☑️",
"submitEnable": "Надіслати як увімкнено ✅",
"use_default": "🏷️ Використати типове",
"change_email": "⚙️📧 Email",
"change_comment": "⚙️💬 Коментар",
"ResetAllTraffics": "Скинути весь трафік",
"SortedTrafficUsageReport": "Відсортований звіт про використання трафіку"
},
"answers": {
"successfulOperation": "✅ Операція успішна!",
"errorOperation": "❗ Помилка в роботі.",
"getInboundsFailed": "❌ Не вдалося отримати вхідні повідомлення.",
"getClientsFailed": "❌ Не вдалося отримати клієнтів.",
"canceled": "❌ {{ .Email }}: Операцію скасовано.",
"clientRefreshSuccess": "✅ {{ .Email }}: Клієнт успішно оновлено.",
"IpRefreshSuccess": "✅ {{ .Email }}: IP-адреси успішно оновлено.",
"TGIdRefreshSuccess": "✅ {{ .Email }}: Користувач Telegram клієнта успішно оновлено.",
"resetTrafficSuccess": "✅ {{ .Email }}: Трафік скинуто успішно.",
"setTrafficLimitSuccess": "✅ {{ .Email }}: Ліміт трафіку успішно збережено.",
"expireResetSuccess": "✅ {{ .Email }}: Успішно скинуто дні закінчення терміну дії.",
"resetIpSuccess": "✅ {{ .Email }}: IP обмеження {{ .Count }} успішно збережено.",
"clearIpSuccess": "✅ {{ .Email }}: IP успішно очищено.",
"getIpLog": "✅ {{ .Email }}: Отримати IP-журнал.",
"getUserInfo": "✅ {{ .Email }}: Отримати інформацію про користувача Telegram.",
"removedTGUserSuccess": "✅ {{ .Email }}: Користувача Telegram видалено успішно.",
"enableSuccess": "✅ {{ .Email }}: Увімкнути успішно.",
"disableSuccess": "✅ {{ .Email }}: Успішно вимкнено.",
"askToAddUserId": "Вашу конфігурацію не знайдено!\r\nБудь ласка, попросіть свого адміністратора використовувати ваш ідентифікатор Telegram у вашій конфігурації.\r\n\r\nВаш ідентифікатор користувача: <code>{{ .TgUserID }}</code>",
"chooseClient": "Виберіть клієнта для Вхідного {{ .Inbound }}",
"chooseInbound": "Виберіть Вхідний"
}
"noIpRecord": "❗ Немає запису IP!"
},
"email": {
"labelStatus": "Статус",
"labelOutbound": "Вихідне з'єднання",
"labelNode": "Вузол",
"labelError": "Помилка",
"labelDelay": "Затримка",
"labelUsername": "Ім'я користувача",
"labelIP": "IP",
"labelReason": "Причина",
"labelSource": "Джерело",
"statusCrashed": "ЗБІЙ",
"statusHigh": "ВИСОКЕ",
"statusSuccess": "УСПІШНО",
"statusFailed": "НЕВДАЛО",
"statusDown": "НЕДОСТУПНО",
"statusUp": "ДОСТУПНО"
}
"email": {}
}