chore(i18n): delete 230 dead translation keys and guard against new ones (#6132)

* chore(i18n): delete 230 dead translation keys and guard against new ones

The 13 locale files carried 230 keys (11% of the set) that nothing in
the frontend or Go sources references — leftovers of renamed features
(the email notifier reuses tgbot.messages.* for subjects, the old
email.subject*/title* set was orphaned; likewise menu.*, the clients
bulk-copy strings, and the secAlert* family). Nothing detected this:
a missing key falls back to en-US and an unused key fails nothing.

A new test now fails the build when an en-US key has no reference in
frontend/src or internal Go sources (dynamic keys are covered by
harvesting concatenation and template-literal prefixes), and pins
that all 13 locales carry exactly the en-US key set, so parity drift
surfaces at test time instead of as a silent fallback.

Each locale shrinks by the same 230 keys; net -2,900 lines across
the translation set.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(i18n): restore the 29 live remarkVars keys, match whole tokens, unmask 9 more

From review: the template-literal harvester required the prefix to end
on a dot, so pages.hosts.remarkVars.desc${token} harvested nothing
and all 29 desc* tooltip keys were wrongly deleted — and the guard
shared the flawed logic, so CI stayed green while the Hosts page
would have shown raw key names in 13 languages. Restored from the
parent commit; the harvester now requires at least one dot but not a
trailing one.

Also from review: references are matched as whole dotted tokens
instead of substrings (a dead key can no longer hide behind a longer
sibling — that unmasked 9 more genuinely dead keys, each verified by
hand before deletion), and the test excludes itself from the scan so
its own prose cannot whitelist a subtree.

Net: -210 keys per locale instead of the previous -230.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
PathGao
2026-07-29 13:59:25 +08:00
committed by GitHub
parent 17e6b5a460
commit ea35884390
14 changed files with 117 additions and 2834 deletions
+2 -218
View File
@@ -48,7 +48,6 @@
"copySuccess": "اتنسخ بنجاح",
"sure": "متأكد؟",
"encryption": "تشفير",
"useIPv4ForHost": "استخدم IPv4 للمضيف",
"transmission": "نقل",
"host": "المضيف",
"path": "المسار",
@@ -74,18 +73,9 @@
"twoFactorCode": "الكود",
"remained": "المتبقي",
"security": "أمان",
"secAlertTitle": "تنبيه أمني",
"secAlertSsl": "الاتصال ده مش آمن. ابعد عن إدخال معلومات حساسة لغاية ما تشغل TLS لحماية البيانات.",
"secAlertConf": "بعض الإعدادات معرضة لهجمات. ينصح بتعزيز بروتوكولات الأمان عشان تمنع الاختراقات المحتملة.",
"secAlertSSL": "البانل مش مؤمن. حمّل شهادة TLS لحماية البيانات.",
"secAlertPanelPort": "بورت البانل الافتراضي معرض للخطر. ياريت تغير لبورت عشوائي أو محدد.",
"secAlertPanelURI": "مسار URI الافتراضي للبانل مش آمن. ياريت تضبط مسار URI معقد.",
"secAlertSubURI": "مسار URI الافتراضي للاشتراك مش آمن. ياريت تضبط مسار URI معقد.",
"secAlertSubJsonURI": "مسار URI الافتراضي لاشتراك JSON مش آمن. ياريت تضبط مسار URI معقد.",
"emptyDnsDesc": "مفيش سيرفر DNS مضاف.",
"emptyFakeDnsDesc": "مفيش سيرفر Fake DNS مضاف.",
"emptyBalancersDesc": "مفيش موازن تحميل مضاف.",
"emptyReverseDesc": "مفيش بروكسي عكسي مضاف.",
"somethingWentWrong": "حدث خطأ ما",
"subscription": {
"title": "معلومات الاشتراك",
@@ -106,8 +96,6 @@
},
"menu": {
"theme": "الثيم",
"dark": "داكن",
"ultraDark": "داكن جدًا",
"dashboard": "نظرة عامة",
"inbounds": "الواردات",
"clients": "العملاء",
@@ -118,7 +106,6 @@
"routing": "التوجيه",
"outbounds": "الصادرات",
"apiDocs": "توثيق API",
"logout": "تسجيل خروج",
"link": "إدارة",
"donate": "تبرع",
"hosts": "المضيفات",
@@ -139,7 +126,6 @@
}
},
"index": {
"title": "نظرة عامة",
"cpu": "المعالج",
"logicalProcessors": "المعالجات المنطقية",
"frequency": "التردد",
@@ -152,7 +138,6 @@
"restartXray": "إعادة تشغيل",
"xraySwitch": "النسخة",
"xrayUpdates": "تحديثات Xray",
"xraySwitchClick": "اختار النسخة اللي عايز تتحول لها.",
"xraySwitchClickDesk": "اختار بحذر، النسخ القديمة ممكن ما تتوافقش مع الإعدادات الحالية.",
"updatePanel": "تحديث البانل",
"panelUpdateDesc": "ده هيحدث 3X-UI لآخر إصدار وهيعيد تشغيل خدمة البانل.",
@@ -164,12 +149,10 @@
"currentCommit": "الكومِت الحالي",
"latestCommit": "أحدث كومِت",
"updateChannelChanged": "تم تغيير قناة التحديث",
"upToDate": "محدث",
"xrayStatusUnknown": "مش معروف",
"xrayStatusRunning": "شغالة",
"xrayStatusStop": "متوقفة",
"xrayStatusError": "خطأ",
"xrayErrorPopoverTitle": "حصل خطأ أثناء تشغيل Xray",
"operationHours": "مدة التشغيل",
"systemHistoryTitle": "تاريخ النظام",
"historyTitleCpu": "استخدام المعالج",
@@ -211,9 +194,6 @@
"xrayObservatoryDead": "غير متصل",
"xrayObservatoryLastSeen": "آخر مشاهدة",
"xrayObservatoryLastTry": "آخر محاولة",
"trendLast2Min": "آخر دقيقتين",
"systemLoad": "تحميل النظام",
"systemLoadDesc": "متوسط تحميل النظام في الدقائق 1, 5, و15",
"connectionCount": "إحصائيات الاتصال",
"ipAddresses": "عناوين IP",
"toggleIpVisibility": "بدل إظهار IP",
@@ -223,13 +203,11 @@
"totalData": "إجمالي البيانات",
"sent": "مرسل",
"received": "مستقبل",
"documentation": "التوثيق",
"xraySwitchVersionDialog": "هل تريد حقًا تغيير إصدار Xray؟",
"xraySwitchVersionDialogDesc": "سيؤدي هذا إلى تغيير إصدار Xray إلى #version#.",
"xraySwitchVersionPopover": "تم تحديث Xray بنجاح",
"panelUpdateDialog": "هل فعلاً عايز تحدث البانل؟",
"panelUpdateDialogDesc": "ده هيحدث 3X-UI للإصدار #version# وهيعيد تشغيل البانل.",
"panelUpdateCheckPopover": "فشل التحقق من تحديث البانل",
"panelUpdateStartedPopover": "بدأ تحديث البانل",
"panelUpdateFailedTitle": "فشل تحديث البانل",
"panelUpdateFailedDesc": "لم يكتمل التحديث بنجاح. تحقق من سجلات الخادم، أو نفّذ الأمر «x-ui update» من سطر الأوامر.",
@@ -258,7 +236,6 @@
"accessLogs": "سجلات الوصول",
"autoUpdate": "تحديث تلقائي",
"config": "الإعدادات",
"backup": "نسخ احتياطي",
"backupTitle": "نسخ احتياطي واستعادة",
"exportDatabase": "اخزن نسخة",
"exportDatabaseDesc": "اضغط عشان تحمل ملف .db يحتوي على نسخة احتياطية لقاعدة البيانات الحالية على جهازك. نفس الملف ممكن كمان يترجع على لوحة شغالة بـ PostgreSQL.",
@@ -276,7 +253,6 @@
"migrationDownloadPgDesc": "انقر لتنزيل قاعدة بيانات SQLite بامتداد .db مبنية من بيانات PostgreSQL الخاصة بك، جاهزة لتشغيل هذه اللوحة على SQLite."
},
"inbounds": {
"title": "الواردات",
"totalDownUp": "إجمالي المرسل/المستقبل",
"totalUsage": "إجمالي الاستخدام",
"inboundCount": "عدد الإدخالات",
@@ -288,21 +264,11 @@
"localPanel": "بانل محلي",
"fallbacks": {
"title": "Fallbacks",
"help": "عند وصول اتصال إلى هذا الـ inbound لا يطابق أي عميل، يتم توجيهه إلى مكان آخر. اختر inbound فرعيًا أدناه لملء حقول التوجيه (SNI / ALPN / Path / xver) تلقائيًا من نقله، أو اترك القائمة فارغة واضبط Dest مباشرةً (مثل 8080 أو 127.0.0.1:8080) للتوجيه إلى خادم خارجي مثل Nginx. يجب أن يستمع كل inbound فرعي على 127.0.0.1 مع security=none.",
"empty": "لا توجد fallbacks بعد",
"add": "إضافة fallback",
"pickInbound": "اختر inbound",
"matchAny": "أي",
"destPlaceholder": "تلقائي (listen:port للفرع)",
"rederive": "إعادة الملء من الفرع",
"rederived": "تم إعادة الملء من الفرع",
"editAdvanced": "تحرير حقول التوجيه",
"hideAdvanced": "إخفاء المتقدم",
"quickAddAll": "إضافة سريعة لكل الـ inbounds المؤهلة",
"quickAdded": "تمت إضافة {n} fallback",
"quickAddedNone": "لا توجد inbounds جديدة مؤهلة للإضافة",
"routesWhen": "يوجَّه عندما",
"defaultCatchAll": "افتراضي — يلتقط أي شيء آخر",
"needsTls": "تصبح الـ Fallbacks متاحة بعد اختيار TLS أو Reality في تبويب الأمان (فقط VLESS/Trojan عبر RAW)."
},
"protocol": "بروتوكول",
@@ -310,8 +276,6 @@
"portMap": "تعيين المنفذ",
"traffic": "حركة المرور",
"speed": "السرعة",
"details": "تفاصيل",
"transportConfig": "النقل",
"expireDate": "المدة",
"createdAt": "تاريخ الإنشاء",
"updatedAt": "تاريخ التحديث",
@@ -319,8 +283,6 @@
"addInbound": "أضف إدخال",
"generalActions": "إجراءات عامة",
"modifyInbound": "تعديل الإدخال",
"deleteInbound": "حذف الإدخال",
"deleteInboundContent": "متأكد إنك عايز تحذف الإدخال؟",
"deleteConfirmTitle": "حذف الإدخال \"{remark}\"؟",
"deleteConfirmContent": "سيؤدي هذا إلى إزالة الإدخال وجميع عملائه. لا يمكن التراجع.",
"resetConfirmTitle": "إعادة تعيين ترافيك \"{remark}\"؟",
@@ -364,8 +326,6 @@
"exportAllLinksFileName": "جميع-الواردات",
"exportAllSubsFileName": "جميع-الواردات-Subs",
"inboundJsonTitle": "JSON الوارد",
"deleteClient": "حذف العميل",
"deleteClientContent": "متأكد إنك عايز تحذف العميل؟",
"resetTrafficContent": "متأكد إنك عايز تعيد ضبط الترافيك؟",
"copyLink": "انسخ الرابط",
"address": "العنوان",
@@ -376,36 +336,19 @@
"meansNoLimit": "= غير محدود. (الوحدة: GB)",
"totalFlow": "إجمالي التدفق",
"leaveBlankToNeverExpire": "سيبها فاضية عشان ماتنتهيش",
"noRecommendKeepDefault": "ننصح باستخدام الافتراضي",
"certificatePath": "مسار الملف",
"certificateContent": "محتوى الملف",
"publicKey": "المفتاح العام",
"privatekey": "المفتاح الخاص",
"clickOnQRcode": "اضغط على كود QR للنسخ",
"client": "عميل",
"export": "تصدير كل الروابط",
"clone": "استنساخ",
"cloneInbound": "استنساخ الإدخال",
"cloneInboundContent": "كل إعدادات الإدخال ده، غير البورت، IP الاستماع، والعملاء، هتتطبق على الاستنساخ.",
"cloneInboundOk": "استنساخ",
"resetAllTraffic": "إعادة ضبط ترافيك كل الإدخالات",
"resetAllTrafficTitle": "إعادة ضبط ترافيك كل الإدخالات",
"resetAllTrafficContent": "متأكد إنك عايز تعيد ضبط الترافيك لكل الإدخالات؟",
"resetInboundClientTraffics": "إعادة ضبط ترافيك العملاء",
"resetInboundClientTrafficTitle": "إعادة ضبط ترافيك العملاء",
"resetInboundClientTrafficContent": "متأكد إنك عايز تعيد ضبط ترافيك عملاء الإدخال ده؟",
"resetAllClientTraffics": "إعادة ضبط ترافيك كل العملاء",
"resetAllClientTrafficTitle": "إعادة ضبط ترافيك كل العملاء",
"resetAllClientTrafficContent": "متأكد إنك عايز تعيد ضبط ترافيك كل العملاء؟",
"delDepletedClients": "حذف العملاء اللي خلصت",
"delDepletedClientsTitle": "حذف العملاء اللي خلصت",
"delDepletedClientsContent": "متأكد إنك عايز تحذف كل العملاء اللي خلصت؟",
"email": "البريد",
"emailDesc": "ادخل إيميل فريد.",
"IPLimit": "تحديد IP",
"IPLimitDesc": "بيعطل الإدخال لو العدد زاد عن القيمة المحددة. (0 = تعطيل)",
"IPLimitlog": "سجل IP",
"IPLimitlogDesc": "سجل تاريخ الـ IPs. (عشان تفعل الإدخال بعد التعطيل، امسح السجل)",
"IPLimitlogclear": "امسح السجل",
"setDefaultCert": "استخدم شهادة البانل",
"setDefaultCertEmpty": "لا توجد شهادة معدّة للوحة. عينّ واحدة من الإعدادات أولاً.",
@@ -438,21 +381,15 @@
"sniffing": "Sniffing",
"sniffingHelp": "غلاف كتلة sniffing في Xray:",
"stream": "Stream",
"streamHelp": "غلاف كتلة stream في Xray:",
"jsonErrorPrefix": "JSON متقدم"
"streamHelp": "غلاف كتلة stream في Xray:"
},
"telegramDesc": "ادخل ID شات Telegram. (استخدم '/id' في البوت) أو ({'@'}userinfobot)",
"subscriptionDesc": "عشان تلاقي رابط الاشتراك، ادخل على 'التفاصيل'. وكمان ممكن تستخدم نفس الاسم لعدة عملاء.",
"subSortIndex": "ترتيب الاشتراك",
"same": "نفسه",
"inboundInfo": "معلومات الإدخال",
"exportInbound": "تصدير الإدخال",
"import": "استيراد",
"importInbound": "استيراد إدخال",
"periodicTrafficResetTitle": "إعادة تعيين حركة المرور",
"periodicTrafficResetDesc": "إعادة تعيين عداد حركة المرور تلقائيًا في فترات محددة",
"periodicTrafficResetDay": "يوم إعادة التعيين الشهري",
"lastReset": "آخر إعادة تعيين",
"periodicTrafficReset": {
"never": "أبداً",
"daily": "يومياً",
@@ -464,7 +401,6 @@
"obtain": "تم الحصول عليه",
"updateSuccess": "تم التحديث بنجاح",
"logCleanSuccess": "تم مسح السجل",
"inboundsUpdateSuccess": "تم تحديث الواردات بنجاح",
"inboundUpdateSuccess": "تم تحديث الوارد بنجاح",
"inboundCreateSuccess": "تم إنشاء الوارد بنجاح",
"bulkDeleted": "تم حذف {count} إدخال",
@@ -474,7 +410,6 @@
"inboundClientDeleteSuccess": "تم حذف عميل وارد",
"inboundClientUpdateSuccess": "تم تحديث عميل وارد",
"savedNodeOfflineWillSync": "تم الحفظ محليًا. إحدى العُقد الداعمة غير متصلة أو معطّلة — ستتم مزامنة التغيير بمجرد إعادة الاتصال.",
"delDepletedClientsSuccess": "تم حذف جميع العملاء المستنفذين",
"resetAllClientTrafficSuccess": "تم إعادة تعيين كل حركة المرور من العميل",
"resetAllTrafficSuccess": "تم إعادة تعيين كل حركة المرور",
"resetInboundClientTrafficSuccess": "تم إعادة تعيين حركة المرور",
@@ -717,23 +652,6 @@
"peerNumber": "Peer {n}",
"peerNumberConfig": "تكوين Peer {n}"
},
"stream": {
"general": {
"request": "طلب",
"response": "رد",
"name": "اسم",
"value": "قيمة"
},
"tcp": {
"version": "نسخة",
"method": "طريقة",
"path": "المسار",
"status": "الحالة",
"statusDescription": "وصف الحالة",
"requestHeader": "رأس الطلب",
"responseHeader": "رأس الرد"
}
},
"sniffingDestOverride": "تجاوز الوجهة"
},
"clients": {
@@ -747,24 +665,9 @@
"addExternalSubscription": "إضافة اشتراك خارجي",
"noExternalLinks": "لا توجد روابط خارجية بعد.",
"noExternalSubscriptions": "لا توجد اشتراكات خارجية بعد.",
"add": "إضافة عميل",
"edit": "تعديل العميل",
"submitAdd": "إضافة عميل",
"submitEdit": "حفظ التغييرات",
"clientCount": "عدد العملاء",
"bulk": "إضافة مجمعة",
"copyFromInbound": "نسخ العملاء من الاتصال الوارد",
"copyToInbound": "نسخ العملاء إلى",
"copySelected": "نسخ المحدد",
"copySource": "المصدر",
"copyEmailPreview": "معاينة البريد الناتج",
"copySelectSourceFirst": "يرجى تحديد اتصال وارد مصدر أولاً.",
"copyResult": "نتيجة النسخ",
"copyResultSuccess": "تم النسخ بنجاح",
"copyResultNone": "لا شيء للنسخ: لم يتم تحديد عملاء أو أن المصدر فارغ",
"copyResultErrors": "أخطاء النسخ",
"copyFlowLabel": "Flow للعملاء الجدد (VLESS)",
"copyFlowHint": "يُطبَّق على جميع العملاء المنسوخين. اتركه فارغًا للتخطي.",
"selectAll": "تحديد الكل",
"clearAll": "مسح الكل",
"method": "الطريقة",
@@ -775,7 +678,6 @@
"postfix": "لاحقة",
"delayedStart": "البدء بعد أول استخدام",
"expireDays": "المدة (أيام)",
"days": "يوم",
"renew": "تجديد تلقائي",
"renewDesc": "تجديد تلقائي بعد انتهاء الصلاحية. (0 = تعطيل) (الوحدة: يوم)",
"renewDays": "تجديد تلقائي (أيام)",
@@ -798,7 +700,6 @@
"sortExpiringSoonest": "الأقرب انتهاءً",
"has": "يملك",
"hasNot": "لا يملك",
"title": "العملاء",
"actions": "الإجراءات",
"totalGB": "حد البيانات (جيجابايت)",
"totalGBDesc": "حصة البيانات لهذا العميل. 0 = غير محدود.",
@@ -826,8 +727,6 @@
"addClient": "إضافة عميل",
"qrCode": "رمز QR",
"clientInfo": "معلومات العميل",
"delete": "حذف",
"reset": "إعادة ضبط حركة المرور",
"editClient": "تعديل العميل",
"client": "العميل",
"enabled": "مفعّل",
@@ -841,13 +740,11 @@
"noLinks": "لا توجد روابط للمشاركة — قم بإرفاق هذا العميل بأحد الاتصالات الواردة الداعمة للبروتوكول أولاً.",
"link": "الرابط",
"resetNotPossible": "قم بإرفاق هذا العميل بأحد الاتصالات الواردة أولاً.",
"general": "عام",
"resetAllTraffics": "إعادة ضبط حركة مرور كل العملاء",
"resetAllTrafficsTitle": "إعادة ضبط حركة مرور كل العملاء؟",
"resetAllTrafficsContent": "يُعاد ضبط عدّاد الإرسال/الاستقبال لكل عميل إلى الصفر. لا تتأثر الحصص ومواعيد الانتهاء. لا يمكن التراجع.",
"deleteConfirmTitle": "حذف العميل {email}؟",
"deleteConfirmContent": "سيؤدي هذا إلى إزالة العميل من جميع الاتصالات الواردة المرتبطة وحذف سجل حركة مروره. لا يمكن التراجع.",
"deleteSelected": "حذف ({count})",
"adjustSelected": "تعديل ({count})",
"subLinksSelected": "روابط الاشتراك ({count})",
"addToGroupTitle": "إضافة {count} عميل إلى مجموعة",
@@ -869,12 +766,10 @@
"bulkDisableConfirmTitle": "تعطيل {count} عميل؟",
"bulkDisableConfirmContent": "يُعطّل كل عميل محدد على جميع الإدخالات المرفقة. يفقدون الوصول فورًا لكن تُحفَظ سجلاتهم وحركة بياناتهم.",
"selectedCount": "{count} محدد",
"attachSelected": "إرفاق ({count})",
"attachToInboundsTitle": "إرفاق {count} عميل بالواردات",
"attachToInboundsDesc": "يربط {count} عميل المحدد (نفس UUID/كلمة المرور والمرور المشترك) بالواردات المختارة. يحتفظون بارتباطاتهم الحالية.",
"attachToInboundsTargets": "الواردات الهدف",
"attachToInboundsNoTargets": "لا توجد واردات متعددة المستخدمين للارتباط.",
"detachSelected": "فصل ({count})",
"detach": "فصل",
"detachFromInboundsTitle": "فصل {count} عميل من الواردات",
"detachFromInboundsDesc": "يزيل {count} عميل المحدد من الواردات المختارة. الأزواج التي لم يكن العميل مرتبطاً بها يتم تخطيها بصمت. تُحفظ سجلات العملاء (استخدم Delete للإزالة الكاملة).",
@@ -928,8 +823,6 @@
"reverseTagPlaceholder": "Reverse tag اختياري",
"telegramId": "معرّف مستخدم تلغرام",
"telegramIdPlaceholder": "معرّف مستخدم تلغرام رقمي (0 = لا شيء)",
"created": "تاريخ الإنشاء",
"updated": "تاريخ التحديث",
"ipLimit": "حد IP",
"toasts": {
"deleted": "تم حذف العميل",
@@ -952,7 +845,6 @@
}
},
"groups": {
"title": "المجموعات",
"name": "الاسم",
"clientCount": "العملاء",
"totalGroups": "إجمالي المجموعات",
@@ -994,7 +886,6 @@
"removeFromGroupResult": "تمت إزالة {count} عميل من {name}."
},
"nodes": {
"title": "النودز",
"addNode": "إضافة نود",
"editNode": "تحرير العقدة",
"totalNodes": "إجمالي النودز",
@@ -1013,8 +904,6 @@
"apiTokenPlaceholder": "التوكن من صفحة إعدادات البانل البعيد",
"apiTokenHint": "البانل البعيد بيعرض توكن API بتاعه في المصادقة → توكن API.",
"apiTokenKeepHint": "اتركه فارغًا للإبقاء على التوكن الحالي",
"regenerate": "تجديد التوكن",
"regenerateConfirm": "تجديد التوكن هيلغي التوكن الحالي. أي بانل مركزي بيستخدمه هيفقد الصلاحية لحد ما تحدّث التوكن. تكمّل؟",
"allowPrivateAddress": "السماح بالعنوان الخاص",
"allowPrivateAddressHint": "التفعيل فقط للعقد على شبكة خاصة أو VPN.",
"outboundTag": "اتصال صادر",
@@ -1046,7 +935,6 @@
"updatePanel": "تحديث اللوحة",
"updateSelected": "تحديث المحدد ({count})",
"updateAvailable": "تحديث متاح",
"upToDate": "محدّث",
"updateConfirmTitle": "تحديث {count} عقدة إلى أحدث إصدار؟",
"updateConfirmContent": "كل عقدة محددة ستنزّل أحدث إصدار وتعيد التشغيل عليه. يتم تحديث العقد المفعّلة والمتصلة فقط.",
"updateDevChannel": "التحديث إلى قناة التطوير (أحدث كومِت)",
@@ -1447,13 +1335,8 @@
"secretClearUndo": "تراجع عن المسح"
},
"xray": {
"title": "إعدادات Xray",
"save": "احفظ",
"restart": "إعادة تشغيل Xray",
"restartSuccess": "تم إعادة تشغيل Xray بنجاح",
"restartOutputTitle": "مخرجات إعادة تشغيل Xray",
"restartConfirmTitle": "إعادة تشغيل xray؟",
"restartConfirmContent": "يعيد تحميل خدمة xray بالتكوين المحفوظ.",
"stopSuccess": "تم إيقاف Xray بنجاح",
"restartError": "حدث خطأ أثناء إعادة تشغيل Xray.",
"stopError": "حدث خطأ أثناء إيقاف Xray.",
@@ -1463,7 +1346,6 @@
"generalConfigsDesc": "الخيارات دي هتحدد التعديلات العامة.",
"logConfigs": "السجل",
"logConfigsDesc": "السجلات ممكن تأثر على كفاءة السيرفر. ننصح بتفعيلها بحكمة لما تكون محتاجها.",
"blockConfigsDesc": "الخيارات دي هتحجب الترافيك بناءً على بروتوكولات ومواقع محددة.",
"basicRouting": "توجيه أساسي",
"blockConnectionsConfigsDesc": "الخيارات دي هتحجب الترافيك بناءً على الدولة المطلوبة.",
"directConnectionsConfigsDesc": "الاتصال المباشر بيضمن إن الترافيك المعين مايمرش من سيرفر تاني.",
@@ -1473,10 +1355,6 @@
"directdomains": "اتصالات مباشرة للدومينات",
"ipv4Routing": "توجيه IPv4",
"ipv4RoutingDesc": "الخيارات دي هتوجه الترافيك بناءً على وجهة معينة عبر IPv4.",
"warpRouting": "توجيه WARP",
"warpRoutingDesc": "الخيارات دي هتوجه الترافيك بناءً على وجهة معينة عبر WARP.",
"nordRouting": "توجيه NordVPN",
"nordRoutingDesc": "الخيارات دي هتوجه الترافيك بناءً على وجهة معينة عبر NordVPN.",
"Template": "قالب إعدادات Xray المتقدم",
"TemplateDesc": "ملف إعدادات Xray النهائي هيتولد بناءً على القالب ده.",
"FreedomStrategy": "استراتيجية بروتوكول الحرية",
@@ -1490,10 +1368,7 @@
"outboundTestUrlDesc": "الرابط المستخدم عند اختبار اتصال المخرج",
"Torrent": "حظر بروتوكول التورنت",
"Inbounds": "الواردات",
"InboundsDesc": "قبول العملاء المعينين.",
"Outbounds": "الصادرات",
"OutboundSubscriptions": "اشتراكات الصادرات",
"OutboundSubscriptionsDesc": "استورد الصادرات من روابط اشتراك بعيدة (vmess/vless/trojan/ss/...). الوسوم بتفضل ثابتة عشان تستخدمها في موازنات التحميل وقواعد التوجيه. التحديثات بتتم تلقائياً.",
"importRules": "استيراد القواعد",
"exportRules": "تصدير القواعد",
"importOutbounds": "استيراد الصادرات",
@@ -1520,9 +1395,7 @@
"routeTesterMatchedOutbound": "الصادر المطابق",
"routeTesterViaBalancer": "عبر موازن التحميل",
"routeTesterDefaultOutbound": "ما في قاعدة توجيه اتطابقت — الترافيك رايح للصادر الافتراضي (الأول).",
"OutboundsDesc": "حدد مسار الترافيك الصادر.",
"Routings": "قواعد التوجيه",
"RoutingsDesc": "أولوية كل قاعدة مهمة جداً!",
"completeTemplate": "الكل",
"logLevel": "مستوى السجلات",
"logLevelDesc": "مستوى السجل الخاص بالأخطاء، اللي بيوضح المعلومات المطلوبة للتسجيل.",
@@ -1536,13 +1409,9 @@
"maskAddressDesc": "إخفاء عنوان الـ IP؛ لو مفعل، هيستبدل تلقائياً عنوان IP اللي بيظهر في السجل.",
"statistics": "إحصائيات",
"statsInboundUplink": "إحصائيات رفع الإدخال",
"statsInboundUplinkDesc": "تفعيل جمع الإحصائيات لترافيك الرفع لكل بروكسي من الإدخالات.",
"statsInboundDownlink": "إحصائيات تنزيل الإدخال",
"statsInboundDownlinkDesc": "تفعيل جمع الإحصائيات لترافيك التنزيل لكل بروكسي من الإدخالات.",
"statsOutboundUplink": "إحصائيات رفع المخرجات",
"statsOutboundUplinkDesc": "تفعيل جمع الإحصائيات لترافيك الرفع لكل بروكسي من المخرجات.",
"statsOutboundDownlink": "إحصائيات تنزيل المخرجات",
"statsOutboundDownlinkDesc": "تفعيل جمع الإحصائيات لترافيك التنزيل لكل بروكسي من المخرجات.",
"connectionLimits": "حدود الاتصال",
"connectionLimitsDesc": "سياسات على مستوى الاتصال لمستوى المستخدم 0. اترك الحقل فارغًا لاستخدام القيمة الافتراضية لـ Xray.",
"connIdle": "مهلة الخمول",
@@ -1552,18 +1421,10 @@
"bufferSizePlaceholder": "تلقائي",
"seconds": "ثانية",
"rules": {
"first": "أول",
"last": "آخر",
"up": "فوق",
"down": "تحت",
"source": "المصدر",
"dest": "الوجهة",
"inbound": "إدخال",
"outbound": "مخرج",
"balancer": "موازن",
"info": "معلومات",
"add": "أضف قاعدة",
"edit": "عدل القاعدة",
"useComma": "عناصر مفصولة بفواصل"
},
"routing": {
@@ -1604,7 +1465,6 @@
"ruleN": "القاعدة {n}",
"action": "الإجراء",
"redirect": "Redirect",
"fragment": "Fragment",
"finalRules": "القواعد النهائية",
"overrideXrayPrivateIp": "تجاوز حظر IP الخاص الافتراضي في Xray",
"blockDelay": "تأخير الحظر (ms)",
@@ -1630,43 +1490,17 @@
"keepAliveInterval": "فاصل keep alive",
"markFwmark": "Mark (fwmark)",
"interface": "الواجهة",
"ipv6Only": "IPv6 فقط",
"acceptProxyProtocol": "قبول proxy protocol",
"proxyProtocol": "Proxy protocol",
"tcpUserTimeoutMs": "TCP user timeout (ms)",
"tcpKeepAliveIdleS": "TCP keep-alive idle (ثانية)"
},
"outbound": {
"addOutbound": "أضف مخرج",
"addReverse": "أضف عكسي",
"editOutbound": "عدل المخرج",
"editReverse": "عدل العكسي",
"reverseTag": "وسم العكسي",
"reverseTagDesc": "وسم الخروج لبروكسي VLESS العكسي البسيط. اتركه فارغاً لتعطيله.",
"reverseTagPlaceholder": "وسم الخروج (اتركه فارغاً للتعطيل)",
"tag": "الوسم",
"tagDesc": "تاج فريد",
"address": "العنوان",
"egress": "Egress",
"egressHint": "Run an HTTP test to show egress IP and country.",
"reverse": "عكسي",
"domain": "النطاق",
"type": "النوع",
"bridge": "Bridge",
"portal": "Portal",
"link": "الرابط",
"intercon": "تواصل",
"settings": "إعدادات",
"accountInfo": "معلومات الحساب",
"outboundStatus": "حالة المخرج",
"sendThrough": "أرسل من خلال",
"targetStrategy": "استراتيجية الوجهة",
"test": "اختبار",
"testResult": "نتيجة الاختبار",
"testing": "جاري اختبار الاتصال...",
"testSuccess": "الاختبار ناجح",
"testFailed": "فشل الاختبار",
"testError": "فشل اختبار المخرج",
"modeRealDelay": "التأخير الفعلي",
"testModeTooltip": "TCP: فحص dial سريع. HTTP: طلب كامل عبر xray. التأخير الفعلي: الوقت الكامل شاملاً إنشاء الاتصال.",
"testAll": "اختبار الكل",
@@ -1674,14 +1508,10 @@
"breakdownConnect": "اتصال البروكسي",
"breakdownTls": "TLS عبر الصادر",
"breakdownTtfb": "أول بايت",
"nordvpn": "NordVPN",
"accessToken": "رمز الوصول",
"country": "الدولة",
"server": "الخادم",
"city": "المدينة",
"allCities": "كل المدن",
"privateKey": "المفتاح الخاص",
"load": "الحمل",
"moveToTop": "نقل إلى الأعلى"
},
"outboundSub": {
@@ -1711,16 +1541,11 @@
"active": "الاشتراكات النشطة",
"empty": "مفيش اشتراكات لسه. أضف واحد من فوق.",
"colRemark": "ملاحظة",
"colPrefix": "بادئة",
"colInterval": "الفاصل",
"colLastFetch": "آخر جلب",
"colEnabled": "مفعّل",
"auto": "تلقائي",
"never": "أبداً",
"yes": "نعم",
"no": "لا",
"refreshNow": "حدّث الآن",
"lastError": "آخر خطأ",
"deleteConfirm": "تحذف الاشتراك ده؟",
"restartHint": "بعد الإضافة أو التحديث، أعد تشغيل Xray (أو استنى إعادة التحميل التلقائي اللي جاية) عشان تفعّل الصادرات.",
"fromSubsTitle": "من اشتراكات الصادرات (للقراءة فقط)",
@@ -1737,8 +1562,6 @@
"tabBalancerSettings": "إعدادات الموازن",
"tabObservatory": "المرصد",
"observatory": {
"title": "المرصد",
"burstTitle": "مرصد Burst",
"autoManaged": "تتم إدارة المراصد تلقائيًا من الموازنات لديك. اضبط طريقة الفحص بالأسفل؛ تتبع الوجهات الصادرة المراقَبة محدِّدات الموازن.",
"emptyHint": "لا يوجد مرصد اتصال نشط. تتم إضافة واحد تلقائيًا عند إنشاء موازن Least Ping أو Least Load — أو موازن Random / Round-robin مع fallback — حتى تتمكن الموازنات المعتمدة على المرصد من فحص صحة الوجهات الصادرة قبل اختيار الهدف.",
"mixedLegacy": "يحتوي هذا الإعداد على Observatory و Burst Observatory معًا. يستخدم Xray مرصدًا عالميًا واحدًا، لذلك هذه الحالة القديمة المختلطة غير مدعومة؛ حفظ الموازنات سيحوّلها إلى مرصد واحد.",
@@ -1772,12 +1595,8 @@
"balancerRemoved": "الموازن {tag} — أُزيل (لا توجد أهداف متبقية)"
},
"balancer": {
"addBalancer": "أضف موازن تحميل",
"editBalancer": "عدل موازن التحميل",
"balancerStrategy": "استراتيجية الموازن",
"balancerSelectors": "المحددات",
"tag": "الوسم",
"tagDesc": "تاج فريد",
"tagDuplicate": "الوسم مستخدم بالفعل من قبل موازن آخر",
"tagPlaceholder": "وسم موازن فريد",
"selector": "المحدد",
@@ -1789,7 +1608,6 @@
"tolerance": "التحمل",
"baselines": "Baselines",
"costs": "Costs",
"balancerDesc": "ماينفعش تستخدم balancerTag و outboundTag مع بعض. لو اتستخدموا مع بعض، outboundTag هو اللي هيشتغل.",
"costMatch": "نمط الوسم",
"costValue": "الوزن",
"costRegexp": "مطابقة تعبير نمطي",
@@ -1804,14 +1622,10 @@
"publicKey": "المفتاح العام",
"allowedIPs": "عناوين IP المسموح بها",
"endpoint": "النهاية",
"psk": "المفتاح المشترك",
"domainStrategy": "استراتيجية الدومين"
},
"tun": {
"nameDesc": "اسم واجهة TUN. القيمة الافتراضية هي 'xray0'",
"mtuDesc": "وحدة النقل الأقصى. الحد الأقصى لحجم حزم البيانات. القيمة الافتراضية هي 1500",
"userLevel": "مستوى المستخدم",
"userLevelDesc": "ستستخدم جميع الاتصالات المُرسلة عبر هذا الإدخال مستوى المستخدم هذا. القيمة الافتراضية هي 0"
"userLevel": "مستوى المستخدم"
},
"nord": {
"accessToken": "Access token",
@@ -1896,7 +1710,6 @@
},
"fakedns": {
"add": "أضف Fake DNS",
"edit": "عدل Fake DNS",
"ipPool": "نطاق IP Pool",
"poolSize": "حجم المجموعة"
},
@@ -2032,7 +1845,6 @@
"add": "إضافة",
"month": "شهر",
"months": "أشهر",
"day": "يوم",
"days": "أيام",
"hours": "ساعات",
"minutes": "دقائق",
@@ -2071,7 +1883,6 @@
"userSaved": "✅ حفظت بيانات مستخدم Telegram.",
"loginSuccess": "✅ تسجيل الدخول للبانل تم بنجاح.\r\n",
"loginFailed": "❗️فشل محاولة تسجيل الدخول للبانل.\r\n",
"2faFailed": "فشل 2FA",
"report": "🕰 التقارير المجدولة: {{ .RunTime }}\r\n",
"datetime": "⏰ التاريخ والوقت: {{ .DateTime }}\r\n",
"hostname": "💻 المضيف: {{ .Hostname }}\r\n",
@@ -2104,7 +1915,6 @@
"download": "🔽 التنزيل: ↓{{ .Download }}\r\n",
"total": "📊 الإجمالي: ↑↓{{ .UpDown }} / {{ .Total }}\r\n",
"TGUser": "👤 مستخدم Telegram: {{ .TelegramID }}\r\n",
"exhaustedMsg": "🚨 نفذ {{ .Type }}:\r\n",
"exhaustedCount": "🚨 عدد النفاذ لـ {{ .Type }}:\r\n",
"onlinesCount": "🌐 العملاء الأونلاين: {{ .Count }}\r\n",
"disabled": "🛑 معطل: {{ .Disabled }}\r\n",
@@ -2113,16 +1923,10 @@
"refreshedOn": "\r\n📋🔄 اتحدّث في: {{ .Time }}\r\n\r\n",
"yes": "✅ أيوه",
"no": "❌ لا",
"received_id": "🔑📥 الـ ID اتحدث.",
"received_password": "🔑📥 الباسورد اتحدث.",
"received_email": "📧📥 الإيميل اتحدث.",
"received_comment": "💬📥 التعليق اتحدث.",
"id_prompt": "🔑 الـ ID الافتراضي: {{ .ClientId }}\n\nادخل الـ ID بتاعك.",
"pass_prompt": "🔑 الباسورد الافتراضي: {{ .ClientPassword }}\n\nادخل الباسورد بتاعك.",
"email_prompt": "📧 الإيميل الافتراضي: {{ .ClientEmail }}\n\nادخل الإيميل بتاعك.",
"comment_prompt": "💬 التعليق الافتراضي: {{ .ClientComment }}\n\nادخل تعليقك.",
"inbound_client_data_id": "🔄 الدخول: {{ .InboundRemark }}\n\n🔑 المعرف: {{ .ClientId }}\n📧 البريد الإلكتروني: {{ .ClientEmail }}\n📊 الترافيك: {{ .ClientTraffic }}\n📅 تاريخ الانتهاء: {{ .ClientExp }}\n🌐 حدّ IP: {{ .IpLimit }}\n💬 تعليق: {{ .ClientComment }}\n\nدلوقتي تقدر تضيف العميل على الدخول!",
"inbound_client_data_pass": "🔄 الدخول: {{ .InboundRemark }}\n\n🔑 كلمة المرور: {{ .ClientPass }}\n📧 البريد الإلكتروني: {{ .ClientEmail }}\n📊 الترافيك: {{ .ClientTraffic }}\n📅 تاريخ الانتهاء: {{ .ClientExp }}\n🌐 حدّ IP: {{ .IpLimit }}\n💬 تعليق: {{ .ClientComment }}\n\nدلوقتي تقدر تضيف العميل على الدخول!",
"cancel": "❌ العملية اتلغت! \n\nممكن تبدأ من /start في أي وقت. 🔄",
"error_add_client": "⚠️ خطأ:\n\n {{ .error }}",
"using_default_value": "تمام، هشيل على القيمة الافتراضية. 😊",
@@ -2139,8 +1943,6 @@
"eventXrayCrashError": "الخطأ: {{ .Error }}",
"eventNodeDown": "العقدة {{ .Name }} غير متصلة",
"eventNodeUp": "العقدة {{ .Name }} متصلة",
"eventCPUHigh": "ارتفاع استخدام المعالج",
"eventCPUHighDetail": "المعالج: {{ .Detail }}",
"eventLoginFallback": "فشل تسجيل الدخول من {{ .Source }}",
"memoryThreshold": "استخدام الذاكرة {{ .Percent }}% يتجاوز الحد {{ .Threshold }}%"
},
@@ -2181,11 +1983,8 @@
"submitDisable": "إرسال كمعطّل ☑️",
"submitEnable": "إرسال كمفعّل ✅",
"use_default": "🏷️ استخدام الإعدادات الافتراضية",
"change_id": "⚙️🔑 ID",
"change_password": "⚙️🔑 كلمة السر",
"change_email": "⚙️📧 البريد",
"change_comment": "⚙️💬 تعليق",
"change_flow": "⚙️🚦 Flow",
"ResetAllTraffics": "إعادة ضبط جميع الترافيك",
"SortedTrafficUsageReport": "تقرير استخدام الترافيك المرتب"
},
@@ -2214,31 +2013,16 @@
}
},
"email": {
"subjectOutboundDown": "الصادر {{ .Tag }} غير متصل",
"subjectOutboundUp": "الصادر {{ .Tag }} متصل",
"subjectXrayCrash": "تعطّل Xray",
"subjectCPUHigh": "ارتفاع استخدام المعالج",
"subjectLoginSuccess": "نجح تسجيل الدخول",
"subjectLoginFailed": "فشل تسجيل الدخول",
"titleOutboundDown": "الصادر غير متصل",
"titleOutboundUp": "الصادر متصل",
"titleXrayCrash": "تعطّل Xray",
"titleCPUHigh": "ارتفاع استخدام المعالج",
"titleLoginSuccess": "نجح تسجيل الدخول",
"titleLoginFailed": "فشل تسجيل الدخول",
"labelStatus": "الحالة",
"labelOutbound": "الصادر",
"labelNode": "العقدة",
"labelError": "الخطأ",
"labelDelay": "التأخير",
"labelDetail": "التفاصيل",
"labelUsername": "اسم المستخدم",
"labelIP": "IP",
"labelReason": "السبب",
"labelSource": "المصدر",
"labelTime": "الوقت",
"statusCrashed": "متعطّل",
"statusRunning": "يعمل",
"statusHigh": "مرتفع",
"statusSuccess": "نجاح",
"statusFailed": "فشل",