ITEM6 B4: frontend reshaping — xray page retired, stats switches to settings, template read paths closed

- Delete the xray settings page (routes/menu/title), geodata UI/service,
  XraySettingController/Service and routing-sync write paths; the stored
  xrayTemplateConfig row loses its last readers (GetXrayConfigTemplate now
  returns the embedded factory template; B1 already deleted the row).
- Settings GeneralTab gains the four trafficStatsSwitches switches
  (settings.trafficStatsSwitches, B1) with the dual warning copy; entity
  AllSetting carries the key end to end (TestTrafficStatsSwitchesPlumbing).
- Tag-directory consumers (panelOutbound, mtproto egress, node/host
  outbound pickers) move from POST /xray/ to GET /server/outboundDirectory.
- Shared Mux/Sockopt forms and balancer helpers relocated to lib/xray;
  converter preserves sniffing ips/domains exclusions into the panel
  sidecar instead of dropping them (B2 gap closed by retention).
- Freedom final-rules DB fix seeders retired; getDefaultJsonConfig
  endpoint removed (no in-repo consumer); locales pruned to referenced
  keys (pages.xray 331 -> 68) plus the five new settings keys.
This commit is contained in:
Muse
2026-10-22 23:40:54 +00:00
parent 1762e54d5f
commit 277838d7ca
151 changed files with 780 additions and 22140 deletions
+10 -297
View File
@@ -98,9 +98,6 @@
"clients": "Klien",
"nodes": "Node",
"settings": "Pengaturan Panel",
"xray": "Konfigurasi Xray",
"routing": "Pengalihan",
"outbounds": "Outbound",
"donate": "Donasi",
"hosts": "Host",
"docs": "Dokumentasi",
@@ -272,7 +269,6 @@
"clone": "Duplikat",
"resetAllTraffic": "Reset Semua Traffic Masuk",
"resetAllTrafficTitle": "Reset Semua Traffic Masuk",
"resetAllTrafficContent": "Apakah Anda yakin ingin mereset traffic semua masuk?",
"email": "Email",
"IPLimit": "Batas IP",
"IPLimitlog": "Log IP",
@@ -1211,269 +1207,29 @@
"tgNotifyBackup": "Cadangan Database",
"tgNotifyBackupDesc": "Kirim berkas cadangan database dengan laporan.",
"tgTestFailed": "Uji Telegram gagal",
"tgTestSuccess": "Pesan uji terkirim ke Telegram"
"tgTestSuccess": "Pesan uji terkirim ke Telegram",
"trafficStatsInboundUplink": "Inbound Upload Accounting",
"trafficStatsInboundDownlink": "Inbound Download Accounting",
"trafficStatsOutboundUplink": "Outbound Upload Accounting",
"trafficStatsOutboundDownlink": "Outbound Download Accounting",
"trafficStatsDesc": "Applies to the whole network. A direction pair (inbound or outbound) is counted only while both of its switches are on. While counting is off, that traffic is never recorded and the gap is permanent — it is not backfilled later — and expiry / over-quota auto-disable loses the data it relies on."
},
"xray": {
"save": "Simpan",
"basicTemplate": "Dasar",
"advancedTemplate": "Lanjutan",
"generalConfigs": "Strategi Umum",
"generalConfigsDesc": "Opsi ini akan menentukan penyesuaian strategi umum.",
"logConfigs": "Log",
"logConfigsDesc": "Log dapat mempengaruhi efisiensi server Anda. Disarankan untuk mengaktifkannya dengan bijak hanya jika diperlukan",
"basicRouting": "Perutean Dasar",
"blockConnectionsConfigsDesc": "Opsi ini akan memblokir lalu lintas berdasarkan negara yang diminta.",
"directConnectionsConfigsDesc": "Koneksi langsung memastikan bahwa lalu lintas tertentu tidak dialihkan melalui server lain.",
"blockips": "Blokir IP",
"blockdomains": "Blokir Domain",
"directips": "IP Langsung",
"directdomains": "Domain Langsung",
"ipv4Routing": "Perutean IPv4",
"ipv4RoutingDesc": "Opsi ini akan mengalihkan lalu lintas berdasarkan tujuan tertentu melalui IPv4.",
"FreedomStrategy": "Strategi Protokol Freedom",
"FreedomStrategyDesc": "Atur strategi output untuk jaringan dalam Protokol Freedom.",
"FreedomHappyEyeballs": "Freedom Happy Eyeballs (IPv4/IPv6)",
"FreedomHappyEyeballsDesc": "Panggilan dual-stack untuk outbound langsung (freedom) — berguna pada server keluar dengan IPv4 dan IPv6.",
"FreedomHappyEyeballsTryDelayDesc": "Milidetik sebelum mencoba keluarga alamat lainnya. 150–250 ms adalah titik awal yang baik.",
"RoutingStrategy": "Strategi Pengalihan Keseluruhan",
"RoutingStrategyDesc": "Atur strategi pengalihan lalu lintas keseluruhan untuk menyelesaikan semua permintaan.",
"Torrent": "Blokir Protokol BitTorrent",
"Inbounds": "Inbound",
"Outbounds": "Outbound",
"importRules": "Impor aturan",
"exportRules": "Ekspor aturan",
"importOutbounds": "Impor outbound",
"exportOutbounds": "Ekspor outbound",
"importInvalidJson": "JSON tidak valid — diharapkan berupa array atau objek dengan kunci yang sesuai.",
"metricsListen": "Endpoint metrik",
"metricsListenDesc": "Tampilkan metrik gaya Prometheus dari Xray pada alamat:port ini (mis. 127.0.0.1:11111). Biarkan kosong untuk menonaktifkan. Ikat ke localhost dan reverse-proxy — endpoint ini tanpa autentikasi.",
"metricsTag": "Tag metrik",
"Balancers": "Penyeimbang",
"balancerTagRequired": "Tag wajib diisi",
"balancerSelectorRequired": "Pilih setidaknya satu outbound",
"routeTester": "Uji Rute",
"routeTesterDesc": "Tanyakan kepada Xray yang berjalan outbound mana yang akan menangani koneksi. Tidak ada lalu lintas yang dikirim — keputusan langsung datang dari mesin routing langsung.",
"routeTesterDest": "Domain atau IP",
"routeTesterPort": "Port",
"routeTesterInbound": "Inbound",
"routeTesterProtocol": "Protokol yang terdeteksi",
"routeTesterTest": "Uji Rute",
"routeTesterMatchedOutbound": "Outbound yang cocok",
"routeTesterViaBalancer": "melalui penyeimbang",
"routeTesterDefaultOutbound": "Tidak ada aturan routing yang cocok — lalu lintas menuju outbound default (pertama).",
"Routings": "Aturan Pengalihan",
"logLevel": "Tingkat Log",
"logLevelDesc": "Tingkat log untuk log kesalahan, menunjukkan informasi yang perlu dicatat.",
"accessLog": "Log Akses",
"accessLogDesc": "Jalur file untuk log akses. Nilai khusus 'tidak ada' menonaktifkan log akses",
"errorLog": "Catatan eror",
"errorLogDesc": "Jalur file untuk log kesalahan. Nilai khusus 'tidak ada' menonaktifkan log kesalahan",
"dnsLog": "Log DNS",
"dnsLogDesc": "Apakah akan mengaktifkan log kueri DNS",
"maskAddress": "Alamat Masker",
"maskAddressDesc": "Masker alamat IP, ketika diaktifkan, akan secara otomatis mengganti alamat IP yang muncul di log.",
"statistics": "Statistik",
"statsInboundUplink": "Statistik Unggah Masuk",
"statsInboundDownlink": "Statistik Unduh Masuk",
"statsOutboundUplink": "Statistik Unggah Keluar",
"statsOutboundDownlink": "Statistik Unduh Keluar",
"connectionLimits": "Batas Koneksi",
"connectionLimitsDesc": "Kebijakan tingkat koneksi untuk level pengguna 0. Biarkan kolom kosong untuk menggunakan nilai bawaan Xray.",
"connIdle": "Batas Waktu Idle",
"connIdleDesc": "Menutup koneksi setelah idle selama sekian detik. Menurunkannya membebaskan memori dan file descriptor lebih cepat pada server yang sibuk (bawaan Xray: 300).",
"bufferSize": "Ukuran Buffer",
"bufferSizeDesc": "Ukuran buffer internal per koneksi dalam KB. Setel ke 0 untuk meminimalkan penggunaan memori pada server ber-RAM rendah (nilai bawaan Xray bergantung pada platform).",
"bufferSizePlaceholder": "otomatis",
"seconds": "detik",
"rules": {
"source": "Sumber",
"dest": "Tujuan",
"inbound": "Masuk",
"useComma": "Item yang dipisahkan koma"
},
"routing": {
"dragToReorder": "Seret untuk mengurutkan ulang"
},
"geoBrowser": {
"title": "Kategori geo",
"openTooltip": "Jelajahi kategori geo",
"database": "Basis data",
"searchCategory": "Cari kategori",
"searchEntries": "Filter di dalam kategori",
"selectFound": "Pilih hasil pencarian",
"selected": "Dipilih {count}",
"clearAll": "Hapus semua",
"apply": "Terapkan",
"emptySelection": "Centang kategori — semuanya menjadi token aturan",
"pickCategory": "Pilih kategori di sebelah kiri untuk melihat isinya",
"noMatches": "Tidak ada yang ditemukan",
"noFiles": "Tidak ada basis data geo di folder Xray",
"noFilesHint": "Akan muncul setelah Xray mengunduh geosite.dat dan geoip.dat",
"fileMeta": "{count} kategori · {size} · diperbarui {date}",
"entriesCount": "{count} entri",
"subnetsCount": "{count} subnet",
"shownRange": "Menampilkan {from}–{to} dari {total}",
"loadFailed": "Gagal memuat basis data geo",
"checkFailed": "Tidak dapat memeriksa nilai ini terhadap basis data geo",
"parseFailed": "Berkas rusak atau bukan basis data geosite/geoip",
"tooLarge": "Terlalu besar untuk ditelusuri",
"unknownCategories": "Tidak ada di basis data: {tokens}",
"missingDatabase": "Berkas basis data tidak ditemukan: {tokens} — tambahkan di bagian Geodata",
"unknownAttribute": "Atribut tidak ditemukan, aturan tidak akan cocok dengan apa pun: {tokens}",
"invalidToken": "Xray tidak akan menerima entri ini: {tokens}",
"wrongKind": "Jenis basis data salah untuk kolom ini: {tokens}"
},
"ruleForm": {
"sourceIps": "IP sumber",
"sourcePort": "Port sumber",
"vlessRoute": "Rute VLESS",
"attributes": "Atribut",
"value": "Nilai",
"user": "Pengguna",
"userPlaceholder": "Pilih pengguna",
"userEmpty": "Tidak ada pengguna tersedia",
"userLoadError": "Gagal memuat pengguna",
"inboundTags": "Tag inbound",
"outboundTag": "Tag outbound",
"balancerTag": "Tag balancer",
"balancerTagTooltip": "Mengarahkan trafik melalui salah satu balancer yang dikonfigurasi"
"inbound": "Masuk"
},
"outboundForm": {
"tagDuplicate": "Tag sudah digunakan oleh outbound lain",
"tagRequired": "Tag wajib diisi",
"tagPlaceholder": "tag-unik",
"localIpPlaceholder": "IP lokal",
"dialerProxyPlaceholder": "Pilih outbound untuk dirantai",
"dialerProxyHint": "Hubungkan outbound ini melalui outbound lain (berdasarkan tag) untuk membuat rantai proxy. Kosongkan untuk terhubung langsung.",
"targetStrategyHint": "Cara domain tujuan diresolusi sebelum terhubung: AsIs (default) mengirim apa adanya, UseIP… meresolusi dengan fallback, ForceIP… wajib berhasil diresolusi.",
"addressRequired": "Alamat wajib diisi",
"portRequired": "Port wajib diisi",
"optional": "opsional",
"udpOverTcp": "UDP over TCP",
"uotVersion": "Versi UoT",
"inboundTag": "Tag inbound",
"inboundTagPlaceholder": "tag inbound yang digunakan dalam aturan routing",
"responseType": "Tipe respons",
"rewriteNetwork": "Tulis ulang jaringan",
"unchanged": "(tidak berubah)",
"unchangedAddress": "(tidak berubah) mis. 1.1.1.1",
"rules": "Aturan",
"ruleN": "Aturan {n}",
"action": "Aksi",
"redirect": "Redirect",
"finalRules": "Aturan akhir",
"overrideXrayPrivateIp": "Timpa blok IP privat default Xray",
"blockDelay": "Penundaan blokir (ms)",
"reverseSniffing": "Sniffing terbalik",
"reserved": "Dicadangkan",
"minUploadInterval": "Min. interval upload (ms)",
"maxUploadSizeBytes": "Ukuran upload maks. (byte)",
"uplinkChunkSize": "Ukuran chunk Uplink",
"noGrpcHeader": "Tanpa header gRPC",
"maxConcurrency": "Maks. konkurensi",
"maxConnections": "Maks. koneksi",
"maxReuseTimes": "Maks. pemakaian ulang",
"maxRequestTimes": "Maks. permintaan",
"maxReusableSecs": "Maks. detik dapat dipakai ulang",
"keepAlivePeriod": "Periode keep alive",
"authPassword": "Kata sandi auth",
"visionTestpre": "Vision testpre",
"serverNamePlaceholder": "nama server",
"verifyPeerName": "Verifikasi nama peer",
"pinnedSha256": "SHA256 pinned",
"shortId": "Short ID",
"sockopts": "Sockopts",
"keepAliveInterval": "Interval keep alive",
"markFwmark": "Mark (fwmark)",
"interface": "Interface",
"proxyProtocol": "Proxy protocol",
"tcpUserTimeoutMs": "TCP user timeout (ms)",
"tcpKeepAliveIdleS": "TCP keep-alive idle (d)"
},
"outbound": {
"tag": "Tag",
"outboundStatus": "Status Keluar",
"sendThrough": "Kirim Melalui",
"targetStrategy": "Strategi Target",
"country": "Negara",
"server": "Server",
"city": "Kota",
"allCities": "Semua Kota",
"moveToTop": "Pindahkan ke atas"
},
"outboundSub": {
"manage": "Langganan",
"title": "Langganan Outbound",
"remark": "Catatan (opsional)",
"remarkPlaceholder": "mis. node HK",
"url": "URL langganan",
"urlPlaceholder": "https://... (daftar tautan base64)",
"tagPrefix": "Awalan tag",
"tagPrefixPlaceholder": "hk-",
"interval": "Interval pembaruan",
"hours": "j",
"minutes": "mnt",
"intervalHint": "Default 10 menit. Tugas latar belakang memeriksa secara berkala; setiap langganan hanya diambil ulang ketika intervalnya sendiri telah terlewati.",
"enabled": "Aktif",
"allowPrivate": "Izinkan alamat privat",
"allowPrivateHint": "Izinkan localhost / LAN / IP privat untuk URL langganan ini. Nonaktif secara default demi keamanan — aktifkan hanya untuk sumber lokal yang tepercaya.",
"prepend": "Sebelum outbound manual",
"prependHint": "Tempatkan outbound dari langganan ini sebelum outbound manual Anda, sehingga salah satunya dapat menjadi default.",
"preview": "Pratinjau",
"previewEmpty": "Tidak ada outbound yang ditemukan di URL ini.",
"refreshAll": "Segarkan semua",
"statusOk": "OK",
"toastUpdated": "Langganan diperbarui",
"addButton": "Tambah",
"active": "Langganan aktif",
"empty": "Belum ada langganan. Tambahkan satu di atas.",
"colRemark": "Catatan",
"colLastFetch": "Pengambilan terakhir",
"colEnabled": "Aktif",
"auto": "otomatis",
"never": "tidak pernah",
"refreshNow": "Segarkan sekarang",
"deleteConfirm": "Hapus langganan ini?",
"restartHint": "Setelah menambahkan atau menyegarkan, mulai ulang Xray (atau tunggu muat ulang otomatis berikutnya) agar outbound menjadi aktif.",
"fromSubsTitle": "Dari langganan outbound (hanya-baca)",
"fromSubsDesc": "Diimpor dari langganan aktif Anda. Kelola di panel Langganan di atas.",
"toastLoadFailed": "Gagal memuat langganan",
"toastUrlRequired": "URL langganan wajib diisi",
"toastAdded": "Langganan ditambahkan",
"toastAddFailed": "Gagal menambahkan langganan",
"toastRefreshed": "Disegarkan",
"toastRefreshFailed": "Gagal menyegarkan",
"toastDeleted": "Dihapus",
"toastDeleteFailed": "Gagal menghapus"
},
"pia": {
"menu": "PIA",
"username": "Nama pengguna PIA",
"password": "Kata sandi PIA",
"account": "Akun",
"region": "Wilayah",
"allRegions": "Semua wilayah",
"noServers": "Tidak ada server untuk negara yang dipilih",
"outboundAdded": "Outbound PIA ditambahkan",
"outboundUpdated": "Outbound PIA diperbarui",
"addedServers": "Server yang ditambahkan",
"alreadyAdded": "Server ini sudah ada di daftar outbound. Gunakan {reset} untuk memperbarui kuncinya.",
"provisionFailed": "Gagal membuat outbound PIA. Coba lagi."
},
"observatory": {
"deleteAlsoObservatory": "Ini balancer terakhir yang memakai Observatory, jadi itu juga akan dihapus.",
"deleteAlsoBurst": "Ini balancer terakhir yang memakai Burst Observatory, jadi itu juga akan dihapus."
},
"refCleanup": {
"header": "Menghapus ini juga memperbarui perutean Anda:",
"ruleRemoved": "Aturan {label} — dihapus (tidak ada tujuan tersisa)",
"ruleModified": "Aturan {label} — dipertahankan (kini memakai {keeps})",
"balancerRemoved": "Balancer {tag} — dihapus (tidak ada target tersisa)"
},
"balancer": {
"balancerStrategy": "Strategi",
"balancerFallbackCycle": "Tidak dapat mengatur load balancer ini sebagai fallback — akan menciptakan dependensi siklik.",
"reservedPrefix": "Awalan _bl_ dicadangkan untuk objek loopback internal load balancer"
"keepAlivePeriod": "Periode keep alive"
},
"wireguard": {
"secretKey": "Kunci Rahasia",
@@ -1481,7 +1237,6 @@
"subnetIp": "Subnet",
"subnetCidr": "CIDR Subnet",
"allowedIPs": "IP yang Diizinkan",
"endpoint": "Titik Akhir",
"domainStrategy": "Strategi Domain"
},
"amneziawg": {
@@ -1537,48 +1292,7 @@
},
"tun": {
"userLevel": "Level Pengguna"
},
"nord": {
"accessToken": "Access token",
"privateKey": "Kunci privat",
"noServers": "Tidak ada server ditemukan untuk negara yang dipilih",
"noPublicKey": "Server yang dipilih tidak mengumumkan kunci publik NordLynx.",
"outboundAdded": "Outbound NordVPN ditambahkan",
"outboundUpdated": "Outbound NordVPN diperbarui"
},
"warp": {
"changeIp": "Ganti IP",
"changeIpSuccess": "IP WARP berhasil diganti!",
"autoUpdateIp": "Perbarui Alamat IP Otomatis",
"intervalDays": "Interval (Hari)",
"intervalDesc": "0 untuk menonaktifkan. Mengganti alamat IP secara otomatis.",
"licenseError": "Gagal mengatur lisensi WARP.",
"fetchFirst": "Ambil konfig WARP terlebih dahulu.",
"createAccount": "Buat akun WARP",
"accessToken": "Access token",
"deviceId": "ID perangkat",
"licenseKey": "Kunci lisensi",
"privateKey": "Kunci privat",
"deleteAccount": "Hapus akun",
"settings": "Pengaturan",
"licenseKeyLabel": "Kunci lisensi WARP / WARP+",
"key": "Kunci",
"keyPlaceholder": "kunci WARP+ 26 karakter",
"accountInfo": "Info akun",
"deviceName": "Nama perangkat",
"deviceModel": "Model perangkat",
"deviceEnabled": "Perangkat aktif",
"accountType": "Tipe akun",
"role": "Peran",
"warpPlusData": "Data WARP+",
"quota": "Kuota",
"usage": "Penggunaan",
"addOutbound": "Tambah outbound"
},
"dns": {},
"fakedns": {},
"defaultOutbound": "Outbound default",
"defaultOutboundDesc": "Lalu lintas tanpa aturan routing memakai outbound ini (yang pertama dalam daftar)."
}
},
"hosts": {
"addHost": "Tambah Host",
@@ -1876,6 +1590,5 @@
"chooseClient": "Pilih Klien untuk Inbound {{ .Inbound }}",
"chooseInbound": "Pilih Inbound"
}
},
"email": {}
}
}