mirror of
https://github.com/MaxiFan/TunnelX.git
synced 2026-05-18 23:54:50 +03:00
0bc8992813
Co-authored-by: Cursor <cursoragent@cursor.com>
737 lines
56 KiB
C#
737 lines
56 KiB
C#
using System.ComponentModel;
|
||
using System.Globalization;
|
||
using System.Runtime.CompilerServices;
|
||
using System.Windows;
|
||
using System.Windows.Controls;
|
||
using System.Windows.Data;
|
||
using System.Windows.Documents;
|
||
using System.Windows.Media;
|
||
using System.Windows.Threading;
|
||
|
||
namespace AppTunnel.Services;
|
||
|
||
public sealed class LocalizationService : INotifyPropertyChanged
|
||
{
|
||
public const string AutoLanguage = "auto";
|
||
public const string PersianLanguage = "fa-IR";
|
||
public const string EnglishLanguage = "en-US";
|
||
|
||
public static LocalizationService Instance { get; } = new();
|
||
|
||
private readonly Dictionary<string, Dictionary<string, string>> _translations = new(StringComparer.Ordinal)
|
||
{
|
||
[EnglishLanguage] = EnglishTranslations()
|
||
};
|
||
|
||
private string _languageSetting = AutoLanguage;
|
||
private string _effectiveLanguage = PersianLanguage;
|
||
|
||
private LocalizationService()
|
||
{
|
||
EventManager.RegisterClassHandler(
|
||
typeof(FrameworkElement),
|
||
FrameworkElement.LoadedEvent,
|
||
new RoutedEventHandler(OnFrameworkElementLoaded),
|
||
handledEventsToo: true);
|
||
}
|
||
|
||
public event PropertyChangedEventHandler? PropertyChanged;
|
||
public event EventHandler? LanguageChanged;
|
||
|
||
public string LanguageSetting => _languageSetting;
|
||
public string EffectiveLanguage => _effectiveLanguage;
|
||
public bool IsRightToLeft => _effectiveLanguage.StartsWith("fa", StringComparison.OrdinalIgnoreCase);
|
||
public System.Windows.FlowDirection FlowDirection => IsRightToLeft
|
||
? System.Windows.FlowDirection.RightToLeft
|
||
: System.Windows.FlowDirection.LeftToRight;
|
||
public System.Windows.TextAlignment TextAlignment => IsRightToLeft
|
||
? System.Windows.TextAlignment.Right
|
||
: System.Windows.TextAlignment.Left;
|
||
public System.Windows.HorizontalAlignment StartHorizontalAlignment => IsRightToLeft
|
||
? System.Windows.HorizontalAlignment.Right
|
||
: System.Windows.HorizontalAlignment.Left;
|
||
public System.Windows.HorizontalAlignment EndHorizontalAlignment => IsRightToLeft
|
||
? System.Windows.HorizontalAlignment.Left
|
||
: System.Windows.HorizontalAlignment.Right;
|
||
public string ToggleLanguageText => IsRightToLeft ? "English" : "فارسی";
|
||
|
||
public void Initialize(string? savedLanguage)
|
||
{
|
||
SetLanguageInternal(string.IsNullOrWhiteSpace(savedLanguage) ? AutoLanguage : savedLanguage!, raiseChanged: false);
|
||
}
|
||
|
||
public void ToggleLanguage()
|
||
{
|
||
SetLanguage(IsRightToLeft ? EnglishLanguage : PersianLanguage);
|
||
}
|
||
|
||
public void SetLanguage(string language)
|
||
{
|
||
SetLanguageInternal(language, raiseChanged: true);
|
||
}
|
||
|
||
public string T(string source)
|
||
{
|
||
if (string.IsNullOrEmpty(source) || IsRightToLeft)
|
||
return source;
|
||
|
||
return _translations.TryGetValue(_effectiveLanguage, out var table) &&
|
||
table.TryGetValue(source, out var translated)
|
||
? translated
|
||
: source;
|
||
}
|
||
|
||
public string Format(string sourceFormat, params object?[] args)
|
||
=> string.Format(CultureInfo.CurrentCulture, T(sourceFormat), args);
|
||
|
||
public void ApplyToOpenWindows()
|
||
{
|
||
foreach (Window window in System.Windows.Application.Current.Windows)
|
||
ApplyTo(window);
|
||
}
|
||
|
||
public void ApplyTo(DependencyObject root)
|
||
{
|
||
ApplyTo(root, new HashSet<DependencyObject>());
|
||
}
|
||
|
||
private void ApplyTo(DependencyObject root, HashSet<DependencyObject> visited)
|
||
{
|
||
if (!visited.Add(root))
|
||
return;
|
||
|
||
ApplyFlowDirection(root);
|
||
ApplyText(root);
|
||
|
||
try
|
||
{
|
||
var visualCount = VisualTreeHelper.GetChildrenCount(root);
|
||
for (var i = 0; i < visualCount; i++)
|
||
ApplyTo(VisualTreeHelper.GetChild(root, i), visited);
|
||
}
|
||
catch (InvalidOperationException)
|
||
{
|
||
// Some logical children, such as Run, are not visual children.
|
||
}
|
||
|
||
foreach (var child in LogicalTreeHelper.GetChildren(root).OfType<DependencyObject>())
|
||
ApplyTo(child, visited);
|
||
}
|
||
|
||
private void OnFrameworkElementLoaded(object sender, RoutedEventArgs e)
|
||
{
|
||
if (sender is not DependencyObject element)
|
||
return;
|
||
|
||
ApplyTo(element);
|
||
}
|
||
|
||
private void SetLanguageInternal(string language, bool raiseChanged)
|
||
{
|
||
_languageSetting = NormalizeLanguageSetting(language);
|
||
_effectiveLanguage = ResolveEffectiveLanguage(_languageSetting);
|
||
|
||
CultureInfo.CurrentCulture = CultureInfo.GetCultureInfo(_effectiveLanguage);
|
||
CultureInfo.CurrentUICulture = CultureInfo.GetCultureInfo(_effectiveLanguage);
|
||
|
||
OnPropertyChanged(nameof(LanguageSetting));
|
||
OnPropertyChanged(nameof(EffectiveLanguage));
|
||
OnPropertyChanged(nameof(IsRightToLeft));
|
||
OnPropertyChanged(nameof(FlowDirection));
|
||
OnPropertyChanged(nameof(TextAlignment));
|
||
OnPropertyChanged(nameof(StartHorizontalAlignment));
|
||
OnPropertyChanged(nameof(EndHorizontalAlignment));
|
||
OnPropertyChanged(nameof(ToggleLanguageText));
|
||
|
||
if (!raiseChanged) return;
|
||
|
||
LanguageChanged?.Invoke(this, EventArgs.Empty);
|
||
|
||
var dispatcher = System.Windows.Application.Current?.Dispatcher;
|
||
dispatcher?.BeginInvoke(ApplyToOpenWindows, DispatcherPriority.Loaded);
|
||
dispatcher?.BeginInvoke(ApplyToOpenWindows, DispatcherPriority.ContextIdle);
|
||
}
|
||
|
||
private static string NormalizeLanguageSetting(string language)
|
||
{
|
||
if (string.Equals(language, EnglishLanguage, StringComparison.OrdinalIgnoreCase))
|
||
return EnglishLanguage;
|
||
if (string.Equals(language, PersianLanguage, StringComparison.OrdinalIgnoreCase) ||
|
||
string.Equals(language, "fa", StringComparison.OrdinalIgnoreCase))
|
||
return PersianLanguage;
|
||
return AutoLanguage;
|
||
}
|
||
|
||
private static string ResolveEffectiveLanguage(string setting)
|
||
{
|
||
if (setting != AutoLanguage)
|
||
return setting;
|
||
|
||
var ui = CultureInfo.CurrentUICulture;
|
||
return ui.TwoLetterISOLanguageName.Equals("fa", StringComparison.OrdinalIgnoreCase)
|
||
? PersianLanguage
|
||
: EnglishLanguage;
|
||
}
|
||
|
||
private static bool HasBinding(DependencyObject element, DependencyProperty property)
|
||
=> BindingOperations.GetBindingExpressionBase(element, property) != null;
|
||
|
||
private static readonly DependencyProperty OriginalTextProperty =
|
||
DependencyProperty.RegisterAttached("OriginalText", typeof(string), typeof(LocalizationService));
|
||
|
||
private static readonly DependencyProperty OriginalContentProperty =
|
||
DependencyProperty.RegisterAttached("OriginalContent", typeof(string), typeof(LocalizationService));
|
||
|
||
private static readonly DependencyProperty OriginalHeaderProperty =
|
||
DependencyProperty.RegisterAttached("OriginalHeader", typeof(string), typeof(LocalizationService));
|
||
|
||
private static readonly DependencyProperty OriginalToolTipProperty =
|
||
DependencyProperty.RegisterAttached("OriginalToolTip", typeof(string), typeof(LocalizationService));
|
||
|
||
private static readonly DependencyProperty OriginalTagProperty =
|
||
DependencyProperty.RegisterAttached("OriginalTag", typeof(string), typeof(LocalizationService));
|
||
|
||
private void ApplyFlowDirection(DependencyObject element)
|
||
{
|
||
if (element is not FrameworkElement fe)
|
||
return;
|
||
|
||
if (HasBinding(fe, FrameworkElement.FlowDirectionProperty))
|
||
return;
|
||
|
||
var local = fe.ReadLocalValue(FrameworkElement.FlowDirectionProperty);
|
||
if (local == DependencyProperty.UnsetValue ||
|
||
local is System.Windows.FlowDirection.LeftToRight)
|
||
return;
|
||
|
||
// Explicit RTL follows the selected language. Explicit LTR is reserved
|
||
// for technical fields: IP, path, port, config and logs.
|
||
fe.FlowDirection = FlowDirection;
|
||
}
|
||
|
||
private void ApplyText(DependencyObject element)
|
||
{
|
||
switch (element)
|
||
{
|
||
case Window window when !HasBinding(window, Window.TitleProperty):
|
||
window.Title = TranslateProperty(window, Window.TitleProperty, OriginalTextProperty, window.Title);
|
||
break;
|
||
|
||
case TextBlock textBlock when !HasBinding(textBlock, TextBlock.TextProperty) && !textBlock.Inlines.Any():
|
||
textBlock.Text = TranslateProperty(textBlock, TextBlock.TextProperty, OriginalTextProperty, textBlock.Text);
|
||
if (textBlock.ReadLocalValue(TextBlock.TextAlignmentProperty) == DependencyProperty.UnsetValue)
|
||
textBlock.TextAlignment = textBlock.FlowDirection == System.Windows.FlowDirection.LeftToRight
|
||
? System.Windows.TextAlignment.Left
|
||
: TextAlignment;
|
||
break;
|
||
|
||
case Run run:
|
||
run.Text = TranslateProperty(run, Run.TextProperty, OriginalTextProperty, run.Text);
|
||
break;
|
||
|
||
case HeaderedContentControl headered when headered.Header is string header && !HasBinding(headered, HeaderedContentControl.HeaderProperty):
|
||
headered.Header = TranslateProperty(headered, HeaderedContentControl.HeaderProperty, OriginalHeaderProperty, header);
|
||
break;
|
||
|
||
case ContentControl contentControl when contentControl.Content is string content && !HasBinding(contentControl, ContentControl.ContentProperty):
|
||
contentControl.Content = TranslateProperty(contentControl, ContentControl.ContentProperty, OriginalContentProperty, content);
|
||
break;
|
||
|
||
case System.Windows.Controls.TextBox textBox when textBox.Tag is string tag && !HasBinding(textBox, FrameworkElement.TagProperty):
|
||
textBox.Tag = TranslateProperty(textBox, FrameworkElement.TagProperty, OriginalTagProperty, tag);
|
||
ApplyTextBoxAlignment(textBox);
|
||
break;
|
||
|
||
case System.Windows.Controls.TextBox textBox:
|
||
ApplyTextBoxAlignment(textBox);
|
||
break;
|
||
}
|
||
|
||
if (element is FrameworkElement fe && fe.ToolTip is string toolTip && !HasBinding(fe, FrameworkElement.ToolTipProperty))
|
||
fe.ToolTip = TranslateProperty(fe, FrameworkElement.ToolTipProperty, OriginalToolTipProperty, toolTip);
|
||
}
|
||
|
||
private void ApplyTextBoxAlignment(System.Windows.Controls.TextBox textBox)
|
||
{
|
||
if (textBox.ReadLocalValue(System.Windows.Controls.TextBox.TextAlignmentProperty) != DependencyProperty.UnsetValue)
|
||
return;
|
||
|
||
textBox.TextAlignment = textBox.FlowDirection == System.Windows.FlowDirection.LeftToRight
|
||
? TextAlignment.Left
|
||
: TextAlignment;
|
||
}
|
||
|
||
private string TranslateProperty(DependencyObject owner, DependencyProperty property, DependencyProperty originalProperty, string current)
|
||
{
|
||
var original = owner.GetValue(originalProperty) as string;
|
||
var resolvedCurrent = ResolveSourceText(current);
|
||
if (original == null || !string.Equals(original, ResolveSourceText(original), StringComparison.Ordinal))
|
||
{
|
||
original = resolvedCurrent;
|
||
owner.SetValue(originalProperty, original);
|
||
}
|
||
|
||
return T(original);
|
||
}
|
||
|
||
private string ResolveSourceText(string current)
|
||
{
|
||
if (string.IsNullOrEmpty(current))
|
||
return current;
|
||
|
||
foreach (var table in _translations.Values)
|
||
{
|
||
if (table.ContainsKey(current))
|
||
return current;
|
||
|
||
foreach (var pair in table)
|
||
{
|
||
if (string.Equals(pair.Value, current, StringComparison.Ordinal))
|
||
return pair.Key;
|
||
}
|
||
}
|
||
|
||
return current;
|
||
}
|
||
|
||
private void OnPropertyChanged([CallerMemberName] string? propertyName = null)
|
||
=> PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
||
|
||
private static Dictionary<string, string> EnglishTranslations() => new(StringComparer.Ordinal)
|
||
{
|
||
["TunnelX — Split Traffic Per App"] = "TunnelX - Split Traffic Per App",
|
||
["Per-app split tunneling"] = "Per-app split tunneling",
|
||
["تانلکس"] = "TunnelX",
|
||
["تفکیک ترافیک برنامه ها"] = "Per-app traffic splitting",
|
||
["جزئیات"] = "Details",
|
||
["کوچک کردن به System Tray"] = "Minimize to system tray",
|
||
["خروج از برنامه"] = "Exit app",
|
||
["وضعیت اتصال VPN و کنترل اتصال"] = "VPN connection status and controls",
|
||
["اتصال VPN"] = "VPN Connection",
|
||
["انتخاب برنامههایی که باید از تونل عبور کنند"] = "Select apps that should use the tunnel",
|
||
["برنامهها"] = "Apps",
|
||
["تنظیمات عمومی تونل و DNS"] = "General tunnel and DNS settings",
|
||
["تنظیمات"] = "Settings",
|
||
["قوانین Include و Exclude مسیرها"] = "Include and exclude routing rules",
|
||
["قوانین مسیر"] = "Routing Rules",
|
||
["مقصدهای مستقیم و مقصدهای اجباری تونل را اینجا مدیریت کنید."] = "Manage direct and forced tunnel destinations here.",
|
||
["🚫 مستقیم بماند"] = "🚫 Stay Direct",
|
||
["این مقصدها از تونل عبور نمیکنند."] = "These destinations do not use the tunnel.",
|
||
["نمونه کاربرد"] = "Example",
|
||
["سایتهای داخلی یا سرورهای بازی را مستقیم نگه دارید."] = "Keep internal sites or game servers direct.",
|
||
["دامنه یا آیپی (مثلاً google.com یا 1.2.3.4)"] = "Domain or IP, e.g. google.com or 1.2.3.4",
|
||
["افزودن"] = "Add",
|
||
["آدرسهای مستقیم"] = "Direct Addresses",
|
||
["حذف"] = "Delete",
|
||
["✅ از تونل عبور کند"] = "✅ Use Tunnel",
|
||
["این مقصدها همیشه از تونل عبور میکنند."] = "These destinations always use the tunnel.",
|
||
["دامنه یا آیپی (مثلاً example.com یا 1.2.3.4)"] = "Domain or IP, e.g. example.com or 1.2.3.4",
|
||
["آدرسهای اجباری"] = "Forced Addresses",
|
||
["نمایش ترافیک، تاریخچه و آمار اتصال"] = "Traffic, history, and connection stats",
|
||
["ترافیک/تاریخچه"] = "Traffic/History",
|
||
["ترافیک و تاریخچه"] = "Traffic and History",
|
||
["⏱ مدت"] = "⏱ Duration",
|
||
["🌐 IP"] = "🌐 IP",
|
||
["📊 تونل"] = "📊 Tunnel",
|
||
["📡 خارج تونل"] = "📡 Direct",
|
||
["📜 تاریخچه اتصالات"] = "📜 Connection History",
|
||
["مصرف تونل به تفکیک برنامه"] = "Tunnel Usage by App",
|
||
["اپهای تونل: "] = "Tunnel apps: ",
|
||
["سایر تونل: "] = "Other tunnel: ",
|
||
["هنوز برنامهای اضافه نشده. از تب «برنامهها» اضافه کنید."] = "No apps added yet. Add apps from the Apps tab.",
|
||
["ساخته شده توسط Maxifan"] = "Made by Maxifan",
|
||
["بروزرسانی"] = "Update",
|
||
["دانلود نسخه جدید از صفحه Releases در GitHub"] = "Download the new version from GitHub Releases",
|
||
["راهنما"] = "Help",
|
||
["راهنما و عیبیابی"] = "Help and troubleshooting",
|
||
["باز کردن صفحه GitHub پروژه TunnelX"] = "Open the TunnelX GitHub project",
|
||
["🔍 جزئیات عملکرد"] = "🔍 Runtime Details",
|
||
["همه"] = "All",
|
||
["خطا"] = "Error",
|
||
["هشدار"] = "Warning",
|
||
["پاک کردن"] = "Clear",
|
||
["کپی آخرین خطا یا هشدار"] = "Copy latest error or warning",
|
||
["کپی کردن"] = "Copy",
|
||
["در حال بارگذاری..."] = "Loading...",
|
||
|
||
["در حال اتصال OpenVPN"] = "Connecting OpenVPN",
|
||
["تا قبل از بالا آمدن آداپتر، مسیرهای سیستم تغییر داده نمیشود. اگر اتصال طولانی شد، فایل .ovpn، نام کاربری/رمز یا نصب OpenVPN Community را بررسی کنید."] = "System routes are not changed until the adapter is ready. If connection takes too long, check the .ovpn file, credentials, or OpenVPN Community installation.",
|
||
["لغو اتصال"] = "Cancel",
|
||
["کانفیگها و پروفایلها"] = "Configs and Profiles",
|
||
["یک کانفیگ را انتخاب کنید، ویرایش کنید یا کانفیگ جدید بسازید."] = "Select, edit, or create a connection profile.",
|
||
["افزودن کانفیگ جدید"] = "Add New Config",
|
||
["فعال"] = "Use",
|
||
["استفاده از این کانفیگ برای اتصال"] = "Use this config for connection",
|
||
["ویرایش"] = "Edit",
|
||
["کپی"] = "Copy",
|
||
["پروفایل فعال: "] = "Active profile: ",
|
||
["شروع اتصال با پروفایل انتخابشده"] = "Start connection with the selected profile",
|
||
["🌐 تنظیمات سرور"] = "🌐 Server Settings",
|
||
["نوع اتصال"] = "Connection Type",
|
||
["آدرس سرور"] = "Server Address",
|
||
["نام کاربری"] = "Username",
|
||
["رمز عبور"] = "Password",
|
||
["کانفیگ V2Ray"] = "V2Ray Config",
|
||
["پیست"] = "Paste",
|
||
["خواندن کانفیگ از کلیپبورد"] = "Read config from clipboard",
|
||
["فایل OpenVPN (.ovpn)"] = "OpenVPN File (.ovpn)",
|
||
["انتخاب فایل"] = "Choose File",
|
||
["حذف فایل"] = "Remove File",
|
||
["دانلود OpenVPN"] = "Download OpenVPN",
|
||
["نوع پراکسی"] = "Proxy Type",
|
||
["پورت"] = "Port",
|
||
["آدرس IP یا دامنه سرور"] = "Server IP or Domain",
|
||
|
||
["✅ برنامههای داخل تونل"] = "✅ Tunneled Apps",
|
||
["برنامههای فعالشده از مسیر تونل عبور میکنند"] = "Enabled apps use the tunnel route",
|
||
["افزودن دستی"] = "Add Manually",
|
||
["افزودن دستی فایل exe"] = "Manually add an exe file",
|
||
["فیلتر برنامههای تونل..."] = "Filter tunneled apps...",
|
||
["🔍 برنامههای نصبشده"] = "🔍 Installed Apps",
|
||
["روی برنامه کلیک کنید تا به لیست تونل اضافه شود"] = "Click an app to add it to the tunnel list",
|
||
["بارگذاری مجدد لیست برنامهها"] = "Reload the app list",
|
||
["جستجوی برنامه..."] = "Search apps...",
|
||
|
||
["🧦 پروکسی محلی"] = "🧦 Local Proxy",
|
||
["پورت پروکسی محلی (SOCKS5/HTTP)"] = "Local proxy port (SOCKS5/HTTP)",
|
||
["پورت داخلی 127.0.0.1 برای پروکسی SOCKS5 و HTTP"] = "Internal 127.0.0.1 port for SOCKS5 and HTTP proxy",
|
||
["پورتهای زیر 1024 و چند پورت رایج مثل 2080، 3000، 3389، 8080 و 9090 مجاز نیستند تا با سرویسهای سیستم یا ابزارهای توسعه تداخل نداشته باشند."] = "Ports below 1024 and common ports like 2080, 3000, 3389, 8080, and 9090 are blocked to avoid conflicts with system services or developer tools.",
|
||
["🚀 بهینهسازی تونل"] = "🚀 Tunnel Optimization",
|
||
["MTU خودکار"] = "Automatic MTU",
|
||
["در زمان اتصال، MTU مناسب بر اساس شبکه فعلی انتخاب میشود."] = "At connection time, the best MTU is selected based on the current network.",
|
||
["برای Resolveها از cache کوتاهمدت استفاده میشود و DNS redirect مسیر پایدارتر میگیرد."] = "Uses a short-lived cache for resolves and keeps DNS redirects more stable.",
|
||
["Game Mode فعال است: Route نگهداری طولانیتر، DNS سریعتر و DSCP برای بستههای بازی اعمال میشود."] = "Game Mode is enabled: longer route retention, faster DNS, and DSCP for game packets.",
|
||
["Game Mode غیرفعال است: حالت متعادل برای مصرف عمومی."] = "Game Mode is disabled: balanced mode for general use.",
|
||
["🖥️ استارتآپ و اتصال خودکار"] = "🖥️ Startup and Auto-Connect",
|
||
["اجرای خودکار هنگام روشن شدن ویندوز"] = "Start automatically with Windows",
|
||
["⚠️ پس از فعال کردن، نباید محل فایل اجرایی TunnelX را تغییر دهید."] = "⚠️ After enabling this, do not move the TunnelX executable.",
|
||
["اتصال خودکار به آخرین کانکشن فعال"] = "Auto-connect to the last active connection",
|
||
["اگر آخرین بار یک پروفایل متصل بوده، هنگام اجرای برنامه به آن وصل میشود."] = "If a profile was connected last time, TunnelX connects to it when the app starts.",
|
||
|
||
["راهنمای TunnelX"] = "TunnelX Help",
|
||
["شروع سریع، پروفایلها، بخشهای اپ و عیبیابی در یک صفحه ساده."] = "Quick start, profiles, app areas, and troubleshooting in one simple page.",
|
||
["پروژه و بروزرسانی"] = "Project and Updates",
|
||
["صفحه انتشار"] = "Release Page",
|
||
["شروع سریع"] = "Quick Start",
|
||
["۱. پروفایل"] = "1. Profile",
|
||
["کانفیگ را بسازید و نوع اتصال را انتخاب کنید."] = "Create a config and select its connection type.",
|
||
["۲. برنامهها"] = "2. Apps",
|
||
["برنامههای داخل تونل را انتخاب یا دستی اضافه کنید."] = "Select tunneled apps or add them manually.",
|
||
["۳. قوانین"] = "3. Rules",
|
||
["مقصدهای مستقیم یا اجباری را مشخص کنید."] = "Set direct or forced destinations.",
|
||
["۴. اتصال"] = "4. Connect",
|
||
["وصل شوید و سلامت، IP و مصرف را بررسی کنید."] = "Connect and check health, IP, and usage.",
|
||
["نوع پروفایل"] = "Profile Type",
|
||
["فقط فیلدهای مربوط به نوع انتخابشده را پر کنید. هر پروفایل برنامهها و قوانین مسیر خودش را نگه میدارد."] = "Only fill the fields for the selected type. Each profile keeps its own apps and routing rules.",
|
||
["بخشهای اپ"] = "App Areas",
|
||
["پروفایل فعال، تست سرور، اتصال/قطع اتصال، IP خروجی، پینگ، مصرف و راهنمای پراکسی دستی اینجاست."] = "Active profile, server test, connect/disconnect, exit IP, ping, usage, and manual proxy guidance are here.",
|
||
["نکات مهم"] = "Essentials",
|
||
["حالت عادی: فقط برنامههای انتخابشده و مقصدهای لزومی وارد تونل میشوند."] = "Normal mode: only selected apps and included destinations use the tunnel.",
|
||
["Full Route: کل سیستم وارد تونل میشود؛ استثناها میتوانند مستقیم بمانند."] = "Full Route: the whole system uses the tunnel; exclusions can stay direct.",
|
||
["پراکسی داخلی"] = "Local Proxy",
|
||
["برای ابزارهایی که آدرس محلی میخواهند:"] = "For tools that need a local address:",
|
||
["سلامت: Leak باید صفر باشد. DNS، IPv6 و Route را بعد از اتصال بررسی کنید."] = "Health: Leak should be zero. Check DNS, IPv6, and Route after connecting.",
|
||
["عیبیابی سریع"] = "Quick Troubleshooting",
|
||
["حمایت و تماس"] = "Support and Contact",
|
||
["حمایت با پیپل"] = "Donate with PayPal",
|
||
["حمایت"] = "Donate",
|
||
["کپی اطلاعات حمایت"] = "Copy donation info",
|
||
["اگر TunnelX برایتان مفید بوده، میتوانید با PayPal یا کریپتو از توسعه آن حمایت کنید."] = "If TunnelX has been useful, you can support its development with PayPal or crypto.",
|
||
["پرداخت با PayPal"] = "Pay with PayPal",
|
||
["پرداخت با کریپتو"] = "Pay with crypto",
|
||
["ترون / USDT روی TRC20"] = "Tron / USDT on TRC20",
|
||
["بیتکوین"] = "Bitcoin",
|
||
["اتریوم / USDT روی ERC20"] = "Ethereum / USDT on ERC20",
|
||
["کپی"] = "Copy",
|
||
|
||
["ویرایش پروفایل"] = "Edit Profile",
|
||
["تنظیمات این کانفیگ بعد از ذخیره در لیست پروفایلها نمایش داده میشود."] = "This config appears in the profile list after saving.",
|
||
["اطلاعات پروفایل"] = "Profile Info",
|
||
["نام پروفایل"] = "Profile Name",
|
||
["مثلاً کار، تلگرام، گیمینگ..."] = "e.g. Work, Telegram, Gaming...",
|
||
["تنظیمات اتصال"] = "Connection Settings",
|
||
["کانفیگ V2Ray / Xray"] = "V2Ray / Xray Config",
|
||
["پیست از کلیپبورد"] = "Paste from Clipboard",
|
||
["فایل .ovpn و اطلاعات احراز هویت OpenVPN را وارد کنید. اگر سرور رمز نمیخواهد، فیلد رمز را خالی بگذارید."] = "Enter the .ovpn file and OpenVPN credentials. Leave password empty if the server does not require one.",
|
||
["برای SOCKS5 یا HTTP Proxy، اطلاعات سرور را جداگانه وارد کنید."] = "For SOCKS5 or HTTP Proxy, enter the server details separately.",
|
||
["لغو"] = "Cancel",
|
||
["ذخیره"] = "Save",
|
||
|
||
["تاریخچه اتصالات"] = "Connection History",
|
||
["سوابق اتصال و مصرف تونل"] = "Connection records and tunnel usage",
|
||
["مجموع مصرف تونل: "] = "Total tunnel usage: ",
|
||
["هنوز اتصالی ثبت نشده است."] = "No connection has been recorded yet.",
|
||
|
||
["آماده اتصال"] = "Ready to connect",
|
||
["نیاز به تکمیل"] = "Needs setup",
|
||
["نامشخص"] = "Unknown",
|
||
["آدرس سرور وارد نشده"] = "Server address is missing",
|
||
["کانفیگ وارد نشده"] = "Config is missing",
|
||
["کانفیگ آماده"] = "Config ready",
|
||
["فایل .ovpn انتخاب نشده"] = ".ovpn file not selected",
|
||
["آدرس پراکسی وارد نشده"] = "Proxy address is missing"
|
||
,
|
||
["وضعیت"] = "Status",
|
||
["نمایش TunnelX"] = "Show TunnelX",
|
||
["بررسی بروزرسانی"] = "Check for Updates",
|
||
["اتصال VPN فعال است. با خروج، اتصال قطع خواهد شد.\nآیا مطمئن هستید؟"] = "A VPN connection is active. Exiting will disconnect it.\nAre you sure?",
|
||
["TunnelX — خروج"] = "TunnelX - Exit",
|
||
["آیا میخواهید از TunnelX خارج شوید؟"] = "Do you want to exit TunnelX?",
|
||
["TunnelX در پسزمینه فعال است"] = "TunnelX is running in the background",
|
||
["برای باز کردن پنجره، روی آیکن کنار ساعت دوبار کلیک کنید."] = "Double-click the tray icon to open the window.",
|
||
["تونل فعال شد"] = "Tunnel enabled",
|
||
["تونل خاموش شد"] = "Tunnel disabled",
|
||
["ارتباط امن متوقف شده و ترافیک دیگر از TunnelX عبور نمیکند."] = "The secure connection stopped and traffic no longer passes through TunnelX.",
|
||
["اتصال برقرار نشد"] = "Connection failed",
|
||
["نسخه جدید آماده است"] = "New version available",
|
||
["از منوی System Tray یا بخش بروزرسانی، صفحه دانلود TunnelX را باز کنید."] = "Open the TunnelX download page from the system tray menu or the update section.",
|
||
["پروفایل «{0}» فعال است و ترافیک انتخابشده از تونل عبور میکند."] = "Profile \"{0}\" is active and selected traffic uses the tunnel.",
|
||
["ترافیک انتخابشده از TunnelX عبور میکند."] = "Selected traffic uses TunnelX.",
|
||
["جزئیات خطا را در پنجره برنامه یا لاگها بررسی کنید."] = "Check the app window or logs for error details.",
|
||
["جزئیات: {0}"] = "Details: {0}",
|
||
["بارگذاری لیست برنامههای نصبشده..."] = "Loading installed apps...",
|
||
["تاییدیه"] = "Confirmation",
|
||
["اطلاعات"] = "Information",
|
||
["موفقیت"] = "Success",
|
||
["بله"] = "Yes",
|
||
["خیر"] = "No",
|
||
["متوجه شدم"] = "OK",
|
||
["عالی"] = "Great",
|
||
["{0} کپی شد"] = "{0} copied",
|
||
["متن"] = "Text",
|
||
["انتخاب فایل OpenVPN"] = "Choose OpenVPN File",
|
||
["OpenVPN config (*.ovpn)|*.ovpn|All files (*.*)|*.*"] = "OpenVPN config (*.ovpn)|*.ovpn|All files (*.*)|*.*",
|
||
["خواندن فایل OpenVPN ناموفق بود: {0}"] = "Failed to read OpenVPN file: {0}",
|
||
["خواندن کلیپبورد ناموفق بود: {0}"] = "Failed to read clipboard: {0}",
|
||
["نام پروفایل را وارد کنید"] = "Enter a profile name",
|
||
["آدرس سرور L2TP را وارد کنید"] = "Enter the L2TP server address",
|
||
["کانفیگ V2Ray/Xray را وارد کنید"] = "Enter the V2Ray/Xray config",
|
||
["فایل OpenVPN (.ovpn) را انتخاب کنید"] = "Choose an OpenVPN (.ovpn) file",
|
||
["آدرس سرور پراکسی را وارد کنید"] = "Enter the proxy server address",
|
||
["پورت پراکسی باید بین 1 تا 65535 باشد"] = "Proxy port must be between 1 and 65535",
|
||
["ذخیره شد"] = "Saved",
|
||
["پورت SOCKS5 را وارد کنید"] = "Enter the SOCKS5 port",
|
||
["فقط عدد مجاز است"] = "Only numbers are allowed",
|
||
["پیشنیاز آماده است: نسخه Community اوپنویپیان پیدا شد: {0}"] = "Prerequisite ready: OpenVPN Community found: {0}",
|
||
["اخطار: نسخه Community اوپنویپیان نصب نیست. برای استفاده از اسپلیتتانلینگ با این نوع اتصال، ابتدا آن را از لینک رسمی نصب کنید."] = "Warning: OpenVPN Community is not installed. Install it from the official link before using split tunneling with this connection type.",
|
||
["برای بررسی نسخه جدید، دکمه بررسی بروزرسانی را بزنید."] = "Click Check for Updates to look for a new version.",
|
||
["در حال بررسی..."] = "Checking...",
|
||
["🔌 اتصال"] = "🔌 Connect",
|
||
["❌ لغو اتصال"] = "❌ Cancel",
|
||
["🔴 قطع اتصال"] = "🔴 Disconnect",
|
||
["⏳ در حال قطع..."] = "⏳ Disconnecting...",
|
||
["🔌 اتصال مجدد"] = "🔌 Reconnect",
|
||
["اتصال"] = "Connect",
|
||
["لغو تلاش اتصال"] = "Cancel connection attempt",
|
||
["اتصال مجدد"] = "Reconnect",
|
||
["IP خروجی"] = "Exit IP",
|
||
["تغییر حالت Full Route ناموفق بود"] = "Failed to change Full Route mode",
|
||
["Full Route فعال است؛ کل سیستم از تونل عبور میکند"] = "Full Route is enabled; the whole system uses the tunnel",
|
||
["Split فعال است؛ فقط برنامهها و مقصدهای انتخابی از تونل عبور میکنند"] = "Split is enabled; only selected apps and destinations use the tunnel",
|
||
["حالت کل سیستم"] = "Full-system Mode",
|
||
["حالت انتخابی"] = "Selected Mode",
|
||
["ترافیک کل سیستم از تونل عبور خواهد کرد؛ برای وقتی مناسب است که همه برنامهها باید پشت تونل باشند."] = "All system traffic will use the tunnel; useful when every app must be behind the tunnel.",
|
||
["فقط برنامهها و مقصدهای انتخابی از تونل عبور میکنند؛ بقیه ترافیک مستقیم میماند."] = "Only selected apps and destinations use the tunnel; the rest stays direct.",
|
||
["متصل به پراکسی"] = "Connected to proxy",
|
||
["متصل به VPN"] = "Connected to VPN",
|
||
["توقف تست"] = "Stop test",
|
||
["تست مقصد"] = "Test target",
|
||
["در حال پینگ..."] = "Pinging...",
|
||
["پینگ سرور"] = "Ping server",
|
||
["در حال تست..."] = "Testing...",
|
||
["تست سرور"] = "Test server",
|
||
["در حال بررسی آخرین نسخه در GitHub..."] = "Checking the latest version on GitHub...",
|
||
["بررسی نسخه جدید ناموفق بود. اتصال اینترنت یا GitHub را بررسی کنید."] = "Version check failed. Check your internet connection or GitHub access.",
|
||
["نسخه جدید آماده است: {0} - برای دانلود از GitHub باز کنید."] = "New version available: {0} - open GitHub to download.",
|
||
["TunnelX بهروز است. نسخه فعلی: {0}"] = "TunnelX is up to date. Current version: {0}",
|
||
["بررسی بروزرسانی به زمان مجاز نرسید."] = "Update check timed out.",
|
||
["بررسی بروزرسانی ناموفق بود: {0}"] = "Update check failed: {0}",
|
||
["آماده تست و اتصال"] = "Ready to test and connect",
|
||
["OpenVPN Community نصب نیست؛ ابتدا آن را از لینک رسمی نصب کنید"] = "OpenVPN Community is not installed; install it from the official link first",
|
||
["فایل .ovpn را انتخاب کنید؛ TunnelX آن را در حالت split-compatible اجرا میکند"] = "Choose a .ovpn file; TunnelX runs it in split-compatible mode",
|
||
["کانفیگ انتخاب شد؛ اگر سرور احراز هویت دارد نام کاربری را وارد کنید"] = "Config selected; enter username if the server requires authentication",
|
||
["کانفیگ و نام کاربری OpenVPN آماده است"] = "OpenVPN config and username are ready",
|
||
["منتظر کانفیگ"] = "Waiting for config",
|
||
["کانفیگ V2Ray/Xray را وارد یا پیست کنید"] = "Enter or paste the V2Ray/Xray config",
|
||
["هسته: Xray-core"] = "Core: Xray-core",
|
||
["هسته: sing-box"] = "Core: sing-box",
|
||
["سرور: {0}:{1}"] = "Server: {0}:{1}",
|
||
["پراکسی آماده است: {0}"] = "Proxy is ready: {0}",
|
||
["پراکسی آماده است: {0} — توجه: این پراکسی محلی است؛ برنامههایی که خودشان مستقیم از همین پراکسی استفاده کنند خارج از لیست برنامههای TunnelX هم پروکسی میشوند."] = "Proxy is ready: {0} - note: this is a local proxy; apps that directly use it will be proxied even outside TunnelX's app list.",
|
||
["آدرس IP یا دامنه سرور پراکسی را وارد کنید"] = "Enter the proxy server IP or domain",
|
||
["تنظیمات پراکسی آماده است"] = "Proxy settings are ready",
|
||
["پورت باید بین 1024 تا 65535 باشد"] = "Port must be between 1024 and 65535",
|
||
["این پورت رایج/حساس است؛ یک پورت آزاد مثل 1080، 1081 یا 18080 انتخاب کنید"] = "This port is common/sensitive; choose a free port like 1080, 1081, or 18080",
|
||
["این پورت همین حالا توسط برنامه دیگری استفاده میشود"] = "This port is currently used by another app",
|
||
["پورت SOCKS5 داخلی آماده است"] = "Internal SOCKS5 port is ready"
|
||
,
|
||
["خطای اتصال خودکار: {0}"] = "Auto-connect error: {0}",
|
||
["حمایت از پروژه"] = "Support the project",
|
||
["تغییر زبان"] = "Change language",
|
||
["پورت پراکسی را وارد کنید"] = "Enter the proxy port",
|
||
["پورت پراکسی باید عدد باشد"] = "Proxy port must be a number",
|
||
["در حال آمادهسازی V2Ray..."] = "Preparing V2Ray...",
|
||
["فایل sing-box.exe پیدا نشد: {0}"] = "sing-box.exe was not found: {0}",
|
||
["خطا در پارس کانفیگ: {0}"] = "Config parse error: {0}",
|
||
["در حال انتظار برای interface TunnelX-V2Ray..."] = "Waiting for TunnelX-V2Ray interface...",
|
||
["sing-box زودتر خارج شد (exit code {0}) — کانفیگ را بررسی کنید"] = "sing-box exited early (exit code {0}) - check the config",
|
||
["interface TunnelX-V2Ray ظاهر نشد (timeout 10s)"] = "TunnelX-V2Ray interface did not appear (timeout 10s)",
|
||
["در حال قطع اتصال V2Ray..."] = "Disconnecting V2Ray...",
|
||
["در حال آماده سازی Xray..."] = "Preparing Xray...",
|
||
["فایل xray.exe پیدا نشد: {0}"] = "xray.exe was not found: {0}",
|
||
["در حال قطع اتصال Xray..."] = "Disconnecting Xray...",
|
||
["در حال ایجاد اتصال VPN..."] = "Creating VPN connection...",
|
||
["خطا در ایجاد VPN: {0}"] = "VPN creation failed: {0}",
|
||
["در حال اتصال به سرور..."] = "Connecting to server...",
|
||
["متصل — IP: {0}"] = "Connected - IP: {0}",
|
||
["نام کاربری یا رمز عبور اشتباه است"] = "The username or password is incorrect",
|
||
["پورت یا دستگاه اشغال است"] = "The port or device is busy",
|
||
["انتظار برای پاسخ سرور به اتمام رسید (زمانبر)"] = "Timed out waiting for the server response",
|
||
["پروتکل PPP بین کلاینت و سرور مطابقت ندارد"] = "PPP protocol does not match between client and server",
|
||
["پروتکل Link Control قطع شد"] = "Link Control Protocol terminated",
|
||
["آدرس درخواستی توسط سرور رد شد"] = "The requested address was rejected by the server",
|
||
["رایانه به اینترنت متصل نیست"] = "The computer is not connected to the internet",
|
||
["رمزنگاری L2TP/IPsec شکست خورد - PSK یا تنظیمات سرور را بررسی کنید"] = "L2TP/IPsec encryption failed - check the PSK or server settings",
|
||
["مقصد در دسترس نیست (سرور خاموش یا آدرس اشتباه)"] = "Destination is unreachable (server is down or address is wrong)",
|
||
["Pre-Shared Key (PSK) اشتباه است"] = "Pre-Shared Key (PSK) is incorrect",
|
||
["رمزنگاری L2TP شکست خورد"] = "L2TP encryption failed",
|
||
["سرور VPN در دسترس نیست"] = "VPN server is not reachable",
|
||
["نوع شبکه را نمیتوان مشخص کرد (فایروال مسدود کرده)"] = "Network type cannot be determined (firewall may be blocking it)",
|
||
["اتصال قبلی باعث تضاد شده"] = "A previous connection caused a conflict",
|
||
["خطای ناشناخته (exit code: {0})"] = "Unknown error (exit code: {0})",
|
||
["xray زودتر خارج شد (exit code {0})"] = "xray exited early (exit code {0})",
|
||
["sing-box bridge زودتر خارج شد (exit code {0})"] = "sing-box bridge exited early (exit code {0})",
|
||
["نوع تانل ناشناخته: {0}"] = "Unknown tunnel type: {0}",
|
||
["در حال لغو اتصال..."] = "Canceling connection...",
|
||
["آدرس سرور را وارد کنید"] = "Enter the server address",
|
||
["کانفیگ V2Ray را وارد کنید"] = "Enter the V2Ray config",
|
||
["کانفیگ OpenVPN (.ovpn) را وارد کنید"] = "Enter the OpenVPN (.ovpn) config",
|
||
["در حال آمادهسازی OpenVPN..."] = "Preparing OpenVPN...",
|
||
["در حال اتصال..."] = "Connecting...",
|
||
["اتصال لغو شد"] = "Connection canceled",
|
||
["پراکسی متصل شد"] = "Proxy connected",
|
||
["در حال دریافت..."] = "Fetching...",
|
||
["در حال قطع اتصال..."] = "Disconnecting...",
|
||
["قطع شد"] = "Disconnected",
|
||
["اتصال VPN قطع شد..."] = "VPN connection dropped...",
|
||
["اتصال VPN بهطور غیرمنتظره قطع شد"] = "VPN connection dropped unexpectedly",
|
||
["اتصال VPN بهطور غیرمنتظره قطع شد.\nلطفاً دوباره متصل شوید."] = "VPN connection dropped unexpectedly.\nPlease reconnect.",
|
||
["قطع اتصال"] = "Disconnect",
|
||
["OpenVPN دوباره متصل شد؛ مسیرهای TunnelX در حال بروزرسانی است..."] = "OpenVPN reconnected; TunnelX routes are being updated...",
|
||
["OpenVPN دوباره متصل شد و مسیرها بروزرسانی شدند"] = "OpenVPN reconnected and routes were updated",
|
||
["آدرس سرور خالی است"] = "Server address is empty",
|
||
["remote سرور در فایل .ovpn پیدا نشد"] = "Server remote was not found in the .ovpn file",
|
||
["کانفیگ UDP است؛ تست دقیق قبل از اتصال ممکن نیست"] = "The config uses UDP; accurate pre-connect testing is not possible",
|
||
["هیچ remote قابلدسترسی نبود ({0})"] = "No reachable remote was found ({0})",
|
||
["خطا: {0}"] = "Error: {0}",
|
||
["در حال پینگ سرور..."] = "Pinging server...",
|
||
["پینگ سرور timeout شد"] = "Server ping timed out",
|
||
["فایل .ovpn انتخاب نشده است"] = ".ovpn file is not selected",
|
||
["کانفیگ خالی است"] = "Config is empty",
|
||
["endpoint سرور از کانفیگ تشخیص داده نشد"] = "Server endpoint could not be detected from the config",
|
||
["پارس کانفیگ ناموفق بود: {0}"] = "Failed to parse config: {0}",
|
||
["آدرس ss:// نامعتبر است"] = "Invalid ss:// address",
|
||
["سرور پیدا نشد"] = "Server not found",
|
||
["پورت نامعتبر است"] = "Invalid port",
|
||
["آدرس نامعتبر"] = "Invalid address",
|
||
[" [پایان]"] = " [done]",
|
||
["۱ پروفایل ذخیرهشده"] = "1 saved profile",
|
||
["{0} پروفایل ذخیرهشده"] = "{0} saved profiles",
|
||
["نوع اتصال نامشخص"] = "Unknown connection type",
|
||
["آدرس سرور هنوز وارد نشده"] = "Server address not entered yet",
|
||
["کانفیگ V2Ray/Xray آماده نمایش نیست"] = "V2Ray/Xray config is not ready to display",
|
||
["فایل OpenVPN انتخاب نشده"] = "OpenVPN file not selected",
|
||
["آدرس پراکسی هنوز وارد نشده"] = "Proxy address not entered yet",
|
||
["تغییرات این پروفایل بهصورت خودکار ذخیره میشود"] = "Profile changes are saved automatically",
|
||
["در حال ذخیره..."] = "Saving...",
|
||
["پیشفرض"] = "Default",
|
||
["پروفایل {0}"] = "Profile {0}",
|
||
["{0} (کپی)"] = "{0} (copy)",
|
||
["کپی پروفایل"] = "Copy Profile",
|
||
["پروفایل «{0}» حذف شود؟"] = "Delete profile \"{0}\"?",
|
||
["حذف پروفایل"] = "Delete Profile",
|
||
["استارتآپ فعال شد.\n\n⚠️ برای کارکرد صحیح، پس از این نباید محل فایل اجرایی TunnelX را تغییر دهید."] = "Startup enabled.\n\n⚠️ For correct behavior, do not move the TunnelX executable after this.",
|
||
["TunnelX — استارتآپ"] = "TunnelX - Startup"
|
||
,
|
||
["برای سرورهای SOCKS5 یا HTTP Proxy، اطلاعات را جداگانه وارد کنید. TunnelX از همین پراکسی یک TUN داخلی میسازد تا اسپلیتتانلینگ برنامههای انتخابی مثل سایر نوعهای اتصال کار کند."] = "For SOCKS5 or HTTP Proxy servers, enter the server details separately. TunnelX builds an internal TUN from this proxy so selected-app split tunneling works like other connection types.",
|
||
["اگر پراکسی شما نام کاربری یا رمز ندارد، فیلدهای احراز هویت را خالی بگذارید."] = "If your proxy has no username or password, leave the authentication fields empty.",
|
||
["🏓 سرور"] = "🏓 Server",
|
||
["قبل از اتصال، دسترسی و latency سرور را تست میکند"] = "Tests server reachability and latency before connecting",
|
||
["وضعیت و پروفایل فعال"] = "Status and active profile",
|
||
["مدت زمان اتصال فعلی از لحظه برقراری اتصال"] = "Current connection duration since connection started",
|
||
["مدت"] = "Duration",
|
||
["IP عمومیای که مقصدهای اینترنتی شما را با آن میبینند"] = "The public IP seen by internet destinations",
|
||
["مجموع ترافیک ارسال و دریافت عبوری از تونل VPN (کل تونل)"] = "Total sent and received traffic through the VPN tunnel",
|
||
["تونل"] = "Tunnel",
|
||
["نمایش تشخیصی ترافیک خارج از تونل. این عدد در مصرف تونل و تاریخچه ثبت نمیشود."] = "Diagnostic view of traffic outside the tunnel. This number is not recorded as tunnel usage or history.",
|
||
["خارج تونل"] = "Direct",
|
||
["🌐 عبور کل سیستم"] = "🌐 Full Route",
|
||
["روشن: کل ویندوز از تونل. خاموش: فقط برنامهها و قوانین انتخابی."] = "On: all Windows traffic uses the tunnel. Off: only selected apps and rules.",
|
||
["اگر برنامهای خودکار وارد تونل نشد، این آدرس را در تنظیمات Proxy همان برنامه وارد کنید."] = "If an app does not enter the tunnel automatically, enter this address in that app's proxy settings.",
|
||
["🧦 پروکسی دستی"] = "🧦 Manual Proxy",
|
||
["این آدرس داخلی را در برنامههایی وارد کنید که تنظیم Proxy جداگانه دارند یا خودکار وارد تونل نمیشوند."] = "Use this internal address in apps with separate proxy settings or apps that do not enter the tunnel automatically.",
|
||
["🏓 تست مسیر"] = "🏓 Route Test",
|
||
["یک دامنه یا IP را از داخل تونل تست کنید."] = "Test a domain or IP from inside the tunnel.",
|
||
["IP یا دامنه مقصد برای تست از داخل تونل"] = "Destination IP or domain to test through the tunnel",
|
||
["تست همین مقصد از داخل مسیر تونل"] = "Test this destination through the tunnel route",
|
||
["دسترسی به سرور همین اتصال را تست میکند"] = "Tests reachability to this connection's server",
|
||
["قطع اتصال فعلی"] = "Disconnect current connection",
|
||
["💡 در حالت انتخابی، فقط برنامههای فعال در تب "] = "💡 In selected mode, only apps enabled in the ",
|
||
["«برنامهها»"] = "\"Apps\"",
|
||
[" از تونل عبور میکنند؛ بقیه مستقیم میمانند."] = " tab use the tunnel; the rest stays direct.",
|
||
["📌 برای تلگرام، واتساپ و برنامههای Store، "] = "📌 For Telegram, WhatsApp, and Store apps, also add ",
|
||
[" را هم به لیست تونل اضافه کنید."] = " to the tunnel list."
|
||
,
|
||
["TunnelX — جزئیات عملکرد"] = "TunnelX - Runtime Details",
|
||
["🔍 جزئیات عملکرد — TunnelX"] = "🔍 Runtime Details - TunnelX",
|
||
["🗑 پاک کردن"] = "🗑 Clear",
|
||
["📋 کپی"] = "📋 Copy",
|
||
["لاگها"] = "Logs",
|
||
["خطا در کپی کردن:\n{0}"] = "Copy failed:\n{0}",
|
||
["لاگها پاک شدند"] = "Logs cleared",
|
||
["لاگی برای کپی وجود ندارد"] = "There are no logs to copy",
|
||
["لاگ کپی شد"] = "Log copied",
|
||
["آخرین خطا یا هشدار پیدا نشد"] = "No recent error or warning found",
|
||
["آخرین خطا یا هشدار کپی شد"] = "Latest error or warning copied",
|
||
["کپی لاگ ناموفق بود"] = "Failed to copy logs",
|
||
["باز کردن لینک ناموفق بود: {0}"] = "Failed to open link: {0}",
|
||
["کپی ناموفق بود: {0}"] = "Copy failed: {0}",
|
||
["آیا مطمئن هستید؟"] = "Are you sure?",
|
||
["در حال اجرای OpenVPN در حالت Split..."] = "Running OpenVPN in split mode...",
|
||
["فقط OpenVPN Connect پیدا شد. برای Split Tunneling باید OpenVPN Community (openvpn.exe) هم نصب باشد."] = "Only OpenVPN Connect was found. Split tunneling requires OpenVPN Community (openvpn.exe).",
|
||
["OpenVPN Community پیدا نشد. برای Split Tunneling باید openvpn.exe نصب باشد."] = "OpenVPN Community was not found. Split tunneling requires openvpn.exe.",
|
||
["کانفیگ OpenVPN (.ovpn) وارد نشده است."] = "OpenVPN (.ovpn) config is missing.",
|
||
["OpenVPN Community نصب نیست؛ ابتدا از لینک رسمی نصب کنید"] = "OpenVPN Community is not installed; install it from the official link first",
|
||
["OpenVPN در حال اتصال است؛ مسیرهای پیشفرض آن برای Split Tunnel نادیده گرفته میشوند..."] = "OpenVPN is connecting; its default routes are ignored for split tunneling...",
|
||
["OpenVPN زودتر از اتصال بسته شد (exit={0})"] = "OpenVPN exited before connecting (exit={0})",
|
||
["منتظر بالا آمدن آداپتر OpenVPN... ({0}s)"] = "Waiting for the OpenVPN adapter... ({0}s)",
|
||
["آداپتور OpenVPN بالا نیامد. لاگ OpenVPN را بررسی کنید؛ ممکن است ریموت اول پاسخ ندهد یا احراز هویت/شبکه مشکل داشته باشد."] = "The OpenVPN adapter did not come up. Check the OpenVPN log; the first remote may not respond or authentication/network may be failing.",
|
||
["OpenVPN متصل شد (Split Tunnel)"] = "OpenVPN connected (Split Tunnel)",
|
||
["در حال قطع اتصال OpenVPN..."] = "Disconnecting OpenVPN...",
|
||
[" • 📊 تونل "] = " • 📊 Tunnel ",
|
||
["برای سرورهای SOCKS5 یا HTTP Proxy، اطلاعات سرور را جداگانه وارد کنید."] = "For SOCKS5 or HTTP Proxy servers, enter the server details separately.",
|
||
["TunnelX فایل .ovpn را با OpenVPN Community اجرا میکند و مسیر/DNS پیشفرض OpenVPN را کنترل میکند تا فقط برنامههای انتخابی از تونل عبور کنند."] = "TunnelX runs the .ovpn file with OpenVPN Community and controls OpenVPN's default route/DNS so only selected apps use the tunnel.",
|
||
["OpenVPN Connect بهتنهایی کافی نیست؛ اگر Community نصب نباشد، از دکمه دانلود پایین استفاده کنید."] = "OpenVPN Connect alone is not enough; if Community is not installed, use the download button below.",
|
||
["انتخاب برنامه"] = "Select App",
|
||
["لایسنس: {0}"] = "License: {0}",
|
||
["برای اتصال VPN ویندوز. آدرس سرور، نام کاربری، رمز عبور و Pre-Shared Key لازم است. اگر وصل نشد، PSK، فایروال و تنظیمات VPN ویندوز را بررسی کنید."] = "For Windows VPN connection. Server address, username, password, and Pre-Shared Key are required. If it does not connect, check the PSK, firewall, and Windows VPN settings.",
|
||
["لینک یا JSON کانفیگ را وارد کنید یا از کلیپبورد پیست کنید. TunnelX معمولاً sing-box را اجرا میکند و برای قابلیتهایی مثل xhttp از Xray-core استفاده میکند."] = "Enter a config link or JSON, or paste it from the clipboard. TunnelX usually runs sing-box and uses Xray-core for features such as xhttp.",
|
||
["برای پراکسی خارجی آماده. نوع پراکسی، آدرس، پورت و در صورت نیاز نام کاربری/رمز را وارد کنید. این با پراکسی داخلی 127.0.0.1 فرق دارد."] = "For an external ready proxy. Enter protocol, address, port, and credentials if needed. This is different from the internal 127.0.0.1 proxy.",
|
||
["فایل ovpn را انتخاب کنید. OpenVPN Community باید جداگانه نصب باشد؛ OpenVPN Connect برای Split Tunneling مناسب نیست. اگر سرور رمز میخواهد، نام کاربری و رمز را در TunnelX وارد کنید."] = "Choose the ovpn file. OpenVPN Community must be installed separately; OpenVPN Connect is not suitable for split tunneling. If the server requires credentials, enter them in TunnelX.",
|
||
["از لیست برنامههای پیدا شده انتخاب کنید یا فایل exe را دستی اضافه کنید. برای Store/MSIX/WebView2 برنامه را باز نگه دارید و بروزرسانی لیست را بزنید."] = "Select from discovered apps or manually add an exe file. For Store/MSIX/WebView2 apps, keep the app open and refresh the list.",
|
||
["«مستقیم بماند» یعنی مقصد از تونل عبور نکند. «از تونل عبور کند» یعنی مقصد حتی بدون انتخاب برنامه وارد تونل شود. دامنهها زیردامنهها را هم پوشش میدهند."] = "\"Stay Direct\" means the destination bypasses the tunnel. \"Use Tunnel\" means the destination enters the tunnel even without selecting an app. Domains also cover subdomains.",
|
||
["پورت پراکسی محلی، MTU خودکار، DNS Optimization، Game Mode، اجرای خودکار ویندوز و اتصال خودکار اینجاست."] = "Local proxy port, automatic MTU, DNS Optimization, Game Mode, Windows startup, and auto-connect are here.",
|
||
["مدت اتصال، IP، مصرف تونل، مصرف خارج تونل، سلامت Split Tunnel، مصرف برنامهها و تاریخچه اتصالها را نشان میدهد."] = "Shows duration, IP, tunnel usage, direct usage, split tunnel health, app usage, and connection history.",
|
||
["جزئیات و لاگها"] = "Details and Logs",
|
||
["از دکمه جزئیات، لاگها را با فیلتر خطا، هشدار، DNS یا Route ببینید. قبل از ارسال عمومی لاگ، رمزها، کلیدها، UUID و endpoint خصوصی را حذف کنید."] = "Use Details to view logs filtered by error, warning, DNS, or route. Before sharing logs publicly, remove passwords, keys, UUIDs, and private endpoints.",
|
||
["اتصال برقرار نمیشود"] = "Connection Does Not Start",
|
||
["برنامه را با Administrator اجرا کنید. فایروال، آنتیویروس، آدرس سرور، پورت، رمزها، PSK، نصب OpenVPN Community و اعتبار کانفیگ را بررسی کنید."] = "Run the app as Administrator. Check firewall, antivirus, server address, port, credentials, PSK, OpenVPN Community installation, and config validity.",
|
||
["ترافیک برنامه از تونل عبور نمیکند"] = "App Traffic Does Not Use Tunnel",
|
||
["برنامه را در تب برنامهها فعال کنید. اگر چندپردازشی است، برنامه را باز نگه دارید و لیست برنامهها را دوباره بارگذاری کنید."] = "Enable the app in the Apps tab. If it is multi-process, keep it open and reload the app list.",
|
||
["پراکسی کار نمیکند"] = "Proxy Does Not Work",
|
||
["برای پروفایل پراکسی، آدرس، پورت، نوع و اطلاعات ورود را بررسی کنید. برای ابزارهای محلی، آدرس 127.0.0.1 و پورت تنظیمات را وارد کنید."] = "For proxy profiles, check address, port, protocol, and credentials. For local tools, enter 127.0.0.1 and the configured port.",
|
||
["DNS، IPv6 یا Leak غیرعادی است"] = "DNS, IPv6, or Leak Looks Wrong",
|
||
["یک بار قطع و وصل کنید تا مسیرها و قوانین DNS دوباره ساخته شوند. اگر مشکل ماند، لاگهای DNS و Route را بررسی کنید."] = "Disconnect and reconnect once so routes and DNS rules are rebuilt. If it persists, check DNS and Route logs."
|
||
};
|
||
}
|