Files
NeoTachyon/tachyon/files/usr/lib/service/i18n.uc
T
Dushnilin 1aa69d5e03 feat(telegram): full i18n — ~230 Russian strings replaced with t() calls
- Added ~120 new i18n keys to both en and ru sections
- Replaced all remaining hardcoded Russian strings in telegram.uc
- Menu, status, connections, diagnostics, help, subscriptions, quiet hours,
  test rule, export, MAC blocking, devices, watchdog/AI, QoS, section
  management, DNS presets, exec, daily digest, update notifications,
  blocked activity, all navigation buttons
- All keys verified present via runtime check
2026-08-25 15:45:44 +03:00

1109 lines
59 KiB
Ucode
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// Telegram bot i18n — string tables for en/ru
// Usage: let i18n = require("service.i18n"); let t = i18n.bind(lang);
let strings = {
en: {
// ─── Setting schema labels ───
dns_type: "DNS Type",
dns_server: "DNS Servers",
bootstrap_dns_server: "Bootstrap DNS",
dns_strategy: "DNS Strategy",
dns_detour_enabled: "DNS Detour",
source_network_interfaces: "Inbound Interfaces",
enable_output_network_interface: "Bind to WAN",
enable_badwan_interface_monitoring: "WAN Monitoring",
enable_yacd: "YACD Panel",
disable_quic: "Block QUIC",
list_update_enabled: "List Updates",
component_update_check_enabled: "Core Updates",
download_lists_via_proxy: "Lists via Proxy",
download_components_via_proxy: "Core via Proxy",
dont_touch_dhcp: "Don't Touch DHCP",
isolate_p2p: "Isolate P2P",
log_level: "Log Level",
exclude_ntp: "Exclude NTP",
shutdown_correctly: "Clean Shutdown",
smart_detect: "Smart Detect",
smart_detect_sections: "Smart Detect Sections",
enabled: "Bot Enabled",
bot_token: "Token",
admin_ids: "Admin IDs",
poll_interval: "Poll Interval",
notify_crash: "Core Crashes",
notify_restart: "Restarts",
notify_server_switch: "Server Switches",
notify_subscription: "Subscription Status",
notify_cert: "Certificates",
notify_dns_leak: "DNS Leaks",
daily_report_enabled: "Daily Report",
daily_report_hour: "Report Time (hour)",
quiet_hours_enabled: "Quiet Hours",
quiet_hours_start: "Quiet Hours Start",
quiet_hours_end: "Quiet Hours End",
fallback_socks: "Fallback SOCKS5",
language: "Language",
section: "Section",
auto_user_agent: "Auto User-Agent",
user_agent: "User-Agent",
auto_hwid: "Auto HWID",
subscription_update_enabled: "Auto Update",
subscription_update_interval: "Update Interval",
download_via_proxy_enabled: "Via Proxy",
show_dashboard_metadata: "Subscription Metadata",
prefix_nodes: "Node Prefix",
node_prefix: "Prefix String",
include_urltest_groups: "URL-Test Groups",
hide_urltest_group_outbounds: "Hide Group Nodes",
hide_detour_outbounds: "Hide Detour Nodes",
label: "Name",
protocol: "Protocol",
routing_mode: "Routing Mode",
// ─── Navigation ───
nav_next: "Next ▶️",
nav_prev: "◀️ Prev",
nav_back: "◀️ Back",
nav_menu: "🏠 Menu",
nav_settings: "⚙️ Settings",
// ─── Menu ───
menu_all_settings: "⚙️ All Settings",
menu_choose_cat: "Select category to edit:",
menu_global: "🌍 Global Settings",
menu_telegram: "🤖 Telegram Settings",
menu_subscriptions: "📋 Subscriptions",
menu_servers: "🖥️ Custom Servers",
menu_servers_short: "🖥 Custom Servers",
menu_dns_presets: "🌐 DNS Servers (Presets)",
menu_quiet_hours: "🔕 Quiet Hours",
menu_test_rule: "🔍 Test Rule",
menu_export_config: "📤 Export Config",
menu_help: "📖 Help",
menu_status: "📊 System Status",
menu_diagnostic: "🩺 Diagnostics",
menu_logs: "📝 Logs",
menu_connections: "🔌 Connections",
menu_outbounds: "🚀 Proxy Servers",
menu_sections: "📁 Routing Sections",
menu_speed: "⚡ Speed Test",
menu_ping: "📡 Ping",
menu_restart: "🔄 Restart Tachyon",
menu_language: "🌐 Language",
menu_extras: "🔧 Extras",
menu_info: "ℹ️ System Info",
menu_close_conn: "🗑️ Close All Connections",
menu_check_updates: "🔄 Check Updates",
menu_doctor: "🩺 Doctor",
menu_test_rule: "🔍 Test Rule",
menu_devices: "💻 Network Devices",
menu_instances: "Live Servers",
menu_categories: "🔙 Categories",
menu_qos: "🎮 Gaming & Voice QoS",
menu_heal: "🤖 AI Self-Healing",
// ─── Status ───
status_version: "Version",
status_uptime: "Uptime",
status_cpu: "Router CPU",
status_active_servers: "Active servers:",
status_no_server: "No server selected",
status_enabled: "Enabled ✅",
status_disabled: "Disabled ❌",
status_target: "Target",
status_running: "🟢 Running",
status_stopped: "🔴 Stopped",
status_unknown: "Unknown",
status_normal: "All systems are operating normally! 🟢",
status_pause: "Paused",
status_header: "System Status",
status_sections: "Sections",
// ─── Stats ───
stat_download: "Downloaded",
stat_upload: "Uploaded",
stat_memory: "Memory",
stat_connections: "Connections",
// ─── Section management ───
section_type: "Type",
section_status: "Status",
section_choose_group: "Select a group to configure the server:",
section_group: "Group",
section_server: "Server",
section_check_singbox: "Check if sing-box is running and Clash API is accessible.",
section_domains: "Domains",
section_sources: "Sources",
section_section: "Section",
section_edit: "Editing",
section_create: "➕ Create section",
section_action: "Action",
section_list: "List",
section_empty: "Empty",
section_showing_partial: "(Showing not all items for deletion)",
btn_rename: "✏️ Rename",
btn_delete: "❌ Delete",
btn_add: "➕ Add",
btn_clear_all: "➖ Clear all",
btn_add_items: "➕ Add items",
btn_clear_list: "➖ Clear list",
btn_back_to_section: "🔙 Back to section",
// ─── Diagnostics ───
diag_running: "Diagnostics already running by another process.",
diag_issues: "Issues: %s",
diag_issues_count: "Issues: %s",
diag_fixed_count: ", fixed: %s",
diag_planned_count: ", planned: %d",
diag_clean: "No issues detected.",
diag_no_output: "No diagnostic output.",
diag_error: "Failed to start diagnostics.",
diag_empty: "Empty diagnostics report.",
diag_all_fixed: "All systems restored to normal! 🟢",
diag_starting: "Running diagnostics...",
diag_results: "Tachyon Doctor Results:",
report_truncated: "report truncated",
// ─── Logs ───
logs_no_records: "No records for this level.\n",
logs_read_error: "Failed to read logs.\n",
// ─── Connections ───
conn_none: "No active connections.",
// ─── Subscriptions ───
sub_none: "No subscriptions. Add a subscription URL to download rules.",
sub_found: "Found subscriptions: ",
// ─── Latency ───
latency_no_data: "No latency data. Press «Refresh».",
latency_none: "No latency data available.",
// ─── Servers ───
servers_none: "No servers found or sing-box is not running.",
servers_api_error: "API parsing error: ",
// ─── QoS ───
qos_status: "Status",
qos_enabled: "🟢 Enabled",
qos_disabled: "❌ Disabled",
qos_start: "Start",
qos_end: "End",
qos_quiet_hint: "During quiet hours, the bot only sends critical notifications.",
// ─── Errors ───
err_invalid_format: "Invalid command format",
err_not_allowed: "Command '%s' is not in the allowed list",
err_args_mismatch: "Arguments don't match the allowed template",
err_wrong_arg_count: "Wrong number of arguments",
err_arg_not_allowed: "Argument not allowed: %s",
err_subcmd_not_allowed: "Subcommand '%s' is not in the whitelist",
err_host_unknown: "Unknown",
err_api_parse: "Failed to read info: ",
err_status_fetch: "Failed to get status.",
err_no_data: "No data.",
err_log_read: "Failed to read logs.",
err_no_output: "No output",
// ─── Notifications ───
notif_restart_services: "Tachyon services restarted",
notif_nft_cleared: "nftables rules table cleared or corrupted",
notif_nft_regenerated: "TachyonTable and TPROXY chain rules regenerated",
notif_qos_not_found: "Gaming & Voice QoS Accelerator rules not found in nftables",
notif_qos_applied: "High-priority DSCP labels applied: EF (0x2e) for Voice/RTC, AF41 (0x22) for Gaming",
notif_restart_skipped: "Restart skipped: rate limit or active block",
notif_singbox_hung: "Proxy port hang or incomplete response sing-box",
notif_singbox_restarted: "sing-box restarted",
notif_cache_cleared: "cache.db cleared; restart skipped by rate limit",
notif_sets_empty: "Empty nftables sets (community) — data not loaded on reload",
notif_sets_restored: "nftables sets restored from persistent cache",
notif_fw_reload: "reload_firewall executed to restore TPROXY rules",
notif_config_invalid: "Restart cancelled: sing-box config fails validation",
notif_restart_rate: "Restart skipped by rate limit",
notif_rpcd_restarted: "rpcd restarted to free file descriptors",
// ─── Route failure ───
route_proxy_alive: "proxy port is listening, but requests through it are failing",
route_proxy_down: "proxy port not listening (sing-box mixed-inbound not up)",
route_hint: "Reason: %s.\nDirect API access enabled as fallback — commands may respond with delay.\nRun /test to check connectivity.",
route_alert_title: "Tachyon Telegram bot",
route_alert_consecutive: "consecutive API poll failures",
route_reason: "Reason:",
route_fallback_hint: "Direct API access enabled as fallback — commands may respond with delay.",
route_heal_hint: "Watchdog will try to restore proxy automatically.",
// ─── Command descriptions (for setMyCommands) ───
cmd_menu: "Main menu",
cmd_status: "System status",
cmd_runtime: "Traffic stats",
cmd_outbounds: "Proxy servers",
cmd_sections: "Routing sections",
cmd_speed: "Speed test",
cmd_ping: "Server latency",
cmd_test: "Quick diagnostics",
cmd_logs: "View logs",
cmd_info: "System info",
cmd_connections: "Active connections",
cmd_test_rule: "Test rule",
cmd_help: "Help",
cmd_check_updates: "Check for updates",
cmd_close_connections: "Close all connections",
cmd_doctor: "Diagnostics",
cmd_restart: "Restart Tachyon services",
cmd_instances: "Live servers",
cmd_lang: "Change language",
// ─── Misc ───
exec_done: "<b>Done (code %s):</b>\n<pre>%s</pre>",
hour_enter: "⏰ Enter the hour for %s (0-23):",
hour_start: "start",
hour_end: "end",
blocked_activity: "Blocked Activity",
blocked_attempts: "Attempts to access blocked sites",
daily_digest_title: "🌅 Morning Tachyon Digest",
daily_rx: "Current RX",
daily_tx: "Current TX",
daily_connections: "Connections",
daily_memory: "Memory",
choose_language: "Select language:",
lang_current: "Current language: %s",
lang_saved: "Language saved!",
ping_enter_host: "Enter a domain or IP to check:",
test_rule_prompt: "Enter the rule to test:",
rule_label: "Rule",
// ─── Speed test ───
speed_starting: "⚡ <b>Starting Speedtest...</b>\n\nTesting via Cloudflare. Takes up to 30 seconds.",
speed_result: "⚡ Speedtest Result",
speed_direct: "📥 Direct:",
speed_proxy: "📤 Via proxy:",
speed_fail_measure: "❌ failed to measure",
speed_error: "❌ Failed to run test. Check if sing-box is running.",
speed_check_hint: "Check internet access and sing-box.",
// ─── Ping ───
ping_api_error: "❌ Failed to get data from Clash API.",
// ─── Quick test ───
test_title: "Quick Diagnostics",
test_direct: "Direct connection",
test_proxy: "Proxy connection",
test_service: "Tachyon service",
test_nft: "nftables rules",
test_pause: "Pause:",
test_rule: "Rule check:",
test_match: "Match",
test_no_match: "No matches found. Traffic goes through default route.",
// ─── Connections ───
conn_total_down: "Total downloaded",
conn_total_up: "Total uploaded",
conn_closed: "All active connections closed.",
// ─── Devices ───
device_block: "🚫 Block device",
device_unblock: "🔓 Unblock device",
device_blocked: "blocked",
device_unblocked: "unblocked",
// ─── AI Doctor ───
ai_doctor_title: "Tachyon AI Doctor",
ai_status_collecting: "Collecting full AI Watchdog status...",
ai_incident: "⚠️ Incident resolved:",
ai_resolution: "🔧 Auto-fix:",
ai_all_ok: "All network services, DNS, nftables and memory are working perfectly.",
ai_diag_ok: "Diagnostics completed successfully.",
ai_diag_done: "Diagnostics completed.",
// ─── Buttons ───
btn_refresh: "🔄 Refresh",
btn_retry: "🔄 Retry",
btn_again: "🔄 Again",
btn_speed_again: "⚡ Again",
btn_back_to_groups: "🔙 Groups",
btn_back_to_sections: "🔙 Sections",
btn_close_all: "❌ Close All",
btn_test: "🩺 Test",
nav_cancel: "⬅️ Cancel",
restart_confirm: "⚠️ <b>Restart Tachyon services?</b>\nCurrent connections will be interrupted during restart.",
restart_yes: "✅ Yes, restart",
restart_in_progress: "Restarting Tachyon services...",
restart_success: "Restart completed successfully!",
restart_error: "Restart failed.",
conn_closed: "All active connections closed.",
// ─── Outbounds ───
servers_not_found: "Servers not found or sing-box not running.",
outbounds_hint: "Press the button to switch servers.",
// ─── Logs ───
logs_level: "level",
// ─── Info ───
info_device: "Device",
err_info_read: "Failed to read info:",
// ─── Updates ───
update_new_build: "New release build available!",
update_available: "Component update available!",
build_label: "Build",
// ─── Healer ───
heal_running: "AI Doctor running diagnostics and self-healing...",
// ─── Batch i18n additions ───
msg_truncated: "... (message truncated)",
menu_version: "Version",
menu_cpu: "Router CPU",
list_header: "⚙️ <b>List:</b>",
outbound_groups_not_found: "Proxy groups not found.",
outbound_switch_failed: "Failed to switch server",
outbound_group: "Group",
outbound_server: "Server",
outbound_check_hint: "Check if sing-box is running and Clash API is accessible.",
section_ips: "IP addresses",
section_list_header: "⚙️ <b>Section:</b>",
backup_archive_empty: "Archive is empty or corrupted.",
backup_archive_unsafe: "Unsafe archive:",
backup_restoring: "Checking and restoring backup...",
backup_extract_failed: "Failed to extract archive.",
backup_not_valid_uci: "config/tachyon in archive is not a valid UCI.",
backup_no_config: "Archive contains neither config/tachyon nor tachyon/ directory.",
backup_save_config_failed: "Failed to save current config.",
backup_save_data_failed: "Failed to save current /etc/tachyon data.",
backup_write_config_error: "Write error /etc/config/tachyon.",
backup_uci_validation_failed: "Restored config failed UCI validation. Rolled back.",
backup_write_data_error: "Write error /etc/tachyon. Rolled back.",
backup_restored: "Backup restored. Restarting Tachyon...",
backup_done: "Done!",
backup_collecting: "Collecting backup...",
backup_create_error: "Backup creation error.",
support_bundle_collecting: "Generating Support Bundle...",
support_bundle_error: "Bundle generation error.",
conn_closed_msg: "All active connections closed.\nThey will be re-established along new routes.",
conn_close_error: "Connection reset error.\nsing-box Clash API is unavailable.",
updates_title: "Component Updates",
updates_disabled: "Update check is disabled in settings.",
updates_cache_empty: "Cache is empty. Check later.",
update_check_error: "Check error",
update_new_release_build: "new release build",
update_dev_build: "dev build",
update_all_current: "All components up to date.",
update_cache_parse_error: "Cache parse error:",
update_cache_unavailable: "Check cache empty or unavailable.",
btn_refresh_cache: "Refresh cache",
api_parse_error: "API parsing error:",
api_connect_failed: "Failed to connect to sing-box API.",
logs_header: "Tachyon Logs",
info_title: "System Information",
info_device_label: "Device",
info_fetch_failed: "Failed to get system information.",
sub_empty_url: "(empty)",
btn_sub_delete: " 🗑 Delete",
btn_add_subscription: "Add subscription",
sub_section_subs: "Subscriptions",
sub_found_count: "Subscriptions found:",
sub_enter_url: "Enter subscription URL:\n\n<i>Send /cancel to cancel</i>",
sub_url_empty: "URL cannot be empty.",
sub_added: "Subscription added to section",
sub_not_found: "Subscription not found.",
sub_removed: "Subscription removed from section",
help_title: "Command Help",
help_main_section: "Main:",
help_diag_section: "Diagnostics:",
help_manage_section: "Management:",
help_settings_section: "Settings:",
help_this: "This help",
quiet_hours_title: "Quiet Hours",
quiet_status: "Status",
quiet_enabled_label: "Enabled",
quiet_disabled_label: "Disabled",
quiet_start_label: "Start:",
quiet_end_label: "End:",
quiet_hint: "During quiet hours, the bot only sends critical notifications.",
btn_enable: "Enable",
btn_disable: "Disable",
quiet_hour_start: "start",
quiet_hour_end: "end",
quiet_enter_hour: "⏰ Enter the hour for %s quiet hours (0–23):\n\n<i>Send /cancel to cancel</i>",
test_rule_header: "Rule check:",
test_match: "Match:",
test_action: "Action:",
export_title: "Exporting config...",
export_done: "Config exported.\n\n⚠️ File contains sensitive data. Do not publish it.",
export_failed: "Failed to export config.",
mac_invalid: "Invalid MAC address.",
mac_firewall_open_failed: "Failed to open firewall configuration.",
mac_block_rule_failed: "Failed to create block rule.",
mac_blocked: "blocked.",
mac_unblocked: "unblocked.",
mac_firewall_bg: "Firewall rules are applying in background (a few seconds).",
devices_title: "Network Devices:",
device_hostname_unknown: "Unknown",
devices_not_found: "No devices found.",
watchdog_stop_btn: "Stop Watchdog",
ai_full_status_btn: "Full AI Status",
watchdog_start_btn: "Start Watchdog",
ai_incident: "⚠️ Incident resolved:",
ai_resolution: "🔧 Auto-fix:",
ai_all_ok: "All network services, DNS, nftables and memory are working perfectly.",
ai_diag_ok: "Diagnostics completed successfully.",
ai_diag_done: "Diagnostics completed.",
ai_status_collecting: "Collecting full AI Watchdog status...",
ai_status_error: "Status fetch error.",
ai_data_truncated: "data truncated",
ai_full_status_header: "AI Watchdog — Full Status:",
qos_title: "Gaming & Voice QoS Accelerator",
qos_enabled_detail: "Enabled (DSCP EF + AF41 Priority)",
qos_disabled_detail: "Disabled",
qos_priority_rules: "Priority rules:",
btn_qos_disable: "Disable QoS",
btn_qos_enable: "Enable QoS",
cb_obsolete: "Button obsolete — open the list again.",
update_component_title: "Starting update",
update_bg_hint: "Process started in background. Check later.",
err_unknown_component: "Unknown component:",
admin_invalid_chat_id: "Invalid Chat ID.",
admin_user_added: "User added to admin list.",
admin_user_already: "User is already an admin.",
sec_enter_name: "Enter a Latin name for the new section (e.g. <code>my_vpn</code>):\n\n<i>Send /cancel to cancel</i>",
sec_enter_label: "Enter a new human-readable name (Label) for section",
sec_enter_target: "Enter outbound interface (target) for section",
sec_not_found: "Section not found.",
sec_deleted: "Section deleted.",
sec_add_items_prompt: "Send items to add (one per line or space-separated):\n\n<i>Send /cancel to cancel</i>",
sec_sub_add_prompt: "Enter section name and subscription URL separated by a space:\n<code>/sec_sub_add Main https://...</code>\n\n<i>Send /cancel to cancel</i>",
sec_enter_value: "Enter new value for",
sec_add_list_prompt: "Send items to add to the list (space or newline separated):\n\n<i>Send /cancel to cancel</i>",
dns_all_protocols: "All protocols",
dns_servers_applied: "DNS servers set:",
dns_restart_hint: "Restart to apply.",
dns_bootstrap_applied: "Bootstrap DNS servers set:",
exec_cmd_error: "Command execution error:",
exec_access_denied: "Access denied. Your Chat ID:",
backup_downloading: "Downloading backup...",
backup_download_error: "File download error.",
backup_url_error: "File URL error.",
backup_format_hint: "Please send the backup in .tar.gz format.",
admin_forward_prompt: "Forwarded a message from user",
btn_admin_add: "Add",
exec_whitelist_msg: "Executing from whitelist:",
exec_no_output: "No output",
action_cancelled: "Action cancelled.",
err_text_expected: "A text message is expected. Try again or /cancel.",
value_saved: "Value saved.",
items_added: "items added.",
section_created: "Section created!",
err_invalid_section_name: "Invalid name. Only letters, numbers, and underscores allowed.",
label_changed: "Name changed.",
target_changed: "Target changed.",
items_added_count: "Added",
nothing_added: "Nothing added.",
err_format_section_url: "Format: <code>section URL</code>\nExample: <code>Main https://...</code>",
err_invalid_hour: "Enter an integer from 0 to 23.",
saved: "Saved.",
daily_unknown: "unknown",
daily_uptime: "OS Uptime:",
daily_rx: "Current RX:",
daily_tx: "Current TX:",
build_label: "Build:",
blocked_activity: "Blocked Activity",
blocked_rule_label: "Rule:",
blocked_rule: "Rule:",
blocked_attempts: "Attempts to access blocked sites",
info_read_error: "Error reading info:",
quiet_start_word: "start",
quiet_end_word: "end",
quiet_saved: "Settings saved.",
sec_created: "Section created!",
sec_invalid_name: "Invalid name. Only Latin letters, digits, underscores.",
sec_invalid_hour: "Invalid hour.",
sec_changed_to: "changed to",
exec_value_saved: "Value saved. Restart needed for changes.",
exec_items_added: "Added",
exec_items_added_count: "Added",
exec_nothing_added: "Nothing added.",
exec_changed_to: "changed to",
exec_format_hint: "Format: domain.com or [ip]/prefix.",
update_new_release_header: "New build of current release!",
update_build_label: "Build",
critical_keyword_fallen: "Down",
critical_keyword_error: "Error",
btn_update_component: "Update",
},
ru: {
// ─── Setting schema labels ───
dns_type: "Тип DNS",
dns_server: "DNS Серверы",
bootstrap_dns_server: "Bootstrap DNS",
dns_strategy: "Стратегия DNS",
dns_detour_enabled: "DNS Detour",
source_network_interfaces: "Входящие интерфейсы",
enable_output_network_interface: "Привязка к WAN",
enable_badwan_interface_monitoring: "Мониторинг WAN",
enable_yacd: "Панель YACD",
disable_quic: "Блокировать QUIC",
list_update_enabled: "Обновление списков",
component_update_check_enabled: "Обновление ядра",
download_lists_via_proxy: "Списки через прокси",
download_components_via_proxy: "Ядро через прокси",
dont_touch_dhcp: "Не трогать DHCP",
isolate_p2p: "Изолировать P2P",
log_level: "Уровень логов",
exclude_ntp: "Исключить NTP",
shutdown_correctly: "Корректное завершение",
smart_detect: "Smart Detect",
smart_detect_sections: "Секции Smart Detect",
enabled: "Бот Включен",
bot_token: "Токен",
admin_ids: "Admin IDs",
poll_interval: "Интервал опроса",
notify_crash: "Сбои ядра",
notify_restart: "Перезапуски",
notify_server_switch: "Переключение серверов",
notify_subscription: "Статус подписок",
notify_cert: "Сертификаты",
notify_dns_leak: "Утечки DNS",
daily_report_enabled: "Ежедневный отчет",
daily_report_hour: "Время отчета (час)",
quiet_hours_enabled: "Тихие часы",
quiet_hours_start: "Начало тихих часов",
quiet_hours_end: "Конец тихих часов",
fallback_socks: "Резервный SOCKS5",
language: "Язык",
section: "Секция",
auto_user_agent: "Auto User-Agent",
user_agent: "User-Agent",
auto_hwid: "Auto HWID",
subscription_update_enabled: "Автообновление",
subscription_update_interval: "Интервал обновления",
download_via_proxy_enabled: "Через прокси",
show_dashboard_metadata: "Метаданные подписки",
prefix_nodes: "Префикс узлов",
node_prefix: "Строка префикса",
include_urltest_groups: "Группы URL-Test",
hide_urltest_group_outbounds: "Скрыть узлы групп",
hide_detour_outbounds: "Скрыть Detour узлы",
label: "Название",
enabled: "Включен",
protocol: "Протокол",
routing_mode: "Режим",
// ─── Navigation ───
nav_next: "След ▶️",
nav_prev: "◀️ Пред",
nav_back: "◀️ Назад",
nav_menu: "🏠 Меню",
nav_settings: "⚙️ Настройки",
// ─── Menu ───
menu_all_settings: "⚙️ Все Настройки",
menu_choose_cat: "Выберите категорию для редактирования:",
menu_global: "🌍 Глобальные настройки",
menu_telegram: "🤖 Настройки Telegram",
menu_subscriptions: "📋 Подписки",
menu_servers: "🖥️ Пользовательские серверы",
menu_servers_short: "🖥 Кастомные серверы",
menu_dns_presets: "🌐 DNS Серверы (Пресеты)",
menu_quiet_hours: "🔕 Тихие часы",
menu_test_rule: "🔍 Проверка правила",
menu_export_config: "📤 Экспорт конфига",
menu_help: "📖 Справка",
menu_status: "📊 Статус системы",
menu_diagnostic: "🩺 Диагностика",
menu_logs: "📝 Логи",
menu_connections: "🔌 Подключения",
menu_outbounds: "🚀 Прокси серверы",
menu_sections: "📁 Секции маршрутизации",
menu_speed: "⚡ Тест скорости",
menu_ping: "📡 Задержка",
menu_restart: "🔄 Перезапуск Tachyon",
menu_language: "🌐 Язык",
menu_extras: "🔧 Дополнительно",
menu_info: "ℹ️ Информация о системе",
menu_close_conn: "🗑️ Закрыть все соединения",
menu_check_updates: "🔄 Проверить обновления",
menu_doctor: "🩺 Диагностика",
menu_test_rule: "🔍 Проверка правила",
menu_devices: "💻 Устройства в сети",
menu_instances: "Live серверы",
menu_categories: "🔙 Категории",
menu_qos: "🎮 Игровой QoS",
menu_heal: "🤖 ИИ-Самолечение",
choose_section: "Выберите раздел для управления:",
// ─── Status ───
status_version: "Версия",
status_uptime: "Аптайм",
status_cpu: "Роутер CPU",
status_active_servers: "Активные серверы:",
status_no_server: "Активный сервер: <code>Не выбран</code>",
status_enabled: "Включена ✅",
status_disabled: "Выключена ❌",
status_target: "Цель (Target)",
status_running: "🟢 Запущен",
status_stopped: "🔴 Остановлен",
status_unknown: "Неизвестно",
status_normal: "Все системы приведены в штатную норму! 🟢",
status_pause: "Пауза",
status_header: "Статус Системы",
status_sections: "Секции",
// ─── Stats ───
stat_download: "Скачано",
stat_upload: "Отдано",
stat_memory: "Память",
stat_connections: "Соединений",
// ─── Section management ───
section_type: "Тип",
section_status: "Статус",
section_choose_group: "Выберите группу для настройки сервера:\n\n",
section_group: "Группа",
section_server: "Сервер",
section_check_singbox: "Проверьте, запущен ли sing-box и доступен ли Clash API.",
section_domains: "Домены",
section_sources: "Источники (Source)",
section_section: "Секция",
section_edit: "Редактирование",
section_create: "➕ Создать секцию",
section_action: "Действие",
section_list: "Список",
section_empty: "Пусто",
section_showing_partial: "(Показаны не все элементы для удаления)",
btn_rename: "✏️ Имя",
btn_delete: "❌ Удалить",
btn_add: "➕ Добавить",
btn_clear_all: "➖ Очистить все",
btn_add_items: "➕ Добавить элементы",
btn_clear_list: "➖ Очистить список",
btn_back_to_section: "🔙 Назад к секции",
// ─── Diagnostics ───
diag_running: "Диагностика уже выполняется другим процессом.",
diag_issues: "Проблем: %s",
diag_issues_count: "Проблем: %s",
diag_fixed_count: ", исправлено: %s",
diag_planned_count: ", планируется к исправлению: %d\n(применение: tachyon doctor --fix или кнопка в LuCI)",
diag_clean: "Проблем не обнаружено.",
diag_no_output: "Нет вывода диагностики.",
diag_error: "Ошибка запуска диагностики.",
diag_empty: "Пустой отчёт диагностики.",
diag_all_fixed: "Все системы приведены в штатную норму! 🟢",
diag_starting: "Запуск диагностики...",
diag_results: "Результаты Tachyon Doctor:",
report_truncated: "отчёт сокращён",
// ─── Logs ───
logs_no_records: "Нет записей для данного уровня.\n",
logs_read_error: "Не удалось прочитать логи.\n",
// ─── Connections ───
conn_none: "Нет активных подключений.",
// ─── Subscriptions ───
sub_none: "Нет подписок. Добавьте URL подписки для скачивания правил.",
sub_found: "Найдено подписок: ",
// ─── Latency ───
latency_no_data: "Нет данных о задержках. Нажмите «Обновить».",
latency_none: "Нет данных о задержках.",
// ─── Servers ───
servers_none: "Серверы не найдены или sing-box не запущен.",
servers_api_error: "Ошибка парсинга API: ",
// ─── QoS ───
qos_status: "Статус",
qos_enabled: "🟢 Включены",
qos_disabled: "❌ Выключены",
qos_start: "Начало",
qos_end: "Конец",
qos_quiet_hint: "В тихие часы бот отправляет только критические уведомления.",
// ─── Errors ───
err_invalid_format: "Неверный формат команды",
err_not_allowed: "Команда '%s' не входит в список разрешённых",
err_args_mismatch: "Аргументы не совпадают с разрешённым шаблоном",
err_wrong_arg_count: "Неверное число аргументов",
err_arg_not_allowed: "Аргумент не разрешён: %s",
err_subcmd_not_allowed: "Подкоманда '%s' не входит в whitelist",
err_host_unknown: "Неизвестно",
err_api_parse: "Ошибка чтения информации: ",
err_status_fetch: "Ошибка получения статуса.",
err_no_data: "Нет данных.",
err_log_read: "Не удалось прочитать логи.",
err_no_output: "Нет вывода",
// ─── Notifications ───
notif_restart_services: "Выполнен перезапуск служб Tachyon",
notif_nft_cleared: "Таблица правил nftables очищена или повреждена",
notif_nft_regenerated: "Выполнена быстрая регенерация правил TachyonTable и цепочки TPROXY",
notif_qos_not_found: "Правила Игрового & Голосового QoS Ускорителя не найдены в nftables",
notif_qos_applied: "Применены высокоприоритетные метки DSCP EF (0x2e) для Voice/RTC и DSCP AF41 (0x22) для Gaming",
notif_restart_skipped: "Перезапуск не выполнен: лимит частоты или активная блокировка",
notif_singbox_hung: "Зависание или неполный отклик прокси-порту sing-box",
notif_singbox_restarted: "Выполнен перезапуск sing-box",
notif_cache_cleared: "Очищена база cache.db; перезапуск пропущен по лимиту частоты",
notif_sets_empty: "Пустые nftables sets подсетей (community) — данные не были загружены при reload",
notif_sets_restored: "Восстановлены nftables sets из persistent кеша",
notif_fw_reload: "Выполнен reload_firewall для восстановления TPROXY правил",
notif_config_invalid: "Перезапуск отменён: конфигурация sing-box не проходит валидацию",
notif_restart_rate: "Перезапуск пропущен по лимиту частоты",
notif_rpcd_restarted: "Выполнен перезапуск rpcd для освобождения файловых дескрипторов",
// ─── Route failure ───
route_proxy_alive: "прокси-порт слушается, но запросы через него не проходят",
route_proxy_down: "прокси-порт не слушается (mixed-inbound sing-box не поднялся)",
route_hint: "Причина: %s.\nВключён прямой доступ к API как запасной путь — команды могут отвечать с задержкой.\nВыполните /test для проверки связи.",
route_alert_title: "Tachyon Telegram бот",
route_alert_consecutive: "неудачных попыток связи с API подряд",
route_reason: "Причина:",
route_fallback_hint: "Включён прямой доступ к API как запасной путь — команды могут отвечать с задержкой.",
route_heal_hint: "Watchdog попробует восстановить прокси автоматически.",
// ─── Command descriptions ───
cmd_menu: "Главное меню",
cmd_status: "Статус системы",
cmd_runtime: "Статистика трафика",
cmd_outbounds: "Прокси серверы",
cmd_sections: "Секции маршрутизации",
cmd_speed: "Тест скорости",
cmd_ping: "Задержка до серверов",
cmd_test: "Быстрая диагностика",
cmd_logs: "Просмотр логов",
cmd_info: "Информация о системе",
cmd_connections: "Активные подключения",
cmd_test_rule: "Проверка правила",
cmd_help: "Справка",
cmd_check_updates: "Проверить обновления",
cmd_close_connections: "Закрыть все соединения",
cmd_doctor: "Диагностика",
cmd_restart: "Перезапуск служб Tachyon",
cmd_instances: "Live серверы",
cmd_lang: "Сменить язык",
// ─── Misc ───
exec_done: "<b>Выполнено (код %s):</b>\n<pre>%s</pre>",
hour_enter: "⏰ Введите час %s (0-23):",
hour_start: "начала",
hour_end: "окончания",
blocked_activity: "Заблокированная активность",
blocked_attempts: "Попыток доступа к заблокированным сайтам",
daily_digest_title: "🌅 Утренний дайджест Tachyon",
daily_rx: "Текущий RX",
daily_tx: "Текущий TX",
daily_connections: "Соединений",
daily_memory: "Память",
choose_language: "Выберите язык:",
lang_current: "Текущий язык: %s",
lang_saved: "Язык сохранён!",
ping_enter_host: "Введите домен или IP для проверки:",
test_rule_prompt: "Введите правило для проверки:",
rule_label: "Правило",
// ─── Speed test ───
speed_starting: "⚡ <b>Запуск Speedtest...</b>\n\nТестирую скорость через Cloudflare. Это займёт до 30 секунд.",
speed_result: "⚡ Результат Speedtest",
speed_direct: "📥 Прямое соединение:",
speed_proxy: "📤 Через прокси:",
speed_fail_measure: "❌ не удалось измерить",
speed_error: "❌ Не удалось выполнить тест. Проверьте, запущен ли sing-box.",
speed_check_hint: "Проверьте доступ в интернет и работу sing-box.",
// ─── Ping ───
ping_api_error: "❌ Не удалось получить данные из Clash API.",
// ─── Quick test ───
test_title: "Быстрая диагностика",
test_direct: "Прямое соединение",
test_proxy: "Прокси соединение",
test_service: "Tachyon сервис",
test_nft: "nftables правила",
test_pause: "Пауза:",
test_rule: "Проверка правила:",
test_match: "Совпадение",
test_no_match: "Совпадений не найдено. Трафик пойдёт через default route.",
// ─── Connections ───
conn_total_down: "Всего скачано",
conn_total_up: "Всего отдано",
conn_closed: "Все активные соединения сброшены.",
// ─── Devices ───
device_block: "🚫 Заблокировать",
device_unblock: "🔓 Разблокировать",
device_blocked: "заблокировано",
device_unblocked: "разблокировано",
// ─── AI Doctor ───
ai_doctor_title: "ИИ-Автомеханик Tachyon",
ai_status_collecting: "Сбор полного AI Watchdog статуса...",
ai_incident: "⚠️ Устранён инцидент:",
ai_resolution: "🔧 Авто-решение:",
ai_all_ok: "Все сетевые службы, DNS, nftables и память работают идеально.",
ai_diag_ok: "Диагностика завершена успешно.",
ai_diag_done: "Диагностика завершена.",
// ─── Buttons ───
btn_refresh: "🔄 Обновить",
btn_retry: "🔄 Повторить",
btn_again: "🔄 Ещё раз",
btn_speed_again: "⚡ Ещё раз",
btn_back_to_groups: "🔙 К списку групп",
btn_back_to_sections: "🔙 К списку секций",
btn_close_all: "❌ Закрыть все",
btn_test: "🩺 Тест",
nav_cancel: "⬅️ Отмена",
restart_confirm: "⚠️ <b>Перезапустить службы Tachyon?</b>\nТекущие соединения будут разорваны на время перезапуска.",
restart_yes: "✅ Да, перезапустить",
restart_in_progress: "Перезапускаю службы Tachyon...",
restart_success: "Перезапуск выполнен успешно!",
restart_error: "Ошибка при перезапуске.",
conn_closed: "Все активные соединения сброшены.",
// ─── Outbounds ───
servers_not_found: "Серверы не найдены или sing-box не запущен.",
outbounds_hint: "Нажмите кнопку, чтобы переключить сервер.",
// ─── Logs ───
logs_level: "уровень",
// ─── Info ───
info_device: "Устройство",
err_info_read: "Ошибка чтения информации:",
// ─── Updates ───
update_new_build: "Новая сборка текущего релиза!",
update_available: "Доступно обновление компонента!",
build_label: "Сборка",
// ─── Healer ───
heal_running: "ИИ-Автомеханик выполняет диагностику и самолечение...",
// ─── Batch i18n additions ───
msg_truncated: "... (сообщение сокращено)",
menu_version: "Версия",
menu_cpu: "Роутер CPU",
list_header: "⚙️ <b>Список:</b>",
outbound_groups_not_found: "Группы прокси не найдены.",
outbound_switch_failed: "Не удалось переключить сервер",
outbound_group: "Группа",
outbound_server: "Сервер",
outbound_check_hint: "Проверьте, запущен ли sing-box и доступен ли Clash API.",
section_ips: "IP адреса",
section_list_header: "⚙️ <b>Секция:</b>",
backup_archive_empty: "Архив пуст или повреждён.",
backup_archive_unsafe: "Небезопасный архив:",
backup_restoring: "Проверяю и восстанавливаю бэкап...",
backup_extract_failed: "Не удалось распаковать архив.",
backup_not_valid_uci: "config/tachyon в архиве не похож на валидный UCI.",
backup_no_config: "В архиве нет ни config/tachyon, ни каталога tachyon/.",
backup_save_config_failed: "Не удалось сохранить текущий конфиг.",
backup_save_data_failed: "Не удалось сохранить текущие данные /etc/tachyon.",
backup_write_config_error: "Ошибка записи /etc/config/tachyon.",
backup_uci_validation_failed: "Восстановленный конфиг не прошёл проверку UCI. Выполнен откат.",
backup_write_data_error: "Ошибка записи /etc/tachyon. Выполнен откат.",
backup_restored: "Бэкап восстановлен. Перезапускаю Tachyon...",
backup_done: "Готово!",
backup_collecting: "Собираю бэкап...",
backup_create_error: "Ошибка создания бэкапа.",
support_bundle_collecting: "Формирую Support Bundle...",
support_bundle_error: "Ошибка генерации Bundle.",
conn_closed_msg: "Все активные соединения сброшены.\nОни будут переустановлены по новым маршрутам.",
conn_close_error: "Ошибка сброса соединений.\nsing-box Clash API недоступен.",
updates_title: "Обновления компонентов",
updates_disabled: "Проверка обновлений отключена в настройках.",
updates_cache_empty: "Кэш пуст. Зайдите позже.",
update_check_error: "Ошибка проверки",
update_new_release_build: "новая сборка релиза",
update_dev_build: "dev-сборка",
update_all_current: "Все компоненты актуальны.",
update_cache_parse_error: "Ошибка парсинга кэша:",
update_cache_unavailable: "Кэш проверок пуст или недоступен.",
btn_refresh_cache: "Обновить кэш",
api_parse_error: "Ошибка парсинга API:",
api_connect_failed: "Не удалось подключиться к API sing-box.",
logs_header: "Логи Tachyon",
info_title: "Информация о системе",
info_device_label: "Устройство",
info_fetch_failed: "Не удалось получить информацию о системе.",
sub_empty_url: "(пусто)",
btn_sub_delete: " 🗑 Удалить",
btn_add_subscription: "Добавить подписку",
sub_section_subs: "Подписки секции",
sub_found_count: "Найдено подписок:",
sub_enter_url: "Введите URL подписки:\n\n<i>Отправьте /cancel для отмены</i>",
sub_url_empty: "URL не может быть пустым.",
sub_added: "Подписка добавлена в секцию",
sub_not_found: "Подписка не найдена.",
sub_removed: "Подписка удалена из секции",
help_title: "Справка по командам",
help_main_section: "Основные:",
help_diag_section: "Диагностика:",
help_manage_section: "Управление:",
help_settings_section: "Настройка:",
help_this: "Эта справка",
quiet_hours_title: "Тихие часы",
quiet_status: "Статус",
quiet_enabled_label: "Включены",
quiet_disabled_label: "Выключены",
quiet_start_label: "Начало:",
quiet_end_label: "Конец:",
quiet_hint: "В тихие часы бот отправляет только критические уведомления.",
btn_enable: "Включить",
btn_disable: "Выключить",
quiet_hour_start: "начала",
quiet_hour_end: "окончания",
quiet_enter_hour: "⏰ Введите час %s тихих часов (0–23):\n\n<i>Отправьте /cancel для отмены</i>",
test_rule_header: "Проверка правила:",
test_match: "Совпадение:",
test_action: "Действие:",
export_title: "Экспорт конфига...",
export_done: "Конфиг экспортирован.\n\n⚠️ Файл содержит чувствительные данные. Не публикуйте его.",
export_failed: "Не удалось экспортировать конфиг.",
mac_invalid: "Некорректный MAC-адрес.",
mac_firewall_open_failed: "Не удалось открыть конфигурацию firewall.",
mac_block_rule_failed: "Не удалось создать правило блокировки.",
mac_blocked: "заблокировано.",
mac_unblocked: "разблокировано.",
mac_firewall_bg: "Правила firewall применяются в фоне (несколько секунд).",
devices_title: "Устройства в сети:",
device_hostname_unknown: "Неизвестно",
devices_not_found: "Устройства не найдены.",
watchdog_stop_btn: "Остановить Watchdog",
ai_full_status_btn: "Полный статус AI",
watchdog_start_btn: "Запустить Watchdog",
ai_incident: "⚠️ Устранён инцидент:",
ai_resolution: "🔧 Авто-решение:",
ai_all_ok: "Все сетевые службы, DNS, nftables и память работают идеально.",
ai_diag_ok: "Диагностика завершена успешно.",
ai_diag_done: "Диагностика завершена.",
ai_status_collecting: "Сбор полного AI Watchdog статуса...",
ai_status_error: "Ошибка получения статуса.",
ai_data_truncated: "данные сокращены",
ai_full_status_header: "AI Watchdog — Полный статус:",
qos_title: "Игровой & Голосовой QoS Ускоритель",
qos_enabled_detail: "Включен (DSCP EF + AF41 Priority)",
qos_disabled_detail: "Выключен",
qos_priority_rules: "Приоритетные правила:",
btn_qos_disable: "Отключить QoS",
btn_qos_enable: "Включить QoS",
cb_obsolete: "Кнопка устарела — откройте список заново.",
update_component_title: "Запуск обновления",
update_bg_hint: "Процесс запущен в фоне. Зайдите позже.",
err_unknown_component: "Неизвестный компонент:",
admin_invalid_chat_id: "Неверный Chat ID.",
admin_user_added: "Пользователь добавлен в список администраторов.",
admin_user_already: "Пользователь уже является администратором.",
sec_enter_name: "Введите латинское имя для новой секции (например, <code>my_vpn</code>):\n\n<i>Отправьте /cancel для отмены</i>",
sec_enter_label: "Введите новое понятное имя (Label) для секции",
sec_enter_target: "Введите имя исходящего интерфейса (target) для секции",
sec_not_found: "Секция не найдена.",
sec_deleted: "Секция удалена.",
sec_add_items_prompt: "Отправьте элементы для добавления (по одному в строке или через пробел):\n\n<i>Отправьте /cancel для отмены</i>",
sec_sub_add_prompt: "Введите имя секции и URL подписки через пробел:\n<code>/sec_sub_add Main https://...</code>\n\n<i>Отправьте /cancel для отмены</i>",
sec_enter_value: "Введите новое значение для",
sec_add_list_prompt: "Отправьте элементы для добавления в список (через пробел или с новой строки):\n\n<i>Отправьте /cancel для отмены</i>",
dns_all_protocols: "Все протоколы",
dns_servers_applied: "DNS серверы установлены:",
dns_restart_hint: "Выполните перезапуск для применения.",
dns_bootstrap_applied: "Bootstrap DNS серверы установлены:",
exec_cmd_error: "Ошибка выполнения команды:",
exec_access_denied: "Доступ запрещен. Ваш Chat ID:",
backup_downloading: "Скачиваю бэкап...",
backup_download_error: "Ошибка загрузки файла.",
backup_url_error: "Ошибка получения URL файла.",
backup_format_hint: "Пожалуйста, отправьте бэкап в формате `.tar.gz`.",
admin_forward_prompt: "Вы переслали сообщение от пользователя",
btn_admin_add: "Добавить",
exec_whitelist_msg: "Выполняю из разрешённого набора (whitelist):",
exec_no_output: "Нет вывода",
action_cancelled: "Действие отменено.",
err_text_expected: "Ожидается текстовое сообщение. Попробуйте ещё раз или /cancel.",
value_saved: "Значение сохранено.",
items_added: "элементов.",
section_created: "Секция создана!",
err_invalid_section_name: "Неверное имя. Разрешены только буквы, цифры и подчеркивания.",
label_changed: "Имя изменено.",
target_changed: "Цель изменена.",
items_added_count: "Добавлено",
nothing_added: "Ничего не добавлено.",
err_format_section_url: "Формат: <code>секция URL</code>\nНапример: <code>Main https://...</code>",
err_invalid_hour: "Введите целое число от 0 до 23.",
saved: "Сохранено.",
daily_unknown: "неизвестно",
daily_uptime: "Аптайм ОС:",
daily_rx: "Текущий RX:",
daily_tx: "Текущий TX:",
build_label: "Сборка:",
blocked_activity: "Заблокированная активность",
blocked_rule_label: "Правило:",
blocked_rule: "Правило:",
blocked_attempts: "Попыток доступа к заблокированным сайтам",
info_read_error: "Ошибка чтения информации:",
quiet_start_word: "начала",
quiet_end_word: "окончания",
quiet_saved: "Настройки сохранены.",
sec_created: "Секция создана!",
sec_invalid_name: "Некорректное имя. Только латиница, цифры и _.",
sec_invalid_hour: "Некорректное время.",
sec_changed_to: "изменено на",
exec_value_saved: "Значение сохранено. Для вступления изменений в силу необходим перезапуск.",
exec_items_added: "Добавлено",
exec_items_added_count: "Добавлено",
exec_nothing_added: "Ничего не добавлено.",
exec_changed_to: "изменено на",
exec_format_hint: "Формат: domain.com или [ip]/prefix.",
update_new_release_header: "Новая сборка текущего релиза!",
update_build_label: "Сборка",
critical_keyword_fallen: "Упал",
critical_keyword_error: "Ошибка",
btn_update_component: "Обновить",
}
};
// Resolve language: UCI setting → fallback to "en"
function resolve_lang(cfg_lang) {
let lang = cfg_lang || "en";
if (type(lang) != "string") lang = "en";
// trim whitespace
lang = replace(lang, /^\s+|\s+$/g, "");
if (lang == "" || (lang != "en" && lang != "ru")) lang = "en";
return lang;
}
// Return a translation function bound to the given language.
// Usage: let t = i18n.bind(lang); t("key") → translated string.
// Strings with %s placeholders use sprintf for substitution.
function bind(lang) {
lang = resolve_lang(lang);
return function(key) {
let table = strings[lang];
let val = table ? table[key] : null;
if (val == null) val = strings.en[key];
if (val == null) return key;
// sprintf-style substitution: pass extra args to t("key", arg1, arg2)
if (length(arguments) > 1) {
let args = [];
for (let i = 1; i < length(arguments); i++)
push(args, arguments[i]);
try { return sprintf(val, ...args); } catch(e) { return val; }
}
return val;
};
}
// Return available languages as [{code, label, available}]
function available_languages(cfg_lang) {
let current = resolve_lang(cfg_lang);
let ru_available = (current == "ru");
let langs = [
{ code: "en", label: "English", available: true },
{ code: "ru", label: "Русский", available: ru_available }
];
return langs;
}
// Module exports
if (sourcepath(1) != null && sourcepath(1) != "")
return { resolve_lang, bind, available_languages, strings };