diff --git a/apps/desktop/src/components/editor/__tests__/AiAssistant.writeConfirmationProposal.spec.ts b/apps/desktop/src/components/editor/__tests__/AiAssistant.writeConfirmationProposal.spec.ts index 47ef76ee4c..a363a8bd18 100644 --- a/apps/desktop/src/components/editor/__tests__/AiAssistant.writeConfirmationProposal.spec.ts +++ b/apps/desktop/src/components/editor/__tests__/AiAssistant.writeConfirmationProposal.spec.ts @@ -2,7 +2,7 @@ import { readFileSync } from "node:fs"; import { describe, expect, it } from "vitest"; const source = readFileSync(new URL("../AiAssistant.vue", import.meta.url), "utf8"); -const localePaths = ["az", "en", "es", "it", "ja", "ko", "pt-BR", "ru", "tr", "zh-CN", "zh-TW"]; +const localePaths = ["az", "en", "es", "id", "it", "ja", "ko", "pt-BR", "ru", "tr", "zh-CN", "zh-TW"]; describe("AI assistant write confirmation replacement", () => { it("renders a localized confirmation from the backend's semantic event", () => { diff --git a/apps/desktop/src/i18n/__tests__/backendErrors.spec.ts b/apps/desktop/src/i18n/__tests__/backendErrors.spec.ts index 1fced962e1..4cff70f46c 100644 --- a/apps/desktop/src/i18n/__tests__/backendErrors.spec.ts +++ b/apps/desktop/src/i18n/__tests__/backendErrors.spec.ts @@ -6,6 +6,7 @@ import { BackendErrorException, formatError, normalizeBackendError, sanitizeBack import az from "@/i18n/locales/az"; import en from "@/i18n/locales/en"; import es from "@/i18n/locales/es"; +import id from "@/i18n/locales/id"; import it from "@/i18n/locales/it"; import ja from "@/i18n/locales/ja"; import ko from "@/i18n/locales/ko"; @@ -20,6 +21,7 @@ const LOCALES = { az, en, es, + id, it, ja, ko, diff --git a/apps/desktop/src/i18n/__tests__/doubleClickStringSelectionParity.spec.ts b/apps/desktop/src/i18n/__tests__/doubleClickStringSelectionParity.spec.ts index 0cff591a2b..574c208b2d 100644 --- a/apps/desktop/src/i18n/__tests__/doubleClickStringSelectionParity.spec.ts +++ b/apps/desktop/src/i18n/__tests__/doubleClickStringSelectionParity.spec.ts @@ -2,6 +2,7 @@ import { describe, expect, it } from "vitest"; import az from "../locales/az"; import en from "../locales/en"; import es from "../locales/es"; +import id from "../locales/id"; import it_ from "../locales/it"; import ja from "../locales/ja"; import ko from "../locales/ko"; @@ -15,6 +16,7 @@ const locales: Array<[string, Record]> = [ ["az", az], ["en", en], ["es", es], + ["id", id], ["it", it_], ["ja", ja], ["ko", ko], diff --git a/apps/desktop/src/i18n/__tests__/editorSelectionContextParity.spec.ts b/apps/desktop/src/i18n/__tests__/editorSelectionContextParity.spec.ts index 0fae935ee7..7eebef13e7 100644 --- a/apps/desktop/src/i18n/__tests__/editorSelectionContextParity.spec.ts +++ b/apps/desktop/src/i18n/__tests__/editorSelectionContextParity.spec.ts @@ -12,8 +12,8 @@ function localeSource(name: string): string { return readFileSync(new URL(`../locales/${name}.ts`, import.meta.url), "utf8"); } -// Source of truth: `supportedLocales` in ../index.ts (11 entries, `ru` included). -const LOCALES = ["en", "zh-CN", "zh-TW", "ja", "ko", "es", "it", "pt-BR", "ru", "az", "tr"] as const; +// Source of truth: `supportedLocales` in ../index.ts (12 entries, `ru` included). +const LOCALES = ["en", "zh-CN", "zh-TW", "ja", "ko", "es", "it", "pt-BR", "ru", "az", "tr", "id"] as const; function declaredString(source: string, key: string): string | undefined { return source.match(new RegExp(String.raw`^\s*${key}:\s*"((?:[^"\\]|\\.)*)",\s*$`, "m"))?.[1]; diff --git a/apps/desktop/src/i18n/__tests__/featureMessages.spec.ts b/apps/desktop/src/i18n/__tests__/featureMessages.spec.ts index 86bcf8ae59..932c46c0bc 100644 --- a/apps/desktop/src/i18n/__tests__/featureMessages.spec.ts +++ b/apps/desktop/src/i18n/__tests__/featureMessages.spec.ts @@ -3,6 +3,7 @@ import { createI18n } from "vue-i18n"; import az from "../locales/az"; import en from "../locales/en"; import es from "../locales/es"; +import id from "../locales/id"; import itLocale from "../locales/it"; import ja from "../locales/ja"; import ko from "../locales/ko"; @@ -20,9 +21,9 @@ import zhTW from "../locales/zh-TW"; vi.mock("../locales/fallback", () => ({ withEnglishFallback: (messages: Record) => messages })); type Messages = Record; -type Locale = "az" | "en" | "es" | "it" | "ja" | "ko" | "pt-BR" | "ru" | "tr" | "zh-CN" | "zh-TW"; +type Locale = "az" | "en" | "es" | "id" | "it" | "ja" | "ko" | "pt-BR" | "ru" | "tr" | "zh-CN" | "zh-TW"; -const declared: Record = { az, en, es, it: itLocale, ja, ko, "pt-BR": ptBR, ru, tr, "zh-CN": zhCN, "zh-TW": zhTW }; +const declared: Record = { az, en, es, id, it: itLocale, ja, ko, "pt-BR": ptBR, ru, tr, "zh-CN": zhCN, "zh-TW": zhTW }; const ALL_LOCALES = Object.keys(declared) as Locale[]; const EXCEPT_AZ_TR = ALL_LOCALES.filter((locale) => locale !== "az" && locale !== "tr"); diff --git a/apps/desktop/src/i18n/__tests__/gridCopyExtractorSavedParity.spec.ts b/apps/desktop/src/i18n/__tests__/gridCopyExtractorSavedParity.spec.ts index aa67592afa..2b2c5a81bf 100644 --- a/apps/desktop/src/i18n/__tests__/gridCopyExtractorSavedParity.spec.ts +++ b/apps/desktop/src/i18n/__tests__/gridCopyExtractorSavedParity.spec.ts @@ -2,6 +2,7 @@ import { describe, expect, it } from "vitest"; import az from "../locales/az"; import en from "../locales/en"; import es from "../locales/es"; +import id from "../locales/id"; import it_ from "../locales/it"; import ja from "../locales/ja"; import ko from "../locales/ko"; @@ -15,6 +16,7 @@ const locales: Array<[string, Record]> = [ ["az", az], ["en", en], ["es", es], + ["id", id], ["it", it_], ["ja", ja], ["ko", ko], diff --git a/apps/desktop/src/i18n/__tests__/historyMcpKindParity.spec.ts b/apps/desktop/src/i18n/__tests__/historyMcpKindParity.spec.ts index 9b900bf268..e6b4e15667 100644 --- a/apps/desktop/src/i18n/__tests__/historyMcpKindParity.spec.ts +++ b/apps/desktop/src/i18n/__tests__/historyMcpKindParity.spec.ts @@ -15,7 +15,7 @@ function historyKindsCluster(source: string): string | undefined { return (source.match(/kinds: \{[^}]*\}/g) ?? []).find((cluster) => cluster.includes("redis_command:")); } -const LOCALES = ["en", "zh-CN", "zh-TW", "ja", "ko", "es", "it", "pt-BR", "ru", "az", "tr"] as const; +const LOCALES = ["en", "zh-CN", "zh-TW", "ja", "ko", "es", "it", "pt-BR", "ru", "az", "tr", "id"] as const; describe("history kinds mcp label parity", () => { it.each(LOCALES)("%s: history.kinds declares mcp", (name) => { diff --git a/apps/desktop/src/i18n/__tests__/localePlaceholderParity.spec.ts b/apps/desktop/src/i18n/__tests__/localePlaceholderParity.spec.ts index 647c7d0676..cbc6667226 100644 --- a/apps/desktop/src/i18n/__tests__/localePlaceholderParity.spec.ts +++ b/apps/desktop/src/i18n/__tests__/localePlaceholderParity.spec.ts @@ -2,6 +2,7 @@ import { describe, expect, it } from "vitest"; import az from "../locales/az"; import en from "../locales/en"; import es from "../locales/es"; +import id from "../locales/id"; import itLocale from "../locales/it"; import ja from "../locales/ja"; import ko from "../locales/ko"; @@ -24,6 +25,7 @@ import zhTW from "../locales/zh-TW"; const locales: Array<[string, Record]> = [ ["az", az as Record], ["es", es as Record], + ["id", id as Record], ["it", itLocale as Record], ["ja", ja as Record], ["ko", ko as Record], diff --git a/apps/desktop/src/i18n/__tests__/sqlFileTreeStorageHelpParity.spec.ts b/apps/desktop/src/i18n/__tests__/sqlFileTreeStorageHelpParity.spec.ts index c37d184c6b..cd927cf36d 100644 --- a/apps/desktop/src/i18n/__tests__/sqlFileTreeStorageHelpParity.spec.ts +++ b/apps/desktop/src/i18n/__tests__/sqlFileTreeStorageHelpParity.spec.ts @@ -2,6 +2,7 @@ import { describe, expect, it } from "vitest"; import az from "../locales/az"; import en from "../locales/en"; import es from "../locales/es"; +import id from "../locales/id"; import it_ from "../locales/it"; import ja from "../locales/ja"; import ko from "../locales/ko"; @@ -19,6 +20,7 @@ const locales: Array<[string, Record]> = [ ["en", en as Record], ["az", az as Record], ["es", es], + ["id", id], ["it", it_], ["ja", ja], ["ko", ko], diff --git a/apps/desktop/src/i18n/__tests__/sqlSourcePasteParity.spec.ts b/apps/desktop/src/i18n/__tests__/sqlSourcePasteParity.spec.ts index 849d87d9b9..ca87de0ccd 100644 --- a/apps/desktop/src/i18n/__tests__/sqlSourcePasteParity.spec.ts +++ b/apps/desktop/src/i18n/__tests__/sqlSourcePasteParity.spec.ts @@ -2,6 +2,7 @@ import { describe, expect, it } from "vitest"; import az from "../locales/az"; import en from "../locales/en"; import es from "../locales/es"; +import id from "../locales/id"; import it_ from "../locales/it"; import ja from "../locales/ja"; import ko from "../locales/ko"; @@ -20,6 +21,7 @@ const locales: Array<[string, Record]> = [ ["en", en as Record], ["az", az as Record], ["es", es], + ["id", id], ["it", it_], ["ja", ja], ["ko", ko], diff --git a/apps/desktop/src/i18n/index.ts b/apps/desktop/src/i18n/index.ts index 32a65bf21d..87564f1e76 100644 --- a/apps/desktop/src/i18n/index.ts +++ b/apps/desktop/src/i18n/index.ts @@ -3,19 +3,20 @@ import en from "./locales/en"; import { safeLocalStorageGet } from "@/lib/backend/safeStorage"; import { persistAppLocale } from "@/lib/app/appAppearance"; -export type Locale = "az" | "en" | "es" | "it" | "ja" | "ko" | "pt-BR" | "ru" | "tr" | "zh-CN" | "zh-TW"; +export type Locale = "az" | "en" | "es" | "id" | "it" | "ja" | "ko" | "pt-BR" | "ru" | "tr" | "zh-CN" | "zh-TW"; type LocaleMessages = Record; type I18nGlobal = { locale: { value: Locale }; setLocaleMessage: (locale: Locale, messages: LocaleMessages) => void; }; -const supportedLocales: Locale[] = ["az", "en", "es", "it", "ja", "ko", "pt-BR", "ru", "tr", "zh-CN", "zh-TW"]; +const supportedLocales: Locale[] = ["az", "en", "es", "id", "it", "ja", "ko", "pt-BR", "ru", "tr", "zh-CN", "zh-TW"]; const defaultLocale: Locale = "en"; const loadedLocales = new Set([defaultLocale]); const localeLoaders: Record, () => Promise<{ default: LocaleMessages }>> = { az: () => import("./locales/az"), es: () => import("./locales/es"), + id: () => import("./locales/id"), it: () => import("./locales/it"), ja: () => import("./locales/ja"), ko: () => import("./locales/ko"), @@ -45,6 +46,7 @@ export function localeFromLanguageTag(value: string | null | undefined): Locale if (normalized === "az" || normalized.startsWith("az-")) return "az"; if (normalized === "en" || normalized.startsWith("en-")) return "en"; if (normalized === "es" || normalized.startsWith("es-")) return "es"; + if (normalized === "id" || normalized.startsWith("id-")) return "id"; if (normalized === "it" || normalized.startsWith("it-")) return "it"; if (normalized === "ja" || normalized.startsWith("ja-")) return "ja"; if (normalized === "ko" || normalized.startsWith("ko-")) return "ko"; diff --git a/apps/desktop/src/i18n/locales/consulId.ts b/apps/desktop/src/i18n/locales/consulId.ts new file mode 100644 index 0000000000..cea453fcd1 --- /dev/null +++ b/apps/desktop/src/i18n/locales/consulId.ts @@ -0,0 +1,472 @@ +import type { ConsulMessages } from "./consulUi"; + +export const consulIdMessages = { + ui: { + unknown: "Tidak diketahui", + peeringPending: "Menunggu", + peeringEstablishing: "Sedang dibangun", + peeringActive: "Aktif", + peeringFailing: "Gagal", + peeringDeleting: "Sedang dihapus", + peeringTerminated: "Dihentikan", + refresh: "Segarkan", + cancel: "Batal", + create: "Buat", + update: "Perbarui", + save: "Simpan", + delete: "Hapus", + edit: "Edit", + apply: "Terapkan", + close: "Tutup", + hide: "Sembunyikan", + reveal: "Tampilkan", + copy: "Salin", + copied: "Disalin", + copyFailed: "Gagal menyalin", + copyOnce: "Salin sekali", + pause: "Jeda", + watchAction: "Pantau", + watchPrefix: "Pantau prefiks", + watchModePrefix: "Prefiks", + watchModeKey: "Kunci persis", + sessionProtected: "Dilindungi Sesi", + sessionProtectedHint: "Penyuntingan dan penghapusan dinonaktifkan untuk melindungi kunci terdistribusi ini.", + atomicTransaction: "Transaksi atomik", + nonAtomicBatches: "Tidak atomik antar {count} batch", + batchOperation: "Batch {batch} · OpIndex {op}", + operationTotals: "Berhasil {succeeded} · Konflik {conflicted} · Dilewati {skipped} · Gagal {failed}", + deleteOperationTotals: "Berhasil {succeeded} · Konflik {conflicted} · Gagal {failed}", + clientSideMigration: "DBX membaca dari sumber dan menulis ke target. Ini bukan replikasi antar-Datacenter native Consul.", + bundleFileType: "Paket KV Consul DBX", + sourceKeyMissingModifyIndex: "Kunci sumber tidak memiliki ModifyIndex", + transactionRejected: "Consul menolak transaksi", + overview: "Ringkasan klaster", + capabilities: "Kapabilitas", + probeLoading: "Memuat", + probeReady: "Siap", + probeForbidden: "Terlarang", + probeUnsupported: "Tidak didukung", + probeError: "Galat", + autopilotHealth: "Kesehatan Autopilot", + datacenter: "Datacenter", + agentNode: "Node Agent", + agentAddress: "Alamat Agent", + version: "Versi", + mode: "Mode", + server: "Server", + client: "Klien", + leader: "Leader", + raftPeers: "Peer Raft", + membersAlive: "Anggota hidup", + members: "Anggota", + node: "Node", + address: "Alamat", + status: "Status", + alive: "hidup", + leaving: "keluar", + failed: "gagal", + previousPage: "Halaman sebelumnya", + nextPage: "Halaman berikutnya", + pageStatus: "{page} / {pages} · total {total}", + searchAllServices: "Cari semua layanan", + searchAllNodes: "Cari semua node", + searchLocalServices: "Cari layanan Agent lokal", + query: "Kueri", + searchHealthChecks: "Cari nama, ID, node, layanan, output, atau catatan pemeriksaan", + allCheckTypes: "Semua jenis pemeriksaan", + clearFilters: "Bersihkan filter", + healthResultCount: "{filtered} dari {total} pemeriksaan", + services: "Layanan", + nodes: "Node", + service: "Layanan", + catalogServices: "Layanan katalog", + catalogNodes: "Node katalog", + noVisibleServices: "Tidak ada layanan yang terlihat", + noVisibleNodes: "Tidak ada node yang terlihat", + noMatchingServices: "Tidak ada layanan yang cocok", + noMatchingNodes: "Tidak ada node yang cocok", + agentTarget: "Target Agent: {target}", + agentTargetVerifying: "Memverifikasi target Agent", + unknownWritesDisabled: "tidak diketahui - penulisan dinonaktifkan", + targetAgent: "Agent target", + agentWriteReady: "Dapat ditulis", + agentReadOnly: "Baca saja", + agentWriteDisabledHint: "Tidak ada target Agent yang cocok dikonfigurasi, sehingga pemeliharaan dan pembatalan pendaftaran dinonaktifkan. Agent yang terdeteksi: {target}.", + agentWriteBlocked: { + connectionUnavailable: "Konfigurasi koneksi tidak tersedia. Sambungkan kembali sebelum menulis.", + readOnly: "Koneksi ini baca saja. Pembatalan pendaftaran layanan dinonaktifkan.", + transport: "Penulisan Agent tidak tersedia melalui Transport Layer. Sambungkan langsung ke Agent target.", + targetRequired: "Sunting koneksi dan konfigurasikan node serta alamat target Agent. Node harus cocok dengan Agent saat ini, dan alamat harus cocok dengan endpoint koneksi.", + identityUnavailable: "Tidak dapat membaca identitas Agent. Penulisan dinonaktifkan. Periksa koneksi dan izin baca Agent, lalu segarkan.", + nodeMismatch: "Node target yang dikonfigurasi tidak cocok dengan Agent saat ini. Periksa pengaturan koneksi.", + directAddressRequired: "Penulisan Agent memerlukan endpoint IP langsung atau localhost. Alamat DNS dan load-balanced tidak didukung.", + addressMismatch: "Alamat target Agent tidak cocok dengan endpoint koneksi. Periksa pengaturan koneksi.", + invalidAddress: "Alamat koneksi Consul tidak valid. Periksa pengaturan koneksi.", + }, + register: "Daftarkan", + registrationHint: "Pendaftaran HTTP Agent dimiliki oleh runtime Agent target dan tidak mengubah berkas konfigurasi permanennya.", + name: "Nama", + id: "ID", + port: "Port", + tags: "Tag (dipisahkan koma)", + registerOn: "Daftarkan di {node}", + catalogInstances: "Instansi katalog", + nodeServices: "Layanan node", + serviceId: "ID layanan", + localAgentServices: "Layanan Agent lokal", + enableMaintenance: "Aktifkan mode pemeliharaan", + disableMaintenance: "Nonaktifkan mode pemeliharaan", + deregister: "Batalkan pendaftaran", + deregisterService: "Batalkan pendaftaran layanan lokal {id} dari {node}?", + deregistering: "Membatalkan pendaftaran", + deregisterServiceHint: "Ini menghapus pendaftaran layanan dan pemeriksaan terkait. Katalog akan disinkronkan setelahnya. Proses layanan tetap berjalan dan dapat mendaftarkan dirinya kembali.", + deregisterServiceSucceeded: "Pendaftaran layanan {id} dari {node} dibatalkan. Sinkronisasi katalog dapat memakan waktu; layanan dapat muncul kembali jika aplikasi mendaftarkannya lagi.", + deregisterRefreshFailed: "Layanan dibatalkan pendaftarannya, tetapi penyegaran gagal. Segarkan secara manual", + maintenanceReason: "Permintaan pengguna DBX", + serviceDetails: "Detail {service}", + kind: "Jenis", + serviceKind: "ServiceKind", + standard: "standar", + metadata: "Metadata", + nodeMeta: "Metadata node", + serviceMeta: "Metadata layanan", + nodeId: "ID node", + serviceWeights: "Baik / Peringatan", + taggedAddresses: "TaggedAddresses", + enableTagOverride: "EnableTagOverride", + agent: "Agent", + watch: "Pantau", + writeOperation: "Operasi tulis", + localServiceDetails: "Detail layanan lokal", + agentIdentityRequestTimedOut: "Pemuatan identitas Agent kehabisan waktu.", + localServicesRequestTimedOut: "Pemuatan layanan Agent lokal kehabisan waktu.", + localChecksRequestTimedOut: "Pemuatan pemeriksaan Agent lokal kehabisan waktu.", + healthChecks: "Pemeriksaan kesehatan", + state: "Status", + nodeName: "Nama node", + allStates: "Semua status", + passing: "Baik", + warning: "Peringatan", + critical: "Kritis", + watchPaused: "Pemantauan dijeda", + watchingIndex: "Memantau indeks {index}", + pauseWatch: "Jeda pemantauan", + startWatch: "Mulai pemantauan", + checkRegistrationHint: "Pemeriksaan Agent adalah pendaftaran runtime pada {node} dan tidak disimpan ke berkas konfigurasi Agent.", + type: "Jenis", + ttl: "TTL", + http: "HTTP", + tcp: "TCP", + grpc: "gRPC", + docker: "Docker", + script: "Script", + arguments: "Argumen", + containerId: "ID kontainer", + endpoint: "Endpoint", + interval: "Interval", + timeout: "Batas waktu", + commandArguments: "Argumen perintah", + clusterHealth: "Kesehatan klaster", + nodeHealth: "Kesehatan node: {node}", + serviceHealth: "Kesehatan layanan: {service}", + noMatchingHealthChecks: "Tidak ada pemeriksaan kesehatan yang cocok", + serviceInstances: "Instansi layanan", + localAgentChecks: "Pemeriksaan Agent lokal", + maintenance: "pemeliharaan", + ttlPass: "TTL lulus", + ttlWarn: "TTL peringatan", + ttlFail: "TTL gagal", + deregisterCheck: "Batalkan pendaftaran pemeriksaan {id} dari {node}?", + checkDetails: "Detail {check}", + checkId: "ID pemeriksaan", + notes: "Catatan", + output: "Output", + definition: "Definisi", + indexes: "CreateIndex / ModifyIndex", + sessionsAndLocks: "Sesi dan kunci", + sessions: "Sesi", + sessionDescription: "Sesi adalah kontrak mirip lease yang digunakan oleh kunci KV Consul. Sesi TTL memerlukan pembaruan berkala; Sesi tanpa TTL tetap ada hingga secara eksplisit dihancurkan atau divalidasi oleh pemeriksaannya.", + createSession: "Buat Sesi", + searchSessions: "Cari nama, ID, node, atau pemeriksaan Sesi", + sessionResultCount: "Menampilkan {filtered} dari {total} Sesi", + noMatchingSessions: "Tidak ada Sesi yang cocok", + allSessionTypes: "Semua jenis Sesi", + ttlSessions: "Sesi TTL", + persistentSessions: "Sesi tanpa TTL", + allBehaviors: "Semua perilaku", + aclFilteredSessions: "Daftar Sesi difilter oleh ACL", + sessionRequestTimedOut: "Pemuatan Sesi kehabisan waktu. Periksa koneksi Consul dan coba lagi.", + complete: "Lengkap", + lock: "Kunci", + lockManagement: "Pengelolaan kunci KV", + lockIndex: "LockIndex {index}", + lockDelay: "Penundaan kunci", + lockDelayHint: "0s–60s; menunda pengambilan ulang setelah invalidasi.", + nodeOptional: "Node (opsional)", + behavior: "Perilaku", + behaviorRelease: "release", + behaviorDelete: "delete", + behaviorHint: "release mempertahankan kunci yang dipegang; delete menghapusnya saat Sesi berakhir.", + releaseLocks: "Lepaskan kunci", + deleteKeys: "Hapus kunci", + deleteBehaviorWarning: "Perilaku=delete menghapus setiap kunci yang dipegang oleh Sesi ini saat Sesi divalidasi. Lanjutkan?", + checks: "Pemeriksaan", + nodeChecks: "Pemeriksaan node", + serviceChecks: "Pemeriksaan layanan", + nodeCheckShort: "Node", + serviceCheckShort: "Layanan", + serviceChecksPlaceholder: "service:api:health{'@'}namespace-a", + serviceChecksHint: "ID pemeriksaan dipisahkan koma; gunakan ID{'@'}namespace untuk pemeriksaan tercakup.", + lockHint: "Periksa kunci, pilih Sesi, lalu ambil atau lepaskan kunci advisori.", + key: "Kunci", + inspectKey: "Periksa kunci", + keyExists: "Kunci ada", + keyNotFound: "Kunci tidak ada", + keyUnlocked: "Kunci saat ini tidak dipegang", + keyHeldBy: "Dipegang oleh Sesi {session}", + sessionValue: "Sesi {id}", + modifyIndexValue: "ModifyIndex {index}", + createIndex: "CreateIndex", + modifyIndexLabel: "ModifyIndex", + selectSession: "Pilih Sesi", + sessionId: "ID Sesi", + expectedModifyIndex: "ModifyIndex yang diharapkan (0 untuk kunci baru)", + value: "Nilai", + releaseMatchingSession: "Lepaskan", + acquire: "Ambil", + unnamedSession: "Sesi tanpa nama", + heldKeys: "Kunci yang dipegang", + heldKeysIncomplete: "Hasil tidak lengkap atau terfilter ACL", + stop: "Hentikan", + renewNow: "Perbarui sekarang", + autoRenew: "Perbarui otomatis", + autoRenewPageHint: "Pembaruan otomatis hanya berjalan selama koneksi dan halaman ini tetap aktif.", + noRenewRequired: "Tidak perlu pembaruan", + noTtl: "Tanpa TTL", + ttlOptional: "TTL (opsional)", + ttlRangeHint: "Biarkan kosong untuk Sesi persisten, atau gunakan 10s–24h.", + invalidSessionTtl: "TTL harus kosong atau durasi valid dari 10s hingga 24h.", + invalidLockDelay: "Penundaan kunci harus berupa durasi valid dari 0s hingga 60s.", + destroy: "Hancurkan", + noHeldKeys: "Tidak ada kunci yang dipegang", + noVisibleSessions: "Tidak ada Sesi yang terlihat", + destroySession: "Hancurkan Sesi {id}? Kunci yang menggunakan Sesi ini dapat dilepaskan atau dihapus oleh Perilakunya.", + destroySessionImpact: "Hancurkan Sesi {id}? Perilaku: {behavior}. Kunci yang dipegang ({count}): {keys}", + sessionImpactIncomplete: "Dampak Sesi tidak lengkap atau terfilter ACL. Penghancuran diblokir.", + sessionDetails: "TTL {ttl} · {behavior} · pemeriksaan {checks}", + tokens: "Token", + policies: "Kebijakan", + roles: "Peran", + authMethods: "Metode autentikasi", + bindingRules: "Aturan pengikatan", + templatedPolicies: "Kebijakan templat", + capability: "Kapabilitas: {status}", + capabilitySupported: "Didukung", + capabilityUnsupported: "Tidak didukung", + capabilityDisabled: "Dinonaktifkan", + capabilityForbidden: "Tidak ada izin", + capabilityUnknown: "Tidak diketahui", + loading: "Memuat...", + viewOrEdit: "Lihat atau edit", + cloneToken: "Klon token", + deleteAndInspectReferences: "Hapus dan periksa referensi", + noResources: "Tidak ada sumber daya", + editResource: "Edit {kind}", + createResource: "Buat {kind}", + knownImpact: "Dampak yang diketahui: {tokens} token, {roles} peran, {bindingRules} aturan pengikatan", + incomplete: "(tidak lengkap)", + reviewAclChanges: "Tinjau perubahan ACL", + deleteResource: "Hapus {label}", + tokenReferences: "Referensi token: {tokens} · Referensi peran: {roles} · Referensi aturan pengikatan: {bindingRules}", + impactBlocked: "Dampak tidak lengkap atau terfilter ACL. Penghapusan diblokir.", + cloneTokenDescription: "Deskripsi untuk token klon", + scope: "Cakupan Consul", + adminPartition: "Admin Partition", + namespace: "Namespace", + default: "default", + applyScope: "Terapkan cakupan", + enterpriseCapability: "Kapabilitas Enterprise: {status}. Tindakan siklus hidup tidak tersedia.", + namespaces: "Namespace", + lifecycleImpact: "Dampak sumber daya tercakup", + inspectImpactAndDelete: "Periksa dampak dan hapus", + impactAclFiltered: "Consul melaporkan hasil yang terfilter ACL; penghapusan diblokir.", + impactUnavailable: "Tidak dapat menghitung: {resources}", + impactResource: { + services: "Layanan", + nodes: "Node", + kvKeys: "Kunci KV", + healthChecks: "Pemeriksaan kesehatan", + sessions: "Sesi", + configEntries: "Entri konfigurasi", + intentions: "Intention", + peerings: "Peering", + namespaces: "Namespace", + aclTokens: "Token ACL", + aclPolicies: "Kebijakan ACL", + aclRoles: "Peran ACL", + aclAuthMethods: "Metode autentikasi ACL", + aclBindingRules: "Aturan pengikatan ACL", + }, + configEntries: "Entri Konfigurasi", + intentions: "Intention", + discoveryChain: "Discovery Chain", + peering: "Peering", + exportedServices: "Layanan yang diekspor", + configEntryKind: "Jenis entri konfigurasi", + loadKind: "Muat jenis", + newJson: "JSON baru", + modifyIndex: "ModifyIndex {index}", + rawJson: "JSON mentah", + newIntention: "Intention baru", + sourceService: "Layanan sumber", + destinationService: "Layanan tujuan", + check: "Periksa", + matchSource: "Cocokkan sumber", + matchDestination: "Cocokkan tujuan", + allowed: "Diizinkan", + denied: "Ditolak", + matchedIntentions: "Mencocokkan {count} intention", + details: "Detail", + serviceName: "Nama layanan", + compile: "Kompilasi", + defaultProtocol: "protokol default", + configuredDatacenter: "datacenter yang dikonfigurasi", + start: "Mulai", + next: "Berikutnya: {nodes}", + terminalTarget: "Terminal / target", + upstreamTargets: "Target upstream ({count})", + peerName: "Nama peer", + peeringToken: "Token peering untuk membangun peering", + generateToken: "Buat token", + establish: "Bangun", + editExportedServices: "Edit entri exported-services", + serviceMeshConfigEntry: "Entri konfigurasi Service Mesh", + applyWithCas: "Terapkan dengan CAS", + reviewMeshChanges: "Tinjau perubahan Service Mesh", + deleteConfig: "Hapus {kind}/{name}?", + deleteIntention: "Hapus intention {id}?", + deleteIntentionExact: "Hapus intention {source} -> {destination}?", + deletePeering: "Hapus peering {name}?", + permissions: "{count} izin", + actionRule: "aturan aksi", + tools: "Alat Consul", + preparedQueries: "Prepared query", + events: "Event", + coordinates: "Koordinat jaringan", + queryName: "Nama kueri", + targetService: "Layanan target", + targetServiceValue: "Layanan target: {service}", + cancelEdit: "Batalkan edit", + execute: "Jalankan", + explain: "Jelaskan", + eventName: "Nama event", + payload: "Payload", + fire: "Picu", + deletePreparedQuery: "Hapus prepared query {id}?", + nodesDatacenter: "{count} node · {datacenter}", + coordinateError: "{segment} · galat {error}", + preparedQueriesDescription: + "Kueri service-discovery yang dapat digunakan ulang dan tersimpan di Consul. Eksekusi me-resolve instansi layanan sehat yang cocok; Jelaskan menampilkan kueri efektif. Editor sederhana hanya mengubah nama dan layanan target, dengan mempertahankan field lanjutan yang sudah tersimpan oleh Consul.", + eventsDescription: "Pesan ringan best-effort yang didistribusikan melalui gossip Consul. Event adalah diagnostik atau notifikasi sementara, bukan antrean pesan permanen.", + coordinatesDescription: "Koordinat jaringan baca saja yang diestimasi Consul untuk membandingkan kedekatan jaringan. Ini bukan lokasi geografis.", + noPreparedQueries: "Tidak ada prepared query", + noEvents: "Tidak ada event terbaru", + noCoordinates: "Tidak ada koordinat jaringan", + queryExecutionResult: "Hasil eksekusi · {count} instansi · {datacenter}", + noQueryNodes: "Tidak ada instansi layanan yang cocok dengan kueri ini", + queryExplanation: "Kueri efektif", + eventNodeFilter: "Regex node (opsional)", + eventServiceFilter: "Regex layanan (opsional)", + eventTagFilter: "Regex tag (opsional)", + eventPayloadBytes: "Payload {count} / 100 byte", + segment: "Segmen", + error: "Galat", + adjustment: "Penyesuaian", + height: "Tinggi", + operatorReadOnly: "Operator (baca saja)", + snapshot: "Snapshot", + snapshotRestore: "Pemulihan snapshot", + targetDatacenter: "Datacenter target", + restoreSnapshot: "Pulihkan snapshot", + restoreSnapshotConfirmation: "RESTORE SNAPSHOT {datacenter}", + autopilotUpdate: "Pembaruan Autopilot", + cleanupDeadServers: "Bersihkan server mati", + updateAutopilot: "Perbarui Autopilot", + updateAutopilotConfirmation: "UPDATE AUTOPILOT", + raftOperations: "Operasi Raft", + serverId: "ID server", + peerAddress: "Alamat peer (hanya penghapusan)", + reenterIdAddress: "Masukkan ulang ID atau alamat", + transferLeader: "Transfer leader", + removePeer: "Hapus peer", + gossipKeyring: "Keyring gossip", + operation: "Operasi", + install: "Pasang", + use: "Gunakan", + remove: "Hapus", + gossipKey: "Kunci gossip", + changeKeyring: "Ubah keyring", + changeKeyringConfirmation: "CHANGE KEYRING", + licenseUpdate: "Pembaruan lisensi", + license: "Lisensi", + updateLicense: "Perbarui lisensi", + updateLicenseConfirmation: "UPDATE LICENSE", + }, + tools: { + search: "Cari", + searchTitle: "Cari KV Consul", + searchQuery: "Teks yang dicari", + prefixOptional: "Prefiks (opsional)", + searchAll: "Kunci dan nilai", + searchKeys: "Hanya kunci", + searchValues: "Hanya nilai", + caseSensitive: "Peka huruf besar/kecil", + scanned: "Memindai {count} kunci", + searchLimited: "Hasil dibatasi untuk melindungi koneksi.", + noSearchResults: "Tidak ada kunci yang cocok", + searchSummary: "{matched} kecocokan dari {scanned} kunci yang dipindai", + exportSearchResults: "Ekspor hasil", + searchResultsFileType: "Hasil pencarian KV Consul", + searchResultsExported: "{count} hasil pencarian diekspor", + exportPrefix: "Ekspor prefiks", + prefix: "Prefiks", + emptyPrefixAll: "Biarkan kosong untuk semua kunci yang dapat diakses", + exportLimitHint: "Ekspor mencakup cakupan saat ini dan mempertahankan metadata kunci yang diperlukan untuk impor yang aman.", + exported: "{count} kunci diekspor", + import: "Impor", + importTitle: "Impor paket KV Consul", + invalidBundle: "Berkas ini bukan paket KV Consul DBX yang valid", + importApplied: "{count} kunci diimpor", + migrate: "Migrasikan", + migrateTitle: "Migrasikan KV Consul", + sourcePrefix: "Prefiks sumber", + targetConnection: "Koneksi target", + selectTarget: "Pilih koneksi target", + targetReadOnly: "Koneksi target bersifat baca saja.", + conflictPolicy: "Kebijakan konflik", + policyAbort: "Batalkan saat konflik", + policySkip: "Lewati konflik", + policyCas: "Gunakan CAS", + bundleSummary: "{count} kunci · Datacenter {dc} · Namespace {ns} · Partition {partition}", + creates: "Buat {count}", + updates: "Perbarui {count}", + unchanged: "Tidak berubah {count}", + skipped: "Dilewati {count}", + conflicts: "Konflik {count}", + loadPreview: "Muat pratinjau", + loadingPreview: "Memuat pratinjau...", + apply: "Terapkan", + preview: "Pratinjau", + deletePrefix: "Hapus prefiks", + deletePrefixTitle: "Hapus prefiks KV Consul", + deletePrefixPlaceholder: "Prefiks yang akan dihapus", + deletePrefixWarning: "Operasi ini menghapus setiap kunci yang terlihat di bawah prefiks. Tinjau pratinjau sebelum mengonfirmasi.", + candidates: "Kandidat {count}", + lockedCount: "Terkunci {count}", + filtered: "terfilter", + complete: "lengkap", + confirmDeletePrefix: "Hapus kunci yang dikonfirmasi", + prefixDeleted: "{count} kunci dihapus", + operation: { create: "Buat", update: "Perbarui", unchanged: "Tidak berubah", skipped: "Dilewati", conflict: "Konflik", locked: "Terkunci", succeeded: "Berhasil", conflicted: "Konflik", failed: "Gagal" }, + }, +} satisfies ConsulMessages; diff --git a/apps/desktop/src/i18n/locales/id.ts b/apps/desktop/src/i18n/locales/id.ts new file mode 100644 index 0000000000..1e82bfa4dc --- /dev/null +++ b/apps/desktop/src/i18n/locales/id.ts @@ -0,0 +1,11460 @@ +import { withEnglishFallback } from "./fallback"; +import { consulIdMessages as consul } from "./consulId"; +import { sqlServerTraceMessages as sqlServerTrace } from "./sqlServerTraceMessages"; + +export default withEnglishFallback({ + cellTransform: { + title: "Pratinjau konversi", + description: "Konversi nilai saat ini untuk dilihat atau disalin. Nilai sumber dan draf editor tidak berubah.", + format: "Konversi", + unit: "Satuan timestamp", + timezone: "Zona waktu", + pattern: "Format tanggal", + fromBase: "Basis sumber", + toBase: "Basis target", + convert: "Konversi", + result: "Hasil", + copy: "Salin hasil", + htmlPreview: "Pratinjau HTML", + radixHint: "Hanya bilangan bulat. Masukkan digit tanpa awalan 0x, 0o, atau 0b; tanda opsional didukung.", + urlHint: "Encoding komponen URL (UTF-8). Dekode mempertahankan + sebagai tanda plus literal.", + kinds: { + timestamp: "Timestamp → tanggal/waktu", + json: "Format JSON", + jsonCompact: "JSON ringkas", + xml: "Format XML", + html: "Pratinjau HTML", + base64Encode: "Teks → Base64 (UTF-8)", + base64Decode: "Base64 → teks (UTF-8)", + urlEncode: "Encode komponen URL", + urlDecode: "Decode komponen URL", + radix: "Konversi basis bilangan bulat", + }, + units: { + auto: "Otomatis (10/13 digit)", + seconds: "Detik", + milliseconds: "Milidetik", + }, + errors: { + nullSource: "NULL tidak memiliki teks untuk dikonversi.", + incomplete: "Nilai lengkap belum dimuat. Tunggu hingga selesai dimuat atau buka kembali detail sel.", + unsafeNumber: "Nilai numerik ini tidak dapat direpresentasikan dengan aman. Ambil sebagai teks untuk menjaga presisi.", + tooLarge: "Batas konversi terlampaui: {maxInput} karakter input, {maxOutput} karakter output, atau {maxRadixDigits} karakter bilangan bulat.", + invalid: "Tidak dapat dikonversi. Periksa format input dan opsi konversi.", + invalidTimestamp: "Masukkan timestamp bilangan bulat dalam rentang tanggal yang didukung.", + ambiguousUnit: "Tidak dapat menentukan satuan timestamp. Pilih detik atau milidetik secara eksplisit.", + invalidInteger: "Masukkan bilangan bulat dengan digit yang valid untuk basis sumber yang dipilih, tanpa awalan basis.", + invalidBase64: "Masukkan Base64 berpadding standar yang berisi teks UTF-8 yang valid.", + }, + }, + customType: { + kinds: { + base: "Dasar", + composite: "Komposit", + domain: "Domain", + enum: "Enum", + range: "Rentang", + multirange: "Multirentang", + }, + tabs: { + members: "Anggota", + properties: "Properti", + ddl: "DDL", + }, + members: { + empty: "Tipe ini tidak memiliki anggota.", + name: "Nama", + type: "Tipe", + nullable: "Nullable", + default: "Default", + comment: "Komentar", + }, + properties: { + empty: "Tidak ada atribut yang tersedia.", + baseType: "Tipe dasar", + notNull: "Not null", + default: "Default", + collation: "Collation", + domainConstraint: "Constraint", + rangeSubtype: "Subtipe rentang", + rangeMultirange: "Tipe multirentang", + }, + ddl: { + empty: "Tidak ada DDL yang tersedia untuk tipe ini.", + incomplete: "DDL yang dihasilkan tidak lengkap dan tidak disalin. Buka detail tipe untuk melihat peringatannya.", + }, + }, + app: { + name: "DBX", + }, + pluginPlatform: { + dataAccessConsent: '"{name}" ingin membaca data dari koneksi "{connection}". Selama koneksi tersebut terbuka, plugin dapat menjalankan kueri read-only pada koneksi itu hingga Anda mencabut aksesnya di Plugin Center. Izinkan?', + dataAccessConsentTitle: "Permintaan Akses Data", + aiTools: { + title: "Alat AI bawaan", + description: "Nonaktif secara default: asisten AI DBX (mode Agent) hanya dapat memanggil alat plugin ini pada koneksi terbuka miliknya selama sakelar ini aktif. Alat yang tidak dideklarasikan read-only tetap meminta persetujuan Anda sebelum setiap pemanggilan.", + preview: "Tampilkan alat", + previewHint: "Memulai plugin jika belum berjalan.", + previewFailed: "Tidak dapat menampilkan daftar alat: {message}", + openConnections: "AI akan menggunakan koneksi terbuka ini: {names}", + noOpenConnections: "Tidak ada koneksi plugin ini yang terbuka. Buka salah satu sebelum meminta AI menggunakan alat ini.", + noTools: "Plugin ini tidak menyediakan alat AI.", + readOnly: "Baca saja", + needsApproval: "Perlu persetujuan", + saveFailed: "Tidak dapat menyimpan pengaturan: {message}", + }, + dataAccess: { + title: "Akses data", + description: "Koneksi yang boleh dibaca plugin ini dengan kueri read-only. Plugin akan meminta izin saat pertama kali membutuhkan koneksi; Anda dapat mencabut akses ini kapan saja.", + none: "Belum ada koneksi yang diberi akses.", + revoke: "Cabut", + missingConnection: "Koneksi dihapus ({id})", + revokeFailed: "Tidak dapat mencabut akses: {message}", + }, + shortcutsPluginCenter: "Di samping Plugin Center (dropdown)", + shortcutsToolbar: "Sebelum Update (mengambang)", + shortcutsToolbarCount: "Jumlah ikon bilah alat yang terlihat", + shortcutsToolbarHint: "0 memindahkan semua entri ke menu. Ruang terbatas memindahkan lebih banyak entri ke menu.", + shortcutsMore: "Pintasan plugin lainnya ({count})", + shortcutsLeftTop: "Kiri · Atas dahulu", + shortcutsLeftBottom: "Kiri · Bawah dahulu", + shortcutsRightTop: "Kanan · Atas dahulu", + shortcutsRightBottom: "Kanan · Bawah dahulu", + shortcutsVisiblePlugins: "Plugin yang terlihat", + shortcutsResize: "Seret untuk mengubah ukuran; klik dua kali untuk tinggi otomatis", + globalSettingsTitle: "Pengaturan global", + shortcutsTitle: "Pintasan plugin", + shortcutsDescription: "Pilih lokasi tampilnya pintasan plugin. Seret ikon untuk mengurutkan ulang.", + shortcutsHeading: "Plugin", + shortcutsSettings: "Pengaturan plugin", + shortcutsShowSettings: "Tampilkan pintasan pengaturan plugin", + shortcutsEnabled: "Tampilkan pintasan plugin", + shortcutsPosition: "Posisi", + shortcutsBottom: "Bawah pohon koneksi", + shortcutsSaveFailed: "Tidak dapat menyimpan pintasan plugin", + openResultView: "Buka dengan {label}", + centerTitle: "Plugin Center", + centerDescription: "Temukan kapabilitas opsional DBX dalam satu marketplace, lalu kelola plugin dan repositori yang terpasang secara terpisah.", + marketplace: "Marketplace", + installed: "Terpasang", + settings: "Pengaturan", + searchMarketplace: "Cari plugin, penerbit, atau tag", + sortBy: "Urutkan berdasarkan", + sortByName: "Nama (A–Z)", + sortByRecentlyUpdated: "Baru diperbarui", + sortByRecentlyListed: "Baru dipublikasikan", + sortByUpdatesFirst: "Pembaruan lebih dulu", + allRepositories: "Semua repositori", + marketplaceGuideTitle: "Plugin dikelola oleh pengembang komunitas", + showFewerTags: "Tampilkan lebih sedikit", + marketplaceGuideDescription: "Untuk masalah plugin atau permintaan fitur, silakan buka issue di repositori plugin itu sendiri (gunakan tautan repositori sumber pada kartu plugin); repositori utama DBX hanya menangani masalah aplikasinya sendiri.", + loadingMarketplace: "Memuat marketplace plugin", + noMarketplacePlugins: "Tidak ada plugin untuk ditampilkan", + noMarketplacePluginsDescription: "Konfigurasikan repositori di Pengaturan, atau sesuaikan pencarian dan filter saat ini.", + verified: "Terverifikasi", + noDescription: "Tidak ada deskripsi.", + permissionsCount: "{count} izin", + clipboardReadConsent: '"{name}" ingin membaca clipboard sistem. Workbench-nya akan menerima konten clipboard saat ini (mungkin berisi kata sandi atau token yang Anda salin). Izinkan pembacaan clipboard untuk sesi ini?', + clipboardReadConsentTitle: "Permintaan Baca Clipboard", + unsupportedTarget: "Tidak tersedia untuk {target}", + installedVersion: "Terpasang v{version}", + installedVersionUpdatable: "Terpasang v{installed} · Perbarui ke v{latest}", + licenseUnknown: "Lisensi tidak ditentukan", + sourceRepository: "Repositori sumber", + pluginHomepage: "Beranda", + marketplaceStatus: { + install: "Pasang", + installed: "Terpasang", + update: "Perbarui", + unsupported: "Tidak didukung", + }, + updateSuccess: "{name} diperbarui ke {version}", + installedUpdatesAvailableTitle: "Pembaruan plugin tersedia ({count})", + installedUpdatesAvailableDescription: "Pembaruan memverifikasi tanda tangan dan checksum, serta menyimpan versi sebelumnya untuk rollback sekali klik.", + updateAll: "Perbarui semua", + updatingProgress: "Memperbarui ({current}/{total})", + updateToVersion: "Perbarui ke v{version}", + checkingForUpdates: "Memeriksa pembaruan plugin…", + allPluginsUpToDate: "Semua plugin terpasang sudah versi terbaru.", + updateCheckUnavailable: "Pembaruan plugin tidak dapat diperiksa", + updateCheckUnavailableDescription: "Katalog plugin tidak dapat dimuat, sehingga status pembaruan mungkin sudah tidak akurat.", + updateCheckPartialFailure: "Beberapa repositori plugin gagal diperiksa; status pembaruan mungkin tidak lengkap.", + noRepositoriesEnabled: "Tidak ada repositori plugin yang diaktifkan", + notInRepositories: "Tidak ada di repositori", + notInRepositoriesHint: "Dipasang di luar repositori yang dikonfigurasi (.dbxp lokal atau repositori dinonaktifkan); status pembaruan tidak diketahui.", + updateSourceChangeTitle: "Konfirmasi perubahan sumber pembaruan plugin?", + updateSourceChangeBody: "Kandidat pembaruan berasal dari repositori, penerbit, atau kunci penandatanganan yang berbeda dari instalasi yang tercatat. Memperbarui akan mengganti plugin dan mencatat sumber baru.", + updateSourceChangeConfirm: "Tetap perbarui (catat sumber baru)", + provenanceCurrentInstall: "Instalasi saat ini", + provenanceCandidate: "Kandidat pembaruan", + provenanceRepository: "Repositori", + provenancePublisher: "Penerbit", + provenanceSigningKey: "Kunci penandatanganan", + batchSourceChangeSkipped: "Plugin berikut mengubah sumber pembaruan dan memerlukan konfirmasi per plugin: {names}", + updateSourceChangeRequired: "Sumber pembaruan telah berubah. Konfirmasi perubahan tersebut di Plugin Center terlebih dahulu.", + updateDowngradeRejected: "Menurunkan versi plugin ke versi yang lebih lama tidak diperbolehkan.", + updateBlockedByConnections: "Tutup koneksi berikut sebelum memperbarui atau mengembalikan plugin: {labels}", + updateBlockedByOperations: "Tunggu operasi aktif plugin ini selesai sebelum memperbarui atau mengembalikannya.", + updateInProgress: "Plugin ini sedang diperbarui. Coba lagi setelah pembaruan selesai.", + pinPlugin: "Sematkan plugin", + unpinPlugin: "Lepas sematan plugin", + noInstalledPlugins: "Tidak ada plugin terpasang", + browseMarketplace: "Jelajahi Marketplace", + localInstallTitle: "Pasang paket plugin", + localInstallDescription: "Pasang .dbxp bertanda tangan yang diperoleh di luar marketplace dari file lokal atau URL. DBX memverifikasi integritas dan tanda tangan paket secara otomatis.", + repositoriesTitle: "Repositori plugin", + repositoriesDescription: "Sumber resmi ditandatangani dan dikelola oleh DBX. Repositori khusus menggunakan satu kunci kepercayaan tingkat repositori yang dikonfigurasi di bawah ini.", + repositoryFieldsRequired: "ID repositori, nama, dan URL katalog wajib diisi", + repositorySaved: "Repositori plugin '{name}' disimpan", + removeRepositoryConfirm: "Hapus repositori plugin '{name}'? Plugin yang sudah terpasang akan tetap terpasang.", + repositoryRemoved: "Repositori plugin '{name}' dihapus", + repositoryKind: { + official: "Resmi", + custom: "Khusus", + enterprise: "Enterprise", + }, + repositoryNotConfigured: "URL katalog tidak dikonfigurasi pada build ini", + enabled: "Diaktifkan", + disabled: "Dinonaktifkan", + enable: "Aktifkan", + disable: "Nonaktifkan", + repositoryIdPlaceholder: "ID repositori", + repositoryNamePlaceholder: "Nama repositori", + repositoryCatalogUrlPlaceholder: "https://plugins.example.com/catalog/index.json", + addRepository: "Tambah repositori", + signedPackagesVerifiedAutomatically: "Tanda tangan diverifikasi secara otomatis", + developerOptionsTitle: "Opsi pihak ketiga dan pengembang", + developerOptionsDescription: "Gunakan hanya untuk repositori khusus atau pengembangan plugin lokal.", + pluginDevelopmentDocsTitle: "Dokumentasi pengembangan plugin", + pluginDevelopmentDocsDescription: "Pelajari cara mengembangkan, mengemas, dan mempublikasikan plugin DBX ke marketplace.", + pluginDevelopmentDocsOpen: "Lihat dokumentasi", + developerOptionsWarning: "Plugin tanpa tanda tangan dapat menjalankan kode native dengan izin pengguna Anda. Aktifkan ini hanya untuk paket yang Anda buat dan percayai sendiri.", + connectionManagedInDialog: "Buat dan edit koneksi di dialog Koneksi Baru terpadu. Halaman ini hanya mengelola plugin dan menampilkan kapabilitasnya.", + allowUnsignedDevelopmentPackage: "Izinkan paket pengembangan tanpa tanda tangan", + allowUnsignedDevelopmentPackageDescription: "Hanya berlaku untuk instalasi .dbxp manual dan tidak pernah melonggarkan verifikasi marketplace resmi.", + installPackage: "Pasang .dbxp", + installFromUrl: "Pasang dari URL", + installUrlPlaceholder: "https://example.com/plugin.dbxp", + deepLinkInstallConfirm: "Pasang plugin ini dari tautan di bawah?", + deepLinkInvalid: "Tautan instalasi plugin tidak valid: {message}", + invalidPackageUrl: "Masukkan URL paket plugin http:// atau https:// yang valid", + downloadProgress: "Mengunduh {downloaded} dari {total}", + downloadProgressUnknown: "Mengunduh {downloaded}", + dropToInstall: "Lepaskan untuk memasang paket plugin", + dropInstallHint: "Anda juga bisa melepaskan file .dbxp pada halaman ini", + packageFileType: "Paket plugin DBX", + repositoryTrustTitle: "Kepercayaan repositori khusus", + repositoryTrustDescription: "Operator repositori khusus menandatangani semua paket yang disetujui dengan kunci repositorinya. Peroleh kunci publik tersebut melalui saluran tepercaya yang terpisah.", + repositoryKeyAdded: "Kunci penandatanganan repositori '{keyId}' ditambahkan", + removeRepositoryKeyConfirm: "Hapus kunci penandatanganan repositori '{keyId}'? Plugin yang sudah terpasang akan tetap terpasang.", + repositoryKeyRemoved: "Kunci penandatanganan repositori '{keyId}' dihapus", + repositoryKeyIdPlaceholder: "ID kunci repositori", + repositoryPublicKeyPlaceholder: "Kunci publik repositori Ed25519 Base64 (32 byte)", + trustRepository: "Percayai repositori", + noInstalledPluginsDescription: "Pasang .dbxp bertanda tangan, atau aktifkan paket tanpa tanda tangan secara eksplisit untuk pengembangan lokal.", + compatible: "Kompatibel", + blocked: "Diblokir", + rollback: "Rollback", + uninstall: "Copot", + rollbackConfirm: "Kembalikan plugin ini ke versi sebelumnya yang terpasang?", + rollbackSuccess: "Dikembalikan ke {version}", + uninstallConfirm: "Copot {name}?", + uninstallSuccess: "{name} dicopot", + installSuccess: "{name} {version} terpasang", + batchManage: "Batch", + batchDone: "Selesai", + batchSelected: "{count} dipilih", + batchSelectAllUpdatable: "Pilih semua yang dapat diperbarui", + batchInstallUpdate: "Pasang / perbarui", + batchUninstall: "Copot yang dipilih", + batchUninstallConfirm: "Copot {count} plugin?\n{names}", + batchSummary: "Selesai: {success} berhasil", + batchSummaryWithFailures: "Selesai: {success} berhasil, {failed} gagal ({names})", + batchDuplicateSources: "Beberapa sumber dipilih untuk: {names}. Pertahankan hanya satu sumber yang dipilih per plugin sebelum melanjutkan.", + batchRefreshFailed: "Batch telah selesai, tetapi daftar plugin tidak dapat disegarkan: {error}", + selectConnectionProvider: "Pilih penyedia koneksi terlebih dahulu", + connectionProvider: "Penyedia koneksi", + newConnection: "Baru", + workbenches: "Workbench", + filesystemProviders: "Penyedia sistem file", + open: "Buka", + browse: "Jelajahi", + parentDirectory: "Direktori induk", + filesystemUri: "URI sistem file", + refresh: "Segarkan", + reloadRequired: "Halaman plugin perlu dimuat ulang.", + reloadHintPrefix: "Tekan ", + reloadHintSuffix: " atau klik tombol segarkan di bawah untuk memuat ulang.", + loadingFiles: "Memuat file", + emptyDirectory: "Direktori ini kosong.", + loadMore: "Muat lebih banyak", + fileManagerHint: "Klik dua kali direktori untuk membukanya, atau file untuk pratinjau hingga 256 KB.", + filePreviewResize: "Seret atau gunakan tombol panah untuk mengubah ukuran pratinjau file; klik dua kali untuk mengatur ulang", + loadingPreview: "Memuat pratinjau", + previewTruncated: "Pratinjau dipotong pada 256 KB", + previewSelectedFileHint: "Klik dua kali file yang dipilih untuk memuat pratinjaunya.", + entryCannotPreview: "Entri ini tidak dapat dipratinjau.", + providerNoReadCapability: "Penyedia tidak mendeklarasikan kapabilitas baca.", + filesystemUnavailable: "Sistem file plugin '{pluginId}/{providerId}' tidak tersedia", + loadingFilesystem: "Memuat sistem file plugin", + filesystemUnavailableFallback: "Sistem file plugin tidak tersedia", + workbenchUnavailable: "Workbench plugin '{pluginId}/{contributionId}' tidak tersedia", + loadingWorkbench: "Memuat workbench plugin", + workbenchUnavailableFallback: "Workbench plugin tidak tersedia", + pluginIncompatible: "Plugin tidak kompatibel", + loadingTitle: "Memuat {title}", + }, + auth: { + rateLimited: "Silakan coba lagi dalam {seconds} detik", + setupTitle: "Siapkan kata sandi akses", + setupDescription: "Tetapkan kata sandi untuk melindungi instance Anda", + loginDescription: "Alat manajemen database", + newPassword: "Masukkan kata sandi baru", + confirmPassword: "Konfirmasi kata sandi", + enterPassword: "Masukkan kata sandi akses", + passwordMismatch: "Kata sandi tidak cocok", + setPassword: "Tetapkan Kata Sandi", + login: "Masuk", + processing: "Memproses...", + loginFailed: "Kata sandi salah", + connectFailed: "Koneksi gagal", + changePassword: "Ubah Kata Sandi", + oldPassword: "Kata sandi saat ini", + oldPasswordWrong: "Kata sandi saat ini salah", + passwordChanged: "Kata sandi berhasil diubah", + changePasswordFailed: "Gagal mengubah kata sandi", + changePasswordDescription: "Masukkan kata sandi Anda saat ini dan pilih yang baru", + }, + toolbar: { + commitOutcomeUnknown: "Hasil commit tidak diketahui dan sesi sudah tidak ada lagi. Verifikasi data sebelum menjalankan SQL ini lagi.", + moreActions: "Tindakan lainnya", + newConnection: "Koneksi Baru", + newQuery: "Kueri Baru", + execute: "Eksekusi", + executeShortcut: "Eksekusi pilihan/kueri ({shortcut})", + stopQuery: "Hentikan kueri", + explainPlan: "Explain plan", + stopExplain: "Hentikan explain", + autotrace: "Autotrace (mengeksekusi kueri)", + explainAnalyze: "EXPLAIN ANALYZE (mengeksekusi kueri)", + actualPlan: "Rencana eksekusi aktual (SET STATISTICS XML)", + formatSql: "Format SQL", + formatSqlFailed: "Gagal memformat SQL", + formatAutoDetectFailed: "Tidak dapat mengenali atau memformat konten yang dipilih", + compressSql: "Kompres SQL", + keywordCaseLower: "Gunakan kata kunci SQL huruf kecil", + keywordCaseUpper: "Gunakan kata kunci SQL huruf besar", + sqlSemanticDiagnosticsToggleOn: "Diagnostik semantik SQL: Aktif (klik untuk menonaktifkan)", + sqlSemanticDiagnosticsToggleOff: "Diagnostik semantik SQL: Nonaktif (klik untuk mengaktifkan)", + insertValueHintsToggleOn: "Petunjuk kolom INSERT: Aktif (klik untuk menonaktifkan)", + insertValueHintsToggleOff: "Petunjuk kolom INSERT: Nonaktif (klik untuk mengaktifkan)", + autoCommit: "Auto Commit", + manualTransaction: "Transaksi Manual", + autoCommitAgent: "Auto Commit (bergantung pada backend Agent)", + manualTransactionAgent: "Transaksi Manual (bergantung pada backend Agent)", + commit: "Commit", + rollback: "Rollback", + txnAutoRolledBack: "Transaksi di-rollback otomatis setelah 5 menit tidak aktif", + salesforceIdentityAdmin: "Profil memiliki “Modify All Data” — melewati keamanan tingkat field dan berbagi record", + salesforceIdentityNonAdmin: "Profil tidak memiliki “Modify All Data” — izin field dan berbagi record berlaku", + salesforceIdentityUnknownRights: "Tidak dapat menentukan apakah profil memiliki “Modify All Data”", + salesforceIdentityUnknownProfile: "Profil tidak diketahui", + autoCommitTxnRolledBack: 'Transaksi eksplisit yang dibiarkan terbuka oleh tab ini telah di-rollback secara otomatis; aktifkan "Pertahankan transaksi auto-commit eksplisit" agar tetap bertahan antar eksekusi', + autoCommitSessionTxnRolledBack: "Koneksi ini berjalan dengan auto-commit nonaktif (SET autocommit = 0), sehingga transaksi implisitnya di-rollback setelah eksekusi; DBX melaporkan hal ini sekali per koneksi", + previewSql: "Pratinjau SQL", + previewQuery: "Pratinjau kueri", + hidePreviewSql: "Sembunyikan Pratinjau SQL", + saveSql: "Simpan ke SQL Library", + saveSqlFile: "Simpan ke File Asli", + openSql: "Buka file SQL", + exPasteSqlInCondition: "ExPaste: tempel sebagai kondisi IN", + theme: "Tema", + themeLight: "Terang", + themeDark: "Gelap", + themeSystem: "Ikuti Sistem", + sqlSaved: "SQL disimpan", + sqlOpenFailed: "Gagal membuka file: {message}", + sqlSaveFailed: "Gagal menyimpan file: {message}", + driverManager: "Driver Manager", + pluginCenter: "Plugin Center", + updatableDriverCount: "Jumlah driver yang dapat diperbarui", + mcpUpdateAvailable: "Pembaruan server MCP tersedia", + alwaysOnTop: "Tetap di atas jendela lain", + alwaysOnTopOff: "Jangan tetap di atas", + blockDangerousRedisCommands: "Blokir perintah berbahaya", + multiDbExecute: "Eksekusi multi-database", + }, + multiDbExecute: { + manualTransaction: "Transaksi manual", + manualWarning: + "Setiap target memiliki transaksinya sendiri. Commit dan rollback berlaku untuk satu target pada satu waktu; commit lintas database tidak bersifat atomik. Perintah DDL dan transaksi eksplisit dapat melakukan commit secara independen. Pembatalan menunggu pernyataan aktif selesai sebelum rollback.", + pendingCommit: "Menunggu commit", + rolledBack: "Di-rollback", + commit: "Commit", + rollback: "Rollback", + manualUnsupported: "Target ini tidak mendukung transaksi manual.", + manualCommitUnavailable: "Commit tidak tersedia; rollback transaksi ini.", + discardTitle: "Rollback perubahan yang tertunda?", + discardWarning: "Pernyataan yang sedang berjalan akan selesai sebelum rollback. Target yang sudah di-commit tidak dapat dibatalkan.", + rollbackAndClose: "Rollback dan tutup", + cleanupFailed: "Beberapa transaksi tidak dapat di-rollback.", + title: "Eksekusi multi-database", + progress: "Progres eksekusi ({completed}/{total})", + sqlPreview: "Pratinjau SQL", + databaseType: "Tipe database", + searchTargets: "Cari koneksi, database, skema...", + selectedCount: "{count} dipilih", + selectedTargets: "Target terpilih", + selectGroup: "Grup target eksekusi", + noGroupSelected: "Pilih grup target", + manageGroups: "Kelola grup", + manageGroupsDescription: "Grup target adalah target eksekusi SQL yang dapat dipakai ulang dan tidak mengubah grup koneksi.", + noGroups: "Tidak ada grup target", + loadGroup: "Muat grup", + available: "Tersedia", + typeMismatch: "Tipe tidak cocok", + targets: "target", + saveAsGroup: "Simpan sebagai grup", + saveChanges: "Simpan perubahan", + saveAsNewGroup: "Simpan sebagai grup baru", + renameGroup: "Ganti nama grup", + deleteGroup: "Hapus grup", + deleteGroupConfirm: "Hapus grup target “{name}”? Koneksi dan database tidak akan terpengaruh.", + groupName: "Nama grup", + groupNameRequired: "Masukkan nama grup.", + groupNameExists: "Grup dengan nama ini sudah ada.", + groupSaved: "Grup target disimpan", + groupSaveFailed: "Gagal menyimpan grup target: {message}", + groupLoadFailed: "Gagal memuat grup target: {message}", + groupModified: "Pilihan target diubah", + unsavedChangesConfirm: "Pilihan target saat ini memiliki perubahan yang belum disimpan. Simpan sebelum melanjutkan?", + cancelOperation: "Batalkan operasi", + discardChanges: "Buang perubahan", + internalCatalog: "internal", + defaultDatabase: "database default", + noDatabase: "cakupan koneksi", + clearTargets: "Bersihkan", + noTargets: "Tidak ada target yang dapat dieksekusi.", + removeTarget: "Hapus target", + validTarget: "Target valid", + needsRecheck: "Menunggu validasi target", + needsRecheckCount: "{count} target perlu divalidasi", + invalidTargetCount: "{count} target tidak valid", + invalidTarget: "Target tidak valid", + connectionOnlyTarget: "Target tingkat koneksi", + targetMissingConnection: "Koneksi sudah tidak ada", + targetTypeMismatch: "Tipe database koneksi sudah tidak cocok", + targetCatalogMissing: "Katalog sudah tidak ada", + targetDatabaseMissing: "Database sudah tidak ada atau tidak dapat diakses", + targetSchemaMissing: "Skema sudah tidak ada atau tidak dapat diakses", + targetPermissionDenied: "Izin ditolak saat memvalidasi target", + targetValidationFailed: "Validasi target gagal", + retryValidation: "Coba validasi lagi", + serialContinueOnError: "Eksekusi serial; lanjutkan setelah gagal", + parallelContinueOnError: "Eksekusi paralel; lanjutkan setelah gagal", + serial: "Serial", + parallel: "Paralel", + switchToParallel: "Alihkan ke paralel", + switchToSerial: "Alihkan ke serial", + elapsed: "Berlalu: {duration}", + pending: "Tertunda", + awaitingConfirmation: "Menunggu konfirmasi", + running: "Berjalan", + success: "Berhasil", + failed: "Gagal", + skipped: "Dilewati", + cancelled: "Dibatalkan", + notExecuted: "Tidak dieksekusi", + execute: "Eksekusi", + cancelBatch: "Batalkan batch", + dangerTitle: "Konfirmasi eksekusi target", + dangerConfirm: "Eksekusi pada target ini", + resultTabPrefix: "Multi-db", + mergeResults: "Tampilan hasil gabungan", + mergeResultsBack: "Kembali ke progres", + mergedSourceColumn: "Sumber", + mergedSources: "{count} sumber data · {rows} baris", + mergedSourceRowCap: "Hingga {count} baris per sumber data", + mergedWriteSummary: "{targets} target · {rows} baris terpengaruh", + mergedSourceCapReached: "{count} sumber data mencapai batas per sumber ({limit} baris); mungkin masih ada baris lain", + mergedSummaryLabel: "JUMLAH", + mergedSummaryCellHint: "Jumlah dari {count} nilai numerik", + backgroundBatchDone: "{count} sumber data selesai; tampilan gabungan sudah siap", + statusColumn: "Status", + affectedRowsColumn: "Baris terpengaruh", + durationColumn: "Durasi", + errorColumn: "Galat", + rerunTarget: "Jalankan ulang di sini", + dangerTargets: "Sumber data ({count})", + dangerConfirmCodePrompt: "Ketik kode ini untuk konfirmasi", + dangerConfirmCodeCopy: "Salin kode", + dangerConfirmCodeOnce: "Ditanyakan sekali per batch; tempel jika Anda sudah menyalinnya.", + dangerConfirmCodePlaceholder: "Kode verifikasi", + txnColumn: "Transaksi", + txnOpen: "Belum di-commit", + txnCommitted: "Di-commit", + txnRolledBack: "Di-rollback", + txnOpenHint: "{count} target belum di-commit", + commitAllTargets: "Commit semua ({count})", + rollbackAllTargets: "Rollback semua ({count})", + txnActionFailed: "Aksi transaksi gagal: {message}", + elapsedColumn: "Berlalu: {duration}", + executedAtColumn: "Dieksekusi pada", + executedAtChip: "Dieksekusi pada: {time}", + mergedRowLimit: "Menampilkan {count} baris pertama; total mencakup semua {rows} baris", + mergedTruncated: "Hasil gabungan dipotong (batas {count} baris)", + mergedEmpty: "Batch ini tidak menghasilkan baris untuk digabungkan.", + mergedSheetName: "Hasil gabungan", + exportCurrentPage: "Ekspor halaman saat ini", + exportAllRows: "Ekspor semua (Excel)", + exportedRows: "{rows} baris diekspor", + exportedRowsCapped: "{rows} baris diekspor; {count} sumber data mencapai batas {limit} baris", + }, + externalSqlFile: { + modifiedTitle: "File berubah di luar DBX", + modifiedDescription: "{path} telah diubah oleh program lain. Pilih versi mana yang akan dipertahankan.", + deletedTitle: "File sudah tidak ada", + deletedDescription: "{path} dihapus atau dipindahkan di luar DBX. Konten editor masih tersedia.", + unsavedWarning: "Editor ini juga memiliki perubahan yang belum disimpan. Memuat versi eksternal akan membuangnya.", + deletedUnsavedWarning: "Editor ini memiliki perubahan yang belum disimpan. Menutup tab akan membuangnya.", + keepEditor: "Pertahankan konten editor", + loadLatest: "Muat yang terbaru", + cancelSave: "Batalkan simpan", + loadExternal: "Muat versi eksternal", + overwriteSave: "Timpa file", + keepEditing: "Lanjutkan mengedit", + saveAs: "Simpan sebagai...", + recreate: "Buat ulang file", + closeTab: "Tutup tab", + loadFailed: "Gagal memuat konten file terbaru: {message}", + checkFailed: "Gagal memeriksa file SQL eksternal: {message}", + changedAgain: "File berubah lagi saat sedang disimpan. Coba lagi.", + }, + updates: { + preparationWindowOperation: "Tunggu operasi jendela saat ini selesai sebelum memperbarui.", + preparationBusy: "Pembaruan sudah sedang dipersiapkan.", + preparationCancelled: "Persiapan pembaruan dibatalkan.", + preparationTimeout: "Jendela tidak tersimpan dalam 5 detik. Coba lagi.", + preparationWindowsChanged: "Jendela yang terbuka berubah. Coba lagi pembaruannya.", + preparationTasks: "Selesaikan tugas aktif dan transaksi sebelum memperbarui.", + preparationDrafts: "Simpan atau buang perubahan yang belum disimpan sebelum memperbarui.", + preparationConfig: "Selesaikan pengeditan konfigurasi saat ini sebelum memperbarui.", + preparationNotReady: "Persiapan pembaruan belum siap. Coba lagi.", + downloadedReady: "Versi baru v{version} sudah diunduh. Restart untuk memperbarui.", + restartAndUpdate: "Restart & Perbarui", + preparing: "Mempersiapkan pembaruan…", + retryDownload: "Coba Unduh Lagi", + title: "Pembaruan", + centerTitle: "Update Center", + centerAvailable: "{count} tersedia", + check: "Periksa pembaruan", + checking: "Memeriksa pembaruan…", + updateReadyTooltip: "Pembaruan siap — klik untuk memasang", + restartRequiredTooltip: "Pembaruan terpasang — restart untuk menyelesaikan", + availableTitle: "Pembaruan tersedia", + availableMessage: "DBX {latest} tersedia. Anda menggunakan {current}.", + upToDate: "DBX sudah versi terbaru ({version}).", + failed: "Gagal memeriksa pembaruan: {error}", + rateLimited: "Pemeriksaan pembaruan GitHub sementara dibatasi. Anda masih dapat membuka halaman rilis untuk memeriksa secara manual.", + openRelease: "Buka Rilis", + ignoreVersion: "Abaikan versi ini", + versionIgnored: "Versi {version} diabaikan. Anda akan diingatkan kembali saat versi berikutnya dirilis.", + ignoreVersionFailed: "Gagal menyimpan versi yang diabaikan: {error}", + downloadInBackground: "Unduh di Latar Belakang", + cancelDownload: "Batalkan Unduhan", + downloadStarted: "Mengunduh DBX {version} di latar belakang.", + activeTasksBlockUpdate: "{count} tugas masih berjalan. Tunggu hingga selesai sebelum memperbarui DBX.", + portableAutomaticUpdate: "DBX akan mengunduh ZIP portabel bertanda tangan, mengganti DBX.exe saja setelah keluar, lalu restart otomatis. portable.dbx dan data akan tetap dipertahankan.", + windows7ManualUpdate: "Windows 7 memerlukan installer offline WebView2 109 khusus. Buka halaman rilis dan unduh paket Windows 7 untuk memperbarui.", + downloading: "Mengunduh {progress}%", + downloadFailed: "Unduhan pembaruan gagal: {error}", + cacheWriteFailed: "Tidak dapat menyimpan pembaruan yang diunduh: {error}. Periksa apakah antivirus memblokir DBX atau folder cache pembaruan dapat ditulisi, lalu coba lagi.", + downloadCanceled: "Unduhan pembaruan dibatalkan.", + readyToInstall: "DBX {version} siap dipasang.", + installNow: "Pasang Sekarang", + installedReadyToRestart: "DBX telah diperbarui. Restart untuk menyelesaikan.", + networkOrMirrorFailed: "Koneksi jaringan timeout atau mirror unduhan saat ini tidak dapat dijangkau. Periksa koneksi Anda atau klik 'Buka Rilis' untuk mengunduh secara manual.", + source: "Sumber pembaruan", + sourceOfficial: "Sumber resmi", + sourceCnb: "CNB", + installing: "Memasang pembaruan...", + portableHelperFailed: "Helper pembaruan portabel tidak dapat dijalankan: {error}", + installFailed: "Pemasangan pembaruan gagal: {error}", + restart: "Keluar & Restart", + updateAction: "Perbarui", + updateNow: "Perbarui Sekarang", + updateInBackground: "Jalankan di Latar Belakang", + updating: "Memperbarui…", + notInstalled: "Belum terpasang", + componentsAutoUpdated: "Diperbarui otomatis: {components}.", + componentListSeparator: ", ", + componentsAutoUpdateFailed: "{count} pembaruan komponen gagal. Coba lagi secara manual nanti.", + updateAll: "Perbarui semua", + componentsAutoUpdateSkipped: "Beberapa pembaruan driver ditunda karena sedang digunakan oleh koneksi aktif.", + restartFailed: "Gagal me-restart aplikasi: {error}", + exitAndUpdate: "Keluar & Perbarui", + dockerUsersRun: "Pengguna Docker sebaiknya menjalankan", + toUpdate: "untuk memperbarui", + historyTab: "Versi lama", + historyHint: "Cadangkan data Anda sebelum melakukan rollback. Versi lama mungkin tidak dapat membaca data atau kredensial yang dibuat oleh versi yang lebih baru.", + historyPublishedOn: "Dirilis {date}", + historyLoadFailed: "Gagal memuat versi lama. Silakan coba lagi nanti.", + historyLoadMore: "Muat lebih banyak", + }, + pluginDock: { + close: "Tutup terminal", + hide: "Sembunyikan panel", + collapse: "Ciutkan panel", + expand: "Perluas panel", + maximize: "Maksimalkan panel", + restore: "Pulihkan panel", + newTerminal: "Terminal baru", + newLocalTerminal: "Terminal lokal", + filter: "Filter…", + noMatch: "Tidak ada yang cocok", + }, + sidebar: { + connections: "KONEKSI", + noConnections: "Belum ada koneksi", + importExport: "Impor / Ekspor", + import: "Impor Koneksi", + importDbx: "Impor Konfigurasi DBX", + importNavicat: "Impor Navicat NCX", + importDbeaver: "Impor DBeaver", + importDatagrip: "Impor DataGrip", + export: "Ekspor Koneksi", + collapseAll: "Ciutkan semua", + collapse: "Ciutkan bilah sisi", + expand: "Perluas bilah sisi", + showMore: "Tampilkan {count} lagi...", + filterByType: "Filter berdasarkan tipe", + showActiveConnectionsOnly: "Tampilkan hanya koneksi aktif", + activeConnectionsStatus: "Koneksi aktif: {count}", + disconnectAllActiveConnections: "Putuskan semua koneksi aktif", + sortConnections: "Urutkan koneksi", + sortConnectionsManual: "Urutan manual", + sortConnectionsAscending: "Nama: A–Z", + sortConnectionsDescending: "Nama: Z–A", + searchConnectionSkipped: "Pencarian melewati koneksi ini: {message}", + searchScopeConnection: "Koneksi", + searchScopeDatabase: "Database", + searchScopeSchema: "Skema", + searchScopeTable: "Tabel", + searchScopeView: "Tampilan", + searchTablesInCurrentScope: "Cari tabel di database ini...", + clearTableSearch: "Bersihkan pencarian tabel", + localTableSearch: "Pencarian lokal", + localTableSearchTooltip: "Cari indeks tabel lokal tanpa permintaan jarak jauh. Nonaktifkan untuk mencari secara jarak jauh. Gunakan segarkan untuk membangun atau memperbarui indeks.", + refreshLocalTableSearchIndex: "Segarkan indeks tabel lokal", + globalLocalSearch: "Pencarian lokal", + globalLocalSearchTooltip: "Cari hanya objek bilah sisi yang sudah dimuat tanpa permintaan jarak jauh.", + regexSearch: "Pencarian regex", + regexSearchTooltip: "Cocokkan nama, komentar, dan alias di bilah sisi dengan ekspresi reguler JavaScript.", + clearFilter: "Bersihkan filter", + locateActiveTab: "Cari di bilah sisi", + }, + savedSql: { + saveToLibrary: "Simpan ke SQL Library", + saveToFile: "Simpan Secara Lokal", + save: "Simpan", + saved: "SQL disimpan", + saveFailed: "Gagal menyimpan SQL: {message}", + fileName: "Nama file", + folder: "Folder", + rootFolder: "SQL Library", + newQuery: "Kueri Baru", + newFolder: "Folder SQL Baru", + newSubfolder: "Subfolder Baru", + newFolderDefault: "Folder Baru", + renameFolder: "Ganti Nama Folder", + deleteFolder: "Hapus Folder", + deleteFolderConfirm: "Hapus “{name}” beserta file SQL di dalamnya?", + open: "Buka SQL", + copyFile: "Salin SQL", + pasteFile: "Tempel SQL", + copied: "{count} file SQL disalin", + pasted: "{count} file SQL ditempel", + nothingToPaste: "Tidak ada file SQL untuk ditempel", + pasteFailed: "Gagal menempel SQL: {message}", + renameFile: "Ganti Nama SQL", + renameFailed: "Gagal mengganti nama SQL: {message}", + nameConflict: 'SQL bernama "{name}" sudah ada di lokasi ini', + deleteFile: "Hapus SQL", + deleteFileConfirm: "Hapus “{name}”?", + createFolderOption: "Buat folder “{name}”", + folderPlaceholder: "Pilih folder", + searchPlaceholder: "Cari folder...", + createFolderFailed: "Gagal membuat folder: {message}", + }, + sqlLibrary: { + title: "SQL Library", + storageHelp: "Konten SQL Library disimpan di data aplikasi DBX, bukan sebagai file .sql tersendiri di disk.\nUntuk menggunakan file di sistem berkas, ekspor SQL Library.", + unassociated: "Tidak terkait", + deletedConnection: "Koneksi dihapus", + openInCurrentDatabase: "Buka di Database Saat Ini", + empty: "Belum ada kueri tersimpan", + emptyFolder: "Folder kosong", + unfiled: "Belum dikelompokkan", + exportFile: "Ekspor SQL", + exportFolder: "Ekspor Folder", + exportLibrary: "Ekspor SQL Library", + importDirectory: "Impor Folder Lokal", + importIntoFolder: "Impor Ke Folder", + openStorageDirectory: "Buka Direktori Penyimpanan SQL", + chooseSyncDirectory: "Tetapkan Direktori Sinkronisasi Lokal", + disableSyncDirectory: "Nonaktifkan Direktori Sinkronisasi Lokal", + syncDirectorySaved: "Direktori sinkronisasi lokal SQL disimpan", + syncDirectoryDisabled: "Sinkronisasi lokal SQL dinonaktifkan", + syncDirectoryFailed: "Gagal menetapkan direktori sinkronisasi: {message}", + openDirectoryFailed: "Gagal membuka direktori: {message}", + noSyncDirectory: "Silakan tetapkan direktori sinkronisasi lokal terlebih dahulu", + exported: "Diekspor", + exportFailed: "Ekspor gagal: {message}", + importFailed: "Impor gagal: {message}", + importNone: "Tidak ditemukan file .sql di folder yang dipilih", + imported: "{count} file SQL diimpor", + desktopOnly: "Fitur ini hanya tersedia di aplikasi desktop", + noConnection: "Tidak ada koneksi yang tersedia untuk impor", + batchDelete: "Hapus Massal", + batchDeleteConfirm: "Yakin ingin menghapus {count} item terpilih? Tindakan ini tidak dapat dibatalkan.", + batchDeleteSuccess: "Berhasil menghapus {count} item", + moveToFolder: "Pindahkan ke Folder...", + moveSelectedToFolder: "Pindahkan {count} SQL ke Folder...", + moveSuccess: "{count} file SQL dipindahkan", + moveFailed: "Gagal memindahkan SQL: {message}", + changeTarget: "Ubah Koneksi/Database ({count})...", + changeTargetTitle: "Ubah Koneksi/Database", + changeTargetDescription: "Pilih target eksekusi untuk {count} file SQL yang dipilih.", + targetConnection: "Koneksi", + targetCatalog: "Katalog", + targetDatabase: "Database", + noTargetConnection: "Tidak ada koneksi SQL yang tersedia.", + changeTargetConfirm: "Ubah Target", + changeTargetLoadFailed: "Gagal memuat opsi target: {message}", + changeTargetSuccess: "Target untuk {count} file SQL diubah", + changeTargetPartial: "{count} file SQL diubah; {failed} gagal: {message}", + changeTargetFailed: "Gagal mengubah target SQL: {message}", + clearSelection: "Bersihkan Pilihan", + sortByDate: "Urutkan berdasarkan Tanggal Diubah", + sortByFolder: "Urutkan berdasarkan Struktur Folder", + collapseAll: "Ciutkan semua", + }, + + connection: { + title: "Koneksi Baru", + name: "Nama", + namePlaceholder: "Nama koneksi, dibuat otomatis jika kosong", + note: "Catatan", + noteShow: "Tampilkan", + noteShowInSidebar: "Tampilkan catatan di daftar koneksi", + notePlaceholder: "Jangan simpan kata sandi dalam bentuk teks biasa di catatan", + type: "Tipe", + host: "Host", + addHost: "Tambah Host", + filePath: "Jalur File", + h2FileMode: "File", + h2TcpMode: "TCP", + h2FilePathRequired: "Jalur file H2 tidak boleh kosong", + createDuckDbFile: "Buat file DuckDB", + createSqliteFile: "Buat database SQLite", + memoryDatabasePathHint: "Gunakan :memory: untuk membuat database SQLite atau DuckDB in-memory.", + sqliteCipherKey: "Kunci Enkripsi SQLite", + sqliteCipherKeyPlaceholder: "Biarkan kosong untuk SQLite tanpa enkripsi", + sqliteExtensions: "Ekstensi SQLite", + sqliteExtensionsPlaceholder: "/path/to/regexp.dylib\n/path/to/text.dylib|sqlite3_text_init", + sqliteExtensionsHint: "Satu .dylib/.so/.dll per baris. Gunakan “path|entry point” jika entry point diperlukan. Dimuat saat koneksi dibuat, setelah itu load_extension dinonaktifkan.", + initScript: "Skrip Inisialisasi", + initScriptPlaceholder: "INSTALL quack;\nLOAD quack;\nATTACH 'quack:host' AS remote (TOKEN '...');", + initScriptHint: "Pernyataan SQL yang dijalankan setiap kali koneksi dibuka (INSTALL/LOAD, SET, CREATE SECRET, ATTACH ...). Database yang di-attach di sini akan muncul di bilah sisi.", + sqliteExtensionBrowse: "Pilih ekstensi SQLite", + user: "Pengguna", + password: "Kata Sandi", + dynamodbEndpoint: "Endpoint", + dynamodbRegion: "Region", + dynamodbAccessKeyId: "Access Key ID", + dynamodbSecretAccessKey: "Secret Access Key", + dynamodbSessionToken: "Session Token", + dynamodbSessionTokenPlaceholder: "Opsional", + dynamodbCredentialsRequired: "DynamoDB memerlukan Access Key ID dan Secret Access Key", + savePassword: "Simpan kata sandi", + savePasswordHint: "Kata sandi disimpan, sehingga Anda tidak perlu memasukkannya lagi.", + savePasswordSessionHint: "Kata sandi hanya disimpan untuk sesi ini dan dihapus saat Anda keluar dari aplikasi.", + disconnectAndForgetPassword: "Putuskan Sambungan dan Lupakan Kata Sandi", + passwordForgotten: "Kata sandi dilupakan. Menyambung ulang akan menanyakannya kembali.", + promptPasswordTitle: "Masukkan kata sandi", + promptPasswordMessage: "Masukkan kata sandi untuk koneksi “{connection}”. Untuk kata sandi kosong, hubungkan langsung.", + promptPasswordPlaceholder: "Kata Sandi", + promptPasswordSubmit: "Hubungkan", + promptPasswordCancel: "Batal", + promptRememberPassword: "Ingat kata sandi", + rememberPasswordSaveFailed: "Terhubung, tetapi DBX tidak dapat mengingat kata sandi: {message}", + mysqlMissingPasswordHint: "Tidak ada kata sandi database yang dikirim. Masukkan kata sandi dan coba lagi.", + database: "Database", + databasePlaceholder: "Opsional", + databasePlaceholderRequired: "Wajib diisi, masukkan database yang sudah ada", + databasePlaceholderWithDefault: "Opsional, default ke {database}", + kingbaseDatabaseRequired: "KingbaseES memerlukan database yang sudah ada sebelum menghubungkan atau memuat daftar database.", + xuguDatabaseRequired: "XuguDB memerlukan database yang sudah ada sebelum menghubungkan.", + defaultDatabase: "DB Default", + authDatabase: "DB Auth", + authDatabasePlaceholder: "Opsional, biasanya admin", + authMechanism: "Mekanisme Auth", + authMechanismDefault: "Default", + oidcBrowserAuthHint: "Autentikasi dibuka di browser sistem Anda. Kata sandi database tidak diperlukan.", + driverMode: "Driver", + mongoDriverAuto: "Otomatis", + mongoDriverLegacy: "Legacy", + serviceName: "Service/SID", + serviceNameOnly: "Nama Service", + oracleTnsAlias: "Alias Jaringan", + oracleTnsAliasPlaceholder: "Alias dari tnsnames.ora", + oracleDriverMode: "Mode driver", + oracleOciPathPlaceholder: "Direktori yang berisi oci.dll", + oracleOciPathBrowse: "Pilih direktori Oracle Instant Client", + oracleOciPathHint: "Lokasi Instant Client adalah pengaturan global yang digunakan bersama oleh semua koneksi OCI; koneksi OCI baru akan menggunakannya secara otomatis.", + oracleOciClientPathMissing: "Tidak ada direktori Oracle Instant Client yang dikonfigurasi. Koneksi OCI mungkin gagal memuat oci.dll — tetapkan direktori yang berisi file tersebut di bagian mode driver.", + oracleOciNlsLangPlaceholder: "Pilih set karakter klien", + oracleOciNlsLangFollowGlobal: "Ikuti default global (kosong)", + oracleOciNlsLangFollowGlobalValue: "Mengikuti default global: {value}", + oraclePathPickerDesktopOnly: "Memilih jalur lokal hanya tersedia di aplikasi desktop.", + oracleOciNlsLangPlaceholderGlobal: "Mengikuti default global: {value}", + oracleOciNlsLangSaveGlobal: "Simpan sebagai default global", + oracleOciNlsLangSavedGlobal: "Disimpan sebagai default global: {value}", + oracleOciTnsAdminPlaceholderGlobal: "Mengikuti default global: {value}", + oracleOciTnsAdminHint: "TNS_ADMIN tingkat koneksi: direktori yang berisi tnsnames.ora / sqlnet.ora / wallet; kosong mengikuti default global. Wallet ADB dan opsi jaringan sqlnet.ora berfungsi tanpa beralih ke formulir koneksi TNS.", + oracleOciTnsAdminSaveGlobal: "Simpan sebagai default global", + oracleOciTnsAdminSavedGlobal: "Disimpan sebagai default global: {value}", + oracleOciTnsAdminSaveGlobalEmpty: "Masukkan direktori TNS_ADMIN untuk disimpan terlebih dahulu", + oracleOciNlsLangSaveGlobalEmpty: "Pilih NLS_LANG untuk disimpan terlebih dahulu", + oracleOciNlsLangHint: "Set karakter klien tingkat koneksi (NLS_LANG) untuk OCI; menimpanya memberi koneksi ini proses agent tersendiri. Tetapkan AL32UTF8 agar sesuai dengan database UTF-8 dan menghindari karakter rusak.", + oracleTnsAdminPlaceholder: "Direktori yang berisi tnsnames.ora", + oracleTnsAdminBrowse: "Pilih direktori TNS_ADMIN", + oracleTnsPathHint: "Backend DBX/agent Oracle membaca jalur ini. Jalur desktop bersifat lokal; jalur Web dan Docker berada di server.", + oracleTnsAliasRequired: "Mode TNS Oracle memerlukan alias jaringan.", + oracleTnsAdminRequired: "Mode TNS Oracle memerlukan direktori TNS_ADMIN yang berisi tnsnames.ora.", + oracleTnsTransportUnsupported: "Koneksi TNS Oracle tidak dapat menggunakan lapisan SSH, proxy, atau HTTP tunnel. Hapus lapisan transport atau gunakan mode Service Name/SID.", + igniteVersion: "Versi Ignite", + elasticsearchDirectMode: "Langsung", + elasticsearchKibanaProxyMode: "Proxy Kibana", + elasticsearchKibanaHost: "Host Kibana", + elasticsearchKibanaBasePath: "Base Path", + elasticsearchConnectivityCheckPath: "Jalur Konektivitas", + elasticsearchConnectivityCheckPathPlaceholder: "/ atau /my-index/_search", + elasticsearchConnectivityCheckDisabled: "Nonaktifkan pemeriksaan konektivitas", + elasticsearchConnectivityCheckDisabledHint: "Saat aktif, hubungkan dan uji akan melewati permintaan probe dan menganggap server dapat dijangkau. Gunakan ini saat akun tidak memiliki izin untuk root path dan jalur pemeriksaan mana pun, atau saat izin berbeda antar klaster.", + elasticsearchIndexGroupingPattern: "Regex pengelompokan indeks", + elasticsearchIndexGroupingPatternPlaceholder: "nonaktif secara default; masukkan regex untuk mengaktifkan", + elasticsearchIndexGroupingPatternHint: "Nonaktif secara default (skema penamaan berbeda-beda). Masukkan ekspresi reguler untuk mengaktifkan: indeks rolling atau deret waktu yang cocok akan digabungkan menjadi satu pola wildcard yang dapat dikueri, menyembunyikan detail per hari.", + version: "Versi", + victoriametricsApiPath: "Jalur API", + victoriametricsApiPathHint: "Gunakan /prometheus untuk deployment single-node, atau /select/tenantID/prometheus untuk klaster.", + victoriametricsLookback: "Lookback Metadata", + victoriametricsLookbackHint: "Digunakan untuk penemuan metrik dan kolom label, misalnya 1h atau 7d. Pratinjau metrik menggunakan 1h dan tetap dapat diubah.", + victoriametricsInvalidApiPath: "Jalur API VictoriaMetrics harus kosong atau diawali dengan /.", + victoriametricsInvalidLookback: "Lookback VictoriaMetrics tidak valid. Gunakan nilai seperti 15m, 1h, atau 7d.", + salesforceInstanceUrl: "URL Instance", + salesforceInstanceUrlPlaceholder: "https://acme.my.salesforce.com", + salesforceInstanceUrlHint: "Hostname org atau URL instance lengkap; disegarkan otomatis dari respons token setelah login berhasil.", + salesforceAccessToken: "Access Token", + salesforceAccessTokenPlaceholder: "Session ID atau access token", + salesforceAccessTokenHint: "Tempelkan access token Salesforce atau session ID. Gunakan opsi OAuth di bawah untuk login berbasis browser atau otorisasi device code.", + salesforceApiVersion: "Versi API", + salesforceApiVersionHint: "Versi REST API Salesforce, misalnya v62.0. Biarkan kosong untuk menggunakan versi default yang ditetapkan.", + salesforceAuthMode: "Autentikasi", + salesforceAuthModeToken: "Access Token", + salesforceAuthModeOauth: "OAuth Browser", + salesforceAuthModeDevice: "Device Code", + salesforceAuthModePassword: "Username & Password", + salesforceAuthModeOauthDesktopOnly: "OAuth Browser hanya tersedia di aplikasi desktop.", + salesforceEnvironment: "Environment", + salesforceEnvironmentProduction: "Production", + salesforceEnvironmentSandbox: "Sandbox", + salesforceEnvironmentCustom: "Kustom", + salesforceLoginUrl: "URL Login", + salesforceLoginUrlPlaceholder: "https://login.salesforce.com", + salesforceLoginUrlHint: "Timpa URL login Salesforce saat org Anda menggunakan endpoint identitas kustom.", + salesforceClientId: "Client ID", + salesforceClientIdPlaceholder: "Consumer Key dari Connected App Anda", + salesforceClientIdHint: "Buat Connected App di Salesforce Setup → App Manager, aktifkan OAuth dengan PKCE, dan tetapkan Callback URL ke {callbackUrl}.", + salesforceClientIdHintShared: "Consumer key Connected App. Kedua mode ini tidak menggunakan callback URL, sehingga aplikasi yang sudah dibuat admin Anda dapat langsung digunakan.", + salesforceClientSecret: "Client Secret", + salesforceClientSecretPlaceholder: "Opsional — hanya untuk Connected App rahasia; biarkan kosong untuk klien publik PKCE", + salesforceOauthAuthorize: "Otorisasi dengan Salesforce", + salesforceOauthAuthorizing: "Menunggu login browser…", + salesforceOauthAuthorizingHint: "Jendela browser seharusnya sudah terbuka. Selesaikan login di Salesforce; tampilan ini akan diperbarui otomatis saat selesai.", + salesforceOauthAuthorized: "Terotorisasi (kredensial tersimpan)", + salesforceOauthReauthorize: "Otorisasi ulang", + salesforceOauthClientIdRequired: "Client ID Salesforce wajib diisi.", + salesforceOauthLoginUrlRequired: "URL Login kustom Salesforce wajib diisi.", + salesforceDeviceGetCode: "Dapatkan Device Code", + salesforceDeviceFlowNote: "Jika permintaan kode gagal dengan error unsupported atau disabled-flow, admin harus mengaktifkan Device Flow di pengaturan OAuth Connected App.", + salesforceDeviceUserCodeLabel: "Kode Pengguna", + salesforceDeviceUserCodeCopied: "Kode pengguna disalin", + salesforceDeviceOpenVerification: "Buka halaman verifikasi", + salesforceDeviceVerificationCopied: "URL verifikasi disalin", + salesforceDevicePolling: "Menunggu otorisasi…", + salesforceDevicePollingHint: "Buka halaman verifikasi di browser mana pun dan masukkan kode pengguna yang ditampilkan di atas.", + salesforceDeviceCancel: "Batal", + salesforceDeviceExpired: "Device code kedaluwarsa. Klik di bawah untuk meminta yang baru.", + salesforceDeviceDenied: "Otorisasi ditolak", + salesforceDeviceRestart: "Mulai lagi", + salesforceDeviceSecondsLeft: "{seconds} detik tersisa", + salesforceUsernameLabel: "Username", + salesforceUsernamePlaceholder: "user{'@'}example.com", + salesforceUsernameHint: "Username Salesforce. Untuk sandbox, sertakan akhiran sandbox (misalnya user{'@'}example.com.qas1).", + salesforceUserPasswordLabel: "Kata Sandi Pengguna", + salesforceUserPasswordPlaceholder: "Kata sandi (opsional + security token)", + salesforceUserPasswordHint: "Kata sandi Salesforce Anda. Jika IP Anda tidak dipercaya oleh org, tambahkan security token langsung setelah kata sandi. Sesi akan diautentikasi ulang secara otomatis dengan kredensial tersimpan ini.", + salesforcePasswordRopcNote: "Tidak perlu callback URL — Connected App yang sudah ada dapat digunakan. Profil Anda perlu API Enabled dan kebijakan pengguna aplikasi harus mencakup Anda. Kata sandi tidak pernah kembali ke formulir ini, sehingga tombol sign-in memerlukan pengetikan ulang.", + salesforcePasswordSignIn: "Masuk", + salesforcePasswordSignInAgain: "Masuk Lagi", + salesforceUsernameRequired: "Username Salesforce wajib diisi.", + salesforceUserPasswordRequired: "Kata sandi Salesforce wajib diisi.", + salesforceOauthSuccess: "Terhubung ke {instanceUrl}", + driverInstallHintPrefix: "Pasang driver yang diperlukan dari ", + driverInstallHintSuffix: " di bilah alat atas sebelum menghubungkan.", + driverName: "Nama Driver", + driverNamePlaceholder: "Nama vendor atau environment", + urlParams: "Parameter URL", + sessionVariablesHint: + "DBX menaikkan variabel sesi group_concat_max_len ke 1048576 agar hasil GROUP_CONCAT tidak terpotong secara diam-diam. Untuk mengikuti konfigurasi server sebagai gantinya, gunakan sessionVariables=group_concat_max_len={'@'}{'@'}global.group_concat_max_len (sintaks MySQL Connector/J; pisahkan beberapa variabel dengan koma).", + localInfilePathHint: "Untuk LOAD DATA LOCAL INFILE, whitelist setiap file secara eksplisit dengan localInfilePath=/absolute/path/file.csv. Ulangi parameter untuk file tambahan.", + d1AccountId: "Account ID", + d1DatabaseId: "Database ID", + d1ApiToken: "API Token", + d1TokenHint: "Token memerlukan izin D1 Read; penulisan, DDL, dan impor juga memerlukan D1 Write.", + d1FieldsRequired: "Cloudflare Account ID, D1 Database ID, dan API Token wajib diisi.", + spannerStructuredMode: "Resource ID", + spannerResourcePathMode: "Resource path", + spannerProject: "Project ID", + spannerInstance: "Instance ID", + spannerDatabase: "Database ID", + spannerResourcePathHint: "projects/my-project/instances/my-instance/databases/my-database", + spannerHostHint: "Biarkan host kosong untuk Google Cloud. Untuk emulator lokal, tetapkan host ke localhost dengan port 9010; gRPC plaintext diaktifkan otomatis untuk host loopback.", + spannerCredentialsHint: "Autentikasi menggunakan Application Default Credentials. Untuk menggunakan file kunci service account, tambahkan credentials=/path/key.json ke Parameter URL.", + spannerFieldsRequired: "Project, instance, dan database Cloud Spanner wajib diisi.", + hiveAuthMode: "Auth", + hiveAuthNone: "Tidak ada", + hivePrincipal: "Principal", + hiveKerberosPrincipalRequired: "Principal Kerberos Hive wajib diisi", + hiveKrb5ConfBrowse: "Pilih krb5.conf", + hiveJaasConfigBrowse: "Pilih konfigurasi JAAS", + hiveTicketCache: "Ticket Cache", + hiveTicketCacheFallback: "Tetapkan useSubjectCredsOnly=false", + hiveJvmOptions: "Opsi JVM", + hiveJvmOptionsPlaceholder: "-Dsun.security.krb5.debug=true", + gbaseServer: "GBASEDBTSERVER", + gbaseServerHint: "Harus cocok dengan DBSERVERNAME atau DBSERVERALIASES server.", + gbaseServerMismatch: "Koneksi GBase 8s gagal karena GBASEDBTSERVER tidak cocok dengan DBSERVERNAME atau DBSERVERALIASES server. Isi GBASEDBTSERVER dengan nama server yang sebenarnya.", + informixServer: "INFORMIXSERVER", + sslEnable: "Aktifkan koneksi terenkripsi", + caCertPath: "Sertifikat CA", + caCertPathPlaceholder: "Opsional, mis. ~/.yandex/RootCA.crt", + caCertPathBrowse: "Jelajahi sertifikat", + cassandraTruststore: "Truststore", + cassandraTruststorePlaceholder: "/path/to/client.truststore", + cassandraTruststorePassword: "Kata sandi truststore", + cassandraTruststoreBrowse: "Pilih truststore Cassandra", + cassandraTruststoreHint: "Truststore JKS atau PKCS#12 yang digunakan untuk memverifikasi sertifikat server Cassandra.", + cassandraTruststorePasswordRequiresPath: "Pilih truststore Cassandra sebelum memasukkan kata sandinya.", + cassandraKeystore: "Keystore Klien", + cassandraKeystorePlaceholder: "/path/to/client.keystore", + cassandraKeystorePassword: "Kata sandi keystore", + cassandraKeystoreBrowse: "Pilih keystore klien Cassandra", + cassandraKeystoreHint: "Keystore JKS atau PKCS#12 opsional untuk autentikasi sertifikat klien.", + cassandraKeystorePasswordRequiresPath: "Pilih keystore klien Cassandra sebelum memasukkan kata sandinya.", + damengSslFilesPath: "Direktori sertifikat", + damengSslFilesPathPlaceholder: "/path/to/dmcert", + damengSslFilesPathBrowse: "Pilih direktori sertifikat", + damengSslKeystorePassword: "Kata sandi keystore", + damengSslHint: "JDBC DM8 membaca sertifikat SSL dari direktori ini dan meneruskan kedua field melalui parameter URL.", + damengSslProtocol: "Protokol SSL", + damengSslProtocolPlaceholder: "Opsional, mis. TLSv1.2", + damengSslVerificationHint: "Verifikasi sertifikat dikendalikan oleh pengaturan ENABLE_ENCRYPT server DM8. Mode 5 memverifikasi sertifikat server; mode 4 mengenkripsi tanpa verifikasi sertifikat.", + damengJvmOptions: "Properti sistem JVM", + damengJvmOptionsPlaceholder: "-Djava.net.preferIPv4Stack=true", + damengJvmOptionsHint: "Satu -Dkey atau -Dkey=value per baris. Nilai dengan spasi tidak memerlukan tanda kutip shell.", + damengJvmOptionsInvalid: "Baris {line} harus berupa properti sistem -Dkey atau -Dkey=value tanpa tanda kutip shell.", + damengBuiltinDriver: "DM8 Bawaan", + damengCustomDriver: "DM6 / JAR Kustom", + damengDriverModeHint: "Gunakan driver bawaan untuk DM8. Untuk DM6 atau versi kompatibel lainnya, pilih JAR JDBC resminya.", + damengCustomDriverHint: "Pilih JAR JDBC Dameng dari sumber berlisensi. Driver kustom diisolasi di dalam agent Dameng dan tidak memerlukan plugin JDBC generik.", + damengCustomDriverRequired: "Pilih JAR driver JDBC Dameng.", + sundbCustomDriverHint: "SunDB Agent sudah menyertakan driver JDBC vendor, jadi tidak diperlukan JAR (driver class csii.sundb.jdbc.SundbDriver). Sediakan JAR di sini hanya untuk memuat driver vendor yang lebih baru; driver kustom dimuat secara terisolasi di dalam Agent.", + redisTlsInsecure: "Lewati verifikasi sertifikat", + redisTlsInsecureHint: "Setara dengan redis-cli --tls --insecure, untuk sertifikat self-signed atau CA privat.", + mysqlTlsMode: "Mode TLS", + mysqlTlsModePreferred: "Preferred", + mysqlTlsModeDisabled: "Dinonaktifkan", + mysqlTlsModeRequired: "Wajib", + mysqlTlsModeVerifyCa: "Verifikasi CA", + mysqlTlsModeVerifyIdentity: "Verifikasi Identitas", + mysqlCleartextPasswordAuth: "Auth Kata Sandi Cleartext", + mysqlCleartextPasswordAuthHint: "Aktifkan hanya jika server MySQL memerlukan plugin autentikasi kata sandi cleartext.", + mysqlCaCertHint: "Diperlukan untuk Verifikasi CA dan Verifikasi Identitas saat sertifikat server menggunakan CA privat.", + mysqlClientCert: "Auth Klien", + mysqlClientCertPlaceholder: "/path/to/client.crt", + mysqlClientKeyPlaceholder: "/path/to/client.key", + mysqlClientCertHint: "Sertifikat klien dan private key harus diberikan bersamaan saat MySQL memerlukan mTLS.", + mysqlTlsConnectionFailureHint: "Jika server MySQL tidak memerlukan TLS, edit koneksi, tetapkan Mode TLS ke Dinonaktifkan, lalu coba lagi.", + mysqlUnsupportedCertVersionHint: "Verifikasi ketat tidak mendukung versi sertifikat server ini. Gantilah dengan sertifikat X.509 v3, atau gunakan mode Wajib hanya pada jaringan tepercaya.", + mysqlClientCertBrowse: "Pilih sertifikat klien", + mysqlClientKeyBrowse: "Pilih private key klien", + postgresSslMode: "Mode TLS", + postgresSslModeDisable: "Nonaktifkan", + postgresSslModePrefer: "Prefer", + postgresSslModeRequire: "Wajib", + postgresSslModeVerifyCa: "Verifikasi CA", + postgresSslModeVerifyFull: "Verifikasi Penuh", + postgresLegacyTls: "Kompatibilitas TLS lama", + postgresLegacyTlsHint: "Mendukung server yang dibatasi pada pertukaran kunci static RSA TLS 1.2. Ini kurang aman dibanding mode default; aktifkan hanya saat konfigurasi TLS server tidak dapat ditingkatkan.", + postgresServerCert: "CA Server", + postgresRootCertPlaceholder: "/path/to/ca.crt", + postgresRootCertHint: "Gunakan ini untuk verify-ca atau verify-full saat sertifikat server ditandatangani oleh CA privat.", + postgresRootCertBrowse: "Pilih sertifikat CA", + postgresClientCert: "Auth Klien", + postgresClientCertPlaceholder: "/path/to/client.crt", + postgresClientKeyPlaceholder: "/path/to/client.key", + postgresClientCertHint: "Sertifikat klien dan private key harus diberikan bersamaan saat PostgreSQL memerlukan mTLS.", + postgresClientCertBrowse: "Pilih sertifikat klien", + postgresClientKeyBrowse: "Pilih private key klien", + connectionUrlOptional: "URL (opsional)", + connectionUrlPlaceholder: "postgresql://user:pass{'@'}host:5432/db?sslmode=require", + parseConnectionUrl: "Urai URL koneksi", + parseConnectionUrlApplied: "URL koneksi diterapkan", + parseConnectionUrlFailed: "Gagal mengurai URL koneksi: {message}", + mode: "Mode Koneksi", + modeForm: "Formulir", + redisStandaloneMode: "Standalone", + redisSentinelMode: "Sentinel", + redisClusterMode: "Cluster", + oceanbaseMySQLMode: "Mode MySQL", + oceanbaseOracleMode: "Mode Oracle", + redisFirstSentinel: "Sentinel Pertama", + redisFirstClusterNode: "Seed Node Pertama", + redisSentinelNodes: "Node Sentinel", + redisClusterNodes: "Seed Node Cluster", + redisSentinelMaster: "Nama Master", + redisSentinelUser: "Pengguna Sentinel", + redisSentinelPassword: "Kata Sandi Sentinel", + redisSentinelTls: "TLS Sentinel", + redisSentinelTlsHint: "Gunakan TLS saat menghubungkan ke node Sentinel", + redisKeySeparator: "Pemisah Namespace Key", + redisKeyTemplates: "Template pencarian key", + redisKeyTemplatesPlaceholder: "Contoh:\nuser:{'{'}$userId{'}'}\nv3:adui:{'{'}$positionID{'}'}", + redisKeyTemplatesHint: "Satu template per baris. Jika ditetapkan, template ini menggantikan template key Redis global untuk koneksi ini.", + etcdEndpoints: "Endpoint", + etcdEndpointsHint: "Satu endpoint per baris. Biarkan kosong untuk menggunakan host dan port di atas.", + etcdV2ApiHint: "API v2 hanya tersedia pada etcd 2.x, atau etcd 3.0–3.5 yang dijalankan dengan --enable-v2. Riwayat key, lease, compaction, dan defragmentasi tidak tersedia.", + etcdGrpcMaxInbound: "Batas penerimaan gRPC (MiB)", + etcdGrpcMaxInboundHint: "Ukuran maksimum satu respons etcd. Default 32 MiB dan dibatasi hingga 256 MiB.", + etcdCaCertPlaceholder: "/path/to/ca.crt", + etcdCaCertBrowse: "Pilih sertifikat CA", + etcdClientAuth: "Auth Klien", + etcdClientCertPlaceholder: "/path/to/client.crt", + etcdClientKeyPlaceholder: "/path/to/client.key", + etcdClientCertHint: "Sertifikat klien dan private key harus diberikan bersamaan saat etcd memerlukan mTLS.", + clientCertHint: "Sertifikat klien dan private key harus diberikan bersamaan saat mutual TLS (mTLS) diperlukan.", + etcdClientCertBrowse: "Pilih sertifikat klien", + etcdClientKeyBrowse: "Pilih private key klien", + etcdClientCertPairRequired: "Sertifikat klien dan private key harus diberikan bersamaan.", + consulAddress: "Alamat API Consul", + consulAddressInvalid: "Masukkan alamat API Consul HTTP atau HTTPS absolut tanpa kredensial, parameter kueri, atau fragmen.", + consulToken: "ACL Token", + consulTokenPlaceholder: "ACL Token Consul opsional", + consulDatacenter: "Datacenter", + consulNamespace: "Namespace", + consulPartition: "Admin Partition", + consulAgentTargetNode: "Node target Agent", + consulAgentTargetAddress: "Alamat langsung Agent", + consulAgentTargetHint: "Diperlukan untuk penulisan Agent. Endpoint DNS/load-balanced dan Transport Layer tetap read-only.", + consulMeshFeatures: "Service mesh", + consulMeshVisible: "Tampilkan workspace service mesh lanjutan", + consulMeshVisibleHint: "Aktifkan hanya untuk mengelola Connect, intentions, atau peering. Saat dinonaktifkan, workspace tetap tersembunyi.", + consulOperatorWrites: "Penulisan Operator", + consulOperatorVisible: "Tampilkan workspace Operator eksperimental", + consulOperatorSnapshotRestore: "Aktifkan pemulihan snapshot", + consulOperatorAutopilot: "Aktifkan pembaruan Autopilot", + consulOperatorRaft: "Aktifkan perubahan Raft", + consulOperatorKeyring: "Aktifkan perubahan Keyring", + consulOperatorLicense: "Aktifkan pembaruan License", + consulAgentTargetIncomplete: "Node target Agent dan alamat langsung harus dikonfigurasi bersamaan.", + consulAgentTargetAddressMismatch: "Alamat langsung Agent harus cocok dengan host endpoint Consul.", + consulConsistency: "Konsistensi baca", + consulConsistencyDefault: "Default", + consulConsistencyStale: "Stale", + consulConsistencyConsistent: "Consistent", + consulTlsSkipVerify: "Lewati verifikasi sertifikat", + consulTlsSkipVerifyHint: "Gunakan hanya untuk endpoint Consul self-signed yang tepercaya.", + zookeeperConnectString: "Connect String", + zookeeperConnectStringHint: "Entri host:port yang dipisah koma atau baris, dengan /chroot bersama yang opsional. Biarkan kosong untuk menggunakan host dan port di atas.", + zookeeperClusterInputHint: "Untuk ensemble ZooKeeper, masukkan semua node baik di URL (misalnya zookeeper://zk-1:2181,zk-2:2181/app) atau di Connect String di bawah.", + zookeeperAuthMethod: "Autentikasi", + zookeeperAuthDigest: "Digest (default)", + zookeeperAuthSaslDigest: "SASL DIGEST-MD5", + zookeeperCreateModePersistent: "Persistent", + zookeeperCreateModeEphemeral: "Ephemeral", + zookeeperCreateModePersistentSequential: "Persistent Sequential", + zookeeperCreateModeEphemeralSequential: "Ephemeral Sequential", + nacosConsoleUrl: "Alamat manajemen Nacos", + nacosConsoleUrlHint: "Gunakan alamat yang sesuai dengan profil Nacos yang dipilih. URL browser dan API lengkap dapat digunakan.", + nacosConsoleUrlRequired: "Alamat manajemen Nacos wajib diisi", + nacosConsoleUrlAutoAdjusted: "URL Console Nacos disesuaikan dari {from} ke {to}.", + nacosWebConsoleUrl: "URL Web Console Nacos", + nacosWebConsoleUrlHint: "Opsional. Membuka console Nacos di browser Anda. Nacos 3 memerlukan alamat web-console terpisahnya sendiri; browser memerlukan akses langsung dan tidak menggunakan ulang tunnel atau autentikasi API DBX.", + nacosWebConsoleUrlInvalid: "URL Web Console Nacos harus berupa URL HTTP atau HTTPS yang valid tanpa kredensial tertanam.", + nacosRNacosOpenApiAutoAdjusted: "Beralih ke OpenAPI r-nacos: {from} → {to} (Context Path: /nacos).", + nacosImplementation: "Implementasi layanan", + nacosVersion: "Versi Nacos", + nacosVersionAuto: "Deteksi otomatis", + nacosPrimaryAddressRNacos: "Alamat API kompatibel Nacos", + nacosPrimaryAddressV2: "Alamat layanan (API dan console bersama)", + nacosPrimaryAddressV3: "Alamat Server / Admin API", + nacosPrimaryAddressAuto: "Alamat manajemen Nacos", + nacosPrimaryAddressHint: "Untuk Nacos 3, gunakan alamat Server / Admin API (biasanya http://host:8848/nacos), bukan console port 8080; prefix proxy kustom tetap dipertahankan.", + nacosRequestsUse: "Permintaan akan menggunakan {address}/…", + nacosNamespace: "Namespace", + nacosContextPath: "Context Path", + nacosContextPathPlaceholder: "Biarkan kosong atau /nacos", + nacosContextPathRestoreAuto: "Pulihkan otomatis", + nacosConfigurationHistory: "Riwayat konfigurasi", + nacosConfigurationHistoryEnable: "Aktifkan riwayat konfigurasi", + nacosConfigurationHistoryHint: + "Riwayat konfigurasi r-nacos hanya tersedia melalui console independennya (biasanya port 10848). Console memiliki sesi login terpisah dari OpenAPI kompatibel Nacos: OpenAPI mungkin tidak memerlukan autentikasi sementara console tetap memerlukannya. Gunakan akun pengguna r-nacos yang sama kecuali Anda sengaja memerlukan akun yang berbeda.", + nacosRNacosConsoleUrl: "URL Console r-nacos", + nacosRNacosConsoleUrlPlaceholder: "http://127.0.0.1:10848", + nacosRNacosConsoleUrlHint: "Opsional. Gunakan URL console independen (biasanya port 10848), bukan URL OpenAPI; ini mengaktifkan riwayat konfigurasi dan membaca tipe serta deskripsi konfigurasi r-nacos.", + nacosRNacosOpenApiRequired: "Alamat utama r-nacos harus menggunakan API kompatibel Nacos, bukan URL console independen.", + nacosRNacosConsoleUrlRequired: "Riwayat konfigurasi r-nacos memerlukan URL console.", + nacosConsoleAuthSeparateRequired: "Autentikasi utama adalah None; konfigurasikan kredensial console terpisah.", + nacosAuth: "Auth", + nacosAuthNone: "None", + nacosAuthUserPassword: "User / Password", + nacosConsoleAuthentication: "Autentikasi console", + nacosConsoleAuthInherit: "Gunakan kredensial utama", + nacosConsoleAuthSeparate: "Kredensial terpisah", + nacosConsoleAuthPrimaryNone: "Autentikasi utama adalah None; gunakan kredensial console terpisah.", + nacosConsoleUser: "Pengguna console", + nacosConsolePassword: "Kata sandi console", + nacosConsoleUsernameRequired: "Username console r-nacos wajib diisi", + nacosUsernameRequired: "Username Nacos wajib diisi", + nacosTls: "TLS", + nacosTlsSkipVerify: "Lewati verifikasi sertifikat", + nacosPageSize: "Ukuran Halaman", + nacosMetrics: "Metrik Prometheus", + nacosMetricsAuto: "Deteksi otomatis", + nacosMetricsDisabled: "Dinonaktifkan", + nacosMetricsCustom: "URL Kustom", + nacosMetricsAutoHint: "Dicoba berurutan: {addresses}", + nacosMetricsUrl: "URL Metrik", + nacosMetricsUrlInvalid: "Masukkan URL metrik Prometheus HTTP atau HTTPS absolut tanpa kredensial atau fragmen.", + kafkaKerberosPrincipal: "Principal", + kafkaKerberosKeytab: "Keytab", + kafkaKerberosServiceName: "Nama Service", + kafkaKerberosKrb5Conf: "krb5.conf", + kafkaKerberosPrincipalRequired: "Principal Kerberos Kafka wajib diisi", + kafkaKerberosKeytabRequired: "Jalur keytab Kerberos Kafka wajib diisi", + kafkaKerberosKeytabBrowse: "Pilih Keytab", + kafkaKerberosKrb5ConfBrowse: "Pilih krb5.conf", + kafkaKerberosKeytabPlaceholder: "Jalur pada mesin DBX Agent, mis. /etc/security/keytabs/user.keytab", + kafkaKerberosKrb5ConfPlaceholder: "Jalur opsional pada mesin DBX Agent, mis. /etc/krb5.conf", + kafkaKerberosPathHint: "Jalur keytab dan krb5.conf dibaca oleh DBX Agent dan harus ada di mesin yang menjalankan DBX Agent; file tidak diunggah dari browser ini.", + kafkaKerberosAuthHint: "Menggunakan login GSSAPI + keytab. Jika server memerlukan transport terenkripsi, tetapkan Security ke SASL_SSL; jika tidak, Auto atau SASL_PLAINTEXT dapat digunakan.", + mqSystem: "Sistem", + mqSystemPulsar: "Apache Pulsar", + mqSystemKafka: "Apache Kafka", + mqSystemRocketMq: "Apache RocketMQ", + rocketmqNamesrvAddr: "Alamat NameServer", + rocketmqNamesrvAddrPlaceholder: "127.0.0.1:9876", + rocketmqNamesrvAddrRequired: "Alamat NameServer RocketMQ wajib diisi", + rocketmqNamesrvAddrInvalid: "Alamat NameServer RocketMQ tidak valid", + rocketmqClusterName: "Nama Cluster", + rocketmqClusterNamePlaceholder: "Opsional, mis. DefaultCluster", + rocketmqAccessKey: "Access Key", + rocketmqSecretKey: "Secret Key", + rocketmqAclAuth: "ACL", + mqBootstrapServers: "Bootstrap Servers", + mqBootstrapServersPlaceholder: "127.0.0.1:9092", + mqBootstrapServersRequired: "Bootstrap servers Kafka wajib diisi", + mqBootstrapServersInvalid: "Bootstrap servers Kafka tidak valid", + mqKafkaConnectionSource: "Sumber Koneksi", + mqKafkaConnectionSourceBootstrap: "Bootstrap Servers", + mqKafkaConnectionSourceZooKeeper: "ZooKeeper (Kafka 1.x)", + mqKafkaZooKeeperServers: "Server ZooKeeper", + mqKafkaZooKeeperServersPlaceholder: "zk1:2181,zk2:2181/kafka", + mqSystemRabbitMq: "RabbitMQ", + mqRabbitmqAddresses: "Alamat", + mqRabbitmqAddressesPlaceholder: "127.0.0.1:5672", + mqRabbitmqAddressesRequired: "Alamat RabbitMQ wajib diisi", + mqRabbitmqAddressesInvalid: "Masukkan alamat RabbitMQ sebagai host:port (misalnya, 127.0.0.1:5672), tanpa amqp://", + mqVirtualHost: "Virtual Host", + mqVirtualHostPlaceholder: "/", + mqRabbitmqAdminUrl: "URL Management", + mqRabbitmqAdminUrlPlaceholder: "http://192.168.1.1:15672", + mqRabbitmqAdminUrlHint: "Biarkan kosong hanya untuk port AMQP default; port AMQP kustom memerlukan URL Management API yang dikonfigurasi secara independen. Jalur reverse-proxy seperti https://proxy/rmq didukung", + mqRabbitmqUsernamePlaceholder: "Default ke guest", + mqRabbitmqPasswordPlaceholder: "Default ke guest", + mqSecurity: "Security", + mqSecurityAuto: "Otomatis", + mqAdminUrl: "Admin URL", + mqAdminUrlRequired: "Admin URL MQ wajib diisi", + mqAdminUrlInvalid: "Admin URL MQ tidak valid", + mqAuth: "Auth", + mqAuthNone: "Tidak ada", + mqAuthToken: "Token", + mqAuthBasic: "Basic", + mqAuthKerberos: "Kerberos", + mqAuthApiKey: "API Key", + mqAuthOauth2: "OAuth2", + mqToken: "Token", + mqSaslMechanism: "Mekanisme SASL", + mqApiKeyHeader: "Header", + mqApiKeyValue: "Value", + mqOauthIssuerUrl: "Issuer URL", + mqOauthClientId: "Client ID", + mqOauthClientSecret: "Client Secret", + mqOauthAudience: "Audience", + mqOauthScope: "Scope", + mqOauthIssuerRequired: "Autentikasi OAuth2 memerlukan issuer URL", + mqOauthClientIdRequired: "Autentikasi OAuth2 memerlukan client ID", + mqOauthClientSecretRequired: "Autentikasi OAuth2 memerlukan client secret", + mqTls: "TLS", + mqTlsSkipVerify: "Lewati verifikasi sertifikat", + mqPinnedVersion: "Versi Terpaku", + mqTokenSigning: "Penandatanganan token broker", + mqTokenSigningNone: "Tidak dikonfigurasi", + mqTokenSigningKey: "Kunci penandatanganan", + mqTokenSigningKeyRequired: "Kunci penandatanganan token broker wajib diisi", + mqTokenSigningKeyPlaceholderHs256: "SECRET Broker", + mqTokenSigningKeyPlaceholderRs256: "-----BEGIN PRIVATE KEY-----", + mqTokenSigningHint: "Pilih berdasarkan jwt.broker.token.mode broker: SECRET menggunakan HS256, PRIVATE menggunakan RS256. Kunci disimpan bersama secret koneksi.", + mqttBrokerAddress: "Alamat Broker", + mqttBrokerAddressPlaceholder: "127.0.0.1", + mqttBrokerPort: "Port", + mqttClientId: "Client ID", + mqttClientIdPlaceholder: "Dibuat otomatis", + mqttUsername: "Username", + mqttUsernamePlaceholder: "Opsional", + mqttPassword: "Kata Sandi", + mqttAuthCertificate: "Sertifikat klien", + mqttCaCertPath: "Jalur sertifikat CA", + mqttClientCertPath: "Jalur sertifikat klien", + mqttClientKeyPath: "Jalur private key klien", + mqttPasswordPlaceholder: "Opsional", + mqttTls: "TLS", + mqttTlsSkipVerify: "Lewati verifikasi sertifikat", + mqttKeepAlive: "Keep Alive (detik)", + mqttProtocolVersion: "Versi Protokol", + mqttTransport: "Transport", + mqttTransportTcp: "TCP", + mqttTransportWebSocket: "WebSocket", + mqttWsPath: "Jalur WebSocket", + mqttWsPathPlaceholder: "/mqtt", + mqttConnectTimeout: "Timeout Koneksi (detik)", + mqttMaxPacketSize: "Ukuran Paket Maks (byte)", + mqttConsoleTitle: "Konsol MQTT", + mqttTopics: "Topik", + mqttMessages: "Pesan", + mqttPublish: "Publikasikan Pesan", + mqttSubscribe: "Subscribe", + mqttNoLocal: "No Local", + mqttUnsubscribe: "Unsubscribe", + mqttNoMessages: "Tidak ada pesan", + mqttNoTopics: "Tidak ada topik yang di-subscribe", + mqttQuickSubscribe: "Subscribe Cepat", + mqttTopicPlaceholder: "Nama topik", + mqttConnected: "Terhubung", + mqttDisconnected: "Terputus", + mqttRefresh: "Segarkan", + mqttPublishDialogTitle: "Publikasikan Pesan MQTT", + mqttClearMessages: "Bersihkan pesan", + mqttCollapsePayload: "Ciutkan payload", + mqttExpandPayload: "Perluas payload", + mqttPauseMessages: "Jeda", + mqttResumeMessages: "Lanjutkan", + mqttHidePublishPanel: "Sembunyikan panel publikasi", + mqttShowPublishPanel: "Tampilkan panel publikasi", + mqttNoTopicsHint: "Tidak ada subscription. Gunakan kolom di bawah untuk subscribe ke topik.", + mqttSubscribePlaceholder: "Masukkan filter topik...", + mqttMessagesForTopic: "Pesan: {topic}", + mqttAllMessages: "Pesan (semua topik)", + mqttSent: "Terkirim", + mqttReceived: "Diterima", + mqttRetained: "Ditahan", + mqttTopic: "Topik", + mqttTopicExample: "mis. sensors/temperature", + mqttRetainMessage: "Tahan pesan", + mqttPayloadEncoding: "Encoding payload", + mqttPayload: "Payload", + mqttResizePayload: "Seret untuk mengubah ukuran input pesan", + mqttPayloadPlaceholderPlaintext: "Masukkan konten pesan...", + mqttPayloadPlaceholderJson: "Masukkan JSON, misalnya {example}", + mqttPayloadPlaceholderBase64: "Masukkan data berenkode Base64", + mqttPayloadPlaceholderHex: "Masukkan data heksadesimal, misalnya 48 65 6C 6C 6F", + mqttPayloadPlaceholderStructured: "Masukkan nilai JSON; akan di-encode sebagai {encoding}", + mqttPublishShortcut: "Ctrl+Enter untuk publikasikan", + mqttPublishTopicRequired: "Topik wajib diisi", + mqttPublishTopicWildcard: "Topik publikasi tidak boleh berisi wildcard # atau +. Ganti filter subscription dengan topik konkret.", + mqttPublishSuccess: "Pesan dipublikasikan", + mqttPublishing: "Mempublikasikan...", + mqttQosAtMostOnce: "Paling banyak sekali", + mqttQosAtLeastOnce: "Paling sedikit sekali", + mqttQosExactlyOnce: "Tepat sekali", + mqttSubscriptionConfig: "Konfigurasi subscription", + mqttNewSubscription: "Subscription baru", + mqttEditSubscription: "Edit subscription", + mqttSearchSubscriptionsPlaceholder: "Cari filter subscription...", + mqttSearchPayloadPlaceholder: "Cari payload pesan...", + mqttNoMatchingMessages: "Tidak ada pesan yang dimuat cocok dengan filter payload ini", + mqttNoSavedSubscriptions: 'Tidak ada subscription tersimpan. Klik "Subscription baru" untuk menambahkannya.', + mqttTopicFilter: "Filter Topik", + mqttTopicFilterPlaceholder: "mis. device/+/status", + mqttTopicFilterHint: "Wildcard satu level + dan multi-level # didukung.", + mqttNoLocalMqtt5Only: "Hanya MQTT 5.0", + mqttEnableSubscription: "Aktifkan subscription", + mqttEnableSubscriptionHint: "Subscribe segera setelah disimpan dan dipulihkan saat reconnect.", + mqttSaving: "Menyimpan...", + mqttSubscriptionTopicFilterInvalid: "Topic Filter tidak valid: + harus menempati satu level, dan # harus menjadi level terakhir.", + mqttSubscriptionTopicFilterDuplicate: "Topic Filter ini sudah ada.", + mqttSubscriptionNoLocalProtocolError: "No Local tidak didukung oleh MQTT 3.x. Beralih ke MQTT 5.0.", + mqttDeleteSubscriptionConfirm: 'Hapus konfigurasi subscription "{topic}"?', + mqttSubscriptionStatusActive: "Ter-subscribe", + mqttSubscriptionStatusPending: "Tertunda", + mqttSubscriptionStatusDisabled: "Dinonaktifkan", + mqttSubscriptionDisable: "Nonaktifkan subscription", + mqttSubscriptionEnable: "Aktifkan subscription", + mqttSubscriptionEdit: "Edit konfigurasi", + mqttSubscriptionDelete: "Hapus konfigurasi", + mqttSubscriptionOperationFailed: "Operasi subscription gagal: {error}. Konfigurasi dipertahankan.", + searchDatabasePlaceholder: "Cari tipe database", + searchResults: "Hasil pencarian", + databaseCategories: "Kategori", + databaseCategorySql: "Relasional", + databaseCategoryAnalytics: "Analitik", + databaseCategoryDomestic: "DB Tiongkok", + databaseCategoryLightweight: "Ringan", + databaseCategoryDocument: "Dokumen/Cache/Pencarian", + databaseCategoryGraphAi: "Graf/Vektor", + databaseCategoryTimeseries: "Deret waktu", + databaseCategoryMq: "Message queue", + databaseCategoryRegistryConfig: "Registry/Konfigurasi", + databaseCategoryPlugins: "Plugin", + pluginProviderUnavailable: "Penyedia koneksi plugin ini tidak tersedia. Pasang ulang atau aktifkan plugin, lalu coba lagi.", + pluginRequiredField: "{field} wajib diisi", + pluginSshKeyPickerPlaceholder: "Pilih kunci SSH lokal…", + pluginFieldSelectFile: "Pilih file…", + pluginFieldUploadFile: "Unggah file…", + pluginFieldSelectDirectory: "Pilih folder…", + pluginSshKeyPickerEmpty: "Tidak ditemukan kunci SSH lokal", + pluginSshKeyEncrypted: "terenkripsi", + jdbcConnection: "Koneksi JDBC", + iconView: "Tampilan ikon", + listView: "Tampilan daftar", + selectedDatabase: "Terpilih", + noDatabaseMatches: "Tidak ada database yang cocok", + next: "Berikutnya", + back: "Sebelumnya", + basicTab: "Koneksi", + tlsTab: "TLS/SSL", + test: "Uji", + testing: "Menguji...", + copyTestResult: "Salin hasil uji", + sqlServerLegacyCompatibilityMode: "Mode kompatibilitas lama", + sqlServerLegacyCompatibilityModeEnable: "Aktifkan", + sqlServerLegacyCompatibilityModeHint: "Untuk instance SQL Server yang dibatasi pada TLS 1.0, enkripsi hanya saat login, atau tanpa enkripsi.\nBeberapa fitur mungkin terbatas; gunakan hanya pada jaringan tepercaya.", + sqlServerLegacyCompatibilityComponent: "Komponen kompatibilitas lama SQL Server", + gaussdbConnectionMode: "Mode koneksi", + gaussdbConnectionModeNative: "Kompatibel PostgreSQL (driver bawaan)", + gaussdbConnectionModeMJdbc: "Mode M (driver JDBC vendor)", + gaussdbConnectionModeNativeHint: "Menggunakan protokol kompatibel PostgreSQL bawaan DBX untuk mode kompatibilitas GaussDB A/PG/Oracle.", + gaussdbConnectionModeMJdbcHint: "Menggunakan jdbc:gaussdb dengan com.huawei.gaussdb.jdbc.Driver untuk mode M GaussDB.", + gaussdbMJdbcDriver: "Driver JDBC GaussDB", + gaussdbMJdbcDriverPlaceholder: "Pilih gaussdbjdbc.jar yang sesuai dengan versi server", + gaussdbMJdbcDriverHint: "Driver dirilis bersama setiap versi server GaussDB. Dapatkan gaussdbjdbc.jar dari paket driver GaussDB yang sesuai.", + gaussdbMJdbcDriverRequired: "Mode M GaussDB memerlukan driver JDBC vendor. Pilih gaussdbjdbc.jar yang sesuai dengan versi server.", + gaussdbMJdbcPluginInstalling: "Memasang runtime JDBC...", + gaussdbIdentifierQuoteStyle: "Kompatibilitas identifier", + gaussdbIdentifierQuoteAuto: "Otomatis (driver/default)", + gaussdbIdentifierQuoteDouble: 'Oracle/PostgreSQL (tanda kutip ganda ")', + gaussdbIdentifierQuoteBacktick: "MySQL/M (backtick `)", + gaussdbIdentifierQuoteHint: "Otomatis menggunakan metadata driver JDBC atau default native GaussDB. Pilih mode secara manual hanya saat SQL yang dihasilkan menggunakan tanda kutip identifier yang salah.", + gaussdbTargetServerType: "Tipe server target", + gaussdbTargetServerTypeMaster: "Master (primary)", + gaussdbTargetServerTypeSlave: "Slave (standby)", + gaussdbTargetServerTypeAny: "Any (tanpa preferensi)", + gaussdbTargetServerTypeHint: "Mengontrol node mana di klaster GaussDB yang akan dihubungkan oleh driver JDBC. Master mencoba primary, slave mencoba standby, any menghubungkan ke mana pun yang tersedia. Hanya berlaku pada mode M (JDBC).", + gaussdbCountQueryDop: "Paralelisme COUNT(*)", + gaussdbCountQueryDopHint: "Menetapkan query_dop (derajat paralelisme) untuk kueri COUNT(*) pada tabel besar. Nilai lebih tinggi menggunakan lebih banyak sumber daya. Tetapkan ke 1 (default) untuk menonaktifkan hint optimizer.", + saveAndConnect: "Simpan & Hubungkan", + save: "Simpan", + editTitle: "Edit Koneksi", + testSuccess: "Koneksi berhasil", + databaseInfo: { + title: "Informasi database", + open: "Buka informasi database untuk {database}", + copy: "Salin informasi database", + sourceConfigured: "Konfigurasi saat ini", + sourceTested: "Diuji", + configuredDescription: "Menampilkan informasi yang diketahui dari formulir terlebih dahulu. Uji yang berhasil menambahkan versi server dan metadata driver.", + testedDescription: "Informasi ini berasal dari koneksi yang digunakan pada uji berhasil terakhir.", + productName: "DBMS", + productVersion: "Versi server", + currentDatabase: "Database saat ini", + serverComment: "Komentar server", + serverCharset: "Charset server", + serverCollation: "Collation server", + unquotedIdentifierCase: "Identifier tanpa kutip", + quotedIdentifierCase: "Identifier dengan kutip", + driverName: "Driver", + driverVersion: "Versi driver", + jdbcVersion: "Versi JDBC", + identifierCase: { + lower: "Huruf kecil", + upper: "Huruf besar", + mixed: "Campuran", + }, + }, + connecting: "Menghubungkan ke {name}...", + connectSuccess: "Terhubung ke {name}", + connectFailed: "Koneksi gagal: {message}", + objectCacheRefreshFailed: "Penyegaran cache objek gagal: {message}", + driverNotInstalled: "Driver {driver} belum terpasang. Silakan pasang dari Driver Manager.", + phoenixDriverNotInstalled: "Driver JDBC Apache Phoenix belum terpasang. Pasang dari Driver Manager, lalu coba lagi.", + jreNotInstalled: "Runtime JRE {jre} belum terpasang. Silakan pasang dari Driver Manager.", + systemJavaNotFound: "Runtime Java sistem tidak ditemukan di JAVA_HOME atau PATH. Silakan pasang Java atau pilih executable Java kustom.", + customJavaPathEmpty: "Jalur runtime Java kustom kosong. Silakan pilih executable Java.", + agentJavaTooOld: "Driver ini memerlukan Java 21. Gunakan JRE 21 kelolaan DBX atau pilih executable Java 21 di Driver Manager.", + agentDriverUpdateConnectionHint: "Pembaruan driver bawaan tersedia untuk koneksi ini. Kegagalan koneksi mungkin terkait dengan driver lokal yang sudah usang. Perbarui driver terkait di Driver Manager, lalu coba lagi.", + jdbcPluginNotInstalled: "Plugin JDBC belum terpasang. Pasang plugin JDBC opsional untuk menggunakan koneksi ini.", + connectFailedTitle: "Koneksi gagal", + fullErrorMessage: "Pesan error lengkap", + copyError: "Salin error", + optionalSuffix: " (opsional)", + customColorPlaceholder: "#ff0000 atau rgba(…)", + tursoHostPlaceholder: "your-database.turso.io atau libsql://your-database.turso.io", + tursoHostHint: "Mendukung protokol libsql:// dan https://. Anda juga dapat hanya memasukkan nama host (HTTPS digunakan secara otomatis).", + tursoTokenHint: "Buat token dengan:", + tursoUrlParamsPlaceholder: "authToken=xxx (opsional, kolom Auth Token di atas lebih diutamakan)", + driverInstall: { + installingTitle: "Memasang driver", + failedTitle: "Pemasangan driver gagal", + fullError: "Error lengkap", + statusFailed: "Pemasangan gagal", + statusWaiting: "Menunggu pemasangan", + statusPreparing: "Mempersiapkan pemasangan driver...", + statusExtractingJre: "Mengekstrak JRE...", + stepJre: "Mengunduh JRE", + stepDriver: "Mengunduh driver", + stepDefault: "Memasang driver", + installingButton: "Memasang...", + }, + lastError: "Error koneksi", + errorIndicatorHint: "Error koneksi. Klik untuk melihat detail", + clearError: "Bersihkan error koneksi", + saveFailed: "Gagal menyimpan koneksi: {message}", + savedSettingsFailed: "Koneksi disimpan, tetapi pengaturan tampilan tidak dapat disimpan: {message}. Coba lagi untuk menyimpan pengaturan.", + deleted: "Koneksi dihapus", + deletedSelected: "{count} koneksi dihapus", + copied: "Disalin", + disconnected: "Terputus", + disconnectedSelected: "{count} koneksi diputuskan", + disconnectSelectedPartial: "{succeeded} koneksi diputuskan; {failed} gagal", + databaseConnectionClosed: "Koneksi database ditutup: {name}", + duplicated: "Koneksi diduplikasi", + duplicatedSelected: "{count} koneksi diduplikasi", + groupDeleted: "Grup dihapus", + groupsDeleted: "{count} grup dihapus", + loadFailed: "Gagal memuat koneksi tersimpan: {message}", + sshTunnel: "Tunnel / Proxy", + sshTunnelTest: "Uji tunnel SSH", + sshTunnelTesting: "Menguji tunnel SSH...", + sshTunnelTestSuccess: "Koneksi tunnel SSH berhasil", + advancedTab: "Lanjutan", + sshEnable: "Gunakan tunnel / proxy", + sshHost: "Host SSH", + sshHostPlaceholder: "ssh.example.com atau alias dari ~/.ssh/config", + sshUser: "Pengguna SSH", + sshAuthMethod: "Metode Login", + sshAuthMethodPassword: "Kata Sandi", + sshAuthMethodKey: "Private Key", + sshAuthMethodKeyPassword: "Private Key + Kata Sandi", + sshAuthMethodNone: "Tidak ada", + sshAuthMethodNoneHint: "Tidak ada kredensial yang akan dikirim. Gunakan ini untuk bastion atau proxy yang menerima koneksi tanpa autentikasi.", + sshAuthMethodAgentLegacy: "SSH Agent (legacy)", + sshPassword: "Kata Sandi SSH", + sshPasswordPlaceholder: "Biarkan kosong untuk menggunakan key", + sshKeyPath: "Jalur Key", + sshKeyPassphrase: "Passphrase Key", + sshKeyPassphrasePlaceholder: "Biarkan kosong jika key tidak terenkripsi", + sshKeyPathBrowse: "Jelajahi", + sshExposeLan: "Ekspos tunnel ke LAN", + sshAllowExecChannelProxy: "Aktifkan fallback exec-channel SSH (nc)", + sshConnectTimeout: "Timeout SSH (detik)", + sshHops: "Lapisan Tunnel / Proxy", + sshHopAdd: "Tambah lapisan SSH", + sshHopDuplicate: "Duplikat", + sshHopDelete: "Hapus", + sshHopMoveUp: "Pindah ke atas", + sshHopMoveDown: "Pindah ke bawah", + sshHopName: "Nama Lapisan", + sshHopNamePlaceholder: "Bastion, jump host, gateway produksi", + sshHopDefaultName: "Lapisan {index}", + sshHopInvalidHost: "{hop}: Host SSH wajib diisi", + sshHopInvalidUser: "{hop}: Pengguna SSH wajib diisi", + sshHopInvalidPort: "{hop}: Port SSH harus antara 1 dan 65535", + sshHopInvalidAuth: "{hop}: kata sandi, jalur key, atau ssh-agent wajib diisi", + sshUseAgent: "Gunakan ssh-agent", + sshAgentSockPath: "Jalur Socket Agent", + sshAgentSockPathPlaceholder: "mis. ~/.ssh/agent.sock", + sshHostKeyVerifyTitle: "Konfirmasi Kunci Host SSH Tidak Dikenal", + sshHostKeyVerifyMessage: "Keaslian host '{host}:{port}' tidak dapat dipastikan. Untuk melindungi dari serangan man-in-the-middle, verifikasi sidik jari kunci host dengan administrator server Anda sebelum melanjutkan.", + sshHostKeyVerifyKeyType: "Tipe kunci", + sshHostKeyVerifyFingerprint: "Sidik jari", + sshHostKeyVerifyRemember: "Percayai host ini (ingat kunci ini untuk koneksi selanjutnya)", + sshHostKeyVerifyAccept: "Terima & Hubungkan", + sshHostKeyVerifyReject: "Batal", + sshHostKeyChangedTitle: "Sidik jari host telah berubah", + sshHostKeyChangedMessage: "Sidik jari tersimpan untuk {host} tidak cocok dengan server saat ini.", + sshHostKeyChangedCurrent: "Sidik jari {keyType} adalah SHA256:", + sshHostKeyChangedSaved: "Sidik jari tersimpan", + sshHostKeyChangedWarning: "Lanjutkan hanya jika Anda yakin host ini memang benar-benar berubah.", + sshHostKeyChangedClose: "Tutup", + sshHostKeyChangedContinue: "Lanjutkan", + sshHostKeyChangedUpdate: "Perbarui dan Lanjutkan", + sshInteractiveTitle: "Verifikasi SSH Diperlukan", + sshInteractiveMessage: "Server SSH di {host}:{port} memerlukan verifikasi tambahan.", + sshInteractiveDefaultPrompt: "Masukkan respons verifikasi yang diminta.", + sshInteractivePlaceholder: "Masukkan kode verifikasi", + sshInteractiveSubmit: "Verifikasi", + sshInteractiveCancel: "Batal", + sshPluginInputTitle: "Input Diperlukan", + sshPluginInputMessage: "{source} memerlukan input sebelum dapat melanjutkan.", + sshPluginInputMessageNoSource: "Plugin memerlukan input sebelum dapat melanjutkan.", + sshPluginInputSubmit: "Kirim", + sshHostKeyNoticeChanged: "Kunci host untuk {host}:{port} berubah — ini dapat mengindikasikan serangan man-in-the-middle. Hapus entri lama dan hubungkan kembali hanya jika Anda memang memperkirakan perubahan ini.", + sshHostKeyNoticeRejected: "Anda menolak kunci host untuk {host}:{port}; koneksi dibatalkan dan tidak ada kredensial yang dikirim.", + sshHostKeyNoticeLearnFailed: "Tidak dapat menyimpan kunci host untuk {host}:{port} — host dipercaya hanya untuk sesi ini dan Anda akan diminta memverifikasinya lagi lain kali.", + sshHostKeyNoticeGeneric: "Verifikasi kunci host SSH gagal untuk {host}:{port}.", + sqliteTransportSshOnly: "SQLite jarak jauh hanya mendukung lapisan proxy HTTP CONNECT atau SOCKS5 sebelum hop SSH terakhir. Lapisan HTTP tunnel tidak didukung.", + sqliteRemotePathPlaceholder: "/var/lib/app/data.db", + sqliteRemotePathHint: "Masukkan jalur absolut pada hop SSH terakhir.", + sqliteSshCipherUnsupportedHint: "Database SQLite terenkripsi (SQLCipher) belum didukung melalui SSH.", + sqliteWorkerPlacement: "Worker SQLite", + sqliteWorkerPlacementSession: "Sesi", + sqliteWorkerPlacementPersist: "Persisten", + sqliteWorkerPlacementPreplaced: "Pra-tempat", + sqliteWorkerPlacementSessionHint: "DBX mengunggah worker melalui SSH ke host file, lalu menghapus file jarak jauh saat Anda memutuskan koneksi. Cocok untuk penggunaan sementara.", + sqliteWorkerPlacementPersistHint: "DBX mengunggah worker melalui SSH ke host file dan membiarkannya tetap ada setelah terputus. Tidak dihapus secara otomatis.", + sqliteWorkerPlacementPreplacedHint: "Unggah worker ke host file sendiri, lalu masukkan jalur absolut file tersebut. DBX tidak akan mengunggah atau menghapusnya secara otomatis, tetapi akan memverifikasi bahwa file sesuai dengan versi Desktop ini.", + sqliteWorkerPlacementDefault: "Default", + sqliteWorkerPersistPathPlaceholder: "~/.cache/dbx/sqlite-worker/", + sqliteWorkerPreplacedPathPlaceholder: "/opt/dbx/dbx-sqlite-worker", + sshWorkerUploadConsentTitle: "Unggah Worker SQLite", + sshWorkerUploadConsentMessage: "DBX perlu menyalin worker SQLite berumur pendek ke {host}:{port}. Ini adalah tindakan dengan hak akses tinggi. Tinjau jalur tujuan dan digest sebelum mengizinkan unggahan.", + sshWorkerUploadConsentPath: "Jalur tujuan", + sshWorkerUploadConsentDigest: "Digest worker", + sshWorkerUploadConsentRemember: "Ingat host file dan digest ini", + sshWorkerUploadConsentAccept: "Unggah", + sshWorkerUploadConsentReject: "Batal", + sshHopInvalidTimeout: "{hop}: Timeout SSH harus antara 1 dan 300 detik", + connectTimeout: "Timeout Koneksi (detik)", + queryTimeout: "Timeout Kueri (detik)", + useGlobalQueryTimeout: "Global", + globalConnectTimeoutHint: "Rentang: 1 hingga 300 detik", + globalQueryTimeoutHint: "Rentang: 0 hingga 3600 detik. Tetapkan ke 0 untuk tanpa timeout.", + useConnectionQueryTimeout: "Koneksi", + idleTimeout: "Timeout Idle (detik)", + keepaliveInterval: "Interval Keepalive (detik)", + readOnly: "Read Only", + readOnlyHint: "Blokir semua operasi tulis (INSERT, UPDATE, DELETE, dll.)", + doltShowSystemTables: "Tampilkan Tabel Sistem Dolt", + doltShowSystemTablesHint: "Tampilkan tabel version-control bawaan Dolt di daftar tabel untuk koneksi ini.", + showSystemSchemas: "Tampilkan Skema Sistem", + showSystemSchemasHint: "Tampilkan skema bawaan dan metadata di bilah sisi dan pemilih skema untuk koneksi ini.", + tableLoading: "Pemuatan tabel", + autoLoadAllTables: "Muat semua tabel secara otomatis", + autoLoadAllTablesHint: "Pada tampilan bilah sisi Lanjutan, membuka grup Tables akan memuat setiap halaman untuk koneksi ini sehingga filter nama tabel mencakup semua tabel. Skema besar mungkin memerlukan waktu lebih lama.", + docsNotesPath: "File catatan", + docsNotesPathPlaceholder: "docs/dbx-docs.json", + docsNotesPathHint: "Lokasi penyimpanan catatan dokumentasi. Biarkan kosong untuk menyimpannya di direktori data aplikasi, atau arahkan ke file di repositori Anda untuk meninjau dokumentasi skema di pull request.", + readOnlyBadge: "Read-only", + proxy: "Proxy", + proxyEnable: "Hubungkan database melalui proxy", + proxyType: "Tipe Proxy", + proxyHost: "Host Proxy", + proxyUsername: "Pengguna Proxy", + proxyUsernamePlaceholder: "Opsional", + proxyPassword: "Kata Sandi Proxy", + proxyPasswordPlaceholder: "Opsional", + proxyTestTarget: "Target Uji", + proxyTestTargetPlaceholder: "host:port — kosong = pemeriksaan endpoint, isi untuk uji tunnel penuh", + tunnelProfile: "Profil Tunnel", + tunnelProfileCustom: "Kustom (hanya koneksi ini)", + tunnelProfileManaged: "Dikelola oleh profil tunnel bersama. Edit di Pengaturan > Tunnels — perubahan berlaku untuk setiap koneksi yang menggunakannya pada koneksi berikutnya.", + tunnelProfileMissing: "Profil tunnel yang dirujuk sudah tidak ada. Pilih profil lain atau beralih ke kustom.", + tunnelProfileMissingName: "Profil tunnel hilang", + tunnelProfileManage: "Kelola", + httpTunnel: "HTTP Tunnel", + httpTunnelAdd: "Tambah HTTP tunnel", + httpTunnelUrl: "URL Skrip Tunnel", + httpTunnelToken: "Token Tunnel", + httpTunnelTokenPlaceholder: "Token yang dikonfigurasi di dbx_tunnel.php", + httpTunnelConnectTimeout: "Timeout Tunnel (detik)", + httpTunnelDefaultName: "HTTP Tunnel {index}", + httpTunnelInvalidOrder: "{hop}: HTTP tunnel harus menjadi lapisan tunnel / proxy pertama", + httpTunnelInvalidUrl: "{hop}: URL skrip tunnel wajib diisi", + httpTunnelInvalidTimeout: "{hop}: Timeout HTTP tunnel harus antara 1 dan 300 detik", + dremioArrowFlightSqlMode: "Arrow Flight SQL", + dremioLegacyJdbcMode: "JDBC Legacy", + phoenixDirectMode: "Langsung", + phoenixRuntimeOption: "Apache Phoenix JDBC ({mode})", + phoenixQueryServerMode: "Query Server", + phoenixDirectModeHint: "Terhubung langsung ke HBase. Runtime default menargetkan Phoenix 5.2.1 dengan HBase 2.5; untuk versi klaster lain, pilih klien Phoenix yang kompatibel dan tambahkan hbase-site.xml jika diperlukan.", + phoenixQueryServerModeHint: "Terhubung melalui HTTP melalui Phoenix Query Server (PQS) yang dideploy terpisah menggunakan Phoenix thin client.", + phoenixDriverManagerHintPrefix: "Pasang atau copot runtime default di ", + phoenixDriverManagerHintSuffix: ". Jalur driver kompatibel yang dipilih manual lebih diutamakan.", + phoenixDocs: "Lihat dokumentasi Phoenix", + jdbcUrl: "URL JDBC", + jdbcUrlPlaceholder: "jdbc:postgresql://localhost:5432/database", + jdbcDriverClass: "Driver Class (opsional)", + jdbcDriverClassPlaceholder: "Sebagian besar driver mendaftar otomatis; gunakan com.vendor.jdbc.Driver jika diperlukan", + jdbcDriverPaths: "JAR Driver", + jdbcDriverSelectPlaceholder: "Pilih driver yang diimpor", + jdbcManualClasspath: "Classpath manual", + jdbcManualClasspathCount: "{count} jalur", + jdbcDriverPathsPlaceholder: "/path/to/driver.jar\n/path/to/another-driver.jar", + jdbcDriverBrowse: "Pilih JAR driver JDBC", + jdbcDocs: "Lihat dokumentasi JDBC", + jdbcPluginHint: "Pasang plugin JDBC DBX terlebih dahulu. Untuk driver dengan dependensi eksternal, pasang dari Maven di Driver Manager atau impor driver dan semua JAR dependensinya bersamaan.", + jdbcMissingRuntimeDependencyHint: "Driver JDBC ini kehilangan dependensi runtime. Pasang dari Maven di Driver Manager, atau impor driver dan semua JAR dependensinya bersamaan.", + jdbcxExtensions: "Ekstensi JDBCX", + jdbcxHighPrivilegeExtensions: "Izinkan ekstensi dengan hak akses tinggi", + jdbcxHighPrivilegeExtensionsWarning: "Dinonaktifkan secara default. Mengaktifkannya memungkinkan ekstensi Shell, Script, Web, MCP, dan lainnya untuk menjalankan perintah lokal atau mengakses jaringan.", + dmCompatHint: "Memerlukan driver ODBC DM8 terpasang di sistem Anda.", + dmDownload: "Unduh dari Dameng", + mongoLegacyHint: "Gunakan Legacy untuk server MongoDB lama, terutama versi di bawah 4.2. Jika autentikasi gagal dan pengguna dibuat di admin, tetapkan Auth DB ke admin.", + mongoTlsAllowInvalidCertificates: "Nonaktifkan verifikasi sertifikat TLS", + mongoTlsAllowInvalidCertificatesHint: "Memetakan ke tlsAllowInvalidCertificates=true dan menonaktifkan semua validasi sertifikat, bukan hanya pemeriksaan hostname. Ini meningkatkan risiko MITM. Umumnya diperlukan untuk AWS DocumentDB melalui tunnel SSH.", + mongoRetryWrites: "Coba ulang penulisan", + mongoRetryWritesHint: "Memetakan ke retryWrites. Nonaktifkan untuk AWS DocumentDB, yang tidak mendukung retryable writes.", + compatible: "Kompatibel", + mainstream: "Populer", + color: "Warna", + colorNone: "Tanpa warna", + colorGreen: "Hijau", + colorYellow: "Kuning", + colorOrange: "Oranye", + colorRed: "Merah", + colorBlue: "Biru", + colorPurple: "Ungu", + colorCustom: "Warna kustom", + cancelConnecting: "Batalkan koneksi", + connectCancelled: "Koneksi dibatalkan", + sshTotpCancelled: "Entri kode sekali pakai dibatalkan", + }, + editor: { + duckdbDraining: "Kueri DuckDB sebelumnya masih dalam proses penghentian. Silakan coba lagi sebentar lagi.", + statementExecutionRunning: "{count} pernyataan sedang berjalan | {count} pernyataan sedang berjalan", + statementExecutionSucceeded: "{count} pernyataan berhasil | {count} pernyataan berhasil", + statementExecutionFailed: "{count} pernyataan gagal | {count} pernyataan gagal", + pressToExecute: "Tekan {mod}+Enter untuk eksekusi", + pressToSaveSql: "Tekan {mod}+S untuk menyimpan SQL", + queryTimeoutError: "Kueri timeout ({seconds} detik). Periksa apakah koneksi database berjalan dengan baik.", + changeConnectionTimeout: "Ubah timeout koneksi", + changeQueryTimeout: "Ubah timeout kueri", + locateError: "Cari error (baris {line}, kolom {column})", + errorPositionUnavailable: "Posisi error tidak lagi cocok dengan konten editor, sehingga tidak dapat ditemukan.", + connectionMayBeLost: "Koneksi mungkin terputus. Segarkan data dan coba lagi.", + showResultsPane: "Tampilkan hasil", + hideResultsPane: "Sembunyikan hasil", + noDatabase: "Tidak ada database yang dipilih", + connectionOnlyTarget: "Target tingkat koneksi", + unsavedChangesTitle: "Perubahan belum disimpan", + unsavedChangesMessage: '"{title}" memiliki perubahan yang belum disimpan dan akan hilang jika ditutup. Simpan sebelum menutup?', + unsavedChangesBatchCloseMessage: "Beberapa tab yang Anda tutup memiliki perubahan yang belum disimpan dan akan hilang. Simpan sebelum melanjutkan?", + unsavedChangesBatchCloseMultipleMessage: '{count} tab SQL yang Anda tutup memiliki perubahan yang belum disimpan. DBX saat ini menampilkan "{title}". Simpan sebelum melanjutkan?', + unsavedChangesAppCloseMessage: '"{title}" memiliki perubahan SQL yang belum disimpan dan akan hilang jika Anda keluar dari DBX. Simpan sebelum keluar?', + unsavedChangesAppCloseMultipleMessage: '{count} tab SQL memiliki perubahan yang belum disimpan. DBX saat ini menampilkan "{title}". Simpan sebelum keluar?', + unsavedChangesViewList: "Lihat {count} tab", + unsavedChangesListTitle: "Tab belum disimpan ({count})", + discardChanges: "Buang", + discardAllChanges: "Buang semua", + saveAllChanges: "Simpan semua", + selectConnection: "Pilih koneksi", + searchConnection: "Cari koneksi...", + selectCatalog: "Pilih katalog", + searchCatalog: "Cari katalog...", + selectDatabase: "Pilih database", + selectDatabaseRequired: "Pilih database terlebih dahulu", + searchDatabase: "Cari database...", + selectSchema: "Pilih skema", + searchSchema: "Cari skema...", + setDefaultDatabase: "Tetapkan Default", + defaultDatabase: "Default", + defaultSchema: "Default", + clearDatabase: "Bersihkan database", + exPasteNoValues: "Clipboard tidak memiliki nilai untuk kondisi IN", + exPasteNotList: "Tidak terdeteksi daftar multi-nilai yang dapat dikonversi", + exPasteTooLarge: "Konten clipboard terlalu besar. Panjang maksimum yang didukung adalah {limit} karakter.", + exPasteTooManyValues: "Terlalu banyak nilai. Jumlah maksimum yang didukung adalah {limit}.", + exPasteClipboardReadFailed: "Gagal membaca clipboard: {message}", + exPastePasted: "{count} nilai kondisi IN ditempel", + sqlSourcePasteRestored: "SQL dipulihkan dari kode sumber (undo untuk mendapatkan teks asli)", + sqlSourcePasteNotDetected: "Tidak terdeteksi SQL gabungan; menempel teks asli", + completion: { + nullValue: "Nilai NULL", + isNull: "Periksa apakah NULL", + isNotNull: "Periksa apakah bukan NULL", + stringLiteral: "Literal string", + numericLiteral: "Literal numerik", + booleanValue: "Nilai boolean", + starExpansionColumns: "{count} kolom", + insertSelectedColumns: "Sisipkan kolom terpilih ({count})", + insertSelectedColumnsDetail: "Pilih kolom dengan kotak centang, lalu sisipkan bersamaan", + selectAllColumns: "Pilih semua kolom", + selectAllColumnsDetail: "Centang setiap field sekaligus", + deselectAllColumns: "Batalkan semua pilihan", + selectColumnsBeforeInsert: "Pilih setidaknya satu kolom terlebih dahulu", + tableAlias: "Alias tabel", + functionDescriptions: { + COUNT: "Mengembalikan jumlah baris", + SUM: "Mengembalikan jumlah total kolom numerik", + AVG: "Mengembalikan rata-rata kolom numerik", + MIN: "Mengembalikan nilai minimum", + MAX: "Mengembalikan nilai maksimum", + GROUP_CONCAT: "Menggabungkan nilai grup menjadi satu string", + STRING_AGG: "Menggabungkan string grup", + CONCAT: "Menggabungkan beberapa string", + CONCAT_WS: "Menggabungkan string dengan pemisah", + SUBSTRING: "Mengekstrak substring", + REPLACE: "Mengganti konten dalam string", + TRIM: "Memangkas spasi di awal dan akhir", + UPPER: "Mengonversi ke huruf besar", + LOWER: "Mengonversi ke huruf kecil", + LENGTH: "Mengembalikan panjang string", + REGEXP_REPLACE: "Mengganti menggunakan ekspresi reguler", + DATE_FORMAT: "Memformat tanggal dengan format yang diberikan", + DATEDIFF: "Menghitung selisih antara dua tanggal", + DATE_ADD: "Menambahkan interval ke tanggal", + DATE_SUB: "Mengurangkan interval dari tanggal", + EXTRACT: "Mengekstrak bagian tanggal", + NOW: "Mengembalikan tanggal dan waktu saat ini", + CURRENT_DATE: "Mengembalikan tanggal saat ini", + CURRENT_TIME: "Mengembalikan waktu saat ini", + CURRENT_TIMESTAMP: "Mengembalikan tanggal dan waktu saat ini", + CURDATE: "Mengembalikan tanggal saat ini", + CURTIME: "Mengembalikan waktu saat ini", + LOCALTIME: "Mengembalikan waktu lokal saat ini", + LOCALTIMESTAMP: "Mengembalikan tanggal dan waktu lokal saat ini", + UTC_DATE: "Mengembalikan tanggal UTC saat ini", + UTC_TIME: "Mengembalikan waktu UTC saat ini", + UTC_TIMESTAMP: "Mengembalikan tanggal dan waktu UTC saat ini", + SYSDATE: "Mengembalikan tanggal dan waktu saat ini", + DATE: "Mengekstrak bagian tanggal", + TIME: "Mengekstrak bagian waktu", + TIMESTAMPDIFF: "Mengembalikan selisih antara dua datetime", + YEAR: "Mengekstrak tahun", + MONTH: "Mengekstrak bulan", + DAY: "Mengekstrak hari", + HOUR: "Mengekstrak jam", + MINUTE: "Mengekstrak menit", + SECOND: "Mengekstrak detik", + DAYOFWEEK: "Mengembalikan indeks hari dalam minggu", + DAYOFYEAR: "Mengembalikan hari dalam tahun", + LAST_DAY: "Mengembalikan hari terakhir dalam bulan", + STR_TO_DATE: "Mengonversi string menjadi tanggal", + IF: "Mengembalikan nilai berdasarkan kondisi", + LEFT: "Mengembalikan karakter paling kiri", + RIGHT: "Mengembalikan karakter paling kanan", + SUBSTRING_INDEX: "Mengembalikan substring sebelum jumlah delimiter", + CHAR_LENGTH: "Mengembalikan panjang karakter", + INSTR: "Mengembalikan posisi substring", + LOCATE: "Mengembalikan posisi substring", + LPAD: "Menambahkan padding kiri pada string hingga panjang tertentu", + RPAD: "Menambahkan padding kanan pada string hingga panjang tertentu", + FIND_IN_SET: "Mengembalikan indeks dalam daftar yang dipisahkan koma", + RAND: "Mengembalikan nilai floating-point acak", + MD5: "Mengembalikan hash MD5", + SHA1: "Mengembalikan hash SHA1", + SHA2: "Mengembalikan hash SHA2", + ROUND: "Membulatkan ke jumlah desimal tertentu", + FLOOR: "Membulatkan ke bawah", + CEIL: "Membulatkan ke atas", + ABS: "Mengembalikan nilai absolut", + MOD: "Mengembalikan sisa pembagian", + COALESCE: "Mengembalikan argumen pertama yang bukan NULL", + IFNULL: "Mengembalikan nilai pengganti jika NULL", + NULLIF: "Mengembalikan NULL jika argumen sama", + CAST: "Mengonversi ekspresi ke tipe target", + JSON_EXTRACT: "Mengekstrak nilai dari JSON", + JSON_VALUE: "Mengekstrak nilai skalar dari JSON", + JSON_OBJECT: "Membuat objek JSON", + JSON_ARRAY: "Membuat array JSON", + }, + }, + previewChanges: "Pratinjau perubahan", + previewChangesComment: "Pratinjau perubahan (dry run) untuk pernyataan {operation}", + previewChangesFailed: "Pratinjau perubahan gagal.", + previewChangesNoStatement: "Pilih atau tempatkan kursor pada pernyataan UPDATE / INSERT / DELETE untuk melihat pratinjau perubahannya.", + contextMenu: { + executeSelection: "Eksekusi pilihan", + executeCurrent: "Eksekusi SQL", + export: "Ekspor", + exportQueryResultTo: "Ekspor hasil kueri saat ini ke {format}", + copySelection: "Salin pilihan", + copySelectionAsRichText: "Salin sebagai Rich Text", + screenshotSelection: "Screenshot Kode Terpilih", + commentSelection: "Jadikan komentar pilihan", + blockCommentSelection: "Jadikan komentar blok pilihan", + formatSelectionSql: "Format SQL terpilih", + compressSelectionSql: "Kompres SQL terpilih", + cutSelection: "Potong pilihan", + pasteFromClipboard: "Tempel", + pasteRestoringSourceSql: "Tempel dan pulihkan SQL sumber", + pasteClipboardReadFailed: "Gagal membaca clipboard: {message}", + sendToAi: "Kirim ke AI", + uppercaseSelection: "Konversi ke huruf besar", + lowercaseSelection: "Konversi ke huruf kecil", + convertNamingStyle: "Alihkan gaya penamaan", + delimitedList: "Konversi ke daftar berpemisah", + addNextSelectionOccurrence: "Tambah kemunculan berikutnya", + selectAllSelectionOccurrences: "Pilih semua kemunculan", + expandSelectStar: "Perluas * menjadi kolom", + expandSelectStarUnavailable: "Tidak dapat memuat kolom untuk tabel ini", + findReplace: "Cari/Ganti", + deleteEmptyLines: "Hapus baris kosong", + selectAll: "Pilih semua", + }, + delimitedList: { + title: "Konversi ke Daftar Berpemisah", + columnDelimiter: "Pemisah kolom", + resultDelimiter: "Pemisah hasil", + quoteChar: "Karakter kutip", + wrapColumn: "Bungkus pada kolom", + prefixText: "Teks awalan", + suffixText: "Teks akhiran", + preview: "Pratinjau", + emptyPreview: "Tidak ada yang dapat dipratinjau", + confirm: "Konfirmasi", + selectFirst: "Silakan pilih teks daftar", + }, + structurePeek: { + title: "Struktur: {name}", + hint: "Klik dua kali sel untuk menyisipkan nilainya ke editor", + doubleClickInsert: "Klik dua kali untuk menyisipkan", + drag: "Seret untuk memindahkan", + empty: "Tidak ada kolom", + }, + gotoLine: { + placeholder: "Nomor baris", + total: "{total} baris", + outOfRange: "Masukkan nomor baris antara 1 dan {total}", + empty: "Masukkan nomor baris", + }, + search: { + find: "Cari", + replace: "Ganti", + replaceAll: "Ganti Semua", + caseSensitive: "Case sensitive", + regex: "Ekspresi reguler", + collapseReplace: "Ciutkan ganti", + expandReplace: "Perluas ganti", + prevMatch: "Sebelumnya (Shift+Enter)", + nextMatch: "Berikutnya (Enter)", + selectAll: "Pilih semua kecocokan", + selectAllLimit: "Pilih semua kecocokan (hingga {limit})", + selectionTruncated: "Ditemukan {total} kecocokan; memilih {limit} pertama.", + selectionLimitSummary: "Terpilih {limit}/{total}", + close: "Tutup (Esc)", + noResults: "Tidak ada hasil", + inSelection: "Dalam pilihan", + }, + noExecutableStatementAtCursor: "Tidak ada pernyataan yang dapat dieksekusi pada posisi kursor.", + executionPicker: { + title: "Target Eksekusi", + currentStatement: "SQL Saat Ini", + allStatements: "Semua SQL", + currentCommand: "Perintah saat ini", + allCommands: "Semua perintah", + }, + }, + tabs: { + sql: "SQL", + emptyGroup: "Tidak ada tab terbuka", + table: "Tabel", + tableData: "Data Tabel", + redis: "Redis", + etcd: "etcd", + etcdDashboard: "Dashboard etcd", + etcdAccessControl: "Kontrol Akses etcd", + nacosAccessControl: "Kontrol Akses Nacos", + zookeeper: "ZooKeeper", + consul: "Consul", + mongo: "Mongo", + gridfs: "GridFS", + vector: "Vektor", + databases: "Database", + objects: "Objek", + users: "Pengguna & Hak Akses", + executionSummary: "Ringkasan", + messages: "Pesan", + tooltipTitle: "Judul:", + tooltipFilePath: "Jalur File:", + tooltipFileStatus: "Status File:", + externalFileMissing: "Dihapus atau dipindahkan di luar DBX", + tooltipConnection: "Koneksi:", + tooltipGroup: "Grup:", + tooltipDatabase: "Database:", + tooltipTable: "Tabel:", + tooltipTableComment: "Komentar Tabel:", + tooltipCollection: "Collection:", + tooltipSchema: "Skema:", + resultN: "Hasil {n}", + runN: "Jalankan {n}", + resultRuns: "Hasil eksekusi", + resultSets: "Result set", + allResults: "Semua hasil ({count})", + searchResults: "Cari nomor, nama, atau SQL", + noMatchingResults: "Tidak ada hasil yang cocok", + removeRun: "Hapus eksekusi {n}", + renameResultRun: "Ganti nama tab hasil", + resultRunName: "Nama tab hasil", + pinResultRun: "Sematkan tab hasil", + unpinResultRun: "Lepas sematan tab hasil", + unpinAllResultRuns: "Lepas sematan semua tab hasil", + closeOtherResultRuns: "Tutup tab hasil lainnya", + closeResultRunsToLeft: "Tutup tab hasil di sebelah kiri", + closeResultRunsToRight: "Tutup tab hasil di sebelah kanan", + closeResult: "Tutup hasil", + autoKeepResults: "Pertahankan hasil kueri otomatis", + autoKeepResultsEnabled: "Pertahankan hasil otomatis diaktifkan", + autoKeepResultsDisabled: "Pertahankan hasil otomatis dinonaktifkan", + autoRefresh: "Segarkan hasil otomatis", + autoRefreshShort: "Otomatis", + autoRefreshEvery: "Segarkan setiap {seconds} detik", + startAutoRefresh: "Mulai segarkan otomatis", + stopAutoRefresh: "Hentikan segarkan otomatis", + missingResultRun: "Hasil ini sudah tidak tersedia", + exportResultArchive: "Simpan Hasil", + importResultArchive: "Impor Arsip Hasil", + importedResultArchive: "Hasil diimpor", + resultArchiveExported: "Hasil diekspor", + resultArchiveImported: "Hasil diimpor", + resultArchiveUnavailable: "Tidak ada hasil tersimpan yang tersedia untuk diekspor", + resultArchiveImportInvalid: "Arsip hasil ini tidak dapat dibuka", + resultArchiveExportFailed: "Gagal mengekspor hasil: {message}", + resultArchiveImportFailed: "Gagal mengimpor hasil: {message}", + scrollLeft: "Gulir tab ke kiri", + scrollRight: "Gulir tab ke kanan", + openTabs: "Tab terbuka", + openInNewWindow: "Buka di jendela baru", + returnToMainWindow: "Kembali ke jendela utama", + dragBackToMain: "Seret pegangan ini ke jendela utama", + detachedCloseTitle: "Tutup jendela terpisah", + detachedCloseMessage: "Tab SQL ini memiliki perubahan yang belum disimpan. Simpan sebelum menutup dan menghapus tab terpisah ini?", + detachedTabUnavailable: "Tab terpisah ini sudah tidak tersedia.", + openInNewWindowFailed: "Tidak dapat membuka jendela terpisah.", + minimizeWindow: "Minimalkan", + maximizeWindow: "Maksimalkan", + closeWindow: "Tutup", + searchOpenTabs: "Cari tab terbuka...", + collapseTabBar: "Ciutkan bilah tab", + expandTabBar: "Perluas bilah tab", + switcherTitle: "Beralih Tab", + switcherHint: "terus tekan untuk berpindah, lepas untuk beralih", + noMatchingTabs: "Tidak ada tab yang cocok", + fixedTabs: "Tab tetap", + openDataTabs: "Tabel terbuka", + editGroupTitle: "Edit grup: {name}", + groupName: "Nama grup", + groupColor: "Warna grup", + groupColorAuto: "Gunakan warna default", + groupColorCustom: "Pilih warna kustom", + resetGroup: "Atur ulang", + settingsSaveFailed: "Tidak dapat menyimpan pengaturan tab: {message}", + }, + databaseBrowser: { + search: "Cari database...", + empty: "Tidak ditemukan database", + loadFailed: "Tidak dapat memuat database: {message}", + defaultCharset: "Charset", + defaultCollation: "Collation", + }, + gridfsBrowser: { + bucketCount: "bucket", + fileCount: "file", + name: "Nama", + totalSize: "Ukuran", + chunkSize: "Ukuran Chunk", + uploadDate: "Tanggal Unggah", + contentType: "Content Type", + metadata: "Metadata", + selectBucket: "Pilih bucket GridFS untuk memeriksa atau membukanya.", + selectFile: "Pilih file GridFS untuk memeriksa atau mengelolanya.", + emptyBuckets: "Tidak ditemukan bucket GridFS. Buat satu untuk mulai menyimpan file.", + emptyFiles: "Bucket ini belum memiliki file. Unggah satu untuk memulai.", + createBucket: "Bucket Baru", + openBucket: "Buka Bucket", + deleteBucket: "Hapus Bucket", + createTitle: "Buat Bucket GridFS", + deleteTitle: "Hapus Bucket GridFS", + deleteMessage: "Hapus bucket GridFS terpilih beserta semua file di dalamnya?", + bucketName: "Nama Bucket", + bucketNamePlaceholder: "example_bucket", + bucketCreated: "Bucket {bucket} dibuat.", + bucketDeleted: "Bucket {bucket} dihapus.", + uploadFile: "Unggah File", + downloadFile: "Unduh File", + downloadSelected: "Unduh yang Dipilih", + deleteFile: "Hapus File", + selectedCount: "{count} dipilih", + deleteFileTitle: "Hapus File GridFS", + deleteFileMessage: "Hapus file terpilih dari bucket GridFS ini?", + fileUploaded: "{fileName} diunggah.", + fileDeleted: "{fileName} dihapus.", + }, + executionSummary: { + empty: "Tidak ada ringkasan", + executing: "Mengeksekusi...", + finished: "Eksekusi selesai", + statement: "Pernyataan", + sql: "SQL", + status: "Status", + type: "Tipe", + rows: "Baris", + affected: "Terpengaruh", + time: "Waktu", + success: "Berhasil", + error: "Galat", + returnedTable: "Mengembalikan tabel hasil dengan {count} kolom", + noTable: "Tidak ada tabel hasil yang dikembalikan", + noSql: "SQL tidak tersedia", + lineColumn: "baris {line}, kolom {column}", + navigationHint: "Klik baris untuk melihat pratinjau SQL-nya; klik dua kali untuk fokus ke editor.", + recoveryPrompt: "Pernyataan #{statement} gagal; {count} pernyataan tidak dijalankan.", + stop: "Hentikan", + retry: "Coba Lagi", + skipAndContinue: "Lewati dan lanjutkan", + skipAll: "Lewati semua galat", + skipAllHint: "Lanjutkan dan lewati galat berikutnya secara otomatis dalam batch ini", + statuses: { + pending: "Tertunda", + running: "Berjalan", + success: "Berhasil", + error: "Galat", + skipped: "Tidak dijalankan", + cancelled: "Dibatalkan", + }, + }, + queryMessages: { + empty: "Tidak ada pesan", + code: "Kode: {code}", + }, + chart: { + title: "Chart", + type: "Tipe", + line: "Garis", + bar: "Batang", + pie: "Pai", + noNumericData: "Tidak ada data numerik yang tersedia untuk membuat chart", + }, + grid: { + rows: "{count} baris", + totalRows: "Total {count} baris", + loadedRows: "{count} baris dimuat", + totalRowCount: "({count} total)", + totalRowCountWithAction: "({button}{count} total)", + totalRowCountAtLeast: "(minimal {count} total)", + totalRowCountEstimated: "(~{count})", + totalRowCountLoading: "(menghitung...)", + loadingMore: "Memuat data lainnya...", + pageJumpLoading: "Melompat ke halaman {page}", + pageJumpProgress: "Permintaan selesai {current}/{total}", + esDeepPageJumpConfirmTitle: "Konfirmasi lompatan halaman Elasticsearch yang dalam", + esDeepPageJumpConfirmMessage: + "Elasticsearch search_after tidak bisa langsung melompat ke suatu halaman. DBX harus mengambil cursor yang hilang secara berurutan, dan navigasi mundur dimulai ulang dari halaman 1. Melompat ke halaman {page} diperkirakan mengirim {requests} kueri. Ini bisa memakan waktu lama dan meningkatkan beban cluster. Lanjutkan?", + esDeepPageJumpContinue: "Lanjutkan", + allLoaded: "semua telah dimuat", + loadAllAndGoToLastRow: "Muat semua dan ke baris terakhir", + loadAllRowsConfirmTitle: "Konfirmasi memuat semua baris", + loadAllRowsConfirmMessage: "Memuat semua akan mengambil hingga {count} baris tambahan dalam satu permintaan. Hasil yang sangat besar memakan banyak memori dan bisa memakan waktu lama. Lanjutkan?", + loadAllRowsContinue: "Muat semua baris", + calculateTotalRows: "Hitung total baris", + calculateTotalRowsInline: "(hitung total baris)", + calculateTotalRowsFailed: "Penghitungan gagal: {message}", + rowsAffected: "{count} baris terpengaruh", + agentExecuteTime: "Eksekusi: {duration}", + serverExecuteTime: "Eksekusi database: {duration}", + serverExecuteTimeUnavailable: "Eksekusi database: tidak tersedia", + serverExecuteTimeHint: + "OceanBase SQL Audit EXECUTE_TIME mengukur eksekusi rencana di server. Cursor JDBC menampilkan sampel pernyataan yang telah selesai; kueri halaman independen menampilkan jumlah hanya ketika setiap halaman di-sampling. Ini tumpang tindih dengan waktu eksekusi dan waktu tunggu. Tidak tersedia selagi cursor masih terbuka atau ketika data audit tidak dapat dibaca atau dicocokkan.", + agentExecuteTimeHint: "Waktu Agent dari penyiapan skema hingga eksekusi JDBC. Tidak termasuk pengambilan baris; bukan waktu eksekusi server database.", + timingNumber: "No.", + timingStage: "Tahap", + timingDuration: "Waktu", + timingDetails: "Detail waktu kueri", + timingUnavailable: "Tidak diukur", + timingPages: "Kumulatif pada {count} permintaan; rendering untuk pembaruan terbaru.", + timingPhase_request: "Tunggu permintaan", + timingPhase_prepare: "Persiapan (di luar waktu tunggu)", + timingPhase_core_lock: "Tunggu kunci eksekusi", + timingPhase_pool_acquire: "Peroleh koneksi", + timingPhase_session_prepare: "Siapkan sesi", + timingPhase_pool_release: "Kembalikan koneksi", + timingPhase_schema: "Atur skema", + timingPhase_statement_prepare: "Siapkan pernyataan", + timingPhase_jdbc_execute: "Eksekusi SQL (JDBC)", + timingPhase_metadata: "Baca metadata kolom", + timingPhase_fetch: "Baca baris dan tutup cursor", + timingPhase_agent_other: "Pemrosesan Agent lainnya (sisa)", + timingPhase_remainder: "Tunggu lainnya (sisa, bukan waktu jaringan)", + timingPhase_result: "Proses hasil (di luar waktu tunggu)", + timingBackend: "Waktu yang dilaporkan backend (tumpang tindih tahap)", + timingPhase_render: "Perbarui grid (di luar waktu tunggu)", + clientRequestWait: "Tunggu: {duration}", + clientRequestWaitHint: "Waktu desktop dari pengiriman permintaan kueri hingga seluruh payload hasil tiba. Termasuk pemrosesan backend, pengambilan data, dan transport; tidak termasuk persiapan permintaan dan rendering grid. Dijumlahkan pada halaman yang dimuat.", + resultViewUpdate: "Pembaruan grid: {duration}", + resultViewUpdateHint: "Waktu dari grid mengamati hasil ini hingga pembaruan DOM-nya selesai atau gambar Canvas dikirim. Tidak termasuk compositing GPU dan presentasi layar.", + querySuccess: "Kueri berhasil dieksekusi", + noRows: "Tidak ada data", + noRowsDescription: "Hasil ini tidak memiliki data.", + noSearchResults: "Tidak ada kecocokan", + noSearchResultsDescription: "Coba kata kunci lain.", + noFilteredRows: "Tidak ada baris yang cocok dengan filter", + noFilteredRowsDescription: "Sesuaikan teks pencarian atau filter status baris.", + copy: "Salin", + copyExtractorSmart: "Salin Cerdas", + copyExtractorRaw: "Teks Sel", + copyExtractorWithHeaders: "{format} dengan Header", + copyExtractorOneRow: "Satu baris", + copyExtractorJsonArray: "Larik JSON", + copyExtractorSqlInList: "Daftar IN SQL", + copyExtractorSqlInserts: "SQL Insert", + copyExtractorSqlInsertsWithPrimaryKeys: "SQL Insert (dengan Kunci Utama)", + copyExtractorSqlInsertsWithoutPrimaryKeys: "SQL Insert (tanpa Kunci Utama)", + copyExtractorSqlUpdates: "SQL Update", + copyExtractorSqlSelect: "SQL Select", + copyExtractorWhereClause: "Klausa Where", + copyExtractorPipeSeparated: "Dipisah Pipe", + copyExtractorPretty: "Tabel Rapi", + copyExtractorConfigure: "Konfigurasi Ekstraktor Data…", + copyExtractorSaved: "Pengaturan ekstraktor data disimpan", + copyExtractorDefaultFormat: "Perilaku salin bawaan", + copyExtractorFormat: "Ekstraktor", + copyExtractorColumnSeparator: "Pemisah kolom", + copyExtractorRowSeparator: "Pemisah baris", + copyExtractorNullText: "Teks NULL", + copyExtractorQuote: "Karakter kutip", + copyExtractorQuotePolicy: "Pengutipan", + copyExtractorQuoteMinimal: "Saat diperlukan", + copyExtractorQuoteAlways: "Selalu", + copyExtractorQuoteNever: "Tidak pernah", + copyExtractorIncludeHeader: "Sertakan header kolom", + copyExtractorIncludeRowHeader: "Sertakan nomor baris", + copyExtractorSkipComputed: "Lewati kolom hasil hitungan", + copyExtractorSkipGenerated: "Lewati kolom generated", + copyExtractorExcludePrimaryKeys: "Kecualikan kunci utama", + copyExtractorIncludeDatabaseName: "Sertakan nama database", + copyExtractorInsertMode: "Pernyataan INSERT", + copyExtractorInsertMerged: "Gabungkan baris", + copyExtractorInsertRowByRow: "Satu pernyataan per baris", + copyExtractorPrettyJson: "Format JSON rapi", + copyExtractorCamelCaseJsonFields: "Ubah field snake_case menjadi camelCase", + copyExtractorPreview: "Pratinjau (pilihan saat ini)", + copyExtractorEmptySelection: "Pilih data untuk melihat pratinjau hasil ekstraktor.", + copyExtractorUnsupportedSelection: "Ekstraktor ini mengharuskan kolom yang sama dipilih di setiap baris.", + copyExtractorPreviewTruncated: "Menampilkan pratinjau 100 baris pertama dari {count} baris terpilih.", + copyExtractorWarningOmittedColumns: "Hasil salinan tidak menyertakan kolom ini: {columns}.", + copyExtractorWarningDuplicateJsonColumns: "Nama kolom JSON yang duplikat telah diganti nama untuk mencegah kehilangan data.", + copyExtractorValidation: { + "column-separator-empty": "Pemisah kolom tidak boleh kosong.", + "row-separator-empty": "Pemisah baris tidak boleh kosong.", + "separator-too-long": "Pemisah maksimal boleh berisi 8 karakter.", + "null-text-too-long": "Teks NULL maksimal boleh berisi 64 karakter.", + "separators-overlap": "Pemisah kolom dan baris tidak boleh tumpang tindih.", + "invalid-quote": "Kutip harus tepat satu karakter.", + "quote-conflicts": "Kutip tidak boleh menjadi bagian dari pemisah kolom atau baris.", + }, + mongoJsonPreview: "Pratinjau JSON", + mongoJsonPreviewEmpty: "Pilih dokumen MongoDB untuk melihat pratinjau.", + copyJson: "Salin JSON", + copyDdl: "Salin DDL", + hoverSearchPlaceholder: "Cari kolom…", + hoverSearchNoResult: "Tidak ada kolom yang cocok", + copyCell: "Salin Sel", + copyRow: "Salin Seluruh Baris (Objek JSON)", + copyColumnJson: "Salin Kolom (JSON)", + copyColumnNames: "Salin Nama Kolom", + copyColumnNamesSelected: "Salin Nama Kolom Terpilih ({count})", + copyColumnNamesTitle: "Salin Nama Kolom ({count})", + copyColumnNamesSeparator: "Pemisah Kolom", + copyColumnNamesQuote: "Beri Kutip Nama Kolom", + copyColumnNamesShowComment: "Tampilkan dengan Komentar", + copyColumnNamesPreview: "Pratinjau", + copyAll: "Salin Semua (TSV)", + selectionSum: "SUM: {value}", + selectionAverage: "AVG: {value}", + selectionCells: "{count} sel", + clearSelection: "Bersihkan Pilihan", + export: "Ekspor", + exportCsv: "Ekspor CSV", + exportXlsx: "Ekspor XLSX", + exportXlsxWithSql: "Ekspor XLSX dengan SQL", + exportCurrentPageCsv: "Ekspor Halaman Saat Ini sebagai CSV", + exportCurrentPageXlsx: "Ekspor Halaman Saat Ini sebagai XLSX", + exportCurrentPageXlsxWithSql: "Ekspor Halaman Saat Ini sebagai XLSX dengan SQL", + exportCurrentPageJson: "Ekspor Halaman Saat Ini sebagai JSON", + exportCurrentPageMarkdown: "Ekspor Halaman Saat Ini sebagai Markdown", + exportCurrentPageHtml: "Ekspor Halaman Saat Ini sebagai HTML", + exportCurrentPageSql: "Ekspor Halaman Saat Ini sebagai SQL INSERT", + exportCurrentPageTxt: "Ekspor Halaman Saat Ini sebagai TXT", + exportCurrentResultCsv: "Ekspor Semua Data Hasil Saat Ini sebagai CSV", + exportCurrentResultXlsx: "Ekspor Semua Data Hasil Saat Ini sebagai XLSX", + exportCurrentResultXlsxWithSql: "Ekspor Semua Data Hasil Saat Ini sebagai XLSX dengan SQL", + exportCurrentResultJson: "Ekspor Semua Data Hasil Saat Ini sebagai JSON", + exportCurrentResultMarkdown: "Ekspor Semua Data Hasil Saat Ini sebagai Markdown", + exportCurrentResultHtml: "Ekspor Semua Data Hasil Saat Ini sebagai HTML", + exportCurrentResultSql: "Ekspor Semua Data Hasil Saat Ini sebagai SQL INSERT", + exportCurrentResultTxt: "Ekspor Semua Data Hasil Saat Ini sebagai TXT", + exportAllResultsXlsx: "Ekspor Semua Hasil dari Eksekusi Ini sebagai XLSX", + exportAllResultsXlsxWithSql: "Ekspor Semua Hasil dari Eksekusi Ini sebagai XLSX dengan SQL", + exportJson: "Ekspor JSON", + exportMarkdown: "Ekspor Markdown", + exportHtml: "Ekspor HTML", + exportSql: "Ekspor SQL INSERT", + sqlInsertModeTitle: "Mode Ekspor SQL INSERT", + sqlInsertModePrompt: "Pilih cara baris ditulis ke file SQL INSERT:", + sqlInsertModeBatch: "Gabung secara batch", + sqlInsertModeBatchDescription: "Gabungkan beberapa baris ke setiap pernyataan INSERT untuk file yang lebih kecil dan eksekusi yang lebih cepat.", + sqlInsertModeSingle: "Satu baris per pernyataan", + sqlInsertModeSingleDescription: "Tulis satu pernyataan INSERT lengkap per baris agar lebih mudah dieksekusi dan ditelusuri satu per satu.", + exportTxt: "Ekspor TXT", + exportSelectedRowsCsv: "Ekspor Baris Terpilih sebagai CSV", + exportSelectedRowsXlsx: "Ekspor Baris Terpilih sebagai XLSX", + exportSelectedRowsXlsxWithSql: "Ekspor Baris Terpilih sebagai XLSX dengan SQL", + exportSelectedRowsJson: "Ekspor Baris Terpilih sebagai JSON", + exportSelectedRowsMarkdown: "Ekspor Baris Terpilih sebagai Markdown", + exportSelectedRowsHtml: "Ekspor Baris Terpilih sebagai HTML", + exportSelectedRowsSql: "Ekspor Baris Terpilih sebagai SQL INSERT", + exportSelectedRowsTxt: "Ekspor Baris Terpilih sebagai TXT", + exported: "Diekspor", + exportFailed: "Ekspor gagal: {message}", + xlsxHeaderTitle: "Format Header", + xlsxExportTitle: "Opsi Ekspor", + xlsxHeaderPrompt: "Pilih format header untuk file Excel yang diekspor:", + xlsxHeaderOriginal: "Gunakan nama kolom sebagai header", + xlsxHeaderComment: "Gunakan komentar kolom sebagai header", + xlsxHeaderNameAndComment: "Gunakan nama dan komentar kolom sebagai header", + xlsxFilterPrompt: "Pilih apakah file Excel yang diekspor menyertakan filter:", + xlsxIncludeAutoFilter: "Sertakan filter", + copied: "Disalin", + copyFailed: "Salin gagal: {message}", + previewSqlEmpty: "Tidak ada perubahan SQL tertunda untuk dipratinjau", + renderMode: "Mode Render", + domRenderMode: "DOM", + canvasRenderMode: "Canvas", + renderModeHint: "Beralih antara rendering Canvas dan grid cadangan DOM.", + tableFontFamily: "Font tabel", + tableFontSize: "Ukuran font tabel", + filter: "Filter", + conditionHistoryEmpty: "Belum ada riwayat", + conditionHistoryNoMatches: "Tidak ada riwayat yang cocok", + filterBuilder: "Filter", + filterBuilderTitle: "Filter", + filterBuilderHint: "Buat kondisi dengan klik-dan-pilih lalu gabungkan dengan input WHERE.", + filterView: "Tampilan filter", + filterQuickView: "Tampilan cepat", + filterConditionView: "Tampilan kondisi", + filterTextView: "Tampilan teks", + resizeFilterPanel: "Ubah ukuran panel filter", + filterConditionPanel: "Kondisi filter", + filterManualWhere: "WHERE manual", + filterSqlPreview: "Pratinjau kondisi SQL", + filterSqlPreviewEmpty: "Belum ada kondisi filter yang valid", + filterSqlPreviewReady: "Kondisi siap; terapkan untuk menyegarkan hasil", + copyFilterSql: "Salin kondisi SQL", + filterSqlCopied: "Kondisi SQL disalin", + filterBuilderSummary: "{count} aturan", + filterBuilderAddRule: "Tambah aturan", + filterBuilderApplyOnly: "Filter hanya aturan ini", + filterBuilderCompleteRuleFirst: "Lengkapi aturan filter ini terlebih dahulu", + filterBuilderEnableRule: "Aktifkan aturan", + filterBuilderDisableRule: "Nonaktifkan aturan", + filterBuilderReorderRule: "Seret atau gunakan tombol panah untuk mengurutkan ulang kondisi", + filterBuilderColumn: "Kolom", + filterBuilderSearchColumns: "Cari kolom...", + filterBuilderNoMatchingColumns: "Tidak ada kolom yang cocok", + filterBuilderValue: "Nilai", + filterBuilderTextValue: "", + filterBuilderValueTypeAuto: "Otomatis", + filterBuilderValueTypeString: "String", + filterBuilderValueTypeNumber: "Angka", + filterBuilderValueTypeBoolean: "Boolean", + filterBuilderValueTypeObjectId: "ObjectId", + filterBuilderValueTypeDate: "Tanggal", + filterBuilderValueTypeInt32: "Int32", + filterBuilderValueTypeInt64: "Int64", + filterBuilderValueTypeDecimal128: "Decimal128", + filterBuilderValueTypeJson: "JSON", + filterBuilderValueShortcutHint: "Shift+Enter dapat menambahkan aturan", + filterBuilderValues: "Nilai (dipisah koma atau baris baru)", + filterBuilderRangeStart: "Nilai awal", + filterBuilderRangeEnd: "Nilai akhir", + filterBuilderNoValue: "Tidak perlu nilai", + filterBuilderEmpty: "Tambahkan aturan untuk mulai memfilter baris.", + resetFilterBuilder: "Atur ulang aturan", + filterBuilderEquals: "Sama dengan", + filterBuilderNotEquals: "Tidak sama dengan", + filterBuilderContains: "Mengandung", + filterBuilderNotContains: "Tidak mengandung", + filterBuilderBeginsWith: "Diawali dengan", + filterBuilderEndsWith: "Diakhiri dengan", + filterBuilderGreaterThan: "Lebih besar dari", + filterBuilderGreaterThanOrEqual: "Lebih besar dari atau sama dengan", + filterBuilderLessThan: "Lebih kecil dari", + filterBuilderLessThanOrEqual: "Lebih kecil dari atau sama dengan", + filterBuilderIn: "Dalam daftar", + filterBuilderNotIn: "Tidak dalam daftar", + filterBuilderBetween: "Dalam rentang", + filterBuilderNotBetween: "Di luar rentang", + filterBuilderIsNull: "Adalah NULL", + filterBuilderIsNotNull: "Bukan NULL", + filterBuilderIsBlank: "Kosong (NULL atau kosong)", + filterBuilderIsNotBlank: "Tidak kosong (bukan NULL dan tidak kosong)", + columnActions: "Aksi kolom", + localFilter: "Filter nilai lokal", + localFilterFor: "Nilai Lokal Untuk '{column}'", + databaseValueFilter: "Filter nilai database", + databaseValueFilterFor: "Nilai Database Untuk '{column}'", + columnFormatter: "Pemformat kolom", + columnFormatterActive: "Tampilan terformat sedang aktif", + columnFormatterFor: "Pemformat untuk '{column}'", + columnFormatterHint: "Hanya memformat tampilan; nilai mentah tetap tidak berubah.", + formatterType: "Jenis", + formatterDatetime: "Timestamp Unix", + formatterJsonPath: "Path JSON", + formatterMask: "Teks mask", + formatterForeignKeyDisplay: "Label kunci asing", + formatterForeignKeyTarget: "Kunci yang direferensikan", + formatterForeignKeyManualHint: "Kolom ini tidak memiliki kunci asing kolom tunggal. Pilih tabel yang direferensikan dan kolom yang cocok secara manual.", + formatterForeignKeySchema: "Skema", + formatterForeignKeySchemaPlaceholder: "Pilih skema", + formatterForeignKeySearchSchema: "Cari skema...", + formatterForeignKeyNoSchemas: "Tidak ada skema yang tersedia", + formatterForeignKeyTable: "Tabel yang direferensikan", + formatterForeignKeyTablePlaceholder: "Pilih tabel yang direferensikan", + formatterForeignKeySearchTable: "Cari tabel yang direferensikan...", + formatterForeignKeyNoTables: "Tidak ada tabel yang direferensikan tersedia", + formatterForeignKeyReferenceColumn: "Kolom yang cocok", + formatterForeignKeyReferenceColumnPlaceholder: "Pilih kolom yang cocok dengan nilai ini", + formatterForeignKeyReferenceMetadataUnavailable: "Tidak dapat memverifikasi keunikan kolom yang cocok: {error}", + formatterForeignKeyReferenceInvalid: "Kolom ini tidak ada atau tidak dijamin unik oleh kunci unik dan filter kesetaraan saat ini. Pilih kolom lain.", + formatterForeignKeyReferenceUnavailable: "Tabel target tidak memiliki kunci unik yang dapat digunakan. Untuk kunci unik komposit, perbaiki kolom lain dengan filter kesetaraan.", + formatterForeignKeyDisplayColumn: "Kolom tampilan", + formatterForeignKeyDisplayColumnPlaceholder: "Pilih kolom tampilan", + formatterForeignKeyFilter: "Batasi baris yang direferensikan", + formatterForeignKeyFilterColumnPlaceholder: "Pilih kolom filter", + formatterForeignKeyHint: "Memuat label untuk kunci yang cocok pada halaman saat ini. Pengeditan, pemfilteran, pengurutan, penyalinan, dan ekspor tetap menggunakan nilai mentah.", + formatterCustomTemplate: "Templat kustom", + formatterTimestampUnit: "Satuan timestamp", + formatterUnitAuto: "Otomatis", + formatterUnitSeconds: "Detik", + formatterUnitMilliseconds: "Milidetik", + formatterDatetimePattern: "Pola datetime", + formatterDatetimePatternPlaceholder: "Pilih atau masukkan pola datetime", + formatterDatetimePatternEmpty: "Format ISO8601 bawaan", + formatterDatetimeTimezone: "Zona waktu", + formatterDatetimeTimezonePlaceholder: "Pilih zona waktu", + formatterJsonPathInput: "Path JSON", + formatterMaskPrefix: "Awalan yang terlihat", + formatterMaskSuffix: "Akhiran yang terlihat", + formatterSavedCustom: "Templat tersimpan", + formatterNewCustom: "Templat baru", + formatterDeleteCustom: "Hapus templat", + formatterDeleteCustomMessage: 'Hapus "{name}"? Pemformatan akan dihapus dari setiap kolom yang menggunakan templat ini.', + formatterCustomName: "Nama templat", + formatterCustomNamePlaceholder: "Contoh: Label pengguna", + formatterCustomTemplateInput: "Templat", + formatterCustomTemplateHint: "Variabel yang tersedia: ${value}, ${upper}, ${lower}, ${length}. Beri nama untuk menyimpannya ke daftar.", + formatterPreview: "Pratinjau", + saveFormatter: "Simpan", + clearFormatter: "Bersihkan", + searchValues: "Cari nilai...", + loadingValues: "Memuat nilai...", + serverValuesLimited: "Menampilkan {count} nilai pertama", + filterTypedValue: "Gunakan '{value}'", + value: "Nilai", + count: "Jumlah", + applyFilter: "Terapkan Filter", + clearLocalFilters: "Bersihkan filter nilai lokal", + clearLocalFiltersShort: "Bersihkan lokal", + localFiltersActive: "{count} filter nilai lokal", + localFilterMoreValues: " +{count} lagi", + columnVisibility: "Kolom", + autoFitColumnWidths: "Sesuaikan kolom dengan konten", + autoFitColumnWidthsHint: "Mengatur ukuran setiap kolom yang terlihat sesuai isi selnya. Anda masih bisa menyeret batas kolom setelahnya.", + columnVisibilityHint: "Minimal satu kolom tetap terlihat.", + columnReorderHint: "Seret untuk mengurutkan ulang kolom.", + columnReorderSearchHint: "Hapus pencarian untuk mengurutkan ulang kolom.", + searchColumns: "Cari kolom...", + dragColumnToReorder: "Seret header kolom untuk mengurutkan ulang", + invertColumnVisibility: "Balikkan", + resetColumnOrder: "Atur ulang urutan", + showAllColumns: "Tampilkan semua", + viewOptions: "Opsi tampilan", + resultRunDisplayMode: "Tab hasil", + resultRunDisplayList: "Daftar", + resultRunDisplayTabs: "Berjajar", + hideNullColumns: "Sembunyikan NULL", + hideNullColumnsHint: "Alihkan kolom yang nilainya seluruhnya NULL pada hasil saat ini.", + searchMode: "Mode pencarian", + searchModeHint: "Pilih apakah Ctrl+F memfilter baris yang cocok atau tetap menampilkan semua baris dan menyorot kecocokan.", + searchModeFilter: "Filter", + searchModeHighlight: "Sorot", + rowNumberMode: "Tampilan nomor baris", + rowNumberModeHint: "Pilih apakah kolom nomor baris menampilkan posisi tampilan saat ini atau nomor baris asli sebelum pemfilteran. Nomor baris asli tetap stabil saat baris difilter keluar.", + rowNumberModeView: "Posisi tampilan", + rowNumberModeSource: "Nomor asli", + colorizeDataTypes: "Warna jenis data", + numericColumnAlign: "Perataan Kolom Numerik", + numericColumnAlignLeft: "Kiri", + numericColumnAlignRight: "Kanan", + booleanDisplayMode: "Tampilan boolean", + booleanDisplayCheckbox: "Centang", + booleanDisplayDropdown: "Dropdown", + moreValues: "{count} nilai lagi, terus ketik untuk mempersempit hasil", + filterByValue: "Filter berdasarkan Nilai Ini", + filterExcludeValue: "Kecualikan Nilai Ini", + filterLike: "Mengandung Nilai", + filterNotLike: "Tidak Mengandung", + filterLessThan: "Kurang dari Nilai", + filterGreaterThan: "Lebih dari Nilai", + filterIsNull: "Tampilkan Nilai NULL", + filterIsNotNull: "Tampilkan Nilai Non-NULL", + clearFilter: "Bersihkan Filter", + sort: "Urutkan", + sortAscending: "Urutkan Naik", + sortDescending: "Urutkan Turun", + sortCurrentPageAscending: "Urutkan Halaman Saat Ini Naik", + sortCurrentPageDescending: "Urutkan Halaman Saat Ini Turun", + sortDatabaseAscending: "Urutkan Database Naik", + sortDatabaseDescending: "Urutkan Database Turun", + clearSort: "Bersihkan Urutan", + sortBuilderTitle: "Urutkan", + sortBuilderAddRule: "Tambah bidang", + sortBuilderSelectColumn: "Pilih bidang", + sortBuilderReorderRule: "Seret untuk mengurutkan ulang bidang pengurutan", + sortBuilderApplyOnly: "Urutkan hanya berdasarkan bidang ini", + sortBuilderEnableRule: "Aktifkan bidang pengurutan", + sortBuilderDisableRule: "Nonaktifkan bidang pengurutan", + sortBuilderEmpty: "Tambahkan bidang untuk mengatur pengurutan.", + sortBuilderApply: "Terapkan Urutan", + sortBuilderReset: "Atur ulang urutan", + sortBuilderCompleteRuleFirst: "Pilih bidang untuk setiap aturan urutan yang diaktifkan.", + sortSqlPreview: "Pratinjau SQL urutan", + sortSqlPreviewEmpty: "Belum ada bidang urutan yang valid", + copySortSql: "Salin SQL urutan", + sortSqlCopied: "SQL urutan disalin", + resizeSortPanel: "Ubah ukuran panel urutan", + sortTextView: "Tampilan teks urutan", + freezeToColumn: "Bekukan hingga Kolom Ini", + freezeSelectedColumns: "Bekukan Kolom Terpilih ({count})", + freezeCurrentColumn: "Bekukan Kolom Saat Ini", + unfreezeCurrentColumn: "Batalkan Pembekuan Kolom Saat Ini", + unfreezeColumns: "Batalkan Pembekuan Kolom ({count})", + hideColumn: "Sembunyikan Kolom Ini", + hideSelectedColumns: "Sembunyikan Kolom Terpilih ({count})", + showAllColumnsMenu: "Tampilkan Semua Kolom", + pasted: "Ditempel!", + batchAppendPasteNotEditable: "Hasil ini tidak dapat diedit.", + batchAppendPasteInvalidTarget: "Pilih nomor baris dari baris baru yang kosong sebelum menempel.", + batchAppendPasteTargetNotEmpty: "Baris baru yang dipilih sudah berisi data.", + batchAppendPasteEmpty: "Clipboard tidak berisi baris untuk ditambahkan.", + batchAppendPasteReadonlyColumn: "Data yang ditempel menyertakan kolom yang tidak dapat diedit.", + batchAppendPasteNoMatchingColumns: "Tidak ada nama kolom dari pernyataan INSERT yang cocok dengan kolom hasil ini.", + replaceText: "Ganti dengan", + replaceCurrentCell: "Ganti semua teks yang cocok pada sel saat ini", + replaceScope: "Cakupan penggantian", + replaceLoadedResults: "Hasil yang dimuat", + replaceCurrentColumn: "Kolom saat ini", + replaceSelectedCells: "Sel terpilih", + replaceChooseColumn: "Pilih kolom", + replaceMatchedCells: "{count} sel yang cocok", + replaceStagedCells: "{count} sel diganti; menunggu disimpan", + search: "Cari...", + searchTruncatedValuesHint: "Beberapa nilai teks/JSON yang panjang dipotong untuk tampilan; pencarian hanya mencakup teks sel yang dimuat dan mungkin melewatkan kecocokan.", + searchOrWhere: "Cari, atau masukkan klausa WHERE...", + applyWhere: "Terapkan WHERE", + filterRows: "Filter baris", + filterAllRows: "Semua baris", + filterChangedRows: "Berubah", + page: "Halaman {page}", + jumpToPage: "Lompat ke halaman", + rowsPerPage: "Baris per halaman", + customRowsPerPage: "Baris kustom", + applyPageSize: "Terapkan", + currentAndDefaultPageSize: "Saat ini: {current} · Bawaan: {default}", + applyForThisQuery: "Untuk sekarang", + applyAndSetDefault: "Jadikan bawaan", + save: "Simpan", + discard: "Buang", + dismiss: "Tutup", + addRow: "Tambah Baris", + insertMultipleRows: "Sisipkan Beberapa Baris…", + insertRowsTitle: "Sisipkan Beberapa Baris", + insertRowsDescription: "Buat baris draf yang belum disimpan sebanyak ini. Baris kosong diabaikan saat menyimpan; setelah disimpan, urutan tampilan mengikuti kueri saat ini.", + insertRowCountLabel: "Jumlah baris", + insertRowCountInvalid: "Masukkan bilangan bulat lebih besar dari 0.", + insertRowsMaxHint: "Hingga {max} baris.", + insertRowsConfirm: "Sisipkan", + insertAboveSelected: "Sisipkan di Atas Baris Terpilih", + insertBelowSelected: "Sisipkan di Bawah Baris Terpilih", + insertRowPositionLabel: "Posisi", + insertPositionAbove: "Di atas baris terpilih", + insertPositionBelow: "Di bawah baris terpilih", + insertPositionEnd: "Di akhir data", + quickEntryDraftPlaceholder: "Baru", + cloneRow: "Klon sebagai Baris Baru", + deleteRow: "Hapus Baris", + deleteRows: "Hapus {count} Baris", + cloneRows: "Klon {count} sebagai Baris Baru", + restoreRows: "Pulihkan {count} Baris", + copyRows: "Salin {count} Baris (Larik JSON)", + copyColumnsJson: "Salin {count} Kolom (JSON)", + selectedRows: "{count} baris terpilih", + restoreRow: "Pulihkan Baris", + statusClean: "Bersih", + statusNew: "Item Baru", + statusEdited: "Item Diperbarui", + statusDeleted: "Item Dihapus", + pendingChanges: "{count} tertunda", + selectedCells: "{count} terpilih", + bulkEditSelection: "Edit Massal Pilihan", + bulkEditTitle: "Edit Massal Pilihan", + bulkEditDescription: "Atur {count} sel terpilih ke nilai ini.", + bulkEditValuePlaceholder: "Nilai, atau NULL", + applyBulkEdit: "Terapkan", + bulkEditSelectionScope: "Hanya sel terpilih", + bulkEditSelectionScopeDescription: "Tahan perubahan untuk {count} sel terpilih.", + bulkEditConditionalScope: "Semua baris yang cocok dengan kondisi", + bulkEditConditionalScopeDescription: "Perbarui {column} untuk setiap baris database yang cocok dengan kondisi yang Anda berikan.", + bulkEditConditionalConditionSource: "Kondisi pencocokan", + bulkEditConditionalUseCurrentFilter: "Gunakan filter tabel saat ini", + bulkEditConditionalUseCurrentFilterDescription: "Pertahankan kondisi database yang sedang diterapkan pada tabel ini.", + bulkEditConditionalBuildFilter: "Atur kondisi pencocokan", + bulkEditConditionalBuildFilterDescription: "Pilih kolom, operator, dan nilai tanpa menulis SQL.", + bulkEditConditionalAdvancedWhere: "Lanjutan: WHERE SQL", + bulkEditConditionalAdvancedWhereDescription: "Tulis kondisi SQL kustom.", + conditionalBulkEditPreviewCount: "Pratinjau baris yang terpengaruh", + conditionalBulkEditPreviewingCount: "Memuat pratinjau…", + conditionalBulkEditPreviewCountResult: "Perkiraan {count} baris terpengaruh", + conditionalBulkEditPreviewCountStale: "Kondisi telah berubah. Pratinjau lagi.", + conditionalBulkEditPreviewCountFailed: "Tidak dapat mempratinjau baris yang terpengaruh: {message}", + bulkEditConditionalWhere: "Kondisi WHERE (wajib diisi)", + bulkEditConditionalWherePlaceholder: "Contoh: tenant_id = 1 AND status = 'pending'", + bulkEditConditionalWhereDescription: "Masukkan klausa WHERE atau hanya kondisinya. Filter tabel yang aktif diisi otomatis bila tersedia.", + conditionalBulkEditUnavailable: "Edit massal bersyarat tidak lagi tersedia untuk pilihan atau filter ini.", + conditionalBulkEditConditionRequired: "Atur minimal satu kondisi pencocokan sebelum memperbarui semua baris yang cocok.", + conditionalBulkEditPrepareFailed: "Gagal menyiapkan pembaruan bersyarat: {message}", + conditionalBulkEditConfirmTitle: "Konfirmasi pembaruan massal bersyarat", + conditionalBulkEditConfirmMessage: "Ini dieksekusi segera terhadap setiap baris yang cocok dengan kondisi pada saat eksekusi. Baris yang belum dimuat juga disertakan, dan DBX tidak dapat membuat rollback yang andal untuknya.", + conditionalBulkEditConfirm: "Eksekusi pembaruan", + conditionalBulkEditAppliedCount: "{count} baris yang cocok diperbarui", + conditionalBulkEditApplied: "Baris yang cocok telah diperbarui", + conditionalBulkEditPendingChanges: "Simpan atau buang perubahan tertunda saat ini sebelum memperbarui semua baris yang cocok dengan kondisi.", + generateValue: "Hasilkan Nilai", + generateEmptyString: "String Kosong", + generateNull: "NULL", + generateCurrentDatetime: "Datetime Saat Ini", + generateCurrentDate: "Tanggal Saat Ini", + generateUuidV4: "UUID v4", + generateUuidV7: "UUID v7", + generateIncrementId: "ID Increment", + generateSnowflakeId: "ID Snowflake", + generateSequenceDescription: "Hasilkan nilai berurutan untuk {count} sel terpilih. Masukkan nilai awal.", + generateStartInvalid: "Nilai awal harus berupa bilangan bulat", + generatedValuesApplied: "{count} nilai dihasilkan", + cellDetails: "Detail Sel", + cellDetailLayoutBottom: "Pindahkan ke Bawah", + cellDetailLayoutRight: "Pindahkan ke Kanan", + collapseCellDetailMetadata: "Ciutkan metadata sel", + expandCellDetailMetadata: "Perluas metadata sel", + openCellDetailsDialog: "Buka Detail Sel", + rowDetails: "Detail Baris", + rowDetailsFor: "Detail Baris {row}", + openRowDetailsDialog: "Buka Detail Baris", + openColumnDetailsDialog: "Buka Detail Kolom", + columnDetailsFor: "Detail Kolom {column}", + columnsCount: "{count} kolom", + rowCount: "Baris", + rowsCount: "{count} baris", + fieldIndex: "No.", + cellValue: "Nilai", + valueEditor: "Editor Nilai", + hexViewer: "Penampil Hex", + hexViewerByteCount: "{count} byte", + hexViewerOffset: "Offset", + hexViewerHex: "Hex", + hexViewerAscii: "ASCII", + hexViewerEmpty: "Tidak ada byte biner untuk ditampilkan.", + imagePreview: "Pratinjau Gambar", + imageLoadFailed: "Gambar gagal dimuat", + geometryPreview: "Pratinjau Geometri", + layerPreview: "Pratinjau Lapisan", + layerPreviewSkipped: "{count} fitur dilewati", + layerPreviewNoSupportedCrs: "Tidak dapat mempratinjau: sistem koordinat hilang atau tidak didukung", + layerPreviewNoGeometryData: "Tidak dapat mempratinjau: tidak ada data geometri yang valid", + layerPreviewLabel: "Label", + layerPreviewExport: "Ekspor gambar", + layerPreviewMaximize: "Maksimalkan", + layerPreviewRestore: "Pulihkan", + layerPreviewLoading: "Memuat peta...", + layerPreviewCustomCrs: "EPSG Kustom…", + layerPreviewCustomCrsPlaceholder: "Kode EPSG", + layerPreviewUnsupportedCrs: "Sistem koordinat tidak didukung: EPSG:{srid}", + layerPreviewCrsManual: "Sistem koordinat: manual", + layerPreviewCrsDetected: "Sistem koordinat: terdeteksi", + layerPreviewCrsAssumed: "Sistem koordinat: diasumsikan WGS 84", + layerPreviewCustomBasemap: "Basemap kustom", + layerPreviewCustomBasemapAction: "Basemap kustom…", + layerPreviewCustomBasemapTitle: "Basemap kustom", + layerPreviewCustomBasemapName: "Nama", + layerPreviewCustomBasemapNamePlaceholder: "mis. Jalan Gaode", + layerPreviewCustomBasemapHint: "Masukkan URL tile XYZ menggunakan {z}, {x}, dan {y}. URL overlay opsional berguna untuk label, seperti anotasi Tianditu.", + layerPreviewCustomBasemapUrl: "URL Tile", + layerPreviewCustomBasemapOverlayUrl: "URL Overlay", + layerPreviewCustomBasemapAttribution: "Atribusi", + layerPreviewCustomBasemapMaxZoom: "Zoom maksimum", + layerPreviewCustomBasemapOptional: "Opsional", + layerPreviewCustomBasemapApply: "Terapkan", + layerPreviewCustomBasemapInvalid: "Masukkan nama dan URL tile XYZ HTTP(S) yang valid berisi {z}, {x}, dan {y}.", + insertRowsNotSupported: "Target penyimpanan saat ini tidak mendukung penambahan baris.", + zoomIn: "Perbesar", + zoomOut: "Perkecil", + fitImage: "Sesuaikan ke Tampilan", + openImage: "Buka Gambar", + columnName: "Kolom", + columnType: "Jenis", + columnComment: "Komentar", + rowNumber: "Baris", + valueLength: "Panjang", + nullValue: "NULL", + emptyStringValue: "String kosong", + noComment: "Tidak ada komentar", + formattedJson: "JSON Terformat", + formatted: "Terformat", + formattedValue: "Nilai Terformat", + detailSearchPlaceholder: "Cari bidang atau nilai…", + detailSearchNoMatch: "Tidak ada kecocokan", + rawValue: "Nilai Mentah", + largeValuePreviewHint: "Mempratinjau {count} karakter pertama. Salin tetap menggunakan nilai lengkap.", + largeValueRowUnavailable: "Baris tidak dapat ditemukan di database. Operasi dibatalkan tanpa menggunakan nilai pratinjau.", + largeValueColumnUnavailable: "Kolom sumber untuk nilai besar ini tidak dapat ditemukan.", + largeValueLoadFailed: "Gagal memuat nilai lengkap bidang besar.", + largeValueNeedsStableKey: "Tabel ini tidak memiliki kunci utama yang dapat digunakan, sehingga nilai lengkap bidang besar tidak dapat dimuat dengan aman. Operasi dibatalkan.", + largeValueLoadFailedWithMessage: "Gagal memuat nilai lengkap bidang besar: {message}", + largeValueLocalSortUnavailable: "Kolom ini berisi pratinjau nilai besar dan tidak dapat diurutkan secara lokal berdasarkan isi pratinjau. Gunakan pengurutan database sebagai gantinya.", + copyValue: "Salin Nilai", + importBinaryValue: "Impor dari File", + binaryImportApplied: "{count} byte diimpor. Simpan perubahan untuk menuliskannya ke database.", + binaryImportFailed: "Gagal mengimpor file: {message}", + binaryImportTooLarge: "File terlalu besar ({size}, batas {limit}). Mengimpor file besar ke satu sel tidak didukung.", + downloadBinaryValue: "Unduh Nilai", + downloadSaved: "Disimpan ke {path}", + downloadStarted: "Unduhan dimulai: {fileName}", + binaryDownload: { + binary: "Biner mentah", + utf8: "Teks terdekode (UTF-8)", + gbk: "Teks terdekode (GBK)", + }, + binaryTextPreview: "Lihat sebagai teks", + binaryTextPreviewTitle: "Pratinjau teks biner", + binaryTextPreviewDescription: "Mendekode secara ketat byte hex 0x dengan charset yang dipilih. Pratinjau hanya-baca; nilai asli tidak diubah.", + binaryTextPreviewEncoding: "Charset", + binaryTextPreviewEncodings: { + utf8: "UTF-8", + gbk: "GBK", + }, + binaryTextPreviewByteCount: "{count} byte", + binaryTextPreviewResult: "Teks terdekode", + binaryTextPreviewCopy: "Salin hasil", + binaryTextPreviewOriginalHint: "Nilai asli tetap berupa hex 0x; pratinjau ini tidak mengubah sel atau database.", + binaryTextPreviewErrors: { + notBinary: "Nilai ini bukan nilai biner lengkap, sehingga tidak dapat didekode.", + incomplete: "Nilai lengkap belum dimuat; mendekode pratinjau yang tidak lengkap bisa menyesatkan.", + undecodable: "Dekode ketat gagal: ini tampak seperti data biner sungguhan (gambar, arsip, atau urutan byte tidak valid), bukan teks.", + }, + copyRowTsv: "Salin Baris (TSV)", + copyColumnValues: "Salin Kolom (JSON)", + copyColumnTsv: "Salin Kolom (TSV)", + editValue: "Edit Nilai", + formatJson: "Format JSON", + compactJson: "Padatkan JSON", + compareJson: "Bandingkan", + valueDiffTitle: "Perbedaan JSON {column}", + valueDiffFormat: "Format perbandingan", + valueDiffRaw: "Mentah", + valueDiffOriginal: "Asli", + valueDiffCurrent: "Saat Ini", + copyOriginalValue: "Salin nilai asli", + copyCurrentValue: "Salin nilai saat ini", + cellValueCopied: "Nilai sel disalin", + valueDiffInvalidJson: "JSON tidak valid; menampilkan nilai mentah: {message}", + valueDiffTooLarge: "Nilai melebihi {limit} karakter; menampilkan nilai mentah.", + formattedJsonEditWarning: "Anda sedang mengedit JSON terformat. Menyimpan akan menuliskannya sebagai JSON, sehingga format asli mungkin berubah.", + setNull: "Atur NULL", + restoreOriginalValue: "Pulihkan Asli", + copyColumnName: "Salin Nama Kolom", + columnDragChipMany: "{names} ({count} kolom)", + copyAlterColumnSql: "Salin sebagai SQL ALTER", + alterSqlCopied: "SQL ALTER disalin ke clipboard", + alterSqlCopiedWithWarnings: "SQL ALTER disalin ke clipboard ({count} peringatan)", + noAlterSqlAvailable: "Tidak ada SQL ALTER yang tersedia untuk kolom ini", + copyAlterSqlFailed: "Salin gagal: {message}", + copySqlCondition: "Salin Kondisi SQL", + copyQuerySql: "Salin SQL", + copyExecutableSql: "Salin SQL (tanpa komentar)", + transpose: "Transpos Baris", + transposeMultiRowToggle: "Multi-baris", + transposeSingleRow: "Baris saat ini", + transposeMultiRow: "Multi-baris", + transposeMultiRowHint: "Jika diaktifkan, tampilan transpos menampilkan beberapa baris. Jika dinonaktifkan, hanya menampilkan baris saat ini.", + rowsPerPageShort: " baris", + columnDetails: "Detail Kolom", + tableInfo: "Info Tabel", + tableInfoOverview: "Ringkasan", + tableInfoEstimatedRows: "Perkiraan baris", + tableInfoTotalSize: "Ukuran total", + tableInfoDataLength: "Panjang data", + tableInfoEngine: "Engine", + tableInfoCreatedAt: "Dibuat pada", + tableInfoUpdatedAt: "Diperbarui pada", + tableInfoCollation: "Collation", + tableInfoRowFormat: "Format baris", + tableInfoAvgRowLength: "Panjang baris rata-rata", + tableInfoMaxDataLength: "Panjang data maksimum", + tableInfoCheckTime: "Waktu pemeriksaan", + tableInfoIndexLength: "Panjang indeks", + tableInfoAutoIncrement: "Auto increment", + tableInfoDataFree: "Data free", + pinTableInfo: "Sematkan panel info tabel", + unpinTableInfo: "Lepas sematan panel info tabel", + tableInfoColumns: "Kolom", + tableInfoIndexes: "Indeks", + columnPrimaryIndex: "Indeks kunci utama", + columnUniqueIndex: "Indeks unik", + columnRegularIndex: "Indeks reguler", + tableInfoForeignKeys: "Kunci Asing", + foreignKeyNavigate: "Buka {table}", + openUrl: "Buka URL di browser", + tableInfoConstraints: "Constraint", + tableInfoConstraintDisabled: "Dinonaktifkan", + tableInfoConstraintNotValidated: "Belum divalidasi", + tableInfoTriggers: "Trigger", + tableInfoNullable: "Nullable", + tableInfoEmpty: "Tidak ada metadata", + tableInfoSearch: "Cari...", + tableOwner: "Pemilik", + tableOwnerUnavailable: "Tidak tersedia", + tableInfoNoResults: "Tidak ada hasil", + goToColumn: "Buka kolom", + columnWidth: "Lebar Kolom", + columnWidthCompact: "Ringkas", + columnWidthStandard: "Standar", + columnWidthComfortable: "Longgar", + columnWidthMode: "Tata letak lebar", + columnWidthModeFill: "Isi lebar yang tersedia", + columnWidthModeContent: "Lebar sesuai konten", + searchColumn: "Cari kolom/komentar...", + noColumnsFound: "Tidak ada kolom yang ditemukan", + queryError: "Galat Kueri", + saveErrorTitle: "Gagal Menyimpan Perubahan", + dataUnavailable: "Data tabel perlu dimuat ulang.", + viewSnapshotSelectionNotRestored: "Tampilan sebelumnya telah dipulihkan, tetapi pilihannya terlalu besar untuk dipertahankan.", + cachedResultUnavailable: "Hasil yang di-cache hilang atau tidak kompatibel.", + reexecuteQuery: "Jalankan kueri lagi", + dataUnavailableHintPrefix: "Tekan ", + dataUnavailableHintSuffix: " atau klik Segarkan di bawah untuk memuat ulang.", + refresh: "Segarkan", + undoChange: "Urungkan perubahan", + redoChange: "Ulangi perubahan", + commit: "Commit", + rollback: "Rollback", + transactionSaveHint: "Commit {count} perubahan tertunda dalam satu transaksi.", + nonTransactionalSaveHint: "Simpan {count} perubahan tertunda satu per satu. Jika salah satu gagal, perubahan sebelumnya yang berhasil tidak akan di-rollback.", + salesforceSaveConfirmTitle: "Terapkan Perubahan ke Salesforce", + salesforceSaveConfirmMessage: "{count} perubahan tertunda dikirim ke Salesforce sebagai satu panggilan REST per record. Tidak ada transaksi: jika sebuah panggilan gagal di tengah jalan, record yang sudah ditulis tetap berubah.", + salesforceSaveUpdates: "{count} pembaruan", + salesforceSaveInserts: "{count} record baru", + salesforceSaveDeletes: "{count} penghapusan", + salesforceSaveTarget: "Objek: {object}", + salesforceSaveUnknownObject: "tidak diketahui", + salesforceSaveProfile: "profil {name}", + salesforceSaveAdminIdentity: "Menulis sebagai {user} ({profile}); profil ini memiliki “Modify All Data”, yang melewati keamanan tingkat bidang dan berbagi record — mohon periksa ulang.", + salesforceSaveNonAdminIdentity: "Masuk sebagai {user} ({profile}).\nBidang yang tidak dapat Anda tulis sudah bersifat hanya-baca di sini;\nkegagalan akibat berbagi record atau aturan validasi dikembalikan per baris, dengan kata-kata Salesforce sendiri.", + salesforceSaveUnknownRights: "Masuk sebagai {user} ({profile}); tidak dapat menentukan apakah profil ini memiliki “Modify All Data” — Salesforce tetap menerapkan izinnya sendiri dan melaporkan kegagalan per baris.", + salesforceSaveConfirm: "Terapkan ke Salesforce", + influxDeleteConfirmTitle: "Hapus Titik InfluxDB", + influxDeleteConfirmMessage: "Hapus permanen {count} titik terpilih dari InfluxDB 1.x? Setiap predikat menggunakan waktu persis dan setiap tag yang tersedia. Penghapusan tidak dapat diurungkan, dan galat dapat terjadi setelah sebagian titik terhapus.", + influxDeleteTarget: "Pengukuran: {measurement}", + influxDeleteConfirm: "Hapus Titik", + keylessEditWarning: "Tidak ada kunci utama", + keylessEditWarningHint: "Tabel ini tidak memiliki kunci utama. Update dan delete menggunakan semua nilai baris asli pada klausa WHERE; baris duplikat persis dapat terpengaruh bersamaan.", + queryEditReadOnly: "Hasil hanya-baca", + queryEditUnsupported: { + "not-select": "Hanya hasil kueri SELECT yang dapat diedit langsung.", + cte: "Kueri dengan WITH/CTE belum dapat diedit. Gunakan SELECT satu tabel yang sederhana.", + "set-operation": "Hasil UNION, INTERSECT, atau EXCEPT tidak dapat dipetakan kembali dengan aman ke baris sumber.", + aggregation: "Hasil DISTINCT, GROUP BY, HAVING, dan agregat tidak dapat diedit langsung.", + "external-source": "File eksternal dan hasil fungsi tabel tidak dapat ditulis kembali secara langsung. Impor ke tabel database terlebih dahulu sebelum mengedit.", + "complex-source": "DBX tidak dapat mengidentifikasi dengan pasti satu tabel target tulis-balik yang aman untuk hasil ini.", + "computed-columns": "Ekspresi hasil hitungan atau hasil fungsi tidak dapat ditulis kembali. Pilih nama kolom mentah sebagai gantinya.", + "no-table": "Tidak ada tabel sumber yang dapat diedit terdeteksi.", + "no-primary-key": "Tabel target tidak memiliki kunci utama, sehingga baris tidak dapat diperbarui atau dihapus dengan aman.", + "primary-key-not-returned": "Hasil tidak menyertakan kolom kunci utama mentah. Sertakan dengan nama kolom aslinya.", + "aliased-columns": "Kolom hasil menggunakan alias atau ekspresi. Pilih kolom yang dapat diedit dengan nama aslinya.", + "metadata-unavailable": "DBX tidak dapat memuat metadata tabel, sehingga pengeditan hasil dinonaktifkan.", + }, + sortUnsupported: "SQL ini tidak mendukung pengurutan hasil penuh. Coba lagi dengan satu kueri SELECT.", + truncatedHint: "Hasil dipotong setelah memuat {count} baris. Gunakan paginasi footer untuk menelusuri data yang dimuat; mengekspor hasil penuh akan menjalankan ulang kueri database.", + victoriaMetricsTruncatedHint: "Hasil melebihi batas pemuatan, sehingga hanya {count} baris pertama yang dimuat. Baris per halaman hanya memaginasi data yang dimuat; persempit rentang waktu atau tambahkan filter untuk mendapatkan hasil lengkap.", + cut: "Potong", + }, + exportProgress: { + streamingUnsupported: "Ekspor streaming tidak didukung untuk kueri ini. Sederhanakan kueri atau gunakan driver yang didukung.", + agentSessionMissing: "Ekspor streaming memerlukan sesi result-set, tetapi driver ini tidak mengembalikan session_id.", + title: "Mengekspor Data Tabel", + fetching: "Mengambil data dari database...", + writing: "Menulis ke file...", + done: "Ekspor selesai!", + error: "Ekspor gagal", + cancelled: "Ekspor dibatalkan.", + rowsCount: "{exported} / {total} baris", + rowsExported: "{count} baris diekspor", + rowsShort: "baris", + cancel: "Batal", + minimize: "Minimalkan ke latar belakang", + openFolder: "Buka folder berisi file", + openFolderFailed: "Gagal membuka folder: {message}", + close: "Tutup", + tooltip: "Tugas Latar Belakang", + failedTooltip: "{count} tugas latar belakang gagal | {count} tugas latar belakang gagal", + popoverTitle: "Tugas Latar Belakang", + noTasks: "Tidak ada tugas latar belakang", + clearFinished: "Bersihkan yang selesai", + showMore: "Tampilkan {count} lagi", + showLess: "Tampilkan lebih sedikit", + delete: "Hapus", + databaseExportTitle: "Ekspor database: {name}", + databaseBackupTitle: "Pencadangan database: {name}", + sqlFileTitle: "File SQL: {name}", + dataTransferTitle: "Transfer data: {name}", + dataGenerationTitle: "Pembuatan data: {name}", + multiDbExecutionTitle: "Eksekusi multi-database: {name}", + schemaDiffTitle: "Perbandingan skema: {name}", + dataCompareTitle: "Perbandingan data: {name}", + compareRunning: "Berjalan", + compareDone: "Selesai", + compareError: "Galat", + compareCancelled: "Dibatalkan", + comparePhase: { + loadingTableLists: "Memuat daftar tabel", + loadingSourceDetails: "Memuat detail sumber", + loadingTargetDetails: "Memuat detail target", + loadingExtraObjects: "Memuat objek tambahan", + comparing: "Membandingkan", + generating: "Menghasilkan hasil", + complete: "Selesai", + }, + schemaDiffSummary: "{count} objek yang berbeda", + dataCompareSummary: "{tables} tabel: {same} sama, {different} berbeda, {failed} gagal · +{added} / -{removed} / ~{modified}", + multiDbTargets: "Target {completed}/{total}, berhasil {success}, gagal {failed}", + openTask: "Buka tugas", + objectsCount: "{current} / {total} objek", + tablesCount: "{current} / {total} tabel", + statementsCount: "{done} berhasil, {failed} gagal", + elapsed: "Berlalu: {duration}", + showFailureDetails: "Detail kegagalan ({count})", + hideFailureDetails: "Sembunyikan detail kegagalan", + failureDetailTruncated: "Detail galat dipotong", + failureDetailsOmitted: "{count} detail kegagalan tambahan tidak ditampilkan", + copyFailureDetail: "Salin detail kegagalan", + failureDetailCopied: "Detail kegagalan disalin", + failureDetailCopyFailed: "Gagal menyalin detail kegagalan: {message}", + }, + welcome: { + title: "Ruang Kerja Database", + subtitle: "Pilih koneksi di sebelah kiri untuk menjelajahi skema, atau buka tab kueri secara langsung.", + connections: "Koneksi", + connected: "Terhubung", + databaseTypes: "Jenis Database", + quickConnections: "Mulai Cepat", + quickConnectionsHint: "Klik koneksi untuk membuka tab kueri.", + shortcuts: "Pintasan", + shortcutsHint: "Mulai aksi berikutnya dari sini.", + sqlHistory: "Riwayat Kueri", + sqlHistoryEmpty: "Belum ada catatan SQL Library", + sqlHistoryOpenCount: "Dibuka {count} kali", + unknownConnection: "Koneksi tidak dikenal", + tip: "Anda juga dapat memperluas koneksi di sebelah kiri dan klik kanan database atau tabel untuk aksi lainnya.", + tipSidebar: "Klik tabel di sebelah kiri untuk melihat data", + tipExecute: "untuk menjalankan kueri", + fileOpened: "{name} dibuka", + fileOpenFailed: "Gagal membuka {name}: {message}", + mcpTitle: "Integrasi AI Agent", + mcpDescription: "Selain asisten AI bawaan, Anda juga dapat menggunakan Claude Code, Cursor, dan agent pengkodean lainnya untuk melakukan kueri database Anda melalui MCP.", + mcpLearnMore: "Pelajari lebih lanjut", + }, + backendErrors: { + jdbc: { + connectionFailed: "Koneksi database gagal sebelum operasi dimulai (tahap: {stage}).", + connectionInterrupted: "Koneksi database terputus saat operasi sedang berjalan (tahap: {stage}).", + operationTimedOut: "Operasi database melebihi batas waktu (tahap: {stage}).", + operationCanceled: "Operasi database dibatalkan (tahap: {stage}).", + busyRetryLater: "Agent database sedang sibuk; coba lagi nanti (tahap: {stage}).", + runtimeReplaced: "Runtime agent database telah diganti (tahap: {stage}).", + sqlFailed: "Database mengembalikan galat SQL (tahap: {stage}).", + protocolFailed: "Protokol agent database gagal.", + contractInvalid: "Agent database mengembalikan kontrak galat yang tidak valid.", + legacyFailure: "Agent database mengembalikan galat yang tidak terklasifikasi.", + }, + transaction: { + sessionExpired: "Transaksi manual kedaluwarsa setelah {timeoutSecs} detik tidak ada aktivitas dan telah di-rollback. Transaksi baru akan dimulai secara otomatis.", + }, + legacy: "Backend mengembalikan galat.", + unknown: "Terjadi galat backend yang tidak terduga.", + }, + startup: { + loading: "Memulai DBX…", + loadFailed: "Tidak dapat memuat DBX. Silakan coba lagi.", + }, + common: { + fileNotFound: "File tidak ada: {path}", + language: "Bahasa", + loading: "Memuat...", + stopping: "Menghentikan...", + close: "Tutup", + cancel: "Batal", + confirm: "Konfirmasi", + save: "Simpan", + clear: "Bersihkan", + copy: "Salin", + import: "Impor", + remove: "Hapus", + retry: "Coba Lagi", + refresh: "Segarkan", + more: "Lainnya", + decrease: "Kurangi", + increase: "Tambah", + showPassword: "Tampilkan kata sandi", + hidePassword: "Sembunyikan kata sandi", + done: "Selesai", + connection: "Koneksi", + database: "Database", + table: "Tabel", + view: "Tampilan", + schema: "Skema", + materializedView: "Materialized View", + procedure: "Prosedur", + function: "Fungsi", + sequence: "Sequence", + package: "Package", + packageBody: "Package Body", + noResults: "Tidak ada hasil", + edit: "Edit", + delete: "Hapus", + disabled: "Dinonaktifkan", + back: "Kembali", + action: "Aksi", + actions: "Aksi", + }, + dateTimePicker: { + open: "Buka pemilih tanggal dan waktu", + inputLabel: "Tanggal dan waktu", + inputPlaceholder: "YYYY-MM-DD HH:mm:ss", + previousMonth: "Bulan sebelumnya", + nextMonth: "Bulan berikutnya", + calendarLabel: "Kalender", + timeLabel: "Waktu", + hour: "Jam", + minute: "Menit", + second: "Detik", + cancel: "Batal", + apply: "Terapkan", + invalidDateTime: "Masukkan tanggal dan waktu yang valid", + outOfRange: "Tanggal dan waktu berada di luar rentang yang diizinkan", + }, + quickOpen: { + placeholder: "Cari koneksi, database, tabel, file SQL, dan objek lainnya...", + emptyPlaceholder: "Mulai mengetik untuk mencari", + noResults: "Tidak ada hasil ditemukan", + results: "hasil", + navigate: "Navigasi", + select: "Pilih", + close: "Tutup", + sqlFile: "File SQL", + sqlLibraryFile: "SQL Library", + pluginWorkbench: "Plugin", + searchingContent: "Mencari isi file…", + globalSearchHint: "Pencarian konten global", + modeObjects: "Cari objek dan file", + modeContent: "Cari isi file", + contentPlaceholder: "Cari dalam isi file…", + searchSettings: "Pengaturan pencarian", + searchRoots: "Direktori pencarian", + addDirectory: "Tambah direktori", + noRootsConfigured: "Tidak ada direktori pencarian yang dikonfigurasi", + removePath: "Hapus", + searchExtensions: "Ekstensi file", + extensionsPlaceholder: "mis. sql, txt, md", + apply: "Terapkan", + }, + explain: { + estimatedTime: "Perkiraan waktu", + title: "Explain Plan", + standardTable: "Tabel", + tree: "Pohon", + summary: "Ringkasan", + running: "Membaca explain plan...", + empty: "Tidak ada explain plan", + nodeCount: "{count} node", + node: "Node", + relation: "Tabel", + index: "Indeks", + cost: "Biaya", + rows: "Baris", + details: "Detail", + canvas: "Canvas", + costShare: "Porsi biaya", + estRows: "Perkiraan baris", + actualRows: "Baris aktual", + zoomIn: "Perbesar", + zoomOut: "Perkecil", + zoomFit: "Sesuaikan", + legendHeat: "Panas = % dari total biaya", + legendEdge: "Lebar garis = jumlah baris", + inspectorEmpty: "Pilih sebuah node", + catResult: "Hasil", + catSort: "Urutkan", + catJoin: "Join", + catTscan: "Pemindaian tabel", + catIscan: "Pemindaian indeks", + catLookup: "Pencarian baris", + catMat: "Materialize", + catAgg: "Agregat", + catXchg: "Paralelisme", + catMod: "Modifikasi", + catOther: "Lainnya", + unsupported: "Explain plan belum didukung untuk database ini", + emptySql: "Tidak ada SQL untuk dijelaskan", + unsafe: "Versi pertama ini hanya menjelaskan pernyataan SELECT / WITH / TABLE / VALUES", + }, + profile: { + title: "Profil", + emptyShards: "Tidak ada data profil shard", + emptyProfile: 'Respons ini tidak berisi bagian `profile`. Tambahkan `"profile": true` ke isi pencarian dan jalankan kembali kueri.', + collapseAll: "Ciutkan semua", + expandAll: "Perluas semua", + selfTime: "Diri Sendiri", + totalTime: "Total", + breakdown: "Fase", + criticalPath: "Jalur kritis", + criticalPathTag: "Kritis", + shard: "Shard", + searches: "pencarian", + collapsedProtection: "Profil besar: node dalam mulai diciutkan ({nodes} node)", + legendSelfTime: "Waktu diri sendiri tidak termasuk turunan; bilah menampilkan porsi dari total waktu kueri shard.", + }, + lineage: { + title: "Lineage Bidang", + open: "Lihat Lineage Bidang", + loading: "Membaca metadata {done}/{total}", + empty: "Tidak ditemukan lineage terkait", + noFiltered: "Tidak ada hasil yang cocok dengan filter saat ini", + targetField: "Bidang Saat Ini", + searchPlaceholder: "Cari tabel, bidang, tampilan, atau cuplikan SQL...", + showing: "Menampilkan {shown}/{total} hasil", + all: "Semua", + certain: "Pasti", + likely: "Kemungkinan Besar", + possible: "Mungkin", + queryHistory: "Riwayat Kueri", + openTable: "Buka tabel", + copy: "Salin nama", + copied: "Disalin", + kind: { + foreignKey: "Kunci Asing", + viewReference: "Tampilan", + historyReference: "Riwayat SQL", + sameName: "Nama Sama", + }, + description: { + foreignKeyIncoming: "{target} menunjuk ke bidang saat ini melalui kunci asing. Ini adalah dependensi yang terverifikasi.", + foreignKeyOutgoing: "Bidang saat ini mereferensikan {target} melalui kunci asing. Ini adalah dependensi yang terverifikasi.", + viewLikely: "Definisi tampilan menyebutkan tabel dan bidang target, biasanya menunjukkan dependensi kueri.", + viewPossible: "Definisi tampilan menyebutkan bidang dengan nama sama tetapi bukan tabel target, sehingga perlu konfirmasi.", + historyLikely: "Pernyataan SQL historis menyebutkan tabel dan bidang target. Gunakan sebagai konteks analisis dampak.", + historyPossible: "Pernyataan SQL historis menyebutkan bidang dengan nama sama. Mungkin terkait tetapi perlu konteks.", + sameName: "Tabel lain memiliki bidang dengan nama sama. Ini mungkin berbagi makna bisnis tetapi bukan dependensi database yang terverifikasi.", + }, + cancel: "Batal", + refresh: "Analisis Lagi", + }, + tableVGroup: { + moveToGroup: "Pindahkan ke Grup", + moveToNewGroup: "Buat Grup Baru dan Pindahkan", + removeFromGroup: "Keluarkan dari Grup", + newGroupDefault: "Grup Baru", + newSubgroup: "Subgrup Baru", + deleteGroup: "Hapus Grup", + disableGroups: "Sembunyikan Grup", + enableGroups: "Tampilkan Grup", + deleteGroupConfirmTitle: "Hapus Grup", + deleteGroupConfirmMessage: 'Hapus grup "{name}"? Anggotanya akan kembali ke daftar objek; database tidak terpengaruh.', + groupDeleted: "Grup dihapus", + }, + connectionGroup: { + createGroup: "Grup Baru", + group: "Grup", + groupNamePlaceholder: "Nama grup", + selectConnection: "Pilih koneksi", + deselectConnection: "Batalkan pilihan koneksi", + selectAllConnections: "Pilih semua koneksi", + deselectAllConnections: "Batalkan pilihan semua koneksi", + selectedConnections: "{count} terpilih", + exitMultiSelect: "Keluar dari pilihan", + renameGroup: "Ganti Nama Grup", + closeConnections: "Tutup Koneksi dalam Grup ({count})", + deleteGroup: "Hapus Grup", + deleteSelectedGroups: "Hapus {count} Grup Terpilih", + moveToGroup: "Pindahkan ke Grup", + moveToNewGroup: "Pindahkan ke Grup Baru", + ungrouped: "Tanpa Grup", + ungroupedLabel: "Bawaan", + newGroup: "Grup Baru...", + newGroupDefault: "Grup Baru", + deleteGroupConfirmTitle: "Hapus Grup", + deleteGroupConfirmMessage: 'Hapus grup "{name}" beserta semua subgrupnya? Pilih di bawah apakah juga akan menghapus koneksi di dalamnya.', + deleteSelectedGroupsConfirmMessage: "Hapus {count} grup terpilih beserta semua subgrupnya? Pilih di bawah apakah juga akan menghapus koneksi di dalamnya.", + deleteConnectionsWithGroup: "Hapus juga semua koneksi dalam grup terpilih dan subgrupnya", + selectGroup: "Pilih grup", + deselectGroup: "Batalkan pilihan grup", + }, + databaseSearch: { + title: "Cari Database", + open: "Cari Database", + keyword: "Kata Kunci", + keywordPlaceholder: "Masukkan ID pengguna, email, nomor pesanan...", + limitPerTable: "Per tabel", + search: "Cari", + searching: "Mencari", + stop: "Hentikan", + hint: "Memindai tabel reguler di database atau skema saat ini. Kolom biner dilewati dan setiap tabel dibatasi agar tidak memuat terlalu banyak data sekaligus.", + loadingTables: "Membaca daftar tabel...", + progress: "{done}/{total} tabel dipindai", + resultCount: "{count} kecocokan", + continueNextBatch: "Pindai {count} berikutnya", + scanAllRemaining: "Pindai {count} sisanya", + results: "Hasil", + openResult: "Buka", + waiting: "Menunggu kecocokan...", + noResults: "Belum ada kecocokan", + errors: "Beberapa tabel gagal", + }, + configExport: { + passphraseTitle: "Enkripsi & Ekspor", + passphraseImportTitle: "Dekripsi File", + passphraseExportHint: "Untuk menyertakan kata sandi koneksi dalam ekspor, atur passphrase untuk enkripsi. Anda akan memerlukan passphrase yang sama untuk mengimpor.", + passphraseImportHint: "File ini terenkripsi. Masukkan passphrase untuk mendekripsinya, lalu pilih koneksi yang akan diimpor.", + passphrase: "Passphrase", + passphraseConfirm: "Konfirmasi Passphrase", + passphrasePlaceholder: "Masukkan passphrase", + passphraseConfirmPlaceholder: "Masukkan ulang passphrase", + passphraseRequired: "Passphrase wajib diisi", + passphraseMismatch: "Passphrase tidak cocok", + passphraseTooShort: "Passphrase harus minimal 4 karakter", + exportEncrypted: "Ekspor terenkripsi", + exportUnencrypted: "Ekspor tanpa enkripsi", + unencryptedWarningTitle: "Ekspor tanpa enkripsi?", + unencryptedWarningDescription: + "File konfigurasi yang tidak dienkripsi dapat berisi kata sandi database, kredensial SSH Tunnel, dan informasi sensitif lainnya. Siapa pun yang dapat mengakses file tersebut dapat membaca kredensial ini. Gunakan ini hanya untuk migrasi sementara di lingkungan tepercaya.", + confirmUnencryptedExport: "Ekspor tanpa enkripsi", + decryptImport: "Dekripsi", + wrongPassphrase: "Passphrase salah atau file rusak", + cryptoUnavailable: "Impor konfigurasi terenkripsi tidak tersedia dalam konteks browser ini. Gunakan HTTPS, localhost, atau DBX Desktop.", + exportFailed: "Gagal mengekspor koneksi", + exportSuccess: "Koneksi berhasil diekspor", + importSuccess: "{count} koneksi diimpor", + importNavicatSuccess: "{count} koneksi Navicat diimpor. Isi kata sandi untuk setiap koneksi yang masih kosong sebelum menguji.", + importDatagripSuccess: "{count} koneksi DataGrip diimpor, {filled} kata sandi terisi dari macOS Keychain.", + importDatagripSelectFiles: "Silakan pilih dataSources.xml (wajib), dan secara opsional dataSources.local.xml / db-forest-config.xml", + importDatagripDialogTitle: "Pilih file konfigurasi DataGrip", + importDbeaverSuccess: "{count} koneksi DBeaver diimpor. Isi kata sandi untuk setiap koneksi yang masih kosong sebelum menguji.", + importNone: "Tidak ada koneksi baru untuk diimpor", + importLayoutConfirm: "File yang diimpor berisi grup koneksi. Terapkan grup tersebut?", + importLayoutTitle: "Impor Grup", + importLayoutApply: "Terapkan", + selectExportTitle: "Pilih koneksi untuk diekspor", + selectImportTitle: "Pilih koneksi untuk diimpor", + selectAll: "Pilih semua", + deselectAll: "Batalkan pilihan semua", + selectedCount: "{selected} / {total}", + next: "Berikutnya", + importSelected: "Impor {count}", + noConnections: "Tidak ada koneksi yang tersedia", + }, + ai: { + placeholder: "Jelaskan kueri Anda dalam bahasa alami...", + settings: "Pengaturan AI", + noConfig: "AI belum dikonfigurasi. Silakan atur provider AI Anda di Pengaturan > AI.", + provider: "Provider", + providerCustom: "Kustom", + builtinProviders: "Dukungan bawaan", + partnerProviders: "Sponsor premium", + jalapenoSponsored: "Kredit gratis $1", + hualongSponsored: "Kredit gratis $1", + aicodemirrorSponsored: "Kredit gratis ¥8", + jalapenoDescription: "🎉 AI tingkat enterprise yang dipercaya tim-tim terkemuka kini tersedia untuk Anda! Coba model mutakhir dengan diskon 50% dan dapatkan bonus kredit lebih besar saat top up lebih banyak!", + hualongDescription: "🐉 Relay model sumber resmi untuk developer AI berat! Seri Codex dan Claude 100% asli dengan penagihan berbasis token yang dapat diverifikasi, kontrak enterprise, dan invoicing.\n🎉Daftar dengan kode promo DBX&HUALONG untuk kredit gratis $1!", + aicodemirrorDescription: "⚡ AICodeMirror menghadirkan konkurensi tingkat enterprise, invoicing cepat, dan dukungan khusus 7×24; pengguna baru mendapat kredit gratis ¥8 plus diskon 20% untuk top up pertama.", + visitPartner: "Kunjungi situs web mitra", + getApiKey: "Dapatkan API key", + providerStatusActive: "Aktif", + providerStatusConfigured: "Terkonfigurasi", + switchProvider: "Ganti Provider", + model: "Model", + defaultModel: "Model Default", + browseModels: "Jelajahi model", + refreshModels: "Segarkan model", + loadingModels: "Memuat model...", + modelLoadFailed: "Gagal memuat model", + retry: "Coba Lagi", + searchModels: "Cari model", + noModels: "Tidak ada model yang dimuat", + noModelMatch: "Tidak ada model yang cocok", + selectModel: "Pilih model", + noModel: "Tidak ada model yang dikonfigurasi", + manualModel: "Masukkan ID model secara manual", + manualModelPlaceholder: "ID Model", + effort: "Effort", + providerDefault: "Default provider", + loadingEffort: "Memuat level effort...", + effortLoadFailed: "Gagal memuat level effort", + effortEnabled: "Diaktifkan", + effortDisabled: "Dinonaktifkan", + customEffortPlaceholder: "Masukkan nilai effort", + effortUnsupported: "Model ini tidak mendukung effort yang dapat dikonfigurasi", + configNameEmpty: "Nama konfigurasi tidak boleh kosong", + configNameExists: "Nama konfigurasi '{name}' sudah ada", + deepLinkInvalid: "Tidak dapat membuka tautan konfigurasi AI: {message}", + deepLinkClipboardTitle: "Impor API Key", + deepLinkClipboardPrompt: "Baca API key dari clipboard?", + deepLinkClipboardEmpty: "Clipboard tidak berisi API key. Masukkan secara manual.", + deepLinkClipboardInvalid: "Clipboard tidak berisi API key satu baris yang valid. Masukkan secara manual.", + deepLinkClipboardReadFailed: "Gagal membaca clipboard: {message}", + + configList: "Daftar Konfigurasi AI", + addConfig: "Tambah Konfigurasi", + noAiConfigs: "Tidak ada konfigurasi AI", + setDefault: "Jadikan Default", + editConfig: "Edit Konfigurasi", + configName: "Nama Konfigurasi", + configNamePlaceholder: "Masukkan nama konfigurasi", + modelList: "Daftar Model", + modelId: "ID Model", + modelDisplayName: "Nama Tampilan", + add: "Tambah", + fetching: "Mengambil...", + fetchModelList: "Ambil Model dari API", + default: "Default", + deleteConfigTitle: "Hapus Konfigurasi", + deleteConfigConfirm: "Hapus konfigurasi ini?", + modelListHint: "Klik segarkan untuk memuat model dari provider.", + modelListUnsupported: "Provider ini tidak mendukung pengambilan daftar model.", + modelListEndpointRequired: "Masukkan endpoint sebelum memuat model.", + modelListApiKeyRequired: "Masukkan API key sebelum memuat model.", + run: "Jalankan", + readingSchema: "Membaca skema", + noConnection: "Tidak ada koneksi yang tersedia untuk tab ini", + noSql: "Tidak ada SQL untuk diproses", + sqlPreview: "Pratinjau SQL", + copySql: "Salin SQL", + copyCode: "Salin Kode", + executeSql: "Eksekusi SQL", + tempRunSql: "Jalankan tanpa mengubah editor", + copyAll: "Salin Semua", + copyMessage: "Salin pesan", + retryMessage: "Kirim ulang pesan ini", + retryConfirmDescription: "Kirim ulang pesan ini? Giliran ini dan balasan berikutnya akan diganti.", + copied: "Tersalin", + copyTestResult: "Salin hasil tes", + testErrorAuth: "Autentikasi atau akses gagal. Periksa API key, izin proyek, dan ketersediaan API.", + testErrorModelNotFound: "Model tidak tersedia. Periksa ID model dan akses akun Anda.", + testErrorRateLimit: "Batas laju atau kuota terlampaui. Coba lagi nanti atau periksa kuota akun.", + testErrorTimeout: "Permintaan habis waktu. Periksa jaringan, proxy, dan endpoint.", + testErrorTokenLimit: "Tidak ada teks yang terlihat dihasilkan karena batas token output telah habis.", + testErrorSafety: "Gemini memblokir prompt atau respons berdasarkan kebijakan keamanannya.", + testErrorEmptyResponse: "Layanan atau proxy menutup stream tanpa mengembalikan teks yang terlihat.", + testErrorNetwork: "Koneksi jaringan gagal. Periksa endpoint dan proxy.", + testErrorUnknown: "Tes gagal karena alasan yang tidak terklasifikasi.", + replace: "Ganti Editor", + append: "Tambahkan ke Editor", + apply: "Terapkan ke Editor", + clear: "Hapus Obrolan", + maximize: "Maksimalkan", + restore: "Pulihkan", + welcome: "Beri tahu saya apa yang ingin Anda pahami, dan saya akan membantu menganalisisnya", + requestFailed: "Permintaan AI gagal", + requestCancelled: "Permintaan dibatalkan", + backgroundRunCompleted: "Respons AI selesai di latar belakang", + backgroundRunNeedsConfirmation: "AI memerlukan konfirmasi Anda untuk melanjutkan", + recoveredDraftBanner: "Permintaan yang diantrekan sebelum restart telah dipulihkan", + recoveredDraftHint: "Edit dan kirim ulang, atau hapus.", + discardDraft: "Hapus draf", + runStatusRunning: "Berjalan", + runStatusWaitingToStart: "Menunggu dimulai", + runStatusAwaitingConfirmation: "Menunggu konfirmasi", + runStatusPendingDraft: "Menunggu input", + runStatusCompleted: "Selesai", + runStatusFailed: "Gagal", + runStatusInterrupted: "Terganggu", + runStatusCancelled: "Dibatalkan", + runUnread: "Ada pembaruan baru dalam percakapan ini", + closeWithRunsTitle: "Tugas AI masih berjalan", + closeWithRunsDescription: "Keluar dari DBX akan menghentikan {count} tugas AI yang sedang berjalan atau diantrekan. Anda dapat menutup dialog ini dan membiarkannya selesai.", + closeWithRunsQuit: "Keluar dan hentikan", + queueSend: "Antrekan pengiriman", + queueSendHint: "Masih ada tugas yang berjalan untuk percakapan ini; pesan akan dikirim setelah selesai", + inputQueued: "Pesan diantrekan untuk dikirim setelah tugas saat ini selesai", + queuedInputWaiting: "Menunggu — {text}", + queuedInputPending: "Diantrekan untuk dikirim — {text}", + sendQueuedInput: "Kirim pesan yang diantrekan", + queuedInputEdit: "Edit pesan yang diantrekan", + queuedInputRemove: "Hapus pesan yang diantrekan", + rowQueuedInput: "Input yang diantrekan", + retryRound: "Ulangi giliran ini", + deleteConversation: "Hapus percakapan", + deleteActiveConversationTitle: "Percakapan memiliki tugas aktif", + deleteActiveConversationDescription: "Percakapan ini masih memiliki tugas yang berjalan atau menunggu. Batalkan tugas dan hapus percakapan, atau simpan saja?", + cancelTaskAndDelete: "Batalkan tugas dan hapus percakapan", + keepConversation: "Simpan percakapan", + awayUpdatesDivider: "Pembaruan saat Anda tidak ada", + jumpToLatest: "Lompat ke terbaru", + openPanel: "Buka panel", + runRowPhaseTool: "Menjalankan {tool}", + runRowPhaseThinking: "Menganalisis…", + toolbarAwaitingConfirmation: "{count} tugas AI menunggu konfirmasi Anda", + newChat: "Obrolan Baru", + thinking: "Berpikir...", + reasoningProcess: "Proses berpikir", + chars: "karakter", + stopGenerating: "Hentikan pembuatan", + scrollToBottom: "Kembali ke bawah", + csvAttachmentSelect: "Lampirkan CSV", + csvAttachmentInvalidType: "Pilih file CSV.", + csvAttachmentEmpty: "File CSV kosong.", + csvAttachmentReadFailed: "Tidak dapat membaca file CSV.", + csvAttachmentTruncated: "CSV dipotong sebelum dikirim ke AI.", + attachmentSelect: "Lampirkan gambar atau file teks", + attachmentSelectHint: "Lampirkan gambar atau file teks. Hingga 4 gambar (total 12 MB) dan 8 file teks (total 32.000 karakter).", + attachmentDropHint: "Lepas file untuk menambahkan lampiran", + attachmentInvalidType: "Pilih gambar PNG, JPEG, GIF, atau WebP.", + attachmentReadFailed: "Tidak dapat membaca lampiran.", + attachmentImageTooLarge: "Gambar harus berukuran 5 MB atau lebih kecil.", + attachmentImageLimit: "Anda dapat melampirkan hingga 4 gambar sekaligus.", + attachmentImageTotalLimit: "Total gambar yang dilampirkan tidak boleh melebihi 12 MB.", + attachmentTextLimit: "Anda dapat melampirkan hingga 8 file teks sekaligus.", + attachmentTextTotalLimit: "Total teks yang dilampirkan tidak boleh melebihi 32.000 karakter.", + selectionContextLimit: "Anda dapat melampirkan hingga 8 seleksi sekaligus.", + selectionContextTotalLimit: "Total seleksi yang dilampirkan tidak boleh melebihi 32.000 karakter.", + attachmentFileTooLarge: "File yang dijatuhkan harus berukuran 5 MB atau lebih kecil.", + attachmentTruncatedStatus: "Dipotong", + selectionChipLabel: "Seleksi editor", + selectionChipDetail: "{name} · {count} karakter", + attachmentEncoding: "Encoding teks", + attachmentEncodingReadFailed: "Tidak dapat mendekode lampiran dengan encoding tersebut.", + attachmentUnsupportedProvider: "Koneksi provider ini tidak dapat mengirim lampiran gambar. Hapus gambar atau pilih provider yang mendukung gambar.", + attachmentUnsupportedFormat: "Provider yang dipilih tidak mendukung format gambar ini. Hapus atau gunakan PNG, JPEG, atau WebP.", + attachmentPreview: "Pratinjau lampiran", + attachmentUnavailableAfterReload: "Konten tidak tersedia setelah reload; tidak akan dikirim lagi", + attachmentUnsupportedDocument: "Jenis file ini belum didukung. Lampirkan gambar atau file berbasis teks sebagai gantinya.", + externalTargetUnavailable: "Koneksi sumber tidak tersedia (mungkin telah dihapus). Pilih koneksi untuk percakapan ini, lalu kirim ulang.", + tableMentionEmpty: "Tidak ada tabel atau file SQL yang cocok", + tableMentionPlaceholderHint: "Ketik {'@'} untuk menambahkan objek atau file yang tersedia sebagai konteks", + tableMentionTypes: { + table: "Tabel", + view: "Tampilan", + systemTable: "Tabel sistem", + temporaryTable: "Tabel sementara", + }, + modes: { + ask: "Tanya", + agent: "Agent", + }, + modeHints: { + ask: "Hasilkan SQL dan penjelasan tanpa menjalankannya secara otomatis", + agent: "Gunakan alat untuk mengkueri data dan menjawab berdasarkan hasil nyata", + }, + fixWithAi: "Perbaiki dengan AI", + truncated: "Konteks dipotong", + contextSummary: "{database} · {tables} tabel", + autoSqlBlocked: "SQL yang dihasilkan AI terlihat terlalu berisiko untuk dieksekusi otomatis. Tinjau secara manual sebelum menjalankannya.", + redisConsoleUnreachable: "Perintah AI tidak dapat menjangkau konsol Redis percakapan ini. Buka konsol Redis koneksi yang terhubung dan coba lagi.", + writeSqlConfirmationRequired: "SQL ini mengubah data atau skema. Tinjau dengan hati-hati sebelum eksekusi.", + writeSqlConfirmationQuestion: "Eksekusi SQL ini sekali?", + writeSqlConfirmYes: "Konfirmasi eksekusi", + writeSqlConfirmNo: "Batal", + writeSqlConfirmationReplyYes: "Eksekusi SQL persis seperti yang ditampilkan di atas sekali saja. Jangan minta konfirmasi lagi.", + writeSqlConfirmationReplyNo: "Jangan eksekusi SQL yang ditampilkan di atas. Lanjutkan percakapan.", + productionWriteBlocked: "AI tidak dapat mengeksekusi perubahan data atau skema pada database produksi. Tinjau SQL ini dan jalankan secara manual di DBX.", + proposalConfirmReplyYes: "Eksekusi tindakan yang baru saja Anda ajukan di atas; jangan minta konfirmasi lagi.", + proposalConfirmReplyNo: "Jangan eksekusi tindakan yang disebutkan di atas; lanjutkan percakapan saat ini.", + proposalConfirmYes: "Ya, lanjutkan", + proposalConfirmNo: "Tidak, terima kasih", + proposalConfirmTitle: "Konfirmasi tindakan diperlukan", + toolApproval: { + prompt: "{plugin} ingin menjalankan {tool} pada {connection}. Tinjau argumen di bawah ini.", + approve: "Izinkan sekali", + deny: "Tolak", + expiresAt: "Ditolak otomatis pada {time} jika tidak dijawab", + waiting: "Menunggu persetujuan", + answerFailed: "Tidak dapat mengirim jawaban Anda: {message}", + status: { + approved: "Disetujui", + denied: "Ditolak", + timed_out: "Tidak dijawab tepat waktu; panggilan tidak dijalankan", + cancelled: "Dibatalkan", + expired: "Persetujuan ini sudah tidak tertunda lagi", + }, + }, + agentSteps: { + generated: "SQL dihasilkan", + noSql: "Tidak ditemukan SQL", + safe: "Lolos pemeriksaan keamanan", + needsConfirm: "Memerlukan konfirmasi", + blocked: "Diblokir", + autoExecute: "Siap dijalankan", + notRequested: "Eksekusi tidak diminta", + skipped: "Tidak dijalankan", + callingTool: "Memanggil alat...", + executing: "Mengeksekusi…", + toolDone: "Alat selesai", + toolError: "Galat alat", + executeSafe: "Pemeriksaan keamanan lolos · Dieksekusi", + executeBlocked: "Diblokir oleh pemeriksaan keamanan", + contextCompacted: "Konteks dikompresi", + skillsLoaded: "Skill dimuat", + }, + agentStepTitles: { + riskCheck: "Pemeriksaan risiko: {action} · {category} · {environment} · {reasons}", + blocked: "Eksekusi diblokir oleh kebijakan risiko. Tinjau SQL secara manual.", + requiresConfirmation: "SQL ini memerlukan konfirmasi sebelum eksekusi.", + askMode: "Mode Tanya tidak menjalankan SQL secara otomatis.", + unsupportedAction: "Tindakan AI saat ini tidak menjalankan SQL secara otomatis.", + noSql: "Respons tidak menyertakan blok kode SQL yang dapat dieksekusi.", + notRequested: "Pengguna tidak meminta untuk menjalankan SQL ini.", + skipped: "Langkah ini tidak dijalankan.", + }, + status: { + waitingModel: "Menunggu respons model · Berjalan {elapsed}dtk", + waitingModelLive: "Menunggu respons model", + generating: "Menghasilkan balasan · Berjalan {elapsed}dtk", + generatingLive: "Menghasilkan balasan", + runningTool: "Giliran {turn} · Menjalankan {tool} · {elapsed}dtk", + runningToolAction: "· Berjalan", + runningToolElapsed: "· {elapsed}dtk", + turnBadge: "Giliran {turn}", + idle: "Menunggu langkah ini · Aktivitas terakhir {idle}dtk yang lalu", + idleLive: "Menunggu langkah ini", + idleWithTool: "Menunggu langkah ini · Aktivitas terakhir {idle}dtk yang lalu · Menjalankan {tool}", + longRunningHint: "Ini memakan waktu lebih lama dari perkiraan. Anda dapat terus menunggu atau menghentikannya.", + cancelling: "Membatalkan…", + toolLabels: { + executeQuery: "Eksekusi kueri", + executeSql: "Eksekusi SQL", + listTables: "Daftar tabel", + getColumns: "Dapatkan kolom", + getCurrentTime: "Dapatkan waktu saat ini", + explainQuery: "Jelaskan rencana kueri", + getSampleData: "Dapatkan data contoh", + listCollections: "Daftar koleksi", + browseCollection: "Jelajahi koleksi", + executeRedisCommand: "Jalankan perintah Redis", + }, + }, + proxy: "Proxy", + proxyEnable: "Kirim permintaan AI melalui proxy", + proxyUrl: "URL Proxy", + sslVerification: "Sertifikat SSL", + skipTlsVerify: "Lewati verifikasi sertifikat SSL", + skipTlsVerifyHint: "Hanya lewati untuk endpoint tepercaya dengan sertifikat self-signed. Melewati verifikasi membuat lalu lintas rentan terhadap intersepsi.", + customHeaders: "Header Kustom", + customHeadersAdd: "Tambah header", + customHeadersHint: "Header tambahan dikirim bersama penemuan model, uji koneksi, obrolan, dan permintaan Agent. Nilai header dapat bersifat sensitif.", + customHeadersNamePlaceholder: "X-Tenant-ID", + customHeadersValuePlaceholder: "tenant-a", + customHeadersInvalidName: "Nama header tidak valid: {name}", + customHeadersInvalidValue: "Nilai header tidak valid untuk: {name}", + customHeadersDuplicate: "Nama header duplikat: {name}", + customHeadersReserved: "Header ini dikelola oleh DBX: {name}", + enableThinking: "Berpikir", + enableThinkingOn: "Diaktifkan", + enableThinkingOff: "Dinonaktifkan", + enableThinkingHint: "Opsi ini hanya berlaku untuk API /chat/completions dan model yang didukung. Saat dinonaktifkan, ini dapat secara signifikan mengurangi penggunaan token, tetapi kualitas hasil yang dihasilkan mungkin sedikit menurun.", + anthropicMessagesHint: "API yang kompatibel dengan Anthropic Messages biasanya menggunakan /v1/messages.", + openAiCompatibleEndpointHint: "Sebagian besar API yang kompatibel dengan OpenAI memerlukan prefiks path /v1.", + contextWindow: "Jendela Konteks", + contextWindowAuto: "Otomatis (deteksi dari nama model)", + contextWindowHint: "Token. Biarkan kosong untuk deteksi otomatis. Atur manual untuk model lokal/kustom.", + maxOutputTokens: "Token Output Maksimum", + maxOutputTokensAuto: "Otomatis (per tindakan)", + maxOutputTokensHint: "Batas opsional per konfigurasi yang dikirim ke provider. Rentang: {min}–{max}. Permintaan Thinking tetap menggunakan setidaknya 8192 token.", + maxRetries: "Percobaan Ulang Maksimum", + maxRetriesHint: "Coba lagi saat batas laju, timeout, dan galat jaringan sementara. 0 = tidak pernah, maksimum 10.", + maxRetriesGlobal: "Percobaan Ulang Maksimum", + maxRetriesGlobalDescription: "Jumlah percobaan ulang otomatis pada galat API sementara (batas laju, timeout, gangguan jaringan). Berlaku untuk semua provider AI berbasis API. Provider CLI tidak terpengaruh.", + maxRetriesRange: "{min}–{max}, default {default}", + maxRetriesSaved: "Percobaan ulang maksimum disimpan", + codexCliPath: "Path Codex CLI", + codexCliPathHint: "Biarkan kosong untuk menggunakan codex dari PATH. Masuk secara terpisah dengan codex login.", + codexCliPathEnvError: "Path Codex CLI hanya boleh berisi path eksekutabel. Tambahkan variabel lingkungan di bawah.", + codexCliEnv: "Variabel lingkungan", + codexCliEnvAdd: "Tambah variabel", + codexCliEnvHint: "Variabel opsional yang dikirim ke Codex CLI, seperti HTTPS_PROXY, NO_PROXY, SSL_CERT_FILE, atau CODEX_CA_CERTIFICATE.", + codexCliEnvKeyPlaceholder: "HTTPS_PROXY", + codexCliEnvValuePlaceholder: "http://proxy:9800", + codexCliEnvInvalidName: "Nama variabel lingkungan tidak valid: {name}", + codexCliEnvReservedName: "{name} dikelola oleh DBX untuk server MCP dan tidak dapat diatur di sini.", + cliMcpRequiredTitle: "DBX MCP Server diperlukan", + cliMcpRequiredDescription: "{provider} menggunakan DBX MCP Server untuk mengakses skema database dan alat kueri. Instal sebelum menggunakan provider ini di asisten AI.", + cliPath: "Path {provider}", + cliPathHint: "Biarkan kosong untuk menggunakan {command} dari PATH. Masuk secara terpisah dengan {loginCommand}.", + cliPathEnvError: "Path {provider} hanya boleh berisi path eksekutabel. Tambahkan variabel lingkungan di bawah.", + cliEnv: "Variabel lingkungan", + cliEnvAdd: "Tambah variabel", + cliEnvHint: "Variabel opsional yang dikirim ke {provider}, seperti HTTPS_PROXY, NO_PROXY, atau SSL_CERT_FILE.", + cliEnvKeyPlaceholder: "HTTPS_PROXY", + cliEnvValuePlaceholder: "http://proxy:9800", + cliEnvInvalidName: "Nama variabel lingkungan tidak valid: {name}", + cliEnvReservedName: "{name} dikelola oleh DBX untuk server MCP dan tidak dapat diatur di sini.", + codexMcpRequiredTitle: "DBX MCP Server diperlukan", + codexMcpRequiredDescription: "Codex CLI menggunakan DBX MCP Server untuk mengakses skema database dan alat kueri. Instal sebelum menggunakan Codex di asisten AI.", + reasoningLevel: "Level penalaran", + reasoningLevelDefault: "Default", + reasoningLevelMinimal: "Minimal", + reasoningLevelLow: "Rendah", + reasoningLevelMedium: "Sedang", + reasoningLevelHigh: "Tinggi", + reasoningLevelXhigh: "Sangat tinggi", + reasoningLevelMax: "Maksimum", + reasoningLevelHint: "Mengontrol model_reasoning_effort Codex CLI. Default menggunakan konfigurasi Codex Anda.", + claudeCodeEffortHint: "Level yang tersedia dilaporkan oleh model yang dipilih melalui Claude Code CLI lokal Anda.", + claudeCodeEffortUnavailable: "Model yang dipilih tidak melaporkan level effort yang dapat dikonfigurasi. Claude Code akan menggunakan default-nya.", + cliErrors: { + code: "Kode galat: {code}", + details: "Detail diagnostik:", + reportHint: "Saat melaporkan masalah ini, sertakan kode galat dan detail diagnostik di bawah ini.", + claudeCodeNotInstalled: "Claude Code CLI tidak ditemukan. Instal Claude Code atau atur path eksekutabelnya di Pengaturan > AI.", + claudeCodeCliPathInvalid: "Path Claude Code CLI tidak valid. Pilih hanya eksekutabel Claude dan konfigurasikan variabel lingkungan secara terpisah.", + claudeCodeEnvInvalid: "Nama variabel lingkungan Claude Code CLI tidak valid. Gunakan nama seperti HTTPS_PROXY.", + claudeCodeEnvReserved: "Variabel lingkungan MCP yang dikelola DBX telah ditimpa. Hapus variabel DBX_MCP_* dari konfigurasi provider.", + claudeCodeNotAuthenticated: "Claude Code CLI tidak terautentikasi. Jalankan `claude auth login` di terminal dan coba lagi.", + claudeCodeMcpConfigInvalid: "Claude Code tidak dapat membaca atau mengurai konfigurasi DBX MCP. Periksa versi Claude Code CLI dan path eksekutabel.", + dbxMcpMissing: "Instalasi DBX MCP Server yang kompatibel tidak ditemukan. Periksa Pengaturan > MCP, lalu instal ulang atau perbarui.", + claudeCodeMcpStartupFailed: "Claude Code memuat konfigurasi MCP tetapi tidak dapat memulai DBX MCP Server. Periksa Pengaturan > MCP dan diagnostik di bawah.", + claudeCodeCommandLineTooLong: "Windows menolak perintah Claude Code karena terlalu panjang. Perbarui DBX dan coba lagi menggunakan file konfigurasi MCP yang dihasilkan.", + claudeCodeRunFailed: "Claude Code CLI keluar secara tak terduga. Gunakan kode galat dan diagnostik di bawah untuk mengidentifikasi eksekutabel atau output CLI yang bermasalah.", + piAgentNotInstalled: "Pi Coding Agent tidak ditemukan. Instal Pi atau atur path eksekutabelnya di Pengaturan > AI.", + piAgentCliPathInvalid: "Path Pi Coding Agent tidak valid. Pilih hanya eksekutabel Pi dan konfigurasikan variabel lingkungan secara terpisah.", + piAgentEnvInvalid: "Nama variabel lingkungan Pi Coding Agent tidak valid. Gunakan nama seperti HTTPS_PROXY.", + piAgentEnvReserved: "Variabel lingkungan Pi atau MCP yang dikelola DBX telah ditimpa. Hapus variabel DBX_PI_* dan DBX_MCP_* dari konfigurasi provider.", + piAgentNotAuthenticated: "Pi Coding Agent tidak memiliki provider model yang terautentikasi. Konfigurasikan atau masuk ke provider dengan Pi dan coba lagi.", + piAgentMcpStartupFailed: "Pi tidak dapat memulai bridge DBX MCP yang dibatasi ruang lingkupnya. Periksa Pengaturan > MCP dan diagnostik di bawah.", + piAgentTimeout: "Pi Coding Agent tidak merespons sebelum operasi habis waktu.", + piAgentProtocolError: "Pi Coding Agent mengembalikan respons RPC yang tidak valid. Periksa versi Pi dan diagnostik di bawah.", + piAgentModelInvalid: "Pengenal model Pi yang dipilih tidak valid. Segarkan daftar model dan pilih entri provider/model.", + piAgentRunFailed: "Pi Coding Agent keluar secara tak terduga. Gunakan kode galat dan diagnostik di bawah untuk mengidentifikasi eksekutabel atau output CLI yang bermasalah.", + openCodeNotInstalled: "OpenCode CLI tidak ditemukan. Instal OpenCode atau atur path eksekutabelnya di Pengaturan > AI.", + openCodeCliPathInvalid: "Path OpenCode CLI tidak valid. Pilih hanya eksekutabel OpenCode dan konfigurasikan variabel lingkungan secara terpisah.", + openCodeEnvInvalid: "Nama variabel lingkungan OpenCode CLI tidak valid. Gunakan nama seperti HTTPS_PROXY.", + openCodeEnvReserved: "Variabel lingkungan OpenCode atau yang dikelola DBX telah ditimpa. Hapus variabel kontrol OPENCODE dan variabel DBX_MCP_* dari konfigurasi provider.", + openCodeNotAuthenticated: "OpenCode tidak memiliki provider model yang terautentikasi. Jalankan `opencode auth login` atau konfigurasikan provider di OpenCode, lalu coba lagi.", + openCodeMcpStartupFailed: "OpenCode tidak dapat memulai server DBX MCP yang dibatasi ruang lingkupnya. Periksa Pengaturan > MCP dan diagnostik di bawah.", + openCodeTimeout: "OpenCode CLI tidak merespons sebelum operasi habis waktu.", + openCodeProtocolError: "OpenCode CLI mengembalikan aliran peristiwa JSON yang tidak valid. Periksa versi OpenCode dan diagnostik di bawah.", + openCodeRunFailed: "OpenCode CLI keluar secara tak terduga. Gunakan kode galat dan diagnostik di bawah untuk mengidentifikasi eksekutabel atau output CLI yang bermasalah.", + cursorNotInstalled: "Cursor CLI tidak ditemukan. Instal Cursor CLI atau atur path eksekutabelnya di Pengaturan > AI.", + cursorCliPathInvalid: "Path Cursor CLI tidak valid. Pilih hanya eksekutabel agent dan konfigurasikan variabel lingkungan secara terpisah.", + grokCliNotInstalled: "Grok CLI tidak ditemukan. Instal Grok CLI atau atur path eksekutabelnya di Pengaturan > AI.", + grokCliPathInvalid: "Path Grok CLI tidak valid. Pilih hanya eksekutabel grok dan konfigurasikan variabel lingkungan secara terpisah.", + grokCliEnvInvalid: "Nama variabel lingkungan Grok CLI tidak valid. Gunakan nama seperti HTTPS_PROXY.", + grokCliEnvReserved: "Variabel lingkungan MCP yang dikelola DBX telah ditimpa. Hapus variabel DBX_MCP_* dari konfigurasi provider.", + grokCliNotAuthenticated: "Grok CLI tidak terautentikasi. Jalankan `grok login` di terminal dan coba lagi.", + grokCliMcpStartupFailed: "Grok memuat konfigurasi MCP tetapi tidak dapat memulai DBX MCP Server. Periksa Pengaturan > MCP dan diagnostik di bawah.", + grokCliCommandLineTooLong: "Windows menolak perintah Grok CLI karena terlalu panjang. Perbarui DBX dan coba lagi menggunakan file prompt yang dihasilkan.", + grokCliRunFailed: "Grok CLI keluar secara tak terduga. Gunakan kode galat dan diagnostik di bawah untuk mengidentifikasi eksekutabel atau output CLI yang bermasalah.", + codeBuddyNotInstalled: "CodeBuddy Code CLI tidak ditemukan. Instal CodeBuddy Code atau atur path eksekutabelnya di Pengaturan > AI.", + codeBuddyCliPathInvalid: "Path CodeBuddy Code CLI tidak valid. Pilih hanya eksekutabel codebuddy dan konfigurasikan variabel lingkungan secara terpisah.", + codeBuddyEnvInvalid: "Nama variabel lingkungan CodeBuddy tidak valid. Gunakan nama seperti HTTPS_PROXY.", + codeBuddyEnvReserved: "Variabel lingkungan MCP yang dikelola DBX telah ditimpa. Hapus variabel DBX_MCP_* dari konfigurasi provider.", + codeBuddyNotAuthenticated: "CodeBuddy Code tidak terautentikasi. Buka `codebuddy` di terminal, masuk, dan coba lagi.", + codeBuddyTimeout: "CodeBuddy Code CLI tidak merespons sebelum operasi habis waktu.", + codeBuddyMcpConfigInvalid: "CodeBuddy Code tidak dapat membaca konfigurasi DBX MCP sementara. Periksa diagnostik di bawah.", + codeBuddyMcpStartupFailed: "CodeBuddy Code memuat konfigurasi MCP tetapi tidak dapat memulai DBX MCP Server. Periksa Pengaturan > MCP dan diagnostik di bawah.", + codeBuddyProtocolError: "CodeBuddy Code mengembalikan respons kontrol atau aliran peristiwa JSON yang tidak valid. Periksa versi CodeBuddy Code dan diagnostik di bawah.", + codeBuddyRunFailed: "CodeBuddy Code CLI keluar secara tak terduga. Gunakan kode galat dan diagnostik di bawah untuk mengidentifikasi eksekutabel atau output CLI yang bermasalah.", + qoderNotInstalled: "Qoder CLI tidak ditemukan. Instal Qoder CLI atau atur path eksekutabelnya di Pengaturan > AI.", + qoderCliPathInvalid: "Path Qoder CLI tidak valid. Pilih hanya eksekutabel qodercli dan konfigurasikan variabel lingkungan secara terpisah.", + qoderEnvInvalid: "Nama variabel lingkungan Qoder CLI tidak valid. Gunakan nama seperti HTTPS_PROXY atau QODER_PERSONAL_ACCESS_TOKEN.", + qoderEnvReserved: "Variabel lingkungan MCP yang dikelola DBX telah ditimpa. Hapus variabel DBX_MCP_* dari konfigurasi provider.", + qoderNotAuthenticated: "Qoder CLI tidak terautentikasi. Jalankan `qodercli login` di terminal atau konfigurasikan QODER_PERSONAL_ACCESS_TOKEN, lalu coba lagi.", + qoderTimeout: "Qoder CLI tidak merespons sebelum operasi habis waktu.", + qoderMcpConfigInvalid: "Qoder CLI tidak dapat membaca konfigurasi DBX MCP sementara. Periksa versi Qoder CLI dan diagnostik di bawah.", + qoderMcpStartupFailed: "Qoder CLI memuat konfigurasi MCP tetapi tidak dapat memulai DBX MCP Server. Periksa Pengaturan > MCP dan diagnostik di bawah.", + qoderProtocolError: "Qoder CLI mengembalikan aliran peristiwa JSON yang tidak valid. Periksa versi Qoder CLI dan diagnostik di bawah.", + qoderRunFailed: "Qoder CLI keluar secara tak terduga. Gunakan kode galat dan diagnostik di bawah untuk mengidentifikasi eksekutabel atau output CLI yang bermasalah.", + cursorEnvInvalid: "Nama variabel lingkungan Cursor CLI tidak valid. Gunakan nama seperti HTTPS_PROXY.", + cursorEnvReserved: "Variabel lingkungan Cursor atau yang dikelola DBX telah ditimpa. Hapus variabel CURSOR_CONFIG_DIR, CURSOR_DATA_DIR, dan DBX_MCP_* dari konfigurasi provider.", + cursorNotAuthenticated: "Cursor CLI tidak terautentikasi. Jalankan `agent login` di terminal dan coba lagi.", + cursorMcpStartupFailed: "Cursor tidak dapat memulai server DBX MCP yang dibatasi ruang lingkupnya. Periksa Pengaturan > MCP dan diagnostik di bawah.", + cursorTimeout: "Cursor CLI tidak merespons sebelum operasi habis waktu.", + cursorProtocolError: "Cursor CLI mengembalikan aliran peristiwa JSON yang tidak valid. Periksa versi Cursor CLI dan diagnostik di bawah.", + cursorRunFailed: "Cursor CLI keluar secara tak terduga. Gunakan kode galat dan diagnostik di bawah untuk mengidentifikasi eksekutabel atau output CLI yang bermasalah.", + }, + actions: { + auto: "Otomatis", + general: "Umum", + generate: "Hasilkan SQL", + explain: "Jelaskan SQL", + optimize: "Optimalkan SQL", + fix: "Perbaiki Galat", + convert: "Konversi Dialek", + sampleData: "Data Contoh", + query: "Kueri Data", + exploreSchema: "Periksa Skema", + executeAndExplain: "Jalankan & Jelaskan", + generateNoExec: "Hasilkan (tanpa jalankan)", + }, + routing: { + recognizing: "Mendeteksi maksud…", + chip: "Otomatis · {action}", + switchTo: "Beralih ke {action}", + }, + placeholders: { + general: "Ajukan pertanyaan dan saya akan membantu menganalisisnya...", + generate: "Jelaskan apa yang ingin Anda kueri, mis. pesanan per pengguna dalam 7 hari terakhir", + explain: "Opsional: tambahkan apa yang ingin Anda pahami", + optimize: "Opsional: tambahkan tujuan, mis. mengurangi full table scan", + fix: "Tempel galat atau jelaskan hasil yang diharapkan", + convert: "mis. konversi ke PostgreSQL / MySQL / SQL Server", + sampleData: "Jelaskan data contoh atau pernyataan uji yang akan dihasilkan", + query: "Jelaskan apa yang akan dikueri atau dihitung, mis. total pesanan per wilayah bulan ini", + exploreSchema: "Jelaskan tabel atau struktur yang akan diperiksa, mis. kolom dan indeks dari orders", + executeAndExplain: "Opsional: tambahkan apa yang ingin difokuskan dalam penjelasan", + }, + editMessage: "Edit pesan", + editResend: "Kirim ulang", + editCancel: "Batal", + cannotDeleteActiveConfig: "Tidak dapat menghapus konfigurasi yang sedang aktif. Beralih ke konfigurasi lain terlebih dahulu.", + globalInstructions: "Instruksi Kustom Global", + globalInstructionsDescription: "Diterapkan secara otomatis ke semua percakapan AI.", + globalInstructionsCharCount: "{count}/{max} karakter", + globalInstructionsSaved: "Instruksi global disimpan", + globalInstructionsSave: "Simpan", + globalInstructionsTooLong: "Instruksi global terlalu panjang (maks {max} karakter)", + customInstructionsLoadFailed: "Gagal memuat instruksi AI kustom. Silakan coba lagi.", + maxAgentTurns: "Batas Giliran Agent", + maxAgentTurnsDescription: "Jumlah maksimum giliran pemanggilan alat per eksekusi agent API sebelum berhenti sejenak dan meminta Anda melanjutkan. Provider CLI menggunakan batas eksekusinya sendiri.", + maxAgentTurnsRange: "{min}–{max}, default {default}", + maxAgentTurnsSaved: "Batas giliran agent disimpan", + pluginHttpModelOnly: "Untuk analisis plugin, pilih model HTTP atau Ollama di menu model.", + pluginWelcome: "Tanyakan tentang konteks saat ini dan lanjutkan percakapan di sini", + pluginFollowUp: "Ajukan pertanyaan lanjutan tentang konteks saat ini…", + defaultAiMode: "Mode AI Default", + defaultAiModeDescription: "Mode yang digunakan saat memulai percakapan AI baru. Mengganti mode pada percakapan saat ini tidak mengubah pengaturan ini.", + conversationTypography: "Tipografi Percakapan", + conversationTypographyDescription: "Atur font yang digunakan untuk pesan AI dan input prompt tanpa mengubah editor SQL atau antarmuka.", + conversationFontFamily: "Font Percakapan AI", + conversationFontFollowInterface: "Ikuti font antarmuka", + conversationFontSize: "Ukuran Font Percakapan AI", + conversationFontSizeRange: "{min}–{max} px", + defaultAutoRouting: "Routing Maksud Otomatis Secara Default", + defaultAutoRoutingDescription: "Mulai percakapan AI baru dengan tindakan Otomatis: asisten mendeteksi maksud Anda saat mengirim dan merutekannya ke tindakan konkret. Tidak mengubah percakapan saat ini.", + restoreLastConversation: "Pulihkan percakapan AI terakhir", + restoreLastConversationDescription: "Jika diaktifkan, membuka asisten AI akan memuat percakapan yang paling baru diperbarui alih-alih percakapan kosong.", + promptTemplates: "Template Prompt Skenario", + promptTemplatesDescription: "Pilih satu atau beberapa template di asisten AI untuk menyisipkan konvensi khusus skenario.", + promptTemplateNew: "Template Baru", + promptTemplateEdit: "Edit Template", + promptTemplateName: "Nama Template", + promptTemplateNamePlaceholder: "mis. Aturan DB produksi", + promptTemplateContent: "Konten Template", + promptTemplateContentPlaceholder: "Jelaskan konvensi atau instruksi...", + promptTemplateNameEmpty: "Nama template tidak boleh kosong", + promptTemplateNameExists: "Nama template '{name}' sudah ada", + promptTemplateContentRequired: "Konten template tidak boleh kosong", + promptTemplateDeleteTitle: "Hapus Template", + promptTemplateDeleteConfirm: "Hapus template '{name}'? Tindakan ini tidak dapat dibatalkan.", + promptTemplateTooLong: "Konten template terlalu panjang (maks {max} karakter)", + promptTemplateNameTooLong: "Nama template terlalu panjang (maks {max} karakter)", + promptTemplateSaved: "Template disimpan", + promptTemplateDeleted: "Template dihapus", + promptTemplateNoTemplates: "Belum ada template. Buat satu untuk memulai.", + promptTemplateManage: "Kelola Template", + promptTemplateSavedHint: "Perubahan disimpan secara otomatis.", + templateSelectorNone: "Tidak dipilih", + templateSelectorButton: "Template", + templateSelectorLabel: "Template: {label}", + templateSelectorDeselectAll: "Batalkan Pilihan Semua", + templateSelectorLoading: "Memuat...", + skillsEntry: "Skill", + skillsLoading: "Memuat skill…", + skillsEmpty: "Belum ada skill yang ditemukan", + skillsRefresh: "Segarkan", + skillsLoadError: "Tidak dapat memuat skill", + skillsRetry: "Coba Lagi", + skillsOpenSettings: "Buka Pengaturan", + skillsSendBlocked: "Permintaan tidak terkirim", + skillsGroupDefault: "Direktori default", + skillsGroupCustom: "Direktori kustom", + skillsReasonNotFound: "Folder skill atau SKILL.md sudah tidak ada lagi", + skillsReasonRootUnavailable: "Direktori sumbernya tidak tersedia (dinonaktifkan, dipindahkan, atau dihapus)", + skillsReasonOversized: "SKILL.md melebihi batas ukuran 1 MiB", + skillsReasonNotUtf8: "SKILL.md sudah bukan UTF-8 yang valid", + skillsReasonInvalidFrontmatter: "Frontmatter SKILL.md tidak memiliki name/description atau tidak valid", + skillsReasonUnreadable: "SKILL.md tidak dapat dibaca", + skillsTotalTrimmed: "Beberapa skill yang dipilih melebihi batas konten gabungan ({max} karakter) dan dilewati untuk pengiriman ini.", + templateSelectorEmpty: "Tidak ada template. Klik Kelola untuk menambahkan.", + templateSelectorTooLong: "Template yang dipilih melebihi batas total konten ({max} karakter). Batalkan pilihan beberapa untuk melanjutkan.", + templateSetDefault: "Jadikan default", + templateDefaultsTitle: "Default untuk jenis database", + templateDefaultsEmpty: "Belum menjadi default untuk jenis database mana pun. Template default diterapkan secara otomatis saat panel AI dibuka pada koneksi yang cocok.", + templateDefaultBadgeTitle: "Template default untuk {type}", + exportMarkdown: "Ekspor sebagai Markdown", + analysis: "Analisis AI", + chartDownloadPng: "Unduh PNG", + chartDownloadFailed: "Gagal mengunduh gambar chart", + chartData: "Data chart", + htmlPreviewLabel: "Pratinjau HTML yang dihasilkan AI", + htmlExpandPreview: "Buka pratinjau lebih besar", + htmlExpandPreviewHint: "Pratinjau ini berjalan dalam sandbox penuh — skrip dan akses jaringan diblokir.", + htmlSaveSafe: "Simpan HTML Aman", + htmlSaveFailed: "Gagal menyimpan file HTML", + htmlCopySource: "Salin sumber", + htmlCopyRiskBody: "HTML ini dihasilkan oleh AI. Membukanya di luar DBX dapat menjalankan skrip dan mengakses jaringan.", + htmlCopyRiskAccept: "Tetap salin", + htmlCopyRiskRemember: "Jangan tanya lagi sesi ini", + htmlCopyRiskToast: "Tersalin. HTML yang dihasilkan AI ini dapat menjalankan skrip atau mengakses jaringan saat dibuka di luar DBX.", + exportConversation: "Ekspor percakapan", + conversationExportMarkdown: "Ekspor sebagai Markdown", + conversationExportHtml: "Ekspor sebagai HTML", + conversationRoleUser: "Pengguna", + conversationRoleAssistant: "AI", + conversationFailedMarker: "Balasan ini gagal dihasilkan", + conversationExportEmpty: "Belum ada pesan untuk diekspor", + renameConversation: "Ganti nama percakapan", + conversationRenameFailed: "Gagal mengganti nama percakapan", + clearDatabaseSelection: "Bersihkan pilihan", + searchDatabases: "Cari database…", + noDatabasesFound: "Tidak ada database yang ditemukan", + }, + contextMenu: { + openConnection: "Buka Koneksi", + closeConnection: "Tutup Koneksi", + closeSelectedConnections: "Tutup {count} Koneksi Terpilih", + closeDatabaseConnection: "Tutup Koneksi Database", + deleteConnection: "Hapus Koneksi", + deleteSelectedConnections: "Hapus {count} Koneksi Terpilih", + confirmDeleteTitle: "Hapus Koneksi", + confirmDeleteMessage: 'Apakah Anda yakin ingin menghapus "{name}"? Tindakan ini tidak dapat dibatalkan.', + confirmDeleteSelectedMessage: "Apakah Anda yakin ingin menghapus {count} koneksi terpilih? Tindakan ini tidak dapat dibatalkan.", + editConnection: "Edit Koneksi", + revealDatabaseFile: "Tampilkan di File Manager", + selectVisibleDatabases: "Pilih Database yang Terlihat", + configureVisibleObjects: "Filter Objek Terlihat", + userAdmin: "Pengguna & Hak Akses", + openUserAdmin: "Buka Pengguna & Hak Akses", + xuguUserPermissions: "Pengguna & Hak Akses Xugu", + openXuguUserPermissions: "Buka Pengguna & Hak Akses Xugu", + processList: "Daftar Proses", + sqlServerTrace: "Jejak Aktivitas", + serverDashboard: "Dasbor Server", + damengUsers: "Pengguna Dameng", + openDamengUsers: "Buka Admin Pengguna Dameng", + damengRoles: "Peran Dameng", + openDamengRoles: "Buka Admin Peran Dameng", + damengJobAdmin: "Pekerjaan Agent Dameng", + openDamengJobAdmin: "Buka Pekerjaan Agent Dameng", + duplicateConnection: "Duplikat Koneksi", + duplicateSelectedConnections: "Duplikat {count} Koneksi Terpilih", + newQuery: "Kueri Baru", + addToAi: "Tambahkan ke AI", + addToAiMultiple: "Tambahkan ke AI ({count} tabel)", + instanceInfo: "Info Instance", + newSql: "SQL Baru", + generateSql: "Hasilkan SQL", + newInsert: "Insert Baru", + newUpdate: "Update Baru", + sqlHistory: "Riwayat Kueri", + noSqlHistory: "Tidak ada SQL terkait", + openObjectBrowser: "Jelajahi Objek", + openDatabaseBrowser: "Jelajahi Database", + viewData: "Lihat Data", + openInNewDataTab: "Lihat di Tab Baru", + peekStructure: "Lihat Struktur", + editStructure: "Edit Struktur", + editColumn: "Edit Kolom", + editIndex: "Edit Indeks", + refreshChildren: "Segarkan", + collapseAll: "Ciutkan Semua", + expandAll: "Perluas Semua", + tableNameFilters: "Filter...", + tableNameFiltersDescription: "Hanya tampilkan nama objek yang cocok dengan daftar sertakan, lalu sembunyikan nama yang cocok dengan daftar kecualikan. Satu pola SQL LIKE per baris.", + tableNameFilterInclude: "Sertakan pola nama objek", + tableNameFilterExclude: "Kecualikan pola nama objek", + tableNameFilterIncludePlaceholder: "Contoh:\nads_%\nuser_%", + tableNameFilterExcludePlaceholder: "Contoh:\n%_bak\ntmp_%", + tableNameFilterLikeHint: "Gunakan sintaks SQL LIKE: % cocok dengan karakter apa pun, _ cocok dengan satu karakter. Pencocokan tidak membedakan huruf besar/kecil.", + pin: "Sematkan", + reorderPinned: "Urutkan ulang item yang disematkan", + unpin: "Lepas Sematan", + pinTab: "Sematkan Tab", + unpinTab: "Lepas Sematan Tab", + refreshTab: "Segarkan Data", + renameTab: "Ganti Nama Tab", + duplicateTab: "Duplikat Tab", + splitRight: "Pisah ke Kanan", + splitDown: "Pisah ke Bawah", + changeOrientation: "Ubah Arah Pemisahan", + unsplit: "Batalkan Pemisahan", + compactTabTitle: "Persingkat Judul Tab", + fullTabTitle: "Tampilkan Judul Tab Lengkap", + closeTab: "Tutup Tab", + editTabGroup: "Edit Grup Tab", + resetTabGroup: "Atur Ulang Grup Tab", + closeTabGroup: "Tutup Grup Tab", + closeFixedTab: "Tutup Tab Tetap", + closeLeftTabs: "Tutup Tab di Kiri", + closeRightTabs: "Tutup Tab di Kanan", + closeOtherTabs: "Tutup Tab Lainnya", + closeOtherRegularTabs: "Tutup Tab Reguler Lainnya", + closeOtherFixedTabs: "Tutup Tab Tetap Lainnya", + closeAllTabs: "Tutup Semua Tab", + closeAllRegularTabs: "Tutup Semua Tab Reguler", + closeAllFixedTabs: "Tutup Semua Tab Tetap", + copyName: "Salin Nama", + name: "Nama", + fullPath: "Path Lengkap", + copyFinalProxyPort: "Salin Port Proxy Akhir", + finalProxyPortCopied: "Port proxy akhir {port} disalin", + copyConnectionInfo: "Salin Info Koneksi", + copyConnectionUrl: "URL Koneksi", + copyConnectionUrlWithPassword: "URL Koneksi (dengan kata sandi)", + copyJdbcUrl: "URL JDBC", + copyJdbcUrlWithCredentials: "URL JDBC (dengan kredensial)", + copyHostPort: "Host:Port", + copyDsn: "DSN (key=value)", + copyDsnWithPassword: "DSN (dengan kata sandi)", + copyPsqlCommand: "Perintah psql", + copyPasswordConfirmTitle: "Salin dengan Kata Sandi", + copyPasswordConfirmMessage: "Teks yang disalin akan berisi kata sandi tersimpan dalam teks biasa. Lanjutkan?", + copyPasswordConfirmAction: "Salin", + setDefaultDatabase: "Jadikan Database Default", + clearDefaultDatabase: "Hapus Database Default", + setDefaultSchema: "Jadikan Skema Default", + clearDefaultSchema: "Hapus Skema Default", + exportDatabase: "Ekspor Database", + exportAllDatabases: "Ekspor Semua Database", + exportDatabaseSuccess: "Mengekspor {count} tabel, hingga {limit} baris masing-masing", + exportDatabaseFailed: "Gagal mengekspor database: {message}", + backupSqliteDatabase: "Cadangkan Database SQLite", + restoreSqliteDatabase: "Pulihkan Database SQLite", + backupSqliteDatabaseInProgress: "Mencadangkan database SQLite...", + backupSqliteDatabaseSuccess: "Database SQLite berhasil dicadangkan", + backupSqliteDatabaseFailed: "Gagal mencadangkan database SQLite: {message}", + restoreSqliteDatabaseInProgress: "Memulihkan database SQLite...", + restoreSqliteDatabaseSuccess: "Database SQLite berhasil dipulihkan", + restoreSqliteDatabaseFailed: "Gagal memulihkan database SQLite: {message}", + importData: "Impor Data", + exportData: "Ekspor Data", + standardSqlInsert: "INSERT SQL Standar", + exportDataMultiple: "Ekspor Data ({count} tabel)", + exportDataSelectDirectory: "Pilih folder ekspor", + exportDataMultipleSuccess: "Mengekspor {count} tabel", + exportStructure: "Ekspor Struktur", + exportStructurePreviewTitle: "Struktur - {name}", + exportStructurePreviewTitleMultiple: "Struktur - {count} objek", + exportStructureLoading: "Memuat struktur...", + copyStructure: "Salin Struktur", + copyStructureAs: "Salin Struktur Sebagai", + copyStructureAsTsv: "TSV (untuk Excel)", + copyStructureAsMarkdown: "Tabel Markdown", + structureDocTable: "Tabel", + structureDocColumn: "Kolom", + structureDocType: "Tipe", + structureDocPrimaryKey: "Kunci Utama", + structureDocNullable: "Dapat Null", + structureDocDefault: "Default", + structureDocComment: "Komentar", + structureDocYes: "Ya", + structureDocNo: "Tidak", + structureDocCopied: "Struktur disalin", + structureDocCopyFallbackHint: "Penyalinan otomatis diblokir. Klik Salin lagi, atau pilih konten di bawah.", + saveStructure: "Simpan SQL", + exportStructureCopied: "Struktur disalin", + createTable: "Buat Tabel", + createView: "Buat Tampilan", + createProcedure: "Buat Prosedur", + createFunction: "Buat Fungsi", + createTrigger: "Buat Trigger", + dropTable: "Drop Tabel", + emptyTable: "Kosongkan Tabel", + truncateTable: "Truncate Tabel", + vacuumTable: "Jalankan VACUUM", + vacuumTableTitle: "Jalankan VACUUM", + vacuumTableMessage: 'Jalankan VACUUM pada "{name}"?', + vacuumTableAnalyze: "ANALYZE", + vacuumTableAnalyzeHint: "Segarkan statistik optimizer. Ini dapat mengubah rencana kueri berikutnya dan menambah overhead CPU serta I/O disk.", + vacuumTableFull: "FULL", + vacuumTableFullHint: "Risiko tinggi: menulis ulang seluruh tabel dan mengambil exclusive lock. Baca dan tulis dapat terblokir, dan mungkin memerlukan ruang disk tambahan.", + vacuumTableDefaultRisk: "Pemeliharaan rutin: I/O disk tambahan mungkin terjadi, dan durasi tergantung ukuran tabel.", + vacuumTableAnalyzeRisk: "Statistik optimizer akan disegarkan, yang dapat mengubah rencana kueri berikutnya.", + vacuumTableFullRisk: "Risiko tinggi: menulis ulang seluruh tabel dan mengambil exclusive lock, yang dapat memblokir baca dan tulis serta memerlukan ruang disk tambahan.", + vacuumTableFullConfirm: "Jalankan VACUUM FULL", + vacuumTableRunning: "Menjalankan VACUUM...", + vacuumTableRunningHint: "VACUUM sedang berjalan. Tabel besar mungkin memerlukan waktu lama; biarkan operasi ini tetap terbuka.", + vacuumTableSuccess: 'VACUUM selesai untuk "{name}"', + mysqlAutoIncrement: "Atur AUTO_INCREMENT", + mysqlAutoIncrementTitle: "Atur AUTO_INCREMENT MySQL", + mysqlAutoIncrementMessage: 'Atur nilai AUTO_INCREMENT berikutnya yang diminta untuk "{name}"?', + mysqlAutoIncrementNonemptyHint: "Untuk tabel yang tidak kosong, MySQL tidak menggunakan kembali ID yang sudah terpakai. Nilai efektif berikutnya tetap minimal MAX(id) + 1.", + mysqlAutoIncrementValue: "Nilai berikutnya yang diminta", + duplicateStructure: "Klon sebagai Tabel Baru", + renameObject: "Ganti Nama", + renameObjectTitle: "Ganti Nama Objek", + renameObjectNamePlaceholder: "Nama baru", + renameObjectSuccess: '"{oldName}" diganti nama menjadi "{newName}"', + renameDatabase: "Ganti Nama Database", + renameDatabaseTitle: "Ganti Nama Database", + renameDatabaseNotOwner: 'Hanya pemilik database yang dapat mengganti nama "{name}".', + renameDatabasePreparedTransactions: 'Database "{name}" memiliki {count} transaksi tertunda yang belum diselesaikan. Silakan COMMIT atau ROLLBACK terlebih dahulu.', + confirmDropTableTitle: "Drop Tabel", + confirmDropTableMessage: 'Apakah Anda yakin ingin men-drop "{name}"? Ini akan menghapus permanen tabel dan semua datanya.', + dropTableCascade: "Gunakan CASCADE", + dropTableCascadeHint: "Juga drop objek dependen seperti tampilan. Biarkan tidak dicentang untuk menggunakan perilaku RESTRICT default PostgreSQL.", + truncateTableCascade: "Gunakan CASCADE", + truncateTableCascadeHint: "Juga truncate tabel yang mereferensikan tabel ini melalui kunci asing. Biarkan tidak dicentang untuk menggunakan perilaku RESTRICT default PostgreSQL.", + confirmEmptyTableTitle: "Kosongkan Tabel", + confirmEmptyTableMessage: 'Apakah Anda yakin ingin menghapus semua data dari "{name}"?', + confirmTruncateTableTitle: "Truncate Tabel", + confirmTruncateTableMessage: 'Apakah Anda yakin ingin men-truncate "{name}"? Ini akan menghapus semua baris.', + mysqlAutoIncrementSuccess: 'AUTO_INCREMENT {value} diminta untuk tabel "{name}"', + dropTableSuccess: 'Tabel "{name}" telah di-drop', + editView: "Edit Tampilan", + viewSource: "Lihat Sumber", + viewDependencies: "Lihat Dependensi", + viewObject: "Lihat", + changeOpenMode: "Ubah mode buka", + viewDetails: "Lihat Detail", + viewDdl: "Lihat DDL", + openDdlInNewTab: "Buka di Tab Baru", + viewDdlLoading: "Memuat DDL...", + ddlDisplayMode: "Tampilan DDL", + ddlDisplayFormatted: "Terformat", + ddlDisplayOriginal: "Asli", + ddlOpenMode: "Mode buka DDL", + ddlOpenModeDialog: "Buka di dialog", + ddlOpenModeTab: "Buka di tab baru", + resizeDdlDialog: "Ubah ukuran dialog DDL", + ddlCopied: "DDL disalin", + excludeDdlStorage: "Kecualikan atribut penyimpanan", + excludeDdlStorageHint: "Berlaku untuk tampilan DDL Oracle dan OceanBase Oracle, penyalinan, dan ekspor struktur. Nonaktifkan untuk mempertahankan opsi kompresi, replika, dan penyimpanan. Partisi dan constraint tetap dipertahankan.", + refreshDdlOnOpen: "Segarkan setiap kali dibuka", + refreshDdlOnOpenHint: "Jika diaktifkan, DDL dimuat ulang dari database setiap kali dibuka; jika dinonaktifkan, data cache lebih diutamakan", + ddlRefreshFailed: "Gagal menyegarkan DDL: {message}", + dropObject: "Drop Objek", + dropEventSuccess: 'Event "{name}" telah di-drop', + editObject: "Edit Objek", + createEvent: "Buat Event", + eventEditorTitle: "Event MySQL", + eventDefinition: "Definisi", + eventSchedule: "Jadwal", + eventComment: "Komentar", + eventSqlPreview: "Pratinjau SQL", + eventName: "Nama", + eventBodyPlaceholder: "Isi event, mis. CALL procedure();", + eventExecuteAt: "Eksekusi pada", + eventIntervalValue: "Nilai interval", + eventIntervalUnit: "Satuan interval", + eventStarts: "Mulai", + eventEnds: "Berakhir", + eventCompletion: "Penyelesaian", + eventStatus: "Status", + eventCommentPlaceholder: "Komentar opsional", + eventLoading: "Memuat...", + eventCancel: "Batal", + eventSave: "Simpan", + dropView: "Drop Tampilan", + dropColumn: "Drop Kolom", + dropIndex: "Drop Indeks", + dropAllIndexes: "Drop Semua Indeks", + createMongoIndex: "Buat Indeks", + createMongoIndexTitle: 'Buat Indeks: "{collection}"', + createMongoIndexFields: "Kolom indeks", + createMongoIndexFieldRequired: "Pilih atau masukkan kolom untuk setiap baris indeks.", + mongoIndexAscending: "Menaik (1)", + mongoIndexDescending: "Menurun (-1)", + createMongoIndexNamePlaceholder: "Dihasilkan secara otomatis", + createMongoIndexNameHint: "Biarkan kosong agar MongoDB menghasilkan nama dari kolom dan tipenya.", + createMongoIndexSparse: "Sparse", + createMongoIndexTtlInvalid: "Kedaluwarsa setelah harus berupa bilangan bulat detik.", + createMongoIndexFilterInvalid: 'Filter parsial harus berupa objek, misalnya { "status": "active" }.', + createMongoIndexBucketSizeInvalid: "Ukuran bucket harus berupa bilangan bulat.", + manageMongoIndexes: "Kelola Indeks", + manageMongoIndexesTitle: 'Indeks: "{collection}"', + mongoIndexKeys: "Kunci", + mongoIndexEmpty: "Koleksi ini belum memiliki indeks.", + mongoIndexSelectHint: "Pilih indeks untuk melihat propertinya.", + mongoIndexReadOnlyHint: "MongoDB tidak dapat mengubah indeks yang ada. Drop dan buat yang baru untuk mengubah propertinya.", + editMongoIndex: "Edit Indeks", + saveMongoIndex: "Simpan", + mongoIndexRebuildHint: "Menyimpan akan membangun ulang indeks: indeks lama di-drop dan yang baru dibuat.", + mongoEditIndexSuccess: 'Indeks "{oldName}" dibangun ulang menjadi "{newName}" pada "{collection}"', + mongoEditIndexNotFound: 'Indeks "{name}" sudah tidak ada lagi di server. Daftar mungkin sudah usang — segarkan dan coba lagi.', + mongoEditIndexStale: 'Indeks "{name}" telah diubah oleh sesi lain sejak dialog dibuka. Segarkan daftar dan coba lagi.', + mongoEditIndexIncompleteSameName: 'Indeks "{name}" tidak memiliki spesifikasi server yang lengkap, sehingga tidak dapat dibangun ulang secara destruktif dengan nama yang sama.', + mongoEditIndexDropFailed: 'Indeks "{name}" tidak dapat di-drop; tidak ada pengganti yang dibuat: {error}', + mongoEditIndexDropFailedAfterCreate: 'Indeks "{newName}" telah dibuat, tetapi indeks asli "{oldName}" tidak dapat di-drop: {error}', + mongoEditIndexCreateFailedRolledBack: 'Pengganti untuk indeks "{name}" tidak dapat dibuat, sehingga indeks asli dipulihkan: {error}', + mongoEditIndexCreateAndRollbackFailed: 'Pengganti untuk indeks "{name}" tidak dapat dibuat ({createError}), dan pemulihan indeks asli juga gagal ({rollbackError}).', + mongoIndexExtraOptionsPreserved: "Opsi yang dilaporkan server (collation, wildcardProjection, weights, …) dipertahankan saat dibangun ulang.", + dropForeignKey: "Drop Kunci Asing", + dropTrigger: "Drop Trigger", + batchDrop: "Drop yang dipilih ({count})", + batchEmpty: "Kosongkan yang dipilih ({count})", + batchTruncate: "Truncate yang dipilih ({count})", + batchMysqlAutoIncrement: "Atur AUTO_INCREMENT ({count})", + batchDropIndexes: "Drop Indeks ({count})", + executeProcedure: "Eksekusi Prosedur", + compileObject: "Kompilasi", + compileObjectSuccess: '"{name}" berhasil dikompilasi', + compileObjectFailedTitle: "Kompilasi tampilan gagal", + compileObjectFailedMessage: 'Kompilasi tampilan "{name}" gagal:\n{message}', + confirmExecuteProcedureTitle: "Eksekusi Prosedur", + confirmExecuteProcedureMessage: 'Eksekusi prosedur "{name}"? Anda dapat mengisi atau menyesuaikan nilai parameter terlebih dahulu.', + loadingProcedureParameters: "Memuat parameter...", + procedureParametersUnavailable: "Tidak dapat memuat metadata parameter. Anda tetap dapat mengedit SQL di bawah dan mengeksekusinya.", + noProcedureParameters: "Tidak ditemukan parameter. SQL saat ini akan dieksekusi seperti yang ditampilkan.", + inputParameters: "{count} parameter input", + outputParameters: "{count} parameter output", + parameterName: "Nama", + parameterType: "Tipe", + parameterMode: "Mode", + parameterValue: "Nilai", + parameterNull: "NULL", + parameterDefault: "DEFAULT", + parameterDefaultHint: "Saat DEFAULT dicentang, DBX menghilangkan argumen tersebut sehingga database menggunakan default prosedur.", + parameterValuePlaceholder: "Masukkan nilai", + outputOnly: "Hanya output", + sqlPreview: "Pratinjau SQL", + resetSqlPreview: "Atur Ulang SQL", + openInSqlEditor: "Buka di Editor", + dropProcedure: "Drop Prosedur", + dropFunction: "Drop Fungsi", + manageExtension: "Kelola Ekstensi...", + dropExtension: "Drop Ekstensi", + confirmDropViewTitle: "Drop Tampilan", + confirmDropViewMessage: 'Apakah Anda yakin ingin men-drop tampilan "{name}"?', + confirmDropObjectTitle: "Drop Objek", + confirmDropObjectMessage: 'Apakah Anda yakin ingin men-drop "{name}"?', + confirmDropColumnTitle: "Drop Kolom", + confirmDropIndexTitle: "Drop Indeks", + confirmDropMongoIndexMessage: 'Apakah Anda yakin ingin men-drop indeks "{name}" dari koleksi "{collection}"?', + confirmDropMongoAllIndexesMessage: 'Apakah Anda yakin ingin men-drop semua indeks yang dapat dihapus dari koleksi "{name}"?', + confirmDropMongoAllIndexesDetails: 'MongoDB mempertahankan indeks "_id_". Indeks lain yang diperlukan untuk shard key juga mungkin tetap ada; hasilnya hanya akan mencantumkan indeks yang benar-benar di-drop.', + confirmDropForeignKeyTitle: "Drop Kunci Asing", + confirmDropTriggerTitle: "Drop Trigger", + confirmDropTableChildObjectMessage: 'Apakah Anda yakin ingin men-drop "{name}" dari "{table}"?', + confirmDropBatchIndexesMessage: 'Apakah Anda yakin ingin men-drop {count} indeks terpilih dari "{table}"? Tindakan ini tidak dapat dibatalkan.', + confirmBatchDropTitle: "Drop Objek Terpilih", + confirmBatchDropMessage: "Apakah Anda yakin ingin men-drop {count} objek terpilih? Tindakan ini tidak dapat dibatalkan.", + confirmBatchEmptyTitle: "Kosongkan Tabel Terpilih", + confirmBatchEmptyMessage: "Apakah Anda yakin ingin menghapus semua data dari {count} tabel terpilih?", + confirmBatchTruncateTitle: "Truncate Tabel Terpilih", + confirmBatchTruncateMessage: "Apakah Anda yakin ingin men-truncate {count} tabel terpilih? Ini akan menghapus semua baris.", + batchMysqlAutoIncrementTitle: "Atur AUTO_INCREMENT MySQL ({count} Tabel)", + batchMysqlAutoIncrementMessage: "Atur nilai AUTO_INCREMENT berikutnya yang diminta untuk {count} tabel terpilih?", + batchMysqlAutoIncrementSuccess: "AUTO_INCREMENT {value} diminta untuk {count} tabel", + batchMysqlAutoIncrementPartialFail: "AUTO_INCREMENT diatur untuk {success} tabel, {failed} gagal", + confirmDropProcedureTitle: "Drop Prosedur", + confirmDropProcedureMessage: 'Apakah Anda yakin ingin men-drop prosedur "{name}"?', + confirmDropFunctionTitle: "Drop Fungsi", + confirmDropFunctionMessage: 'Apakah Anda yakin ingin men-drop fungsi "{name}"?', + confirmDropEventTitle: "Drop Event", + confirmDropEventMessage: 'Apakah Anda yakin ingin men-drop event "{name}"?', + dropViewSuccess: 'Tampilan "{name}" telah di-drop', + dropProcedureSuccess: 'Prosedur "{name}" telah di-drop', + dropFunctionSuccess: 'Fungsi "{name}" telah di-drop', + dropTableChildObjectSuccess: '"{name}" telah di-drop', + dropAllIndexesSuccess: '{count} indeks di-drop dari "{name}"', + dropIndexesPartialFailure: "{success} indeks di-drop; {failed} gagal.", + createMongoIndexSuccess: 'Indeks "{name}" dibuat pada "{collection}"', + mongoIndexRefreshFailed: "Daftar indeks tidak dapat disegarkan setelah operasi: {message}", + batchDropSuccess: "{count} objek di-drop", + batchEmptySuccess: "{count} tabel dikosongkan", + batchEmptyPartialFail: "{success} tabel dikosongkan, {failed} gagal", + batchEmptySubmitted: "Tugas pengosongan diajukan untuk {count} tabel", + batchEmptySubmittedPartial: "{success} tugas pengosongan diajukan, {failed} gagal", + batchTruncateSuccess: "{count} tabel di-truncate", + emptyTableSuccess: 'Semua data dihapus dari "{name}"', + emptyTableSubmitted: 'Tugas pengosongan diajukan untuk "{name}"', + truncateTableSuccess: 'Tabel "{name}" telah di-truncate', + duplicateStructureSuccess: 'Tabel dikloning sebagai "{name}"', + tableOperationFailed: "Operasi gagal: {message}", + tableOperationTimedOut: 'Operasi pada "{name}" memakan waktu lebih lama dari perkiraan dan belum dibatalkan — operasi mungkin masih berjalan di database. Periksa hasilnya nanti, atau klik Batal untuk menghentikannya. ({message})', + tableOperationCancelled: 'Operasi pada "{name}" dibatalkan', + tableOperationCancelUnconfirmed: 'Permintaan pembatalan untuk "{name}" tidak dikonfirmasi oleh database — operasi mungkin sudah selesai atau mungkin masih berjalan. Periksa hasilnya untuk memastikan. ({message})', + tableOperationCancelPending: 'Permintaan pembatalan untuk "{name}" belum dikonfirmasi — operasi mungkin masih berjalan di database. Anda dapat mencoba Batal lagi, atau periksa kembali sebentar lagi.', + dangerOperationAlreadyRunning: "Operasi berbahaya lainnya masih berjalan. Tunggu hingga selesai atau batalkan sebelum memulai yang baru.", + objectDropRefreshFailed: "Objek telah dihapus, tetapi penyegaran bilah sisi gagal: {message}", + duplicateNameTitle: "Klon sebagai Tabel Baru", + duplicateNamePlaceholder: "Nama tabel baru", + copyTable: "Salin Tabel", + pasteTable: "Tempel Tabel", + pasteOptionStructureAndData: "Struktur dan Data", + pasteOptionStructureOnly: "Hanya Struktur", + pasteOptionDataOnly: "Hanya Data", + pasteTableSuccess: 'Tabel ditempel sebagai "{name}"', + pasteTableConfirmTitle: "Tempel Tabel", + pasteTableConfirmMessage: "Tempel tabel dari clipboard", + batchPasteTitle: "Tempel Tabel", + batchPasteSuccess: "Berhasil menempel {count} tabel", + batchPastePartialFail: "{success} tabel ditempel, {failed} gagal", + pasteTableRefreshFailed: "Tabel telah ditempel, tetapi daftar objek tidak dapat disegarkan: {message}", + pasteTableCancelledAfterPartial: "Penempelan dibatalkan. Tabel yang dibuat sebelum pembatalan telah disegarkan; clipboard tetap disimpan.", + noTableToPaste: "Tidak ada tabel yang tersedia untuk ditempel", + pasteTableClipboardUpdated: "Tabel disalin ke clipboard", + createDatabase: "Buat Database", + createDuckDbFile: "Buat File Database", + attachSqliteDatabase: "Lampirkan Database SQLite", + dropDatabase: "Drop Database", + confirmDropDatabaseTitle: "Drop Database", + confirmDropDatabaseMessage: 'Apakah Anda yakin ingin men-drop database "{name}"? Ini akan menghapus permanen database dan semua datanya.', + createDatabaseSuccess: 'Database "{name}" telah dibuat', + mysqlCreateDatabasePermissionHint: "Akun MySQL saat ini tidak dapat membuat database ini. Akun bernama root tidak selalu memiliki hak administrator. Gunakan akun administrator dengan GRANT OPTION untuk memberikan izin CREATE, lalu coba lagi.", + createDatabasePartial: 'Database "{name}" telah dibuat, tetapi beberapa grant gagal', + createDatabaseFailed: 'Database "{name}" tidak dapat dibuat', + createDatabaseUsers: "Berikan akses ke pengguna", + createDatabaseUsersHint: "Pengguna yang dipilih akan menerima akses native penuh setelah database dibuat.", + createDatabaseUsersSelected: "{count} dipilih", + createDatabaseUsersLoading: "Memuat pengguna...", + createDatabaseUsersLoadFailed: "Tidak dapat memuat pengguna: {message}", + previewCreateDatabaseSql: "Pratinjau SQL", + createDatabaseSqlPreview: "Pratinjau SQL Buat Database", + applyCreateDatabaseSql: "Buat dan Berikan Izin", + closeCreateDatabaseResult: "Tutup", + createDatabaseStep: 'Buat database "{database}"', + createDatabaseGrantStep: 'Berikan akses database kepada {user} pada "{database}"', + createDatabaseGrantObjectsStep: 'Berikan akses skema dan objek kepada {user} pada "{database}"', + createDatabaseStepSkipped: "Dilewati karena langkah sebelumnya yang diperlukan gagal.", + editDatabaseProperties: "Edit Properti Database", + editDatabasePropertiesTitle: 'Edit Properti Database: "{name}"', + editDatabasePropertiesSaving: "Menyimpan...", + editDatabasePropertiesSuccess: 'Properti database "{name}" diperbarui', + editDatabaseComment: "Komentar database", + editDatabaseCommentPlaceholder: "Masukkan komentar database...", + createDuckDbFileSuccess: 'File database DuckDB "{name}" dibuat dan dilampirkan', + createDuckDbFileDesktopOnly: "Membuat file database DuckDB hanya tersedia di aplikasi desktop", + attachSqliteDatabaseSuccess: 'Database SQLite "{name}" dilampirkan', + attachSqliteDatabaseDesktopOnly: "Melampirkan file database SQLite hanya tersedia di aplikasi desktop", + dropDatabaseSuccess: 'Database "{name}" telah di-drop', + dropCollection: "Drop Koleksi", + elasticsearchViewMapping: "Lihat Mapping", + elasticsearchViewSettings: "Lihat Pengaturan Indeks", + elasticsearchViewStats: "Lihat Statistik Indeks", + elasticsearchClearIndex: "Hapus Data Indeks", + elasticsearchClearIndexMessage: "Ini akan menghapus setiap dokumen di indeks {index}. Mapping, pengaturan, dan alias tetap dipertahankan. Lanjutkan?", + elasticsearchClearIndexPatternMessage: "{index} adalah pola gabungan, bukan satu indeks. Ini akan menghapus setiap dokumen di setiap indeks yang cocok. Mapping, pengaturan, dan alias tetap dipertahankan. Lanjutkan?", + elasticsearchClearIndexTypeToConfirm: "Ketik {index} untuk konfirmasi", + elasticsearchClearIndexDetails: "Dokumen dihapus dengan _delete_by_query; indeks itu sendiri tidak di-drop.", + elasticsearchClearIndexConfirm: "Hapus Data", + elasticsearchClearIndexDone: "{index} dibersihkan: {deleted} dokumen dihapus", + elasticsearchClearIndexPartial: "{index} dibersihkan sebagian: {deleted} dari {total} dokumen dihapus. Periksa konflik atau kegagalan shard dan jalankan lagi.", + cloneCollection: "Klon Koleksi", + cloneCollectionTitle: "Klon sebagai Koleksi Baru", + cloneCollectionNamePlaceholder: "Nama koleksi baru", + cloneCollectionSuccess: 'Koleksi "{name}" dikloning dengan {documents} dokumen dan {indexes} indeks', + confirmDropCollectionTitle: "Drop Koleksi", + confirmDropCollectionMessage: 'Apakah Anda yakin ingin men-drop koleksi "{name}"? Ini akan menghapus permanen koleksi dan semua dokumennya.', + dropCollectionSuccess: 'Koleksi "{name}" telah di-drop', + createDatabaseNamePlaceholder: "Nama database", + createDatabaseCharset: "Character set", + createDatabaseCharsetPlaceholder: "mis. utf8mb4", + createDatabaseCharsetSearchPlaceholder: "Cari atau ketik character set", + createDatabaseCharsetEmpty: "Tidak ada character set yang ditemukan", + createDatabaseCharsetLoading: "Memuat character set...", + createDatabaseCharsetCustomOption: 'Gunakan "{value}"', + createDatabaseCollation: "Collation", + createDatabaseCollationPlaceholder: "mis. utf8mb4_unicode_ci", + createDatabaseCollationSearchPlaceholder: "Cari atau ketik collation", + createDatabaseCollationEmpty: "Tidak ada collation yang ditemukan", + createDatabaseCollationLoading: "Memuat collation...", + createDatabaseCollationCustomOption: 'Gunakan "{value}"', + createSchema: "Buat Skema", + dropSchema: "Drop Skema", + confirmDropSchemaTitle: "Drop Skema", + confirmDropSchemaMessage: 'Apakah Anda yakin ingin men-drop skema "{name}"? Ini akan menghapus permanen skema dan semua objeknya.', + createSchemaSuccess: 'Skema "{name}" telah dibuat', + dropSchemaSuccess: 'Skema "{name}" telah di-drop', + dropDamengSchemaRequiresDifferentDba: "Dameng tidak dapat men-drop skema ini dengan aman dari koneksi saat ini. Hubungkan sebagai pengguna DBA yang berbeda dan coba lagi.", + createSchemaNamePlaceholder: "Nama skema", + editSchemaComment: "Edit Komentar", + editSchemaCommentTitle: 'Edit Komentar: "{name}"', + schemaCommentPlaceholder: "Masukkan komentar skema...", + schemaCommentSaving: "Menyimpan...", + editSchemaCommentSuccess: 'Komentar skema "{name}" diperbarui', + }, + visibleDatabases: { + title: "Database yang Terlihat", + detailLabel: "Database yang terlihat", + detailActionLabel: 'Konfigurasikan database yang terlihat untuk "{connection}"', + description: 'Pilih database mana yang ditampilkan di bawah "{connection}".', + searchPlaceholder: "Cari database...", + selectedCount: "{selected}/{total} terpilih", + patternsPlaceholder: "Wildcard, mis. %n1%, dipisahkan koma", + patternsHint: "Database yang cocok dengan pola ini akan selalu ditampilkan (% = karakter apa pun, _ = satu karakter)", + patternsMatchCount: "{count} cocok", + selectAll: "Pilih semua", + selectFiltered: "Pilih hasil pencarian", + clear: "Bersihkan", + showAll: "Tampilkan semua", + showSystemDatabases: "Tampilkan database sistem", + save: "Simpan", + emptySelection: "Pilih setidaknya satu database, atau gunakan Tampilkan semua untuk menghapus filter.", + loadFailed: "Gagal memuat database: {message}", + }, + visibleSchemas: { + title: "Filter Skema", + detailLabel: "Skema yang terlihat", + detailActionLabel: 'Konfigurasikan skema yang terlihat untuk "{connection}"', + description: 'Pilih skema mana yang ditampilkan di bawah "{connection}".', + searchPlaceholder: "Cari skema...", + selectedCount: "{selected}/{total} terpilih", + selectAll: "Pilih semua", + selectFiltered: "Pilih hasil pencarian", + clear: "Bersihkan", + showAll: "Tampilkan semua", + showSystemSchemas: "Tampilkan skema sistem", + save: "Simpan", + emptySelection: "Pilih setidaknya satu skema, atau gunakan Tampilkan semua untuk menghapus filter.", + loadFailed: "Gagal memuat skema: {message}", + }, + databaseLinks: { + remoteTenant: "Tenant jarak jauh", + remoteProtocol: "Protokol database jarak jauh", + remoteCluster: "Cluster jarak jauh (opsional)", + oceanbaseRecreateHint: "Pembaruan langsung tidak tersedia untuk link OceanBase. Buat dan uji penggantinya sebelum menghapus link lama secara eksplisit. Link yang ada tidak pernah dihapus secara otomatis.", + oceanbasePublic: "Publik", + oceanbaseSharedReadOnly: "Pengguna lain membuat link publik ini. Anda dapat mengujinya dan menggunakannya, tetapi hanya pembuatnya yang dapat menghapusnya.", + shadowed: "Link privat dengan nama yang sama diutamakan dalam sesi ini. Uji link publik dari pengguna yang tidak memiliki link privat tersebut.", + search: "Cari link database", + name: "Nama link", + owner: "Pemilik", + username: "Pengguna jarak jauh", + host: "String koneksi", + password: "Kata sandi jarak jauh", + public: "Link publik (memerlukan CREATE PUBLIC DATABASE LINK)", + create: "Buat link", + alter: "Perbarui kredensial", + test: "Uji link", + testSuccess: "Kueri link database berhasil.", + empty: "Tidak ada link database yang dapat diakses.", + saved: "Link database diperbarui.", + alterHint: "Perbarui kata sandi jarak jauh tersimpan untuk {name}. Untuk mengubah pengguna atau string koneksi, buat link baru.", + dropConfirm: "Hapus link database {owner} / {name}? Ini tidak menghapus data jarak jauh.", + manage: "Kelola link database", + }, + tree: { + savedSql: "Pustaka SQL", + queries: "Kueri", + userAdmin: "Pengguna & Hak Akses", + xuguUserPermissions: "Pengguna & Hak Akses Xugu", + damengUsers: "Pengguna", + damengRoles: "Peran", + damengJobAdmin: "Pekerjaan Agent", + xuguTablespaces: "Ruang Penyimpanan", + xuguDatafiles: "File", + xuguStorage: { + name: "Nama", + nodeId: "ID Node", + spaceId: "ID Tablespace", + spaceType: "Tipe tablespace", + datafileCount: "File data", + totalChunks: "Total chunk", + freeChunks: "Chunk bebas", + usedChunks: "Chunk terpakai", + usage: "Penggunaan", + mediaError: "Galat media", + path: "Path", + fileNo: "Nomor file", + currentSize: "Ukuran saat ini", + maxSize: "Ukuran maksimum", + stepSize: "Langkah pertumbuhan", + reserved: "Dicadangkan", + unlimited: "Tak terbatas", + yes: "Ya", + no: "Tidak", + }, + linkedServers: "Server Tertaut", + defaultDatabase: "DB Default", + elasticsearchAlias: "Alias", + columns: "Kolom", + attributes: "Atribut", + methods: "Metode", + indexes: "Indeks", + foreignKeys: "Kunci Asing", + triggers: "Trigger", + events: "Event", + constraints: "Constraint", + tables: "Tabel", + doltSystemTables: "Tabel Sistem Dolt", + tableNameFilterActive: "difilter", + views: "Tampilan", + materializedViews: "Tampilan Terwujud", + procedures: "Prosedur", + functions: "Fungsi", + sequences: "Sekuens", + schedulerJobs: "Pekerjaan Terjadwal", + databaseLinks: "Link Database", + synonyms: "Sinonim", + packages: "Paket", + types: "Tipe", + gridfs: "GridFS", + buckets: "Bucket", + partitions: "Partisi", + subpartitions: "Subpartisi", + childTables: "Subtabel", + loadMore: "Muat lebih banyak...", + objectBrowser: "Jelajahi di Penjelajah Objek ({count})", + extensions: "Ekstensi", + eventTriggers: "Trigger Event", + }, + eventTrigger: { + detailsTitle: "Detail Trigger Event", + viewDetails: "Lihat detail", + name: "Nama", + event: "Event", + owner: "Pemilik", + function: "Fungsi", + enabled: "Diaktifkan", + tags: "Tag", + definition: "Definisi", + }, + + extension: { + manageTitle: "Kelola Ekstensi", + installTitle: "Instal Ekstensi", + detailsTitle: "Detail Ekstensi", + viewDetails: "Lihat detail", + name: "Nama ekstensi", + namePlaceholder: "mis. pg_stat_statements", + install: "Instal", + drop: "Drop", + available: "Tersedia", + installed: "Terinstal", + noAvailable: "Semua ekstensi yang tersedia sudah terinstal.", + noInstalled: "Belum ada ekstensi yang terinstal.", + }, + processList: { + transactionTitle: "Transaksi Aktif", + transactionScope: "Hanya SYSDBA. Membaca transaksi aktif dari SYSTEM; sesi yang idle tidak ditampilkan.", + transactionRequiresSysdba: "Manajemen transaksi Xugu memerlukan koneksi SYSDBA untuk melakukan kueri ke SYSTEM. Hak DBA pada database bisnis tidak setara dengan SYSDBA.", + transactionCount: "{count} transaksi", + transactionFilter: "Filter transaksi", + transactionNode: "Node", + transactionId: "ID Transaksi", + transactionSession: "ID Sesi", + transactionStart: "Dimulai", + transactionEmpty: "Tidak ada transaksi aktif.", + transactionNeedsSession: "Sesi saat ini tidak dapat diidentifikasi; penghentian transaksi dinonaktifkan.", + transactionLoadFailed: "Tidak dapat memuat transaksi Xugu. Periksa apakah koneksi SYSDBA dapat mengakses SYSTEM dan database dapat dijangkau. Detail: {message}", + transactionKill: "Hentikan transaksi", + transactionCannotKillSelf: "Tidak dapat menghentikan transaksi sesi saat ini", + transactionKillTitle: "Hentikan transaksi", + transactionKillConfirm: "Hentikan transaksi {id} pada node {node} (pengguna {user}, database {db})? Pekerjaan yang belum di-commit akan di-rollback; sesi akan tetap terhubung.", + transactionKillSuccess: "Transaksi {id} dihentikan", + transactionKillFailed: "Tidak dapat menghentikan transaksi: {message}", + batchCancel: "Batalkan kueri terpilih ({count})", + batchNeedsSession: "Sesi saat ini tidak diketahui. Segarkan dan coba lagi.", + selectAll: "Pilih semua sesi yang dimuat dan memenuhi syarat pada filter saat ini", + selectSession: "Pilih sesi {id}", + batchTitle: "Batalkan kueri terpilih", + batchConfirm: "Batalkan kueri yang sedang berjalan pada {count} sesi ini? Sesi akan tetap terhubung.", + batchRunning: "Membatalkan kueri…", + batchSummary: "Permintaan pembatalan: {succeeded} berhasil, {failed} gagal.", + title: "Daftar Proses", + sessionCount: "{count} sesi", + filter: "Filter sesi", + autoRefresh: "Segarkan otomatis", + seconds: "dtk", + colId: "Id", + colUser: "Pengguna", + colHost: "Host", + colDb: "DB", + colCommand: "Perintah", + colTime: "Waktu", + colState: "Status", + colInfo: "Info", + colPid: "PID", + colClient: "Klien", + colApp: "Aplikasi", + colWait: "Tunggu", + colQuery: "Kueri", + colActions: "Aksi", + self: "Anda", + kill: "Batalkan kueri", + cannotKillSelf: "Anda tidak dapat membatalkan kueri pada sesi Anda sendiri", + empty: "Tidak ada sesi aktif.", + killTitle: "Batalkan kueri yang sedang berjalan", + killConfirm: "Batalkan kueri yang sedang berjalan untuk sesi {id} ({user})? Sesi akan tetap terhubung.", + killSuccess: "Kueri yang sedang berjalan untuk sesi {id} dibatalkan", + killFailed: "Gagal membatalkan kueri: {message}", + terminate: "Hentikan sesi", + cannotTerminateSelf: "Anda tidak dapat menghentikan sesi Anda sendiri", + terminateTitle: "Hentikan sesi", + terminateConfirm: "Hentikan sesi {id} ({user})? Koneksi akan segera ditutup dan transaksi yang belum di-commit akan di-rollback.", + terminateSuccess: "Sesi {id} dihentikan", + terminateFailed: "Gagal menghentikan sesi: {message}", + batchTerminate: "Hentikan sesi terpilih ({count})", + batchTerminateTitle: "Hentikan sesi terpilih", + batchTerminateConfirm: "Hentikan {count} sesi ini? Koneksi akan segera ditutup dan transaksi yang belum di-commit akan di-rollback.", + batchTerminateRunning: "Menghentikan sesi…", + batchTerminateSummary: "Permintaan penghentian: {succeeded} berhasil, {failed} gagal.", + previewTitle: "Statement", + copy: "Salin", + copied: "Disalin", + }, + sqlServerTrace, + consul, + serverDashboard: { + title: "Dasbor Server", + autoRefresh: "Segarkan otomatis", + off: "Nonaktif", + qps: "Kueri / detik", + connections: "Koneksi", + running: "Thread berjalan", + trafficIn: "Trafik masuk", + trafficOut: "Trafik keluar", + slowQueries: "Kueri lambat", + uptime: "Waktu aktif", + innodbHit: "Rasio hit InnoDB", + in: "Masuk", + out: "Keluar", + sessions: "Sesi", + qpsChart: "Kueri per detik", + sessionsChart: "Sesi per detik", + trafficChart: "Trafik jaringan /dtk", + commandChart: "Perintah per detik", + rawStatus: "Variabel status", + filterStatus: "Filter variabel status", + tps: "Transaksi / detik", + activeQueries: "Kueri aktif", + cacheHit: "Rasio hit cache", + deadlocks: "Deadlock", + tempFiles: "File sementara", + walRate: "Laju WAL", + commit: "Commit", + rollback: "Rollback", + total: "Total", + active: "Aktif", + idle: "Idle", + fetched: "Diambil", + returned: "Dikembalikan", + read: "Dibaca", + hits: "Hit", + serverSessionsChart: "Sesi server", + transactionsChart: "Transaksi per detik", + tuplesInChart: "Tuple masuk", + tuplesOutChart: "Tuple keluar", + blockIoChart: "I/O Blok", + }, + xuguServerDashboard: { + title: "Dasbor Server Xugu", + off: "Nonaktif", + unsupported: "Halaman ini hanya mendukung koneksi XuguDB.", + loadFailed: "Tidak dapat membaca status runtime Xugu.", + partialData: "Sebagian tampilan monitoring tidak dapat dibaca. Akun saat ini mungkin tidak memiliki hak akses system-view; data yang dapat dibaca tetap ditampilkan.", + readOnlyHint: "Monitoring baca-saja; tidak ada status database yang diubah", + version: "Versi database", + onlineNodes: "Node online", + sessions: "Sesi", + activeCount: "{count} aktif", + transactions: "Transaksi aktif", + lockWaits: "Penantian lock (tingkat tabel)", + lockOwners: "Lock yang dipegang", + nodes: "Status node", + node: "Node", + type: "Tipe", + state: "Status", + cpuLoad: "Beban CPU (referensi)", + diskRead: "Baca disk", + diskWrite: "Tulis disk", + memoryAndCache: "Cache & memori", + memoryHint: "Dari tampilan memori sistem", + bufferPool: "Buffer pool data", + sga: "SGA", + swap: "Swap", + usedPercent: "{percent}% terpakai", + dirtyPages: "Dirty {value}", + runtimeAndWrite: "Runtime & penulisan", + cumulativeHint: "Penghitung kumulatif; tidak di-reset saat penyegaran", + walPending: "WAL menunggu checkpoint", + transactionSpan: "Rentang ID transaksi (sinyal risiko)", + freeStores: "Penyimpanan bebas", + datafiles: "File data", + sessionsAndTransactions: "Sesi & transaksi", + activeSessionHint: "Sesi aktif termasuk kueri monitor ini", + idleSessions: "Sesi idle", + executingSessions: "Sesi yang sedang mengeksekusi", + otherSessions: "Status lainnya", + oldestStatement: "Statement aktif tertua dimulai", + oldestTransaction: "Transaksi aktif tertua dimulai", + locksAndCapacity: "Lock & kapasitas", + tablespaces: "Tablespace", + mediaErrors: "Galat media", + lockModes: "Mode lock yang dipegang", + dataTempFree: "DATA/TEMP bebas {value}", + rowLockLimit: "Penantian lock hanya mencakup lock tingkat tabel; selidiki pemblokiran baris melalui transaksi yang berjalan lama.", + bootTime: "Waktu boot", + rack: "Rak {rack}", + stores: "{count} penyimpanan", + emptyNodes: "Tidak ada data node yang dikembalikan, atau akun tidak dapat mengakses SYS_CLUSTERS.", + nodeState: { + joining: "Bergabung", + running: "Berjalan", + error: "Galat", + offline: "Offline", + unknown: "Tidak diketahui", + }, + nodeType: { + master: "Master", + standby: "Standby", + storage: "Penyimpanan", + query: "Kueri", + worker: "Worker", + change: "Perubahan", + unknown: "Tidak diketahui", + }, + }, + solrAdmin: { + title: "Admin Solr", + refresh: "Segarkan", + selectCore: "Pilih core", + noCore: "Tidak ada core yang dipilih. Pilih core untuk melihat halaman admin tingkat core.", + emptyBody: "Isi respons kosong.", + optional: "opsional", + sections: { + server: "Server", + core: "Core", + }, + views: { + dashboard: "Dasbor", + logging: "Logging", + javaProps: "Properti Java", + threads: "Thread Dump", + coreAdmin: "Admin Core", + metrics: "Metrik", + overview: "Ringkasan", + analysis: "Analisis", + documents: "Dokumen", + paramsets: "Paramset", + files: "File", + ping: "Ping", + plugins: "Plugin / Statistik", + query: "Kueri", + replication: "Replikasi", + schema: "Skema", + segments: "Info segmen", + }, + dashboard: { + instance: "Instance", + start: "Mulai", + uptime: "Waktu aktif", + versions: "Versi", + jvmTitle: "JVM", + runtime: "Runtime", + args: "Argumen", + system: "Sistem", + physMem: "Memori Fisik", + swap: "Ruang Swap", + fd: "Jumlah File Descriptor", + jvmMemory: "Memori JVM", + outdatedWarning: "Rilis Solr ini sudah lebih dari setahun. Pertimbangkan untuk melakukan upgrade.", + mode: "Mode", + solr_home: "Solr Home", + core_root: "Core Root", + processors: "Prosesor", + }, + logging: { + name: "Logger", + level: "Level", + set: "Terapkan", + }, + core: { + name: "Core", + docs: "Dokumen", + size: "Ukuran", + segments: "Segmen", + uptime: "Waktu aktif", + ops: "Aksi", + }, + schema: { + fields: "field", + dynamicFields: "field dinamis", + fieldTypes: "tipe field", + name: "Nama", + type: "Tipe", + flags: "Flag", + }, + analysis: { + field: "Nama field", + indexValue: "Nilai indeks", + queryValue: "Nilai kueri (opsional)", + indexPlaceholder: "Teks yang diindeks ke dalam field", + queryPlaceholder: "Teks kueri yang dianalisis saat kueri dijalankan", + run: "Analisis", + index: "Rantai indeks", + query: "Rantai kueri", + empty: "Tidak ada tahap analisis yang dikembalikan. Periksa nama field.", + }, + segments: { + name: "Segmen", + deleted: "Dihapus", + age: "Usia", + source: "Sumber", + }, + actions: { + create: "Buat Core", + reload: "Muat Ulang", + unload: "Unload", + rename: "Ganti Nama", + swap: "Tukar", + confirm: 'Jalankan {action} pada core "{core}"?', + success: '{action} pada "{core}" berhasil', + failed: "Aksi admin core gagal: {message}", + newName: "Nama core baru", + swapWith: "Tukar dengan core", + }, + queryForm: { + defaultParser: "parser default", + paramsets: "paramset", + jsonHint: "isi non-kosong beralih ke POST JSON DSL", + execute: "Jalankan Kueri", + openInConsole: "Buka di konsol", + rowsReturned: "baris", + tableView: "Tabel", + rawJson: "JSON Mentah", + }, + overview: { + statistics: "Statistik", + instance: "Instance", + replication: "Replikasi", + healthcheck: "Healthcheck", + lastModified: "Terakhir Diubah", + numDocs: "Jumlah Dokumen", + maxDoc: "Dokumen Maks", + deletedDocs: "Dokumen Dihapus", + version: "Versi", + segmentCount: "Jumlah Segmen", + current: "Saat Ini", + cwd: "CWD", + instanceDir: "Instance", + data: "Data", + index: "Indeks", + impl: "Impl", + colVersion: "Versi", + colGen: "Gen", + colSize: "Ukuran", + leaderSearching: "Leader (Pencarian)", + leaderReplicable: "Leader (Dapat Direplikasi)", + noReplication: "Tidak ada detail replikasi leader untuk core ini.", + noHealthcheck: "Handler permintaan ping tidak dikonfigurasi dengan file healthcheck.", + justNow: "baru saja", + minutesAgo: "sekitar {n} menit yang lalu", + hoursAgo: "sekitar {n} jam yang lalu", + daysAgo: "sekitar {n} hari yang lalu", + }, + replication: { + refresh: "Segarkan Status", + disable: "Nonaktifkan Replikasi", + enable: "Aktifkan Replikasi", + index: "Indeks", + settingsLeader: "Pengaturan (Leader)", + settingsFollower: "Pengaturan (Follower)", + noDetails: "Tidak ada detail replikasi untuk core ini.", + }, + }, + userAdmin: { + title: "Pengguna & Hak Akses", + unsupported: "Koneksi yang kompatibel dengan MySQL dan PostgreSQL didukung. SQL Server, Oracle, dan model izin lainnya dapat ditambahkan berikutnya.", + newUser: "Pengguna Baru", + anonymous: "Anonim", + roleName: "Nama peran", + allowLogin: "Izinkan masuk", + searchUser: "Cari pengguna atau host", + loadingUsers: "Memuat pengguna...", + loadingGrants: "Memuat hak akses...", + emptyUsers: "Tidak ada pengguna ditemukan, atau akun saat ini tidak dapat membaca daftar pengguna.", + pluginUnknown: "Plugin autentikasi tidak diketahui", + grants: "Hak Akses", + noGrants: "Tidak ada hak akses ditemukan", + privilegeEditor: "Editor Hak Akses", + privilegeHint: "Pilih hak akses, database, dan tabel, lalu pratinjau SQL sebelum menerapkannya. * berarti global atau semua tabel.", + privilegeAppendHint: "Pilih database dan tentukan cakupan tabel, lalu konfigurasikan hak akses per database. Pemberian hak akses bersifat kumulatif dan tidak pernah mencabut hak akses yang sudah ada.", + globalScope: "Global (*.*)", + database: "Database", + schema: "Skema", + table: "Tabel", + scope: "Cakupan hak akses", + scopeDatabase: "Database", + scopeSchema: "Skema", + scopeTable: "Tabel", + scopeRole: "Keanggotaan peran", + memberRole: "Peran anggota", + privileges: "Hak Akses", + grantOption: "Izinkan pemberian hak akses lebih lanjut (WITH GRANT OPTION)", + grantOptionHint: "Hanya berlaku untuk statement GRANT; REVOKE mengabaikannya.", + adminOption: "Izinkan pengelolaan keanggotaan (WITH ADMIN OPTION)", + grant: "Berikan", + revoke: "Cabut", + username: "Nama Pengguna", + host: "Host", + addHost: "Tambah Host", + changeHost: "Ubah Host", + newHost: "Host Baru", + changePassword: "Ubah Kata Sandi", + newPassword: "Kata sandi baru", + lock: "Kunci", + unlock: "Buka Kunci", + disableLogin: "Nonaktifkan Masuk", + enableLogin: "Aktifkan Masuk", + dropUser: "Hapus Pengguna", + previewSql: "Pratinjau SQL", + sqlPreview: "Pratinjau SQL", + applySql: "Terapkan SQL", + applySuccess: "Hak akses pengguna diperbarui", + applyPartial: "Pengguna berhasil dibuat, tetapi sebagian pemberian hak akses gagal", + applyFailedSummary: "Operasi gagal", + applyFailed: "Eksekusi gagal: {message}", + applyFailedUnknown: "Eksekusi gagal", + standardUser: "Pengguna standar", + standardUserHint: "Hanya berikan database dan hak akses yang dipilih di bawah ini.", + adminUser: "Pengguna administratif", + adminUserHint: "Buat akun tingkat instance dengan hak akses tinggi.", + adminUserWarning: "Akun ini dapat mengelola database dan pengguna lain. Tinjau SQL lengkapnya dengan cermat sebelum menerapkannya.", + databaseAccess: "Akses database", + databaseAccessHint: "Pilih database dan konfigurasikan tingkat izin terpisah untuk masing-masing.", + tableScope: "Cakupan tabel", + allTables: "Semua tabel", + specificTables: "Tabel tertentu", + chooseTables: "Pilih tabel", + selectedTableCount: "{count} tabel terpilih", + searchTable: "Cari tabel", + loadingTables: "Memuat tabel...", + emptyTables: "Tidak ada tabel ditemukan", + loadTablesFailed: "Tidak dapat memuat tabel: {message}", + tableSelectionRequired: "Pilih setidaknya satu tabel.", + selectAllTables: "Pilih semua", + clearAllTables: "Bersihkan", + retry: "Coba Lagi", + selectedDatabaseCount: "{count} database", + searchDatabase: "Cari database", + loadingDatabases: "Memuat database...", + emptyDatabases: "Tidak ada database ditemukan", + loadDatabasesFailed: "Tidak dapat memuat database: {message}", + prepareAuthorizationFailed: "Tidak dapat menyiapkan otorisasi database: {message}", + presetReadWrite: "Baca/Tulis", + presetReadOnly: "Hanya Baca", + presetDdl: "Hanya DDL", + presetDml: "Hanya DML", + presetCustom: "Kustom", + customPrivilegeRequired: "Pilih setidaknya satu hak akses.", + postgresDdlHint: "PostgreSQL memberikan CREATE pada database/skema. Mengubah atau menghapus objek tetap memerlukan kepemilikan.", + resultSuccess: "Semua langkah berhasil diselesaikan", + resultPartial: "Sebagian selesai", + resultFailed: "Eksekusi gagal", + closeResult: "Tutup", + stepCreateUser: "Buat pengguna atau peran", + stepGrantAdmin: "Berikan hak akses administratif ke {user}", + stepGrantDatabase: 'Berikan {user} akses ke database "{database}"', + stepGrantTable: 'Berikan {user} akses ke tabel "{database}.{table}"', + stepRevokeDatabase: 'Cabut akses {user} ke database "{database}"', + stepRevokeTable: 'Cabut akses {user} ke tabel "{database}.{table}"', + stepGrantObjects: 'Berikan {user} hak akses skema dan objek di "{database}"', + stepGrantCurrentObjects: 'Berikan {scope} saat ini di skema "{schema}" kepada {user} di "{database}"', + stepGrantFutureObjects: 'Berikan {scope} mendatang yang dibuat oleh peran saat ini kepada {user} di "{database}"', + stepGrantFutureObjectsForOwner: 'Berikan {scope} mendatang yang dibuat oleh {owner} kepada {user} di "{database}"', + scopeSchemas: "skema", + scopeTables: "tabel", + scopeSequences: "sekuens", + scopeFunctions: "fungsi", + stepSkipped: "Dilewati karena langkah sebelumnya yang diperlukan gagal.", + }, + xuguUserPermissions: { + title: "Pengguna & Hak Akses Xugu", + refresh: "Segarkan", + databaseContext: "Kelola database", + chooseDatabase: "Pilih database", + databaseContextUnknown: "Database aktif tidak dapat diidentifikasi. Pilih salah satu dari daftar di atas jika tersedia; jika tidak, periksa database default koneksi dan segarkan. Perubahan tetap dinonaktifkan hingga konteksnya eksplisit.", + databaseListLimited: "Daftar database tidak dapat dimuat sepenuhnya; halaman ini dibatasi pada konteks database yang telah dikonfirmasi.", + newPrincipal: "Pengguna / Peran Baru", + users: "Pengguna", + roles: "Peran", + search: "Cari pengguna atau peran", + system: "Sistem", + locked: "Terkunci", + active: "Aktif", + expired: "Kedaluwarsa", + validUntil: "Berlaku hingga: {value}", + inheritedRoles: "Peran yang diwariskan: {roles}", + role: "Peran", + user: "Pengguna", + systemPrincipal: "Principal sistem", + readOnly: "Koneksi hanya baca", + readOnlyHint: "Koneksi ini hanya baca; aksi pengelolaan dinonaktifkan.", + limitedCatalog: "Akun ini tidak dapat membaca katalog pengguna dan peran secara lengkap, sehingga hanya principal yang terlihat yang ditampilkan. Aksi pengelolaan dinonaktifkan untuk mencegah kesalahan akibat informasi yang tidak lengkap.", + limitedAcl: "Hanya baris ACL yang terlihat oleh akun saat ini yang tersedia; hak akses untuk pengguna atau peran lain mungkin tidak lengkap.", + managementRequiresDba: "Pengelolaan penuh memerlukan akses ke DBA_USERS, DBA_ROLES, DBA_ROLE_MEMBERS, dan DBA_ACLS. Jika tidak, hanya informasi yang terlihat yang ditampilkan dan perubahan dinonaktifkan.", + targetLookupFailed: "Tidak dapat memuat nama objek/kolom. Anda dapat memasukkan nama yang tepat secara manual; tinjau dengan cermat sebelum eksekusi.", + targetLookupIncomplete: "Daftar kandidat dibatasi hingga 1.000 item. Masukkan nama yang tepat secara manual jika target tidak terdaftar.", + columnGrantOptionUnsupported: "Xugu tidak mendukung WITH GRANT OPTION untuk hak akses tingkat kolom.", + empty: "Tidak ada pengguna atau peran yang terlihat.", + grantsTitle: "Detail Hak Akses", + grantsHint: "Hak akses langsung dan hak akses yang diwariskan melalui peran ditampilkan secara terpisah. Ini bukan laporan hak akses efektif lengkap yang dihitung oleh database.", + loading: "Memuat...", + noGrants: "Tidak ada baris hak akses yang terlihat ditemukan.", + unmappedAuthority: "Wewenang yang tidak terpetakan", + privilege: "Hak Akses", + scope: "Cakupan", + scopeDatabase: "Database saat ini", + scopeSystem: "Tingkat instance", + scopeSchema: "Skema", + scopeObject: "Objek", + scopeColumn: "Kolom", + scopeRole: "Keanggotaan peran", + scopeAdmin: "Wewenang administratif", + target: "Target", + source: "Sumber", + grantable: "Dapat diberikan", + viaRole: "Melalui peran {role}", + direct: "Pemberian langsung", + yes: "Ya", + no: "Tidak", + editorTitle: "Berikan / Cabut", + editorHint: "Kueri katalog menggunakan database yang dipilih di atas. SQL pemberian hak akses ditampilkan untuk ditinjau terlebih dahulu; hak akses tingkat instance memengaruhi seluruh instance.", + systemScopeHint: "Hanya tersedia saat terhubung ke SYSTEM. Membuat, mengubah, atau menghapus database memengaruhi instance saat ini.", + systemWide: "Ini memberikan atau mencabut hak akses tingkat instance dan memengaruhi seluruh instance, bukan hanya database saat ini.", + schema: "Nama skema", + objectType: "Tipe objek", + tableColumn: "Kolom tabel", + viewColumn: "Kolom tampilan", + object: "Nama objek", + column: "Nama kolom", + roleToGrant: "Nama peran yang akan diberikan", + adminAuthority: "Wewenang administratif", + grantOption: "Izinkan pemberian hak akses objek lebih lanjut (WITH GRANT OPTION)", + revokeGrantOptionOnly: "Cabut hanya opsi pemberian hak akses", + grantOptionScope: "WITH GRANT OPTION hanya tersedia untuk pemberian hak akses tingkat objek; Xugu tidak mendukung opsi pemberian hak akses tingkat kolom.", + grant: "Berikan", + revoke: "Cabut", + newUser: "Pengguna Baru", + createUser: "Pengguna", + createRole: "Peran", + name: "Nama", + initialPassword: "Kata sandi awal", + defaultRoles: "Peran default (pilih beberapa)", + createLocked: "Kunci akun setelah dibuat", + createPasswordExpired: "Wajibkan pengaturan ulang kata sandi setelah dibuat", + accountCreateHint: "Atribut akun baru ditampilkan sebagai SQL untuk ditinjau terlebih dahulu; akun yang terkunci atau kata sandinya kedaluwarsa tidak dapat masuk secara normal.", + accountSettings: "Pengaturan akun", + setValidUntil: "Atur tanggal kedaluwarsa akun", + markPasswordExpired: "Tandai kata sandi sebagai kedaluwarsa", + passwordAlreadyExpiredHint: "Kata sandi sudah kedaluwarsa. Gunakan Ubah Kata Sandi untuk menghapus status kedaluwarsa.", + accountSettingsHint: "Biarkan tanggal kedaluwarsa kosong untuk mempertahankan nilai saat ini. Menghapus kedaluwarsa yang sudah ada tidak tersedia di sini; gunakan kartu akun untuk mengunci atau membuka kunci pengguna.", + changePassword: "Ubah kata sandi", + newPassword: "Masukkan kata sandi baru", + lock: "Kunci", + unlock: "Buka Kunci", + dropUser: "Hapus pengguna", + dropRole: "Hapus peran", + preview: "Pratinjau SQL", + review: "Tinjau aksi: {action}", + currentDatabaseOnly: "SQL dijalankan terhadap database yang dipilih di atas. Penghapusan pengguna menggunakan RESTRICT, tidak pernah CASCADE. Principal bawaan dan sistem tidak dapat dihapus di sini.", + execute: "Konfirmasi dan jalankan", + operationSuccess: "Operasi selesai; data hak akses disegarkan.", + operationFailed: "Operasi gagal", + operationFailedWithMessage: "Operasi gagal: {message}", + }, + damengJobAdmin: { + title: "Pekerjaan Agent Dameng", + unsupported: "Halaman ini hanya mendukung koneksi Dameng.", + initEnvironment: "Inisialisasi Lingkungan Pekerjaan", + environmentReady: "Lingkungan Pekerjaan Siap", + newJob: "Pekerjaan Baru", + searchJob: "Cari pekerjaan", + loadFailed: "Gagal memuat", + environmentMissingTitle: "Lingkungan pekerjaan belum diinisialisasi", + environmentMissingHint: "Database ini belum memiliki lingkungan pekerjaan SYSJOB.", + environmentMissingDescription: "Pekerjaan agent Dameng memerlukan tabel dan tampilan sistem di bawah skema SYSJOB. Inisialisasi lingkungan pekerjaan terlebih dahulu; hak akses administrator biasanya diperlukan.", + emptyJobs: "Tidak ada pekerjaan ditemukan, atau akun saat ini tidak dapat membaca daftar pekerjaan.", + emptyDetails: "Tidak ada baris detail", + selectJob: "Pilih pekerjaan", + enabled: "Diaktifkan", + disabled: "Dinonaktifkan", + running: "Berjalan", + enable: "Aktifkan", + disable: "Nonaktifkan", + runAsync: "Jalankan Sekarang", + stopRunning: "Hentikan Proses Berjalan", + stopRunningDisabled: "Hanya pekerjaan yang sedang berjalan yang dapat dihentikan", + clearHistories: "Bersihkan Riwayat", + dropJob: "Hapus", + steps: "Langkah", + schedules: "Jadwal", + histories: "Riwayat", + noDescription: "Tidak ada deskripsi", + jobName: "Nama pekerjaan", + description: "Deskripsi", + stepName: "Nama langkah", + scheduleName: "Nama jadwal", + sqlCommand: "Skrip SQL", + scheduleMode: "Tipe jadwal", + daily: "Harian", + once: "Sekali", + startDate: "Tanggal mulai", + startTime: "Waktu mulai", + endTime: "Waktu selesai", + minuteInterval: "Interval menit", + previewSql: "Pratinjau SQL", + sqlPreview: "Pratinjau SQL", + applySql: "Terapkan SQL", + applySuccess: "Operasi pekerjaan diterapkan", + applyFailed: "Eksekusi gagal: {message}", + }, + xuguSchedulerJob: { + enable: "Aktifkan", + disable: "Nonaktifkan", + run: "Jalankan sekarang", + drop: "Hapus pekerjaan", + confirmDrop: 'Hapus pekerjaan terjadwal "{name}"? Tindakan ini tidak dapat dibatalkan.', + actionSuccess: '{action} selesai untuk "{name}".', + }, + damengUserAdmin: { + title: "Pengguna Dameng", + unsupported: "Halaman ini hanya mendukung koneksi database Dameng.", + newUser: "Pengguna Baru", + searchUser: "Cari pengguna", + loadFailed: "Gagal memuat", + emptyUsers: "Tidak ada pengguna, atau akun saat ini tidak dapat membaca daftar pengguna.", + selectUser: "Pilih pengguna", + username: "Nama Pengguna", + usernamePlaceholder: "mis. APP_USER", + password: "Kata Sandi", + passwordPolicyHint: "Kata sandi harus memenuhi kebijakan kata sandi DM8 (default: minimal 9 karakter; idealnya kombinasi huruf besar, huruf kecil, dan angka)", + tablespace: "Tablespace default", + tablespacePlaceholder: "Masukkan nama tablespace", + locked: "Kunci akun setelah dibuat", + changePassword: "Ubah Kata Sandi", + newPassword: "Kata sandi baru", + confirmPassword: "Konfirmasi kata sandi", + open: "Buka", + systemUser: "Pengguna sistem", + systemUserAdmin: "Pengguna admin", + systemUserAuditor: "Pengguna audit", + systemUserSecurity: "Pengguna keamanan", + systemUserSystem: "Pengguna sistem", + cannotChangePassword: "Kata sandi pengguna ini tidak dapat diubah oleh koneksi saat ini (hanya SYSDBA atau pengguna itu sendiri yang dapat mengubahnya)", + inheritedFrom: "Diwariskan dari {via}", + userType: "Tipe pengguna", + userTypeHint: "Admin secara otomatis memberikan DBA, audit memberikan DB_AUDIT_ADMIN, security memberikan DB_POLICY_ADMIN", + groupOther: "Pengguna lainnya", + systemUserProtected: "Pengguna sistem tidak dapat diubah atau dihapus", + builtinRole: "Peran bawaan", + builtinRoleProtected: "Peran bawaan tidak dapat dicabut", + defaultTablespace: "Tablespace default", + created: "Dibuat", + lock: "Kunci", + unlock: "Buka Kunci", + dropUser: "Hapus Pengguna", + roles: "Peran", + systemPrivileges: "Hak Akses Sistem", + grantedRoles: "Peran yang diberikan", + grantedPrivileges: "Hak akses yang diberikan", + grantRole: "Berikan Peran", + revokeRole: "Cabut Peran", + roleToGrant: "Peran yang akan diberikan", + selectRole: "Pilih peran", + grantRoleHint: "Berikan peran ke pengguna {user}.", + noRolesToGrant: "Tidak ada peran yang tersedia untuk diberikan", + noGrantedRoles: "Pengguna ini tidak memiliki peran yang diberikan", + grantPrivilege: "Berikan Hak Akses", + revokePrivilege: "Cabut Hak Akses", + privilegeToGrant: "Hak akses yang akan diberikan", + selectPrivilege: "Pilih hak akses", + grantPrivilegeHint: "Berikan hak akses sistem ke pengguna {user}.", + noPrivilegesToGrant: "Tidak ada hak akses yang tersedia untuk diberikan", + noGrantedPrivileges: "Pengguna ini tidak memiliki hak akses sistem yang diberikan", + previewSql: "Pratinjau SQL", + sqlPreview: "Pratinjau SQL", + applySql: "Terapkan SQL", + applySuccess: "Operasi pengguna diterapkan", + applyFailed: "Eksekusi gagal: {message}", + enableDdlAnyPrivHint: + "Petunjuk: DM8 menonaktifkan pemberian hak akses DDL ANY secara default (ENABLE_DDL_ANY_PRIV=0). Untuk memberikan hak akses tipe ANY, jalankan sebagai SYSDBA: sp_set_para_value(1,'ENABLE_DDL_ANY_PRIV',1). Untuk hak akses non-ANY, pastikan akun saat ini memiliki ADMIN OPTION untuk hak akses tersebut.", + anyPrivilegeDisabled: "Hak akses tipe ANY dinonaktifkan oleh DM8 (ENABLE_DDL_ANY_PRIV=0) dan tidak dapat diberikan atau dicabut", + }, + damengRoleAdmin: { + title: "Peran Dameng", + unsupported: "Halaman ini hanya mendukung koneksi database Dameng.", + newRole: "Peran Baru", + searchRole: "Cari peran", + loadFailed: "Gagal memuat", + emptyRoles: "Tidak ada peran, atau akun saat ini tidak dapat membaca daftar peran.", + selectRole: "Pilih peran", + roleName: "Nama peran", + roleNamePlaceholder: "mis. APP_ROLE", + members: "Anggota", + systemPrivileges: "Hak Akses Sistem", + grantedToUsers: "Pengguna yang diberikan peran ini", + grantedPrivileges: "Hak akses yang diberikan", + noMembers: "Belum ada pengguna yang diberikan peran ini", + grantToUser: "Berikan ke Pengguna", + userToGrant: "Pengguna yang akan diberikan", + selectUser: "Pilih pengguna", + grantUserHint: "Berikan peran {role} ke pengguna.", + noUsersToGrant: "Tidak ada pengguna yang tersedia untuk diberikan", + revokeFromUser: "Cabut", + systemUser: "Pengguna sistem", + systemUserProtected: "Tidak dapat mencabut dari pengguna sistem", + builtinRole: "Peran bawaan", + builtinRoleProtected: "Peran yang telah ditentukan tidak dapat dihapus atau diubah", + grantPrivilege: "Berikan Hak Akses", + revokePrivilege: "Cabut Hak Akses", + privilegeToGrant: "Hak akses yang akan diberikan", + selectPrivilege: "Pilih hak akses", + grantPrivilegeHint: "Berikan hak akses sistem ke peran {role}.", + noPrivilegesToGrant: "Tidak ada hak akses yang tersedia untuk diberikan", + noGrantedPrivileges: "Peran ini tidak memiliki hak akses sistem yang diberikan", + dropRole: "Hapus Peran", + previewSql: "Pratinjau SQL", + sqlPreview: "Pratinjau SQL", + applySql: "Terapkan SQL", + applySuccess: "Operasi peran diterapkan", + applyFailed: "Eksekusi gagal: {message}", + enableDdlAnyPrivHint: + "Petunjuk: DM8 menonaktifkan pemberian hak akses DDL ANY secara default (ENABLE_DDL_ANY_PRIV=0). Untuk memberikan hak akses tipe ANY, jalankan sebagai SYSDBA: sp_set_para_value(1,'ENABLE_DDL_ANY_PRIV',1). Untuk hak akses non-ANY, pastikan akun saat ini memiliki ADMIN OPTION untuk hak akses tersebut.", + anyPrivilegeDisabled: "Hak akses tipe ANY dinonaktifkan oleh DM8 (ENABLE_DDL_ANY_PRIV=0) dan tidak dapat diberikan atau dicabut", + }, + objects: { + all: "Semua", + tables: "Tabel", + collections: "Koleksi", + views: "Tampilan", + procedures: "Prosedur", + functions: "Fungsi", + sequences: "Sekuens", + packages: "Paket", + table: "Tabel", + collection: "Koleksi", + partitions: "{count} partisi", + view: "Tampilan", + timeseries: "Deret Waktu", + procedure: "Prosedur", + function: "Fungsi", + trigger: "Trigger", + triggerTiming: "Waktu", + triggerEvent: "Event", + triggerLevel: "Level", + triggerStatus: "Status", + triggerCondition: "Kondisi", + triggerLanguage: "Bahasa", + enabled: "Diaktifkan", + disabled: "Dinonaktifkan", + validity: "Validitas", + valid: "Valid", + invalid: "Tidak valid", + validStatus: "VALID", + invalidStatus: "INVALID", + sequence: "Sekuens", + package: "Paket", + packageBody: "Isi Paket", + typeDefinition: "Tipe", + typeBody: "Isi Tipe", + name: "Nama", + type: "Tipe", + rows: "Baris", + series: "Seri", + size: "Ukuran", + statisticsHint: "Diperkirakan dari statistik database; tidak ada COUNT(*) yang dijalankan.", + createdAt: "Dibuat", + updatedAt: "Diperbarui", + source: "Sumber", + saveSource: "Simpan", + cancelEdit: "Batal", + sourceSaved: "Sumber disimpan", + sourceSaveFailed: "Gagal menyimpan sumber: {message}", + refreshDiscardConfirm: "Menyegarkan akan membuang perubahan sumber yang belum disimpan. Lanjutkan?", + postgresViewColumnChangeHint: + "PostgreSQL tidak dapat menggunakan CREATE OR REPLACE VIEW untuk menghapus, mengubah urutan, mengganti nama, atau mengubah tipe kolom tampilan yang sudah ada. Pertahankan jumlah, urutan, nama, dan tipe kolom yang sudah ada tanpa perubahan; kolom baru hanya dapat ditambahkan di akhir. Gunakan ALTER VIEW ... RENAME COLUMN untuk mengganti nama kolom. Untuk menghapus kolom, tinjau dependensinya dan buat ulang tampilan secara manual.", + sourceReadOnly: "Sumber ini hanya baca dan tidak dapat diedit.", + schemaColumn: "Skema", + comment: "Komentar", + loadingSchemas: "Memuat skema...", + schema: "Skema", + search: "Cari tabel, tampilan, fungsi, sekuens, atau prosedur...", + searchCollections: "Cari koleksi...", + loading: "Memuat objek...", + empty: "Tidak ada objek ditemukan", + selectedTables: "{count} tabel terpilih", + exportSelected: "Ekspor terpilih", + dropSelected: "Hapus terpilih", + truncateSelected: "Truncate terpilih", + clearSelection: "Bersihkan pilihan", + confirmBatchDropTitle: "Hapus Tabel Terpilih", + confirmBatchDropMessage: "Apakah Anda yakin ingin menghapus {count} tabel terpilih? Tindakan ini tidak dapat dibatalkan.", + confirmBatchTruncateTitle: "Truncate Tabel Terpilih", + confirmBatchTruncateMessage: "Apakah Anda yakin ingin melakukan truncate pada {count} tabel terpilih? Ini akan menghapus semua baris.", + batchDropSuccess: "{count} tabel dihapus", + batchTruncateSuccess: "{count} tabel di-truncate", + copyTableSelected: "Salin", + pasteTableSelected: "Tempel", + toggleCheckbox: "Alihkan pilihan ganda", + viewList: "Tampilan daftar", + viewGrid: "Tampilan grid", + sortAsc: "Menaik", + sortDesc: "Menurun", + sortBy: "Urutkan berdasarkan", + }, + structureEditor: { + title: "Edit Struktur Tabel", + createTitle: "Buat Tabel", + editTabTitle: "Edit: {tableName}", + tableName: "Nama Tabel", + refresh: "Segarkan Struktur", + density: "Kepadatan", + densityCompact: "Ringkas", + densityStandard: "Standar", + densityComfortable: "Lega", + columns: "Kolom", + indexes: "Indeks", + foreignKeys: "Kunci Asing", + constraints: "Constraint", + constraintDisabled: "Dinonaktifkan", + constraintNotValidated: "Belum divalidasi", + triggers: "Trigger", + partitions: "Partisi", + partitionsEmpty: "Tabel ini tidak dipartisi", + partitionsEmptyChildren: "Tabel yang dipartisi ini belum memiliki partisi", + partitionsParent: "Tabel induk", + partitionsOwnBound: "Batas partisi", + partitionsDefault: "Partisi default", + partitionsRowEstimate: "Perkiraan baris: {count}", + partitionsSize: "Ukuran: {size}", + partitionChildCount: "{count} sub-partisi | {count} sub-partisi", + partitionExpand: "Perluas", + partitionCollapse: "Ciutkan", + partitionSubPartitionBadge: "Sub-partisi", + partitionMemberBadge: "Partisi", + partitionKindRange: "Range", + partitionKindList: "List", + partitionKindHash: "Hash", + partitionBoundDefault: "Default", + partitionEnable: "Aktifkan partisi", + partitionKind: "Strategi partisi", + partitionKeyColumns: "Kolom kunci partisi", + partitionKeyNoColumns: "Tambahkan kolom terlebih dahulu, atau gunakan ekspresi.", + partitionKeyExpression: "Ekspresi kunci partisi (menggantikan kolom)", + partitionInitialPartitions: "Partisi awal", + partitionInitialPartitionsEmpty: "Tidak ada partisi awal; Anda dapat menambahkannya setelah tabel dibuat.", + partitionAdd: "Tambah Partisi", + partitionAttach: "Lampirkan Partisi", + partitionDetach: "Lepaskan", + partitionDrop: "Hapus", + partitionDetachSelf: "Lepaskan Partisi Ini", + partitionDetachConcurrently: "Lepaskan secara konkuren", + partitionDetachWarning: "Melepaskan akan mempertahankan data partisi dalam tabelnya sendiri; partisi tersebut berhenti menjadi bagian dari induknya.", + partitionDropWarning: "Menghapus partisi akan menghapus tabel partisi beserta seluruh datanya secara permanen.", + partitionPendingOperations: "Operasi partisi yang tertunda (diterapkan saat disimpan)", + partitionRemoveOperation: "Hapus", + partitionName: "Nama partisi", + partitionNamePlaceholder: "mis. sales_2025", + partitionBoundKind: "Tipe batas", + partitionBoundFrom: "Dari", + partitionBoundTo: "Sampai", + partitionBoundValues: "Nilai", + partitionBoundModulus: "Modulus", + partitionBoundRemainder: "Sisa", + partitionRangeBoundInvalid: "RANGE memerlukan tuple FROM dan TO dengan jumlah nilai yang sama.", + partitionListBoundInvalid: "LIST memerlukan setidaknya satu nilai.", + partitionHashBoundInvalid: "HASH memerlukan Modulus > 0 dan 0 <= Remainder < Modulus.", + partitionSqlPreview: "SQL yang akan dijalankan", + partitionNameRequired: "Masukkan nama partisi.", + ddl: "DDL", + addColumn: "Tambah Kolom", + copyColumns: "Salin Field dari Tabel Lain", + copyColumn: "Salin Kolom", + copyColumnsTitle: "Salin Kolom dari Tabel Lain", + copyColumnsSourceTable: "Tabel sumber", + copyColumnsSearchSourceTables: "Cari tabel sumber", + copyColumnsSelectFields: "Pilih field", + copyColumnsSearchFields: "Cari field atau tipe", + copyColumnsSelectAll: "Pilih semua", + copyColumnsClearSelection: "Bersihkan pilihan", + copyColumnsNoSourceTables: "Tidak ada tabel lain yang tersedia di skema ini.", + copyColumnsNoMatchingSourceTables: "Tidak ada tabel sumber yang cocok dengan pencarian.", + copyColumnsPreviousSourceTablePage: "Halaman tabel sumber sebelumnya", + copyColumnsNextSourceTablePage: "Halaman tabel sumber berikutnya", + copyColumnsNoFields: "Tabel yang dipilih tidak memiliki field.", + copyColumnsNoMatchingFields: "Tidak ada field yang cocok dengan pencarian.", + copyColumnsAlreadyExists: "Sudah ada", + copyColumnsCancel: "Batal", + copyColumnsApply: "Salin {count} field", + columnTemplates: "Sisipkan Field Preset", + configureColumnTemplates: "Konfigurasikan Field Preset", + presetFieldsTemplate: "Set Field Preset", + searchColumns: "Cari kolom/komentar", + nextColumnMatch: "Ke kolom cocok berikutnya", + searchIndexes: "Cari indeks", + nextIndexMatch: "Ke indeks cocok berikutnya", + addIndex: "Tambah Indeks", + addForeignKey: "Tambah Kunci Asing", + addTrigger: "Tambah Trigger", + columnName: "Kolom", + dataType: "Tipe", + typePlaceholder: "Pilih atau ketik...", + noMatchingType: "Tidak ada tipe yang cocok", + mysqlDataTypeHelp: { + tinyint: "Integer 1-byte. Rentang bertanda (signed): -128 hingga 127; rentang tak bertanda (unsigned): 0 hingga 255.", + smallint: "Integer 2-byte. Rentang signed: -32.768 hingga 32.767; rentang unsigned: 0 hingga 65.535.", + mediumint: "Integer 3-byte. Rentang signed: -8.388.608 hingga 8.388.607; rentang unsigned: 0 hingga 16.777.215.", + int: "Integer 4-byte. Rentang signed: -2.147.483.648 hingga 2.147.483.647; rentang unsigned: 0 hingga 4.294.967.295.", + bigint: "Integer 8-byte. Rentang signed: -2^63 hingga 2^63-1; rentang unsigned: 0 hingga 2^64-1.", + decimal: "Angka fixed-point yang presisi. MySQL mendukung presisi hingga 65 digit dan skala hingga 30 digit; batas versi MariaDB dapat berbeda. Gunakan untuk nilai uang dan nilai eksak lainnya.", + float: "Angka aproksimasi presisi tunggal (single-precision). Gunakan DECIMAL jika nilai desimal yang eksak diperlukan.", + double: "Angka aproksimasi presisi ganda (double-precision). Gunakan DECIMAL jika nilai desimal yang eksak diperlukan.", + real: "Alias untuk DOUBLE secara default; mode SQL REAL_AS_FLOAT menjadikannya alias untuk FLOAT.", + bit: "Field bit dari 1 hingga 64 bit. Lebar default adalah 1 bit.", + boolean: "Alias untuk TINYINT(1): 0 mewakili false dan nilai bukan nol mewakili true.", + serial: "Alias praktis untuk BIGINT UNSIGNED NOT NULL AUTO_INCREMENT UNIQUE.", + date: "Tanggal kalender. Rentang yang didukung: 1000-01-01 hingga 9999-12-31.", + datetime: "Tanggal dan waktu tanpa konversi zona waktu. Rentang yang didukung: 1000-01-01 00:00:00 hingga 9999-12-31 23:59:59; presisi pecahan detik 0 hingga 6 (default 0).", + timestamp: "Tanggal dan waktu yang dikonversi antara zona waktu sesi dan UTC. Rentang yang didukung: 1970-01-01 00:00:01 UTC hingga 2038-01-19 03:14:07 UTC; presisi pecahan detik 0 hingga 6 (default 0).", + time: "Waktu dalam sehari atau durasi yang berlalu. Rentang yang didukung: -838:59:59 hingga 838:59:59; presisi pecahan detik 0 hingga 6 (default 0).", + year: "Nilai tahun. Nilai empat digit berkisar dari 1901 hingga 2155, ditambah 0000.", + char: "String karakter dengan panjang tetap, hingga 255 karakter. Nilai yang disimpan diberi padding spasi di sebelah kanan.", + varchar: "String karakter dengan panjang variabel. Maksimum praktisnya dibatasi oleh ukuran baris dan character set.", + tinytext: "Teks dengan panjang variabel, hingga 255 byte. Batas character set, ukuran baris, dan max_allowed_packet dapat menghasilkan batas praktis yang lebih rendah.", + text: "Teks dengan panjang variabel, hingga 65.535 byte. Batas character set, ukuran baris, dan max_allowed_packet dapat menghasilkan batas praktis yang lebih rendah.", + mediumtext: "Teks dengan panjang variabel, hingga 16.777.215 byte. Batas character set, ukuran baris, dan max_allowed_packet dapat menghasilkan batas praktis yang lebih rendah.", + longtext: "Teks dengan panjang variabel, hingga 4.294.967.295 byte (sekitar 4 GiB). Batas character set, ukuran baris, dan max_allowed_packet dapat menghasilkan batas praktis yang lebih rendah.", + binary: "String byte biner dengan panjang tetap, hingga 255 byte. Nilai yang disimpan diberi padding 0x00.", + varbinary: "String byte biner dengan panjang variabel. Maksimum praktisnya dibatasi oleh ukuran baris.", + tinyblob: "Objek biner besar (BLOB), hingga 255 byte. Batas ukuran baris dan max_allowed_packet dapat menghasilkan batas praktis yang lebih rendah.", + blob: "Objek biner besar (BLOB), hingga 65.535 byte. Batas ukuran baris dan max_allowed_packet dapat menghasilkan batas praktis yang lebih rendah.", + mediumblob: "Objek biner besar (BLOB), hingga 16.777.215 byte. Batas ukuran baris dan max_allowed_packet dapat menghasilkan batas praktis yang lebih rendah.", + longblob: "Objek biner besar (BLOB), hingga 4.294.967.295 byte (sekitar 4 GiB). Batas ukuran baris dan max_allowed_packet dapat menghasilkan batas praktis yang lebih rendah.", + enum: "Satu nilai yang dipilih dari hingga 65.535 literal yang dideklarasikan. Mengubah urutan literal dapat mengubah semantik nilai yang tersimpan.", + set: "Nol atau lebih nilai yang dipilih dari hingga 64 anggota yang dideklarasikan.", + json: "Dokumen JSON yang divalidasi. Representasi penyimpanan dan dukungan fitur JSON bergantung pada produk dan versi server yang terhubung; ukuran dokumen juga dibatasi oleh max_allowed_packet.", + jsonMysql: "Tipe dokumen JSON biner native milik MySQL dengan fungsi dan validasi JSON. Ukuran dokumen dibatasi oleh max_allowed_packet.", + jsonMariaDb: "JSON pada MariaDB adalah alias untuk LONGTEXT dengan constraint JSON_VALID dan collation utf8mb4_bin; ukuran dokumen dibatasi oleh max_allowed_packet.", + nationalCharacter: "Alias string karakter nasional. Pada MySQL menggunakan character set nasional yang telah ditentukan (utf8mb3, deprecated); pilih utf8mb4 secara eksplisit untuk skema baru.", + geometry: "Nilai spasial dari tipe geometri apa pun yang didukung. Indeks SPATIAL InnoDB MySQL memerlukan kolom NOT NULL dengan atribut SRID.", + point: "Titik spasial dengan satu pasangan koordinat. Indeks SPATIAL InnoDB MySQL memerlukan kolom NOT NULL dengan atribut SRID.", + linestring: "Kurva spasial yang terdiri dari satu atau lebih titik yang terhubung. Indeks SPATIAL InnoDB MySQL memerlukan kolom NOT NULL dengan atribut SRID.", + polygon: "Permukaan spasial yang dibatasi oleh satu atau lebih ring. Indeks SPATIAL InnoDB MySQL memerlukan kolom NOT NULL dengan atribut SRID.", + multipoint: "Kumpulan titik spasial. Indeks SPATIAL InnoDB MySQL memerlukan kolom NOT NULL dengan atribut SRID.", + multilinestring: "Kumpulan kurva spasial. Indeks SPATIAL InnoDB MySQL memerlukan kolom NOT NULL dengan atribut SRID.", + multipolygon: "Kumpulan poligon spasial. Indeks SPATIAL InnoDB MySQL memerlukan kolom NOT NULL dengan atribut SRID.", + geometrycollection: "Kumpulan yang dapat berisi campuran tipe geometri spasial. Indeks SPATIAL InnoDB MySQL memerlukan kolom NOT NULL dengan atribut SRID.", + inet4: "Tipe alamat IPv4 MariaDB (tersedia mulai MariaDB 10.10); menyimpan alamat IPv4 dalam empat byte.", + inet6: "Tipe alamat yang kompatibel dengan MariaDB untuk nilai IPv6 dan IPv4 yang dipetakan.", + uuid: "Tipe identifier unik universal (UUID) 128-bit yang disediakan oleh server yang kompatibel.", + vector: "Tipe data vektor untuk beban kerja kemiripan (similarity) atau machine learning; ketersediaan dan dimensinya bergantung pada versi server.", + xmltype: "Tipe data XML yang disediakan oleh server yang kompatibel.", + integerDisplayWidth: "Lebar tampilan integer MySQL (misalnya INT(11)) sudah deprecated dan tidak membatasi rentang nilai yang tersimpan. Jangan tambahkan pada skema MySQL 8 yang baru.", + zerofill: "ZEROFILL sudah deprecated pada MySQL 8. Ini juga secara implisit menjadikan kolom UNSIGNED; gunakan pemformatan eksplisit di aplikasi sebagai gantinya.", + unsignedNumeric: "UNSIGNED untuk DECIMAL, FLOAT, atau DOUBLE sudah deprecated pada MySQL 8. Gunakan constraint CHECK jika domain nonnegatif diperlukan.", + floatPrecision: "Untuk FLOAT(p), nilai p dari 25 hingga 53 akan memilih presisi DOUBLE, bukan FLOAT. Gunakan DOUBLE secara eksplisit jika itu yang dimaksud.", + floatingPointDisplay: "FLOAT(M,D) dan DOUBLE(M,D) sudah deprecated pada MySQL 8. Gunakan FLOAT/DOUBLE tanpa parameter tampilan, atau DECIMAL(M,D) untuk nilai eksak.", + }, + postgresDataTypeHelp: { + smallint: "Integer signed 2-byte, dari -32.768 hingga 32.767.", + integer: "Integer signed 4-byte, dari -2.147.483.648 hingga 2.147.483.647.", + bigint: "Integer signed 8-byte, dari -2^63 hingga 2^63-1.", + serial: "Sintaks praktis yang membuat kolom integer, sequence, NOT NULL, dan default nextval. Tidak unik dengan sendirinya dan nilai sequence dapat memiliki celah (gap); untuk skema baru sebaiknya gunakan IDENTITY.", + numeric: "Angka desimal eksak dengan presisi dan skala yang dipilih pengguna. Gunakan untuk nilai uang dan nilai lain yang tidak boleh menggunakan pembulatan floating-point biner.", + real: "Angka floating-point presisi tunggal 4-byte. FLOAT(p) dengan p dari 1 hingga 24 memilih tipe ini.", + double: "Angka floating-point presisi ganda 8-byte. FLOAT tanpa presisi adalah aliasnya; FLOAT(p) dengan p dari 25 hingga 53 memilih tipe ini.", + money: "Jumlah mata uang yang diformat sesuai locale. Output dan parsing-nya bergantung pada lc_monetary; NUMERIC biasanya lebih aman untuk data finansial yang portabel.", + boolean: "Nilai logika true, false, atau null. BOOL adalah alias untuk BOOLEAN.", + char: "String karakter dengan panjang tetap yang diberi padding spasi. CHARACTER adalah alias; hindari bila spasi di akhir itu signifikan.", + varchar: "String karakter dengan panjang variabel dengan batas karakter opsional. CHARACTER VARYING adalah alias.", + text: "String karakter dengan panjang variabel tanpa batas yang dideklarasikan; perilaku penyimpanannya sama dengan VARCHAR tanpa batas.", + bytea: "String biner dengan panjang variabel. Nilai besar dapat disimpan di luar baris (out of line) oleh TOAST.", + date: "Tanggal kalender tanpa waktu atau zona waktu.", + time: "Waktu dalam sehari tanpa zona waktu, dengan presisi pecahan detik opsional.", + timetz: "Waktu dalam sehari ditambah offset UTC. Kegunaannya terbatas dan umumnya tidak disarankan; gunakan timestamptz untuk sebuah momen waktu (instant).", + timestamp: "Tanggal dan waktu tanpa konversi zona waktu. Gunakan untuk nilai waktu lokal (wall-clock) yang zona waktunya bukan bagian dari data.", + timestamptz: "Momen waktu yang disimpan secara internal dalam UTC dan ditampilkan dalam zona waktu sesi. Tidak mempertahankan nama zona waktu aslinya.", + interval: "Durasi yang dinyatakan dalam bulan, hari, dan mikrodetik. Unit kalender bukan durasi dengan panjang tetap.", + uuid: "Identifier unik universal (UUID) 128-bit.", + json: "Teks JSON yang dipertahankan dalam representasi input aslinya. Parsing divalidasi, tetapi pemrosesannya umumnya lebih lambat daripada JSONB.", + jsonb: "Representasi JSON biner yang telah diuraikan (decomposed) dan dioptimalkan untuk pemrosesan dan pengindeksan. Tidak mempertahankan whitespace yang tidak signifikan, urutan key, atau key duplikat.", + xml: "Nilai XML dengan validasi dokumen atau konten opsional tergantung opsi XML yang digunakan.", + bit: "String bit dengan panjang tetap atau variabel. BIT VARYING dan VARBIT adalah alias panjang variabel.", + tsvector: "Lexeme yang dinormalisasi, digunakan sebagai sisi dokumen yang dapat dicari pada full-text search PostgreSQL; umumnya diindeks dengan GIN atau GiST.", + tsquery: "Kueri full-text search boolean yang dievaluasi terhadap sebuah tsvector.", + cidr: "Jaringan IPv4 atau IPv6 dengan bit host yang dibatasi ke nol.", + inet: "Alamat host IPv4 atau IPv6, opsional dengan network mask; berbeda dari CIDR, bit host boleh bukan nol.", + macaddr: "Alamat MAC. MACADDR menyimpan alamat 6-byte dan MACADDR8 menyimpan alamat 8-byte.", + geometry: "Tipe geometris dua dimensi bawaan. Geometry PostgreSQL bersifat planar dan tidak memiliki SRID; gunakan PostGIS untuk koordinat geografis, proyeksi, atau operasi spasial tingkat lanjut.", + range: "Rentang kontinu tunggal dengan batas inklusif/eksklusif. Nilai range memerlukan subtipe yang kompatibel; gunakan tipe multirange untuk beberapa rentang yang terpisah (disjoint).", + oid: "Identifier objek unsigned. Ini adalah identifier sistem, bukan primary key aplikasi yang tahan lama; gunakan integer biasa atau UUID untuk data aplikasi.", + array: "Array PostgreSQL dari tipe elemen apa pun, termasuk array multidimensi. Dimensi array tidak dipaksakan oleh tipe yang dideklarasikan, dan array sering kali kurang fleksibel dibandingkan baris anak yang dinormalisasi.", + multirange: "Himpunan rentang yang tidak tumpang tindih dari subtipe range yang sesuai. PostgreSQL menormalkan anggota yang berdekatan atau tumpang tindih sesuai aturan subtipe.", + jsonpath: "Ekspresi path SQL/JSON yang digunakan oleh fungsi kueri dan predikat JSONB.", + pgLsn: "Lokasi write-ahead log yang digunakan untuk koordinat replikasi dan recovery; ini bukan nomor urut aplikasi.", + pgSnapshot: "Snapshot visibilitas transaksi. Representasi teksnya ditujukan untuk operasi snapshot database, bukan data aplikasi umum.", + }, + sqliteDataTypeHelp: { + integer: "SQLite menggunakan tipe dinamis dan afinitas INTEGER; kolom biasa tidak memaksakan storage class INTEGER. Nilai disimpan sebagai integer bertanda (signed) jika memungkinkan; INTEGER PRIMARY KEY (ejaan persis ini) adalah alias khusus untuk rowid.", + real: "Afinitas REAL menyimpan nilai floating-point IEEE 754. Cocok untuk pengukuran aproksimatif, bukan untuk uang atau perhitungan desimal yang eksak.", + text: "Afinitas TEXT menyimpan teks dalam encoding database. VARCHAR(n) dan CHAR(n) tidak memaksakan n di SQLite; tambahkan constraint CHECK jika batas panjang itu penting.", + blob: "Afinitas BLOB menyimpan byte persis seperti yang diberikan, tanpa konversi tipe.", + numeric: + "Afinitas NUMERIC mencoba mengonversi teks numerik yang valid ke INTEGER terlebih dahulu, lalu REAL; ini bukan storage class SQLite yang terpisah. Deklarasi DATE, DATETIME, dan TIME juga memiliki afinitas NUMERIC; simpan secara konsisten sebagai TEXT ISO-8601, REAL Julian-day, atau INTEGER Unix-time.", + }, + length: "Panjang", + lengthUnit: "Satuan panjang", + unitPlaceholder: "Satuan", + geometryTypePlaceholder: "Pilih atau ketik tipe geometri", + sridPlaceholder: "mis. 4326", + geometrySridHint: "Tentukan tipe geometri dan SRID untuk mengaktifkan pengindeksan spasial dan kueri spasial yang benar.", + geometryEmptyTypeHint: "Tipe geometri kosong setara dengan GEOMETRY (sub-tipe apa pun); dbx menghasilkan geometry(GEOMETRY, SRID).", + enumValues: "Nilai enum", + enumValueCount: "{count} nilai", + addEnumValue: "Tambah nilai", + removeEnumValue: "Hapus nilai enum", + enumValuePlaceholder: "Nilai (boleh kosong)", + nullable: "Nullable", + notNull: "Not null", + primaryKey: "Kunci Utama", + defaultValue: "Default", + defaultValuePresets: "Preset nilai default", + comment: "Komentar", + characterSet: "Charset", + charsetPlaceholder: "Charset", + collation: "Collation", + collationPlaceholder: "Collation", + editComment: "Edit komentar", + commentPlaceholder: "Masukkan komentar kolom...", + tableCommentPlaceholder: "Masukkan komentar tabel...", + mysqlTableEngine: "Storage engine", + mysqlTableEnginePlaceholder: "Pilih storage engine", + mysqlTableEngineSearchPlaceholder: "Cari storage engine", + mysqlTableEngineEmpty: "Tidak ada storage engine yang tersedia", + mysqlTableEngineLoadFailed: "Gagal memuat storage engine: {message}", + transwarpPartitionColumns: "Kolom partisi", + transwarpBucketColumns: "Kolom bucket", + transwarpBucketCount: "Bucket", + transwarpStorageFormat: "Format penyimpanan", + transwarpTransactional: "Tabel transaksional", + owner: "Pemilik", + ownerPlaceholder: "Masukkan nama peran...", + ownerSearchPlaceholder: "Cari atau masukkan nama peran...", + ownerRolesEmpty: "Tidak ada peran ditemukan; masukkan nama peran secara manual", + ownerLoadFailed: "Gagal memuat pemilik tabel: {message}", + ownerRolesLoadFailed: "Gagal memuat peran; Anda tetap dapat memasukkannya secara manual: {message}", + tableCommentUnsupported: "Komentar tabel tidak didukung oleh database ini", + actions: "Aksi", + indexName: "Indeks", + indexColumns: "Kolom", + indexColumnsPlaceholder: "Pilih kolom...", + unique: "Unique", + indexType: "Tipe", + includedColumns: "Disertakan", + includedColumnsPlaceholder: "Pilih kolom...", + filter: "Filter", + concurrent: "Concurrent", + concurrentTooltip: "Buat indeks secara concurrent untuk menghindari pemblokiran penulisan. Ini biasanya memakan waktu lebih lama dan tidak dapat dijalankan di dalam blok transaksi.", + concurrentExistingIndexTooltip: "Hanya tersedia untuk indeks baru. Membangun ulang indeks yang sudah ada secara concurrent (DROP INDEX CONCURRENTLY + CREATE INDEX CONCURRENTLY) belum didukung.", + concurrentPartitionedTooltip: "Tidak tersedia pada tabel induk yang dipartisi. PostgreSQL menolak pembuatan indeks concurrent pada induk yang dipartisi; buat indeks anak secara concurrent lalu lampirkan sebagai gantinya.", + invalidIndexBlocksSave: 'Penyimpanan diblokir: indeks INVALID (peninggalan dari build concurrent yang dibatalkan) sudah ada dengan nama yang sama: {indexNames}. Hapus terlebih dahulu (mis. DROP INDEX "schema"."name"), lalu coba lagi.', + concurrentUnavailableTooltip: "Tidak tersedia selama status partisi tabel tidak dapat diverifikasi. Pembuatan concurrent hanya ditawarkan pada tabel yang tidak dipartisi.", + concurrentUnavailableBlocksSave: + "Pembuatan indeks concurrent tidak lagi tersedia (status partisi tabel tidak dapat diverifikasi). Opsi Concurrent yang dipilih telah dihapus dan perubahan ini diblokir hingga tabel diverifikasi ulang. Segarkan untuk mencoba lagi, atau hapus indeks untuk melanjutkan dengan perubahan lainnya.", + invalidIndexRetryHint: "Ini mungkin disebabkan oleh indeks INVALID dengan nama yang sama, peninggalan dari build concurrent yang sebelumnya dibatalkan. Hapus indeks tersebut terlebih dahulu, lalu coba lagi.", + foreignKeyName: "Kunci asing", + referencedSchema: "Skema ref", + referencedTable: "Tabel ref", + referencedColumn: "Kolom ref", + onDelete: "Saat hapus", + onUpdate: "Saat update", + defaultAction: "Default", + triggerName: "Trigger", + triggerStatement: "Statement trigger", + primary: "Primary", + drop: "Hapus", + restore: "Pulihkan", + remove: "Hapus", + moveColumnUp: "Pindahkan kolom ke atas", + copySelectedColumns: "Salin field terpilih ({count})", + dropSelectedColumns: "Hapus field terpilih ({count})", + moveColumnDown: "Pindahkan kolom ke bawah", + dragColumn: "Seret untuk mengubah urutan kolom", + localColumnOrderNotice: "Urutan kolom disimpan secara lokal dan tidak mengubah struktur tabel database.", + yes: "Ya", + no: "Tidak", + emptyReadonly: "Tidak ada data", + sqlPreview: "Pratinjau SQL", + collapseSqlPreview: "Ciutkan Pratinjau SQL", + expandSqlPreview: "Perluas Pratinjau SQL", + noChanges: "Tidak ada perubahan", + apply: "Terapkan Perubahan", + ready: "Siap", + saved: "Struktur tabel diperbarui", + created: "Tabel berhasil dibuat", + copySql: "Salin SQL", + sqliteRebuildNotice: "SQLite mempertahankan snapshot data pasif sebagai cadangan, lalu membangun ulang tabel dalam satu transaksi dan melakukan CAST paksa pada kolom yang berubah. Nilai yang tidak dapat direpresentasikan dapat menjadi 0/0.0; kegagalan akan di-rollback.", + ddlEditNotice: "DDL yang diedit dijalankan sebagai skrip persis seperti yang ditulis — tidak dibandingkan (diff) dengan struktur saat ini. Untuk tabel yang sudah ada, tulis ulang sebagai statement ALTER (atau DROP + CREATE).", + ddlEditConflictsWithStructure: "Skrip DDL dan tab struktur keduanya telah diedit. Terapkan atau buang salah satunya sebelum menyimpan.", + resetDdl: "Pulihkan DDL database", + extendedProperties: "Lanjutan", + autoIncrement: "Auto Increment", + mysqlAutoIncrementNextValue: "Nilai auto-increment berikutnya", + editMysqlAutoIncrementValue: "Edit nilai auto-increment berikutnya (saat ini: {value})", + onUpdateCurrentTimestamp: "Perbarui Waktu Otomatis", + identity: "Identity", + identityGeneration: "Generation", + identitySeed: "Seed", + identityIncrement: "Increment", + sqlServerIdentityTypeHint: "Identity SQL Server hanya mendukung tinyint, smallint, int, bigint, dan decimal/numeric dengan skala 0", + }, + diagram: { + title: "Diagram Relasi", + open: "Lihat Diagram", + selectConnection: "Pilih koneksi", + selectDatabase: "Pilih database", + selectSchema: "Pilih skema", + allSchemas: "Seluruh database (Semua skema)", + entireDatabase: "Seluruh database", + selectedSchemasCount: "{count} skema terpilih", + selectAllSchemas: "Pilih semua skema", + deselectAllSchemas: "Bersihkan pilihan", + onlyThisSchema: "Hanya", + searchSchemas: "Cari skema...", + searchTables: "Cari tabel, kolom, kunci...", + refresh: "Segarkan diagram", + refreshConfirm: "Menyegarkan akan memuat ulang metadata tabel dan mereset tata letak kanvas serta riwayat undo. Relasi yang telah dimodelkan dan disimpan tetap dipertahankan. Lanjutkan?", + loading: "Membaca relasi...", + loadingProgress: "Membaca relasi... {loaded}/{total}", + partialError: "Melewati metadata untuk {count} tabel yang gagal dimuat", + selectTarget: "Pilih koneksi dan database", + empty: "Tidak ada tabel untuk ditampilkan", + noMatches: "Tidak ada tabel yang cocok", + tablesCount: "{count} tabel", + relationshipsCount: "{count} relasi", + tableMode: "Tampilan Tabel", + engineeringMode: "ER Rekayasa", + modelRelationships: "Model Relasi", + layers: "Layer", + autoMatch: "Cocokkan Otomatis", + autoLayout: "Tata Letak Otomatis", + matchRelationshipsCount: "{count} kecocokan", + copyJoinSql: "Salin SQL", + customRelationshipsCount: "{count} dimodelkan", + relationshipName: "Nama", + relationshipNamePlaceholder: "Opsional", + sourceTable: "Tabel sumber", + sourceColumn: "Kolom sumber", + targetTable: "Tabel target", + targetColumn: "Kolom target", + cardinality: "Kardinalitas", + cardinalityOneToMany: "Sumber 1 · Target N", + cardinalityManyToOne: "Sumber N · Target 1", + cardinalityOneToOne: "Sumber 1 · Target 1", + cardinalityManyToMany: "Sumber N · Target N", + cardinalityDirected: "Sumber {source} · Target {target}", + matchPickCardinality: "Konfirmasikan kecocokan setelah memilih kardinalitas (1:1 / 1:N / N:1 / N:N).", + manualAddRelationship: "Tambah manual", + confirmMatch: "Konfirmasi", + ignoreMatch: "Abaikan", + addRelationship: "Tambah relasi", + removeRelationship: "Hapus relasi", + relationshipIncomplete: "Pilih kolom sumber dan kolom target", + relationshipSelfInvalid: "Relasi tidak boleh menargetkan kolom yang sama", + relationshipExists: "Relasi ini sudah ada", + relationshipAdded: "Relasi ditambahkan", + noJoinSql: "Tidak ada SQL relasi untuk disalin", + allTables: "Semua Tabel", + relatedTables: "Tabel Terkait", + moreColumns: "+ {count} kolom", + exportSvg: "Ekspor SVG", + exportPng: "Ekspor PNG", + exportJson: "Ekspor JSON", + exportDbml: "Ekspor DBML", + exportMermaid: "Ekspor Mermaid", + export: "Ekspor", + exportedSvg: "SVG diekspor", + exportedFormat: "{format} diekspor", + exportSvgFailed: "Gagal mengekspor SVG: {message}", + exportFailed: "Gagal mengekspor {format}: {message}", + zoomIn: "Perbesar", + zoomOut: "Perkecil", + fitView: "Sesuaikan tampilan", + resetZoom: "Reset zoom", + undo: "Undo", + redo: "Redo", + resetLayout: "Reset tata letak", + fullscreen: "Layar penuh", + exitFullscreen: "Keluar layar penuh", + addLayer: "Tambah Layer", + noLayersYet: "Belum ada layer. Klik + untuk membuatnya.", + layoutFree: "Bebas", + layoutAuto: "Otomatis", + layerLock: "Kunci layer (lewati auto-layout di dalamnya)", + layerUnlock: "Buka kunci layer (izinkan auto-layout di dalamnya)", + layerLocked: "Terkunci", + layerUnlocked: "Tidak terkunci", + hideLayer: "Sembunyikan layer", + showLayer: "Tampilkan layer", + deleteLayer: "Hapus layer", + layerHiddenCannotFocus: "Layer disembunyikan — tampilkan untuk memfokuskan pada kanvas", + createTable: "Tabel baru", + createTableNotSupported: "Membuat tabel tidak didukung untuk database ini", + create: "Buat", + syncToDatabase: "Sinkronkan ke database", + structureSyncNotSupported: "Sinkronisasi struktur tabel tidak didukung untuk database ini", + syncDraftCount: "{count} perubahan untuk disinkronkan (create / alter / drop)", + executeSync: "Jalankan", + syncing: "Menyinkronkan…", + buildingSql: "Membangun SQL…", + noSqlYet: "Belum ada SQL", + copySql: "Salin SQL", + tableName: "Nama tabel", + tableNameRequired: "Nama tabel wajib diisi", + tableNameExists: "Tabel dengan nama ini sudah ada", + assignLayer: "Layer", + noLayer: "Tidak ada layer", + withDefaultIdPk: "Sertakan kunci utama id default", + inspectorTable: "Tabel", + inspectorRelationship: "Relasi", + fieldComment: "Komentar", + fields: "Field", + tabFields: "Field", + tabIndexes: "Indeks", + addIndex: "Tambah indeks", + indexName: "Nama indeks", + indexUnique: "UNIQUE", + indexColumns: "Kolom", + noIndexesYet: "Belum ada indeks", + indexesNotSupported: "Membuat indeks tidak didukung untuk database ini dari editor diagram", + addColumnNotSupported: "Menambahkan kolom tidak didukung untuk database ini", + dropColumnNotSupported: "Menghapus kolom tidak didukung untuk database ini", + dropTableNotSupported: "Menghapus tabel tidak didukung untuk database ini dari editor diagram", + addField: "Tambah field", + deleteField: "Hapus field", + undoDropField: "Batalkan penghapusan field", + noFieldsYet: "Belum ada field — tambahkan satu untuk sinkronisasi", + deleteDraftTable: "Hapus tabel draf", + deleteLiveTable: "Hapus tabel", + deleteLiveTableHint: "Menandai tabel untuk DROP TABLE pada sinkronisasi berikutnya. Batalkan melalui riwayat jika diperlukan.", + deleteLiveTableConfirm: "Tandai tabel ini untuk DROP TABLE saat Anda menyinkronkan ke database?", + liveTableReadOnly: "Tabel live — edit struktur di editor tabel", + liveTableAddColumnsHint: "Tambahkan kolom (ALTER ADD) atau tandai kolom yang ada untuk dihapus (ALTER DROP), lalu sinkronkan. Mengedit tipe kolom yang sudah ada tetap dilakukan di editor struktur tabel.", + liveTableIndexesReadOnly: "Edit indeks untuk tabel live di editor struktur tabel", + pendingColumnsBadge: "Perubahan tertunda", + pendingDropColumnBadge: "Hapus", + pendingDropTableBadge: "Hapus tabel", + source: "Sumber", + target: "Target", + emptyDesignHint: "Belum ada tabel. Buat layer dan tabel, edit field di inspector, lalu sinkronkan ke database.", + removeFromLayer: "Hapus dari layer", + addTables: "Tambah tabel", + tabSelectExisting: "Pilih yang sudah ada", + tabCreateTable: "Tabel baru", + multiSelect: "Pilih banyak", + closeMultiSelect: "Tutup", + selectAll: "Pilih semua", + clearSelection: "Bersihkan", + tablesInOtherLayers: "Tabel di layer lain", + filterTables: "Filter tabel...", + noMatchingTables: "Tidak ada tabel yang cocok", + addSelectedCount: "Tambah {count} terpilih", + layerNameTooLong: "Nama layer harus kurang dari 50 karakter", + layerNameInvalid: "Nama layer dapat berisi huruf, angka, karakter Tionghoa, spasi, garis bawah, tanda hubung, dan titik", + layerNameExists: "Nama layer sudah ada", + total: "total", + confirmed: "dikonfirmasi", + pending: "tertunda", + conflicts: "konflik", + conflict: "Konflik", + ignored: "diabaikan", + confirmAll: "Konfirmasi semua", + ignoreAll: "Abaikan semua", + clearAll: "Bersihkan semua", + confidenceHigh: "Tinggi", + confidenceMedium: "Sedang", + confidenceLow: "Rendah", + noInferred: "Tidak ada relasi yang disimpulkan", + editRelationship: "Edit", + saveRelationship: "Simpan", + deleteRelationship: "Hapus", + confirmDeleteRelationship: "Hapus relasi ini?", + confirmDeleteRelationshipAction: "Hapus", + confirmRelationship: "Konfirmasi", + ignoreRelationship: "Abaikan", + relationshipKindFk: "Kunci asing", + relationshipKindCustom: "Kustom", + relationshipKindInferred: "Disimpulkan", + relationshipReadOnlyFk: "Relasi ini berasal dari kunci asing database dan tidak dapat diedit di sini.", + relationshipUpdated: "Relasi diperbarui", + }, + etcd: { + adminPermissionRequired: "Tampilan etcd ini memerlukan peran root.", + targetKeyWriteDenied: "Koneksi target tidak memiliki izin untuk menulis Key ini.", + selectedKeysWriteDenied: "Koneksi target tidak memiliki izin untuk menulis Key yang dipilih; tidak ada perubahan yang dilakukan.", + prefixPlaceholder: "Cari path Key, mis. /app/ atau service", + newKey: "Key Baru", + loadingKeys: "Memuat key...", + empty: "Tidak ada key ditemukan", + loadMore: "Muat lebih banyak", + selectKey: "Pilih key untuk melihat nilainya", + loadingValue: "Memuat nilai...", + notFound: "Key tidak ditemukan", + edit: "Edit", + editKey: "Edit Key", + delete: "Hapus", + deleteTitle: "Hapus key etcd", + keyPlaceholder: "/path/ke/key", + keyRequired: "Key wajib diisi", + ttl: "TTL (detik)", + ttlPlaceholder: "Masukkan jumlah detik positif", + ttlInvalid: "TTL harus berupa bilangan bulat positif", + ttlUnavailable: "Perbarui Agent etcd dan hubungkan ulang untuk mengonfigurasi TTL.", + expiryMode: "Kebijakan kedaluwarsa", + expiryPermanent: "Permanen", + expiryPermanentHint: "Jangan lampirkan lease; key tidak akan kedaluwarsa secara otomatis", + expiryTtl: "Time to live (TTL)", + expiryTtlHint: "Buat lease sementara yang kedaluwarsa setelah durasi yang dikonfigurasi", + expiryLease: "Ikat lease", + expiryLeaseHint: "Lampirkan key ke ID Lease yang sudah ada", + leaseId: "ID Lease", + leasePlaceholder: "Masukkan ID Lease yang sudah ada", + leaseInvalid: "ID Lease harus berupa integer 64-bit positif yang valid", + valueContent: "Isi nilai", + keyAlreadyExists: "Key dengan nama ini sudah ada. Pilih nama lain, atau tutup dialog ini dan edit Key yang sudah ada.", + conflict: "Key ini berubah setelah dimuat. Segarkan dan coba lagi.", + saved: "Key disimpan", + deleted: "Key dihapus", + base64Readonly: "Edit nilai Base64 dalam mode Base64.", + rename: "Ganti Nama", + clone: "Klon", + copyKey: "Salin key", + export: "Ekspor", + exportAll: "Ekspor semua", + exportSelection: "Ekspor terpilih", + batchExport: "Ekspor batch", + exportAllJson: "Ekspor semua (JSON, dapat diimpor)", + exportAllCsv: "Ekspor semua (CSV)", + exportAllMarkdown: "Ekspor semua (Markdown)", + exportSelectionJson: "Ekspor terpilih (JSON)", + exportSelectionCsv: "Ekspor terpilih (CSV)", + exportSelectionMarkdown: "Ekspor terpilih (Markdown)", + import: "Impor", + sync: "Sinkronkan", + history: "Riwayat", + restore: "Pulihkan versi ini", + compare: "Bandingkan", + format: "Format nilai", + savePreview: "Tinjau perubahan nilai", + globalSearch: "Pencarian global", + searchPrefix: "Batasi ke prefix (opsional)", + searchAll: "Key dan nilai", + searchPlaceholder: "Cari isi key atau nilai", + searchProgress: "Memindai {scanned} key, {matched} cocok", + exportResults: "Ekspor hasil", + clearSearchResults: "Bersihkan hasil", + exported: "{count} key diekspor", + selectAllLoaded: "Pilih semua", + deselectAll: "Bersihkan", + batchDelete: "Hapus batch", + batchDeleteTitle: "Hapus key etcd terpilih", + batchDeleteConfirm: "Hapus {count} key terpilih? Tindakan ini tidak dapat dibatalkan.", + batchDeleteSuccess: "{count} key dihapus", + batchDeletePartial: "{count} key dihapus sebelum batch berhenti: {error}", + importPreview: "Pratinjau impor", + syncPreview: "Pratinjau sinkronisasi", + targetConnection: "Pilih koneksi etcd target", + targetReadOnly: "Koneksi target hanya baca; operasi impor dan sinkronisasi tidak dapat diterapkan.", + mirrorDelete: "Hapus key target yang berlebih (mirror)", + mirrorDeleteWarning: "Mode mirror menghapus key target yang tidak ada di sumber. Tinjau setiap operasi hapus sebelum diterapkan.", + preparingPreview: "Menyiapkan pratinjau perubahan revisi tetap...", + operation: "Operasi", + reason: "Alasan", + selectedOperations: "{count} operasi terpilih", + applyOperations: "Terapkan operasi", + transferApplied: "{count} operasi diterapkan", + operationApplied: "Berhasil diterapkan", + transferPartiallyApplied: "{count} operasi diterapkan sebelum batch berhenti: {error}. Pratinjau telah disegarkan; coba lagi hanya operasi terpilih yang tersisa.", + transferPartialRefreshFailed: "{count} operasi diterapkan sebelum batch berhenti: {error}. Menyegarkan pratinjau juga gagal: {previewError}. Tutup dan buka kembali pratinjau sebelum mencoba lagi.", + targetChangedDuringTransfer: "Koneksi target berubah saat batch sedang berjalan", + watch: "Watch", + lease: "Lease", + key: "Key", + keyOrPrefix: "Key atau prefix", + selectExistingLease: "Pilih Lease yang sudah ada", + enterLeaseId: "Atau masukkan ID Lease secara manual", + leasePickerHint: "Pilih Lease dari sesi ini atau masukkan ID Lease secara manual.", + noLeasePickerHint: "Tidak ada Lease yang tersedia dalam sesi ini. Masukkan ID secara manual dan simpan.", + registryWarning: "Key ini berada di bawah /registry/, namespace yang umum digunakan oleh komponen control-plane. Verifikasi pemilik dan dampaknya sebelum menyimpan.", + access: { + users: "Pengguna", + roles: "Peran", + title: "Kontrol akses", + description: "Kelola pengguna native etcd, peran, dan izin Key", + readOnly: "Koneksi hanya baca", + refresh: "Segarkan", + userCount: "Pengguna ({count})", + roleCount: "Peran ({count})", + createUser: "Buat pengguna", + createRole: "Buat peran", + noUsers: "Belum ada pengguna etcd yang dibuat", + noRoles: "Belum ada peran etcd yang dibuat", + selectUser: "Pilih pengguna di sebelah kiri untuk melihat peran dan aksi kredensial", + selectRole: "Pilih peran di sebelah kiri untuk melihat dan mengelola izin", + loadingUser: "Memuat detail pengguna...", + loadingRole: "Memuat detail peran...", + userRolesSummary: "{count} peran ditetapkan. Kata sandi tidak pernah dibaca, ditampilkan, atau disimpan oleh klien.", + changePassword: "Ubah kata sandi", + deleteUser: "Hapus pengguna", + roleAssignments: "Penetapan peran", + roleAssignmentHint: "Peran menentukan rentang Key yang dapat dibaca dan ditulis oleh pengguna ini.", + revokeAssociation: "Cabut asosiasi", + noAssignedRoles: "Pengguna ini tidak memiliki peran yang ditetapkan.", + assignRole: "Tetapkan peran", + assignRoleHint: "Pilih peran yang belum ditetapkan ke pengguna ini.", + selectRoleOption: "Pilih peran", + noAssignableRoles: "Tidak ada peran yang tersedia untuk ditetapkan", + grantRole: "Tetapkan peran", + rolePermissionHint: "Izin dapat mencakup semua Key, sebuah prefix, atau Key yang tepat. Prefix disimpan sebagai rentang half-open etcd.", + grantPermission: "Berikan izin", + deleteRole: "Hapus peran", + resource: "Resource", + permission: "Izin", + allKeys: "Semua Key", + exactKey: "Key Tepat", + allKeyspace: "Seluruh keyspace", + edit: "Edit", + revoke: "Cabut", + noPermissions: "Peran ini tidak memiliki izin.", + createEtcdUser: "Buat pengguna etcd", + username: "Nama Pengguna", + password: "Kata Sandi", + initialRoles: "Peran awal", + optional: "Opsional", + initialRolesHint: "Peran yang dipilih akan langsung ditetapkan setelah dibuat.", + selectedCount: "{count} terpilih", + noRolesForNewUser: "Belum ada peran. Anda dapat membuat pengguna terlebih dahulu dan menetapkan peran dari detailnya.", + createAndAssignRoles: "Buat dan tetapkan {count} peran", + createUserAction: "Buat pengguna", + createEtcdRole: "Buat peran etcd", + roleName: "Nama peran", + initialPermission: "Izin awal", + initialPermissionHint: "Jika diisi, izin ini akan diberikan saat peran dibuat.", + keyOrPrefixPlaceholder: "Key atau Prefix", + allKeysHint: "Ini memberikan akses ke semua Key.", + createAndGrantPermission: "Buat dan berikan izin", + read: "Baca", + write: "Tulis", + readWrite: "Baca & tulis", + passwordHint: "Kata sandi baru hanya dikirim bersama permintaan ini dan dihapus dari antarmuka setelah dikirim.", + newPassword: "Kata sandi baru", + continue: "Lanjutkan", + editPermission: "Edit izin peran", + permissionUpdateHint: "etcd Auth tidak memiliki pembaruan atomik. Menyimpan akan mencabut izin lama lalu memberikan izin baru. Jika pemberian gagal, DBX akan mencoba memulihkan izin lama.", + saveChanges: "Simpan perubahan", + dangerousTitle: "Konfirmasi operasi berbahaya", + dangerousHint: "Operasi ini langsung mengubah data etcd Auth. Masukkan teks konfirmasi di bawah untuk melanjutkan.", + confirmationPlaceholder: "Masukkan teks konfirmasi", + confirmExecute: "Konfirmasi dan jalankan", + cancel: "Batal", + preflightRequired: "Perubahan izin ini memerlukan kredensial konfirmasi baru. Pilih Simpan perubahan dan konfirmasi lagi.", + preflightExpired: "Konfirmasi telah kedaluwarsa. Pilih Simpan perubahan dan konfirmasi lagi.", + preflightMismatch: "Isi konfirmasi atau izin yang tertunda telah berubah. Konfirmasi lagi sebelum mencoba kembali.", + confirmationMismatch: "Teks konfirmasi tidak cocok. Silakan coba lagi.", + createdUser: "Pengguna {user} dibuat", + createdUserWithRoles: "Pengguna {user} dibuat dan {count} peran ditetapkan", + createdUserRolesFailed: "Pengguna berhasil dibuat, tetapi penetapan peran awal gagal: {error}", + createdRole: "Peran {role} dibuat", + createdRoleWithPermission: "Peran {role} dibuat dan izin awalnya diberikan", + createdRolePermissionFailed: "Peran berhasil dibuat, tetapi pemberian izin awalnya gagal: {error}", + deletedUser: "Pengguna {user} dihapus", + deletedRole: "Peran {role} dihapus", + passwordUpdated: "Kata sandi untuk {user} diperbarui", + roleGranted: "Peran {role} ditetapkan ke {user}", + roleRevoked: "Peran {role} dicabut dari {user}", + permissionGranted: "Izin peran diberikan", + permissionUpdated: "Izin peran diperbarui", + permissionRevoked: "Izin peran dicabut", + }, + admin: { + maintenance: "Pemeliharaan", + watch: "Watch", + lease: "Lease", + refresh: "Segarkan", + maintenanceTitle: "Pemeliharaan riwayat dan disk", + maintenanceDescription: "Bersihkan riwayat yang tidak terpakai terlebih dahulu, lalu putuskan apakah akan memulihkan ruang disk backend. Operasi ini tidak saling menggantikan.", + currentRevision: "Revisi saat ini {revision}", + reachableMembers: "Anggota yang dapat dijangkau {reachable} / {total}", + compactTitle: "Compact riwayat", + compactDescription: "Menghapus riwayat MVCC sebelum revisi yang ditentukan. Nilai Key saat ini tetap ada, tetapi pembacaan historis dan Watch yang dimulai sebelumnya tidak dapat dipulihkan.", + compactDiskHint: "Ini tidak membebaskan ruang disk. Jalankan Defragment setelah compaction untuk mengurangi ukuran file backend.", + compactRevision: "Awal retensi riwayat (revisi)", + compactPlaceholder: "Misalnya {revision}", + compactRequired: "Masukkan revisi untuk mempertahankan riwayat mulai dari sana.", + compactDone: "Compaction riwayat selesai", + compactInputHint: "Menghapus riwayat sebelum revisi ini. Pastikan versi historis ini tidak lagi diperlukan sebelum melanjutkan.", + compactAction: "Compact riwayat", + defragTitle: "Pulihkan ruang disk", + defragDescription: "Defrag menulis ulang backend setiap anggota untuk mengembalikan ruang disk yang dapat dipulihkan ke sistem operasi. Follower diproses secara berurutan sebelum leader saat ini.", + defragWarning: "Setiap anggota tidak tersedia sebentar saat didefragmentasi. Anggota diproses satu per satu dengan leader saat ini diproses terakhir; pastikan cluster dalam keadaan sehat terlebih dahulu.", + defragReachableMembers: "Proses {count} anggota yang dapat dijangkau", + leaderLast: "Leader terakhir: {endpoint}", + defragAction: "Pulihkan ruang disk pada {count} anggota", + defragDone: "Defragmentasi selesai", + newWatch: "Watch baru", + editWatch: "Edit watch", + watchSearch: "Filter watch", + watchKeyPlaceholder: "Misalnya /apps/payment/config", + watchScope: "Cakupan watch", + prefix: "Prefix", + exact: "Key Tepat", + watchKeyHint: "Terima event create, update, dan delete untuk Key ini.", + watchPrefixHint: "Terima event untuk setiap Key yang dimulai dengan prefix ini.", + watchSessionHint: "Watch hanya berjalan dalam sesi koneksi ini dan berhenti saat koneksi ditutup atau halaman etcd ditinggalkan. Satu koneksi dapat menjalankan hingga empat watch.", + watchCount: "{count} dibuat", + runningWatchCount: "{count} berjalan", + watchList: "Watch yang dibuat", + itemCount: "{count} item", + scope: "Cakupan", + status: "Status", + actions: "Aksi", + createWatch: "Buat dan mulai watch", + saveWatch: "Simpan konfigurasi", + running: "Berjalan", + stopped: "Berhenti", + error: "Galat", + editWatchTitle: "Edit watch", + stopWatch: "Hentikan watch", + startWatch: "Mulai watch", + deleteWatch: "Hapus watch", + noMatchingWatches: "Tidak ada watch yang cocok", + noWatches: "Belum ada watch.", + eventStream: "Aliran event", + eventCount: "{count} event", + filter: "Filter", + event: "Event", + create: "Create", + update: "Perubahan nilai", + delete: "Delete", + noFilteredEvents: "Tidak ada event yang cocok dengan filter saat ini", + waitingEvents: "Menunggu perubahan Key...", + watchNotRunning: "Watch ini tidak sedang berjalan.", + selectWatch: "Pilih watch di sebelah kiri untuk melihat aliran eventnya", + leaseDescription: "Saat Lease kedaluwarsa, semua Key yang terlampir akan dihapus secara otomatis.", + grantLease: "Berikan Lease", + renew: "Perpanjang", + revoke: "Cabut", + previousPage: "Sebelumnya", + nextPage: "Berikutnya", + leasePageSize: "Hingga {count} item per halaman", + grantedTtl: "Diberikan {ttl}dtk", + noKnownLeases: "Tidak ada Lease yang diketahui dalam sesi ini", + loadingLease: "Memuat detail Lease...", + keepalive: "Perpanjang otomatis setiap TTL / 3 selama halaman ini tetap terbuka", + attachedKeys: "Key Terlampir", + noAttachedKeys: "Tidak ada Key terlampir", + attachedKeysTruncated: "Hasil Key terlampir dipotong hingga 256 entri.", + selectLease: "Pilih Lease untuk melihat detailnya", + leasePartial: "Klien atau server etcd saat ini tidak dapat mencacah (enumerate) Lease. Hanya Lease yang dibuat atau diakses dalam sesi ini yang ditampilkan; detail dan TTL tetap berasal dari server.", + grantNewLease: "Berikan Lease baru", + ttl: "TTL (detik)", + ttlPlaceholder: "Misalnya 60", + ttlHint: "Durasi Lease harus berupa bilangan bulat positif.", + customLeaseId: "ID Lease Kustom", + customLeasePlaceholder: "Biarkan kosong atau masukkan 0 agar etcd yang mengalokasikannya", + customLeaseHint: "Gunakan integer desimal. etcd akan menolak ID yang sudah ada.", + confirmationHint: "Operasi pemeliharaan cluster ini tidak dapat dibatalkan secara otomatis. Tinjau dampaknya sebelum melanjutkan.", + confirmationCredentialHint: "Masukkan teks konfirmasi di bawah. Kredensial ini hanya berlaku untuk operasi ini.", + confirmationPlaceholder: "Masukkan teks konfirmasi", + confirmationPrompt: "Operasi ini dapat memengaruhi cluster etcd. Masukkan teks konfirmasi:\n{confirmationText}", + confirmExecute: "Konfirmasi dan jalankan", + cancel: "Batal", + noReachableMembers: "Tidak ada anggota yang dapat dijangkau untuk defragmentasi.", + defragStopped: "Defragmentasi dihentikan: {succeeded} berhasil, {failed} gagal, {notExecuted} tidak dijalankan", + defragCompleted: "Defragmentasi selesai: {succeeded}/{total} berhasil", + leaseRenewed: "Lease {id} diperpanjang", + leaseGrantCancelled: "Berhenti menunggu. etcd mungkin masih memproses pemberian; segarkan untuk memastikan apakah Lease telah dibuat.", + leaseCreated: "Lease {id} dibuat", + }, + dashboard: { + title: "Dasbor etcd", + description: "Observasi berdasarkan endpoint yang dapat dijangkau klien; ini bukan pemeriksaan kesehatan quorum yang otoritatif.", + autoRefreshOff: "Auto refresh nonaktif", + refresh: "Segarkan", + retry: "Periksa lagi", + loadFailed: "Tidak dapat memuat Dasbor etcd", + agentUpgradeTitle: "Dasbor tidak tersedia dengan Agent etcd saat ini", + agentUpgradeDescription: "Koneksi ini masih menggunakan Agent lama yang tidak dapat membaca status cluster. Penjelajahan dan pengeditan Key tetap tersedia.", + agentUpgradeSteps: "Perbarui Agent etcd di Driver Manager, lalu putuskan dan hubungkan kembali koneksi etcd ini. Pilih “Periksa lagi” setelah selesai.", + observedHealth: "Kesehatan yang teramati", + reachableMembers: "Anggota yang dapat dijangkau", + keyCount: "Jumlah Key", + backendSize: "Ukuran backend", + fragmentation: "Perkiraan fragmentasi", + cluster: "cluster", + revision: "revision", + leader: "leader", + noAlarms: "Tidak ada alarm aktif yang teramati", + prometheusMetrics: "Metrik runtime Prometheus", + prometheusDescription: "Metrik stabil yang dikumpulkan dari etcd /metrics. Laju dihitung dari dua sampel yang berdekatan.", + collectedAt: "Dikumpulkan pada", + requests: "Laju permintaan gRPC", + requestFailureRate: "Laju kegagalan permintaan", + proposals: "Proposal Raft", + proposalLag: "Selisih committed-ke-applied", + pending: "tertunda", + diskLatency: "Latensi persistensi disk", + walFsync: "Rata-rata WAL fsync", + backendCommit: "Rata-rata commit backend", + networkTraffic: "Trafik jaringan klien", + peerTraffic: "Trafik peer", + processResources: "Sumber daya proses", + runtime: "Runtime Go", + goroutines: "goroutine", + leaderChanges: "Total perubahan leader", + failedProposals: "Total proposal gagal", + failedProposalRate: "Laju kegagalan", + rateNeedsRefresh: "Segarkan lagi untuk menghitung laju secara live", + storageQuota: "Penggunaan kuota backend", + uptime: "Waktu aktif proses", + consensusReliability: "Konsensus dan keandalan", + leadership: "Leadership", + knownPeers: "peer yang diketahui", + proposalState: "Status proposal", + raftFailures: "Kegagalan Raft", + revisionState: "Revisi MVCC", + compactRevision: "Revisi compact", + requestLoad: "Beban permintaan", + grpcMethod: "Metode gRPC", + total: "Total", + rate: "Laju", + failures: "Kegagalan", + lag: "Lag", + slowApply: "Apply lambat", + putBytes: "Byte put", + avgLatency: "Latensi rata-rata", + storageDisk: "Penyimpanan dan disk", + databaseState: "Status database", + inUse: "terpakai", + openReadTransactions: "Transaksi baca terbuka", + backgroundTasks: "Tugas latar belakang", + watchState: "Status watch", + watchers: "Watcher", + watchStreams: "Aliran watch", + events: "Laju event", + slowPending: "Lambat / tertunda", + leaseState: "Siklus hidup Lease", + granted: "Laju pemberian", + renewed: "Laju perpanjangan", + revokedExpired: "Dicabut / kedaluwarsa", + averageTtl: "TTL rata-rata", + runtimeResources: "Sumber daya runtime", + memory: "Memori", + processNetworkGc: "Jaringan proses dan GC", + metricsUnavailable: "Metrik Prometheus tidak tersedia", + metricsUnavailableHint: "Status cluster tetap tersedia. DBX meminta /metrics langsung dari endpoint etcd saat ini; verifikasi bahwa URL yang dihasilkan dapat dijangkau dari aplikasi DBX.", + endpointMember: "Endpoint / member", + role: "Peran", + version: "Versi", + raftTermApplied: "Raft term / applied", + dbSizeInUse: "Ukuran DB / terpakai", + latency: "Latensi", + status: "Status", + learner: "learner", + follower: "follower", + reachable: "dapat dijangkau", + unreachable: "tidak dapat dijangkau", + loading: "Memuat observasi cluster…", + health: { + unknown: "tidak diketahui", + critical: "kritis", + warning: "peringatan", + healthy: "sehat", + }, + }, + }, + zookeeper: { + prefixPlaceholder: "Prefix path, mis. /app/", + newKey: "Znode Baru", + loadingKeys: "Memuat znode...", + empty: "Tidak ada znode ditemukan", + loadMore: "Muat lebih banyak", + selectKey: "Pilih znode untuk melihat nilainya", + loadingValue: "Memuat nilai...", + notFound: "Znode tidak ditemukan", + edit: "Edit", + editKey: "Edit Znode", + delete: "Hapus", + deleteTitle: "Hapus znode ZooKeeper", + keyPlaceholder: "/path/ke/znode", + keyRequired: "Path znode wajib diisi", + rootReadonly: "Znode root tidak dapat diubah. Masukkan path znode turunan.", + saved: "Znode disimpan", + deleted: "Znode dihapus", + base64Readonly: "Nilai Base64 bersifat hanya baca pada versi ini.", + clone: "Klon", + copyKey: "Salin key", + export: "Ekspor", + utf8PreviewLossy: "Byte UTF-8 yang tidak valid ditampilkan sebagai karakter pengganti (�). Nilai Base64 aslinya tidak berubah.", + utf8PreviewUnavailable: "Nilai Base64 tidak valid, sehingga nilai asli ditampilkan.", + createMode: "Mode Pembuatan", + createModePersistent: "Persistent", + createModeEphemeral: "Ephemeral", + createModePersistentSequential: "Persistent Sequential", + createModeEphemeralSequential: "Ephemeral Sequential", + add: "Tambah", + value: "Nilai", + metadata: "Info Node", + prettyJson: "Rapi", + invalidJson: "JSON Tidak Valid", + summaryRevision: "rev", + summaryVersion: "ver", + summaryLease: "lease", + summarySize: "ukuran", + }, + redis: { + monitorStop: "Hentikan mendengarkan", + monitorListening: "MONITOR sedang mendengarkan · 1.000 entri terbaru · entri panjang dipotong", + setDatabaseAlias: "Atur Alias Database", + databaseAliasTitle: "Alias untuk db{db}", + databaseAliasPlaceholder: "mis. orders, cache, development", + databaseAliasHint: "Alias ini hanya untuk tampilan dan pencarian. Perintah Redis tetap menggunakan indeks database numerik.", + clearDatabaseAlias: "Hapus Alias", + databaseAliasSaved: "Alias untuk db{db} diatur ke {alias}", + databaseAliasCleared: "Alias untuk db{db} dihapus", + selectKey: "Pilih key untuk melihat nilainya", + noKeys: "Tidak ada key ditemukan", + noKeysInScanHint: "Tidak ada key ditemukan dalam rentang scan saat ini", + pattern: "pola (mis. user:*)", + fuzzyPattern: "key mengandung...", + keyTemplateSuggestions: "Template key", + keySearchHistory: "Riwayat pencarian", + keySearchHistoryForget: "Hapus dari riwayat", + keySearchHistoryEmpty: "Belum ada riwayat", + fuzzyMatch: "Fuzzy", + fuzzyMatchTitle: "Pencocokan fuzzy: cari key berdasarkan teks biasa yang terkandung", + valueSearchPlaceholder: "nilai mengandung...", + allSearchPlaceholder: "key atau nilai mengandung...", + searchByKey: "Key", + searchByValue: "Nilai", + searchByAll: "Semua", + searchFields: "Cari field dan nilai", + searchMembers: "Cari member", + searchItems: "Cari item", + keys: "{count} key", + loadedKeys: "{loaded} / {total} key dimuat", + loadingKeys: "Memuat key...", + searchingValues: "Mencari nilai...", + searchingAll: "Mencari key dan nilai...", + loadMoreKeys: "Muat lebih banyak key", + fetchAllKeys: "Ambil semua", + stopFetchAll: "Hentikan", + fetchAllProgress: "{loaded} dari {total} key dimuat", + fetchAllProgressUnknown: "{loaded} key dimuat", + items: "{count} item", + fields: "{count} field", + members: "{count} member", + loadedItems: "{loaded} dari {total} item dimuat", + loadedFields: "{loaded} dari {total} field dimuat", + loadedMembers: "{loaded} dari {total} member dimuat", + entries: "{count} entri", + streamData: "Data Stream", + consumerGroups: "Consumer Group", + group: "Group", + consumers: "Consumer", + pending: "Tertunda", + lastDeliveredId: "ID Terkirim Terakhir", + lastDelivered: "Terakhir Terkirim", + entriesRead: "Entri Dibaca", + lag: "Lag", + noConsumerGroups: "Tidak ada consumer group", + streamGroupsLoadFailed: "Gagal memuat consumer group", + backToGroups: "Kembali ke group", + streamConsumers: "Consumer", + streamConsumersLoadFailed: "Gagal memuat consumer", + noStreamConsumers: "Tidak ada consumer", + openConsumerDetails: "Buka detail consumer", + consumer: "Consumer", + idle: "Idle", + inactive: "Tidak aktif", + pendingEntries: "Entri Tertunda", + pendingEntriesLoadFailed: "Gagal memuat entri tertunda", + noPendingEntries: "Tidak ada entri tertunda", + entryId: "ID Entri", + deliveries: "Pengiriman", + loadMoreEntries: "Muat lebih banyak entri", + loadMorePending: "Muat lebih banyak entri tertunda", + noExpiry: "tanpa kedaluwarsa", + noExpiryOnly: "Hanya tanpa kedaluwarsa", + noExpiryOnlyTitle: "Tampilkan hanya key tanpa TTL dalam hasil yang dimuat", + noExpiryKeysEmpty: "Tidak ada key tanpa kedaluwarsa dalam hasil yang dimuat", + ttlCountdownTitle: "Hitung mundur lokal dari TTL saat dimuat", + expired: "kedaluwarsa", + expiry: "Kedaluwarsa", + expiryNone: "Tanpa kedaluwarsa", + expiryTtl: "TTL (detik)", + expiryAt: "Waktu kedaluwarsa (lokal)", + expiryTtlInvalid: "Masukkan TTL berupa bilangan bulat positif dalam detik", + expiryDateRequired: "Pilih waktu kedaluwarsa yang valid", + expiryDatePast: "Waktu kedaluwarsa harus di masa depan", + keyExpiredBeforeDisplay: "Key kedaluwarsa sebelum sempat ditampilkan.", + autoRefresh: "Hitung mundur segarkan otomatis", + ttlDay: "{count}h", + ttlHour: "{count}j", + ttlMinute: "{count}m", + ttlSecond: "{count}d", + columnType: "Tipe", + columnKey: "Key", + columnValue: "Nilai", + columnSize: "Ukuran", + columnTTL: "TTL", + binaryStringReadonlyHint: "Nilai string biner ditampilkan sebagai teks escape dalam mode hanya baca; pengeditan byte mentah tidak didukung.", + bitmapInfo: "bitmap kvrocks · {bits} bit diset · {bytes} byte", + hyperLogLogHint: "kvrocks HyperLogLog: nilai di atas adalah perkiraan kardinalitas PFCOUNT; data mentah tidak dapat dibaca", + unsupportedValueType: "Melihat tipe Redis ini belum didukung: {type}", + unsupportedValueTypeHint: "Ini adalah tipe proprietary dari server yang kompatibel dengan kvrocks; DBX belum mengadaptasinya", + largeStringPreviewHint: "Nilai ini besar. Hanya {loaded} pertama dari {total} yang dimuat, dan pratinjau bersifat hanya baca.", + largeStringPreviewHintUnknown: "Nilai ini besar. Hanya {loaded} pertama yang dimuat, dan pratinjau bersifat hanya baca.", + downloadValue: "Unduh nilai lengkap", + downloadValueFileType: "Nilai Redis", + downloadValueTextFileType: "File teks", + downloadValueSuccess: "Nilai Redis diunduh", + largeStringPreviewActionUnavailable: "Pratinjau nilai besar tidak dapat disalin, didekode, atau digunakan untuk menghasilkan statement insert", + selectedKeys: "Key terpilih", + selectAllLoaded: "Pilih semua", + selectAllLoadedTitle: "Pilih semua key (Ctrl/Cmd+A)", + deselectAll: "Bersihkan", + selectLoadedGroupKeys: "Pilih {count} key yang dimuat dalam folder ini", + loadedMatchingKeys: "{count} key cocok yang dimuat", + loadedGroupKeysPartial: "{count} key dimuat sejauh ini — folder ini mungkin berisi lebih banyak", + fuzzyTreeLimit: "{count} kecocokan fuzzy ditampilkan sebagai daftar datar agar browser tetap responsif. Perhalus pencarian untuk melihat hierarkinya.", + deleteGroup: "Hapus group", + deleteKey: "Hapus key", + deleteGroupDetails: "{target}\n{count} key", + deleteLoadedSearchKeysDetails: "{target}\n{count} key cocok yang dimuat", + deleteGroupSubtreeDetails: "{target}\nSemua key di bawah group ini akan dihapus ({count} dimuat)", + deleteGroupSubtreeSuccess: "{count} key dihapus", + batchExpiry: "Atur kedaluwarsa", + batchExpiryTitle: "Kedaluwarsa batch", + batchExpirySelected: "{count} key terpilih", + batchExpiryApply: "Terapkan", + batchExpirySuccess: "Kedaluwarsa diterapkan pada {count} key", + batchExpiryPartial: "{success} diterapkan, {failed} tidak diterapkan", + flushDb: "Bersihkan DB saat ini", + flushDbMessage: "Ini akan menghapus semua key dalam database Redis saat ini dan tidak dapat dibatalkan. Lanjutkan?", + flushDbDetails: "Target: Redis db{db}\nCakupan: semua key dalam DB saat ini", + flushDbConfirm: "Bersihkan DB", + flushDbSuccess: "Redis db{db} dibersihkan", + keyDetail: "Detail key", + commandLine: "Baris perintah", + selectKeyForDetail: "Pilih key untuk melihat detail", + commandWelcome: "Selamat datang di konsol perintah Redis", + commandPlaceholder: "Perintah Redis, mis. GET user:1", + commandPrefix: "CMD", + commandHint: "Masukkan perintah Redis, mis. SMEMBERS feature:flags", + executeCommand: "Jalankan perintah", + commandEmpty: "Masukkan perintah Redis", + commandEmptyResult: "Jalankan perintah Redis untuk melihat hasilnya", + commandBlocked: "Perintah Redis ini diblokir demi keamanan", + createKey: "Buat key", + createKeyName: "Key", + createKeyNamePlaceholder: "user:1", + createKeyType: "Tipe", + createKeyTypeHelp: { + string: "Nilai tunggal yang aman biner hingga 512 MB. Cocok untuk nilai cache, counter, flag, dan data terserialisasi sederhana.", + hash: "Peta field-nilai datar. Efisien untuk field individual, tetapi membaca hash besar secara penuh adalah O(N).", + list: "Urutan berurutan (ordered). Operasi di head dan tail efisien; akses acak di tengah bersifat linear terhadap panjang list.", + set: "Kumpulan member unik yang tidak berurutan. Operasi satu member bersifat O(1), sedangkan mencacah atau menggabungkan set besar bersifat linear.", + zset: "Member unik yang diurutkan berdasarkan skor floating-point. Penulisan bersifat O(log N); member dengan skor yang sama diurutkan secara leksikografis.", + stream: "Log event append-only. Consumer group memerlukan XACK dan penanganan entri tertunda (pending-entry); trim stream untuk mengontrol retensi dan memori.", + json: "Dokumen JSON yang dapat dialamatkan dengan path. Memerlukan dukungan RedisJSON/Redis Stack JSON.* dan biasanya memiliki overhead lebih besar daripada String atau Hash.", + }, + createValue: "Nilai", + createMember: "Member", + createField: "Field", + createFieldPlaceholder: "nama", + createScore: "Skor", + createKeyTtl: "TTL (detik)", + createKeyTtlPlaceholder: "detik bulat positif", + createKeyAddEntry: "Tambah entri", + createKeyEntryId: "ID Entri", + createKeyRawMode: "Input mentah", + createKeyEntries: "Entri", + createKeyPartialWrite: "Beberapa entri telah ditulis. Perbaiki kesalahannya dan buat lagi untuk menulis entri yang tersisa.", + createValuePlaceholder: "nilai", + createKeySubmit: "Buat", + createKeyNameRequired: "Masukkan nama key", + renameKey: "Ganti Nama Key", + renameKeyName: "Nama key", + renameKeyNameRequired: "Masukkan nama key", + renameKeySuccess: 'Nama "{oldName}" diganti menjadi "{newName}"', + createFieldRequired: "Masukkan field hash", + createScoreInvalid: "Masukkan skor yang valid", + jsonModuleNotAvailable: "Modul ReJSON tidak dimuat pada server Redis ini", + field: "Field", + fieldRequired: "Masukkan nama field", + valueRequired: "Masukkan nilai", + memberRequired: "Masukkan member", + updateAppliedRefreshFailed: "Perubahan berhasil disimpan, tetapi nilai tidak dapat disegarkan: {message}", + zsetAclCompatibilityWarning: "Perubahan disimpan menggunakan mode kompatibilitas ACL; perubahan skor yang konkuren tidak dapat diperiksa.", + ttlInvalid: "Masukkan TTL yang valid dalam detik (-1 untuk tanpa kedaluwarsa)", + member: "Member", + valuePlaceholder: "nilai", + memberPlaceholder: "member", + fieldPlaceholder: "field", + scorePlaceholder: "skor", + pushAction: "Push", + addAction: "Tambah", + setAction: "Set", + memberDetail: "Detail member", + viewMember: "Lihat nilai lengkap", + copyMember: "Salin member", + copyField: "Salin field", + copyFieldValue: "Salin field + nilai", + copyOptions: "Opsi salin", + copyKeyName: "Salin nama key", + copyKeyPath: "Salin path key", + deleteGroupKeys: "Hapus key yang dimuat", + copied: "Disalin", + copyInsertStatement: "Salin Statement Insert", + copyInsertStatementBinary: "Tidak dapat menghasilkan statement insert untuk data biner", + editMember: "Edit", + jsonView: "Tampilan JSON", + jsonViewRaw: "Mentah", + jsonViewDecoded: "Didekode", + rawContent: "Konten mentah", + wordWrap: "Bungkus kata", + codecNone: "Tidak ada", + codecRowLabel: "Decode", + viewRowLabel: "Lihat", + codecBase64: "Base64", + unicodeJsonView: "JSON Unicode", + codecMismatch: "Tidak dapat mendekode dengan codec yang dipilih; menampilkan konten asli", + decompressedView: "Dideskompresi", + decompressedLoading: "Mendekompresi…", + decompressedFailed: "Tidak dapat mendekompresi dengan format yang dipilih", + decompressedRetryAsDeflate: "Coba lagi sebagai DEFLATE", + decompressedLimitExceeded: "Hasil dekompresi melebihi batas 50 MiB", + gzipBadgeTitle: "Dikompresi Gzip — klik untuk melihat konten yang didekompresi", + formatJson: "Format", + compressJson: "Kompres", + jsonFormatError: "Format JSON tidak valid", + clearHistory: "Bersihkan riwayat perintah", + historyCleared: "Riwayat perintah Redis dibersihkan", + blockedCommand: "Perintah {command} diblokir demi keamanan. Nonaktifkan ikon perisai di bilah alat untuk mengizinkannya.", + pubsub: "Pub/Sub", + pubsubConnected: "Terhubung", + pubsubConnecting: "Menghubungkan...", + pubsubDisconnected: "Terputus", + pubsubConnect: "Hubungkan", + pubsubDisconnect: "Putuskan Sambungan", + pubsubChannels: "Channel", + pubsubChannelPlaceholder: "Nama channel", + pubsubSubscribe: "Subscribe", + pubsubPatterns: "Pola", + pubsubPatternPlaceholder: "Pola (mis. news:*)", + pubsubPsubscribe: "PSubscribe", + pubsubMessages: "Pesan", + pubsubClear: "Bersihkan", + pubsubEmpty: "Belum ada pesan. Subscribe ke channel untuk menerima pesan.", + pubsubPublish: "Publish", + pubsubPublishChannel: "Channel", + pubsubPublishMessage: "Pesan", + pubsubSend: "Kirim", + pubsubPublishFailed: "Publish gagal: {error}", + pubsubWsConnectFailed: "Koneksi WebSocket gagal: {error}", + slowlog: "Slow Log", + slowlogCount: "Jumlah", + slowlogQuery: "Kueri", + slowlogNode: "Node", + slowlogSelectNode: "Pilih node", + slowlogNodeRequired: "Silakan pilih node terlebih dahulu", + slowlogEmpty: "Klik Kueri untuk mengambil entri slow log", + slowlogFetchFailed: "Gagal mengambil slow log: {error}", + slowlogColumnId: "ID", + slowlogColumnTimestamp: "Timestamp", + slowlogColumnDuration: "Durasi (μs)", + slowlogColumnCommand: "Perintah", + slowlogColumnClientAddr: "Klien", + slowlogColumnClientName: "Nama Klien", + slowlogTotal: "{count} entri", + slowlogDetailTitle: "Entri Slow Log #{id}", + dashboard: { + totalMemory: "Total Memori", + usedMemory: "Memori Terpakai", + operations: "Operasi", + hitRatio: "Rasio Hit", + keyCount: "Jumlah Key", + clients: "Klien", + searchIndicators: "Cari indikator...", + node: "Node", + off: "Nonaktif", + refresh: "Segarkan", + noMatchingIndicators: "Tidak ada indikator yang cocok", + noDataAvailable: "Tidak ada data tersedia", + sections: { + server: "Server", + clients: "Klien", + memory: "Memori", + persistence: "Persistence", + stats: "Statistik", + replication: "Replikasi", + cpu: "CPU", + modules: "Modul", + commandstats: "Statistik Perintah", + errorstats: "Statistik Galat", + latencystats: "Statistik Latensi", + cluster: "Cluster", + keyspace: "Keyspace", + }, + }, + }, + mongo: { + documents: "{count} dokumen", + addField: "Tambah Field", + deleteField: "Hapus Field", + field: "Field", + value: "Nilai", + fieldPlaceholder: "Nama field", + emptyCollection: "Koleksi kosong", + selectDocument: "Pilih dokumen", + readonlyId: "_id bersifat hanya baca", + invalidJsonValue: "Sel ini bukan nilai JSON yang valid", + invalidJson: "JSON Tidak Valid", + documentMustBeObject: "JSON dokumen harus berupa objek", + unsupportedJsonNumber: "JSON berisi angka di luar rentang int64 MongoDB", + duplicateJsonKey: "Key JSON duplikat: {field}", + duplicateField: "Nama field duplikat: {field}", + indexExpireAfterSeconds: "Kedaluwarsa setelah (detik)", + indexExpireAfterSecondsPlaceholder: "Tidak pernah", + indexExpireAfterSecondsHint: "Hanya untuk indeks satu field. MongoDB menghapus dokumen setelah tanggal yang diindeks melewati usia ini.", + indexPartialFilter: "Filter parsial", + indexLegacyOptions: "Opsi kompatibilitas", + indexLegacyOptionsHint: "Hanya berguna pada server lama: background diabaikan sejak MongoDB 4.2, dan bucket size berhenti berlaku saat indeks geoHaystack dihapus pada 4.4.", + indexBackground: "Background", + indexBucketSize: "Ukuran bucket", + indexSparse: "Sparse", + indexHidden: "Tersembunyi", + indexNoExpiry: "Tidak pernah", + indexOtherOptions: "Opsi lainnya", + indexPropertiesUnavailable: "Driver MongoDB Legacy tidak dapat melaporkan sparse, kedaluwarsa, background, atau ukuran bucket. Hubungkan dengan driver native untuk melihatnya.", + edit: "Edit", + editModeFields: "Field", + editModeJson: "JSON", + jsonReplaceHint: "Menyimpan JSON akan mengganti seluruh dokumen. Mengubah _id akan membuat dokumen baru dan menghapus yang lama.", + jsonIdRequired: "_id yang valid diperlukan saat mengubah identitas dokumen.", + documentView: "Tampilan Dokumen", + tableView: "Tampilan Tabel", + filterPlaceholder: "Filter...", + sortPlaceholder: "Urutkan...", + import: { + title: "Impor data", + target: "Koleksi target", + readonly: "Koneksi ini hanya baca. Buka kunci penulisan sebelum mengimpor.", + chooseFile: "Pilih file", + fileFilter: "Data MongoDB", + noFile: "Tidak ada file dipilih", + back: "Kembali", + format: "Format", + encoding: "Encoding", + delimiter: "Delimiter", + typeMode: "Mode tipe", + typeString: "Semua string", + typeAuto: "Deteksi otomatis", + typeExtendedJson: "Extended JSON", + columnType: "Tipe untuk {name}", + inferredType: { + string: "String", + boolean: "Boolean", + integer: "Integer", + decimal: "Desimal", + date: "Tanggal", + objectId: "ObjectId", + object: "Objek", + array: "Array", + mixed: "Campuran", + }, + hasHeader: "Baris pertama adalah header", + trim: "Trim nilai", + emptyAsNull: "Sel kosong sebagai null", + recognizeObjectIdHex: "Perlakukan hex 24 karakter sebagai ObjectId", + skipErrorRows: "Lewati baris yang error", + previewing: "Menyegarkan pratinjau…", + estimatedRows: "Perkiraan {count} dokumen", + continue: "Lanjutkan", + confirmAppend: "Dokumen akan ditambahkan (append). Dokumen yang ada tidak akan di-truncate atau di-upsert.", + batchSize: "Ukuran batch", + duplicateIdPolicy: "Nilai _id duplikat akan menghentikan impor. Batch yang sudah di-commit tidak akan di-rollback.", + start: "Impor", + success: "{count} dokumen diimpor", + stillRunning: "Impor masih berjalan. Gunakan Batal untuk menghentikan batch baru.", + legacyInsertUnsupported: "Driver MongoDB Legacy ini tidak dapat menyisipkan dokumen secara massal (bulk). Upgrade atau instal ulang driver MongoDB Legacy.", + legacyCursorInvalid: "Cursor ekspor MongoDB Legacy sudah tidak tersedia lagi. Coba ekspor lagi.", + legacyExportUnsupported: "Driver MongoDB Legacy ini tidak dapat mempertahankan tipe BSON selama ekspor. Upgrade atau instal ulang driver MongoDB Legacy.", + legacyExportStalled: "Driver MongoDB Legacy mengembalikan halaman ekspor yang sama dua kali. Upgrade atau instal ulang driver MongoDB Legacy dan coba ekspor lagi.", + legacyExportMissingId: "Driver MongoDB Legacy mengembalikan dokumen tanpa _id, sehingga ekspor tidak dapat melakukan paging dengan aman.", + rowsRead: "Baris dibaca", + rowsInserted: "Baris disisipkan", + rowsFailed: "Baris gagal", + batchesCommitted: "Batch di-commit", + phase: { + preparing: "Menyiapkan", + parsing: "Parsing", + writing: "Menulis", + done: "Selesai", + }, + }, + insert: { + partialFailure: "Driver MongoDB Legacy menolak {failed} dari {total} dokumen: {message}", + }, + }, + dynamodb: { + tableMetadataUnavailable: "Metadata tabel DynamoDB belum dimuat. Segarkan dan coba lagi.", + keyRequired: "Item DynamoDB memerlukan atribut kunci {key}", + baseTable: "Tabel dasar", + filter: "filter", + sortKey: "sort key", + items: "{count} Item", + index: "Indeks DynamoDB", + keySummary: "Partition key: {partitionKey}; sort key: {sortKey}", + none: "tidak ada", + sortKeyOnly: "Kueri DynamoDB hanya dapat mengurutkan berdasarkan sort key indeks saat ini: {key}", + pageCursorUnavailable: "Cursor halaman DynamoDB tidak tersedia. Muat ulang dari halaman pertama.", + repeatedCursor: "DynamoDB mengembalikan cursor halaman yang berulang. Ekspor dihentikan.", + partialProjectionReadOnly: "Indeks {projection} ini tidak berisi item lengkap. Pengeditan dinonaktifkan untuk mencegah atribut yang tidak diproyeksikan tertimpa.", + exportLimitReached: "Ekspor DynamoDB dihentikan pada {count} item untuk membatasi penggunaan memori dan pembacaan. Atur batas baris ekspor untuk memilih batasan yang berbeda.", + documentDetails: "Tabel DynamoDB: {table}\nKunci item: {id}", + }, + vector: { + collectionFallback: "koleksi", + productCollection: "Koleksi {product}", + browse: "Jelajahi", + search: "Cari", + upsert: "Upsert", + delete: "Hapus", + reset: "Reset", + refresh: "Segarkan", + run: "Jalankan", + apply: "Terapkan", + requestEditor: "Editor permintaan vektor", + operationSuccess: "Operasi selesai. Pratinjau koleksi telah disegarkan.", + vectorLabel: "Vektor", + vectorDimensionRequired: "Dimensi koleksi belum tersedia. Masukkan vektor yang sesuai dengan dimensi koleksi.", + }, + hbase: { + prefix: "Prefix", + exact: "Tepat", + rowKeyPrefix: "Prefix row key", + rowKey: "Row key", + rows: "baris", + schema: "Skema", + writeRow: "Tulis baris", + loadedRows: "{count} baris dimuat", + resultTruncated: "Masih ada baris lainnya", + tableSchema: "Skema: {table}", + rowSaved: "Baris HBase disimpan", + cellsObjectRequired: "cells harus berupa objek JSON", + cellRequired: "Setidaknya satu cell diperlukan", + noColumnFamilies: "Tabel HBase ini tidak memiliki column family", + invalidJsonValue: "Nilai tidak valid untuk {label}; gunakan teks, primitif, atau base64:...", + createTable: "Buat tabel", + create: "Buat", + tableCreated: "Tabel HBase {table} dibuat", + tableDeleted: "Tabel HBase {table} dihapus", + createTableIn: "Buat tabel di {namespace}", + tableName: "Nama tabel", + columnFamiliesPlaceholder: "Column family, dipisahkan koma", + deleteTable: "Hapus tabel", + deleteTableConfirm: "Hapus tabel HBase {table}? Semua baris akan dihapus secara permanen.", + }, + history: { + pendingRollback: "SQL rollback sedang tertunda. Commit untuk menerapkannya atau buang perubahan ini.", + discardRollback: "Buang perubahan rollback", + manualRollbackHint: "SQL rollback menunggu Commit. DDL mungkin tetap ter-commit secara implisit.", + transactionEnded: "Transaksi telah berakhir atau di-rollback. Tidak ada keberhasilan rollback yang tercatat.", + rollbackBeforeClose: "Buang perubahan rollback yang belum di-commit dan tutup riwayat?", + title: "Riwayat", + sources: { all: "Semua", sql: "Kueri SQL", mcp: "Panggilan MCP" }, + refresh: "Segarkan", + mcp: { + legacyResponse: "Catatan lama ini hanya berisi ringkasan. Respons asli tidak dapat dipulihkan. Panggilan yang dibuat dengan layanan MCP yang diperbarui akan mencatat isi respons.", + request: "Parameter permintaan", + response: "Isi respons", + toolSearch: "Filter berdasarkan nama tool MCP...", + allTools: "Semua tool", + }, + search: "Cari riwayat...", + conversationSearch: "Cari percakapan...", + empty: "Belum ada riwayat", + emptyConversationSearch: "Tidak ada percakapan yang cocok dengan pencarian Anda", + emptyFilteredRecent: "Tidak ada catatan yang cocok dalam 200 entri riwayat eksekusi terbaru", + failed: "Gagal", + success: "Berhasil", + restore: "Pulihkan ke editor", + copy: "Salin SQL", + delete: "Hapus", + clear: "Bersihkan Riwayat", + viewDetails: "Lihat detail", + analyzeWithAi: "Analisis dengan AI", + aiAnalyzeNoConnection: "Tidak dapat menganalisis entri riwayat ini karena koneksinya sudah tidak ada.", + aiAnalysisTab: "Analisis Riwayat", + rollback: "Rollback", + rollbackSql: "SQL Rollback", + rollbackAvailable: "Tersedia", + rollbackUnavailable: "Tidak ada SQL rollback", + rollbackConfirm: "Jalankan SQL rollback yang dihasilkan untuk entri riwayat ini?", + rollbackSuccess: "Rollback dijalankan", + rollbackFailed: "Rollback gagal: {message}", + confirmDelete: "Hapus entri riwayat ini?", + confirmClear: "Bersihkan semua riwayat?", + confirmClearSource: "Bersihkan semua riwayat {source}?", + emptyFiltered: "Tidak ada riwayat yang cocok dengan filter saat ini", + loadMore: "Muat lebih banyak", + scope: { + title: "Koneksi dan database", + search: "Cari koneksi atau database...", + reset: "Reset", + allConnections: "Semua koneksi", + current: "Saat ini", + connections: "Koneksi", + databases: "Database", + connectionCount: "{count} koneksi", + databaseCount: "{count} database", + unknownConnection: "Koneksi tidak diketahui", + noOptions: "Tidak ada opsi yang cocok", + }, + filters: { + all: "Semua", + query: "Kueri", + data_change: "Perubahan data", + schema_change: "Perubahan skema", + failed: "Gagal", + mcp_success: "Berhasil", + }, + dateRange: { + title: "Rentang waktu", + label: "Waktu eksekusi:", + start: "Tanggal mulai", + end: "Tanggal selesai", + apply: "Terapkan", + clear: "Bersihkan", + invalid: "Tanggal mulai tidak boleh lebih akhir dari tanggal selesai", + unboundedStart: "Mulai", + unboundedEnd: "Selesai", + }, + kinds: { + query: "Kueri", + data_change: "Perubahan data", + schema_change: "Perubahan skema", + import: "Impor", + transfer: "Transfer", + redis_command: "Perintah Redis", + mcp: "Panggilan MCP", + }, + kindShort: { + query: "SQL", + data_change: "Data", + schema_change: "DDL", + import: "Impor", + transfer: "Pindah", + redis_command: "Redis", + }, + detail: { + mcpTool: "Tool MCP", + kind: "Tipe", + operation: "Operasi", + connection: "Koneksi", + database: "Database", + target: "Target", + time: "Waktu", + duration: "Durasi", + affectedRows: "Baris terdampak", + rollback: "Rollback", + status: "Status", + error: "Galat", + }, + }, + dangerDialog: { + title: "Operasi Berbahaya", + message: "Statement SQL ini dapat mengubah atau menghapus data secara tidak dapat dibatalkan. Apakah Anda yakin ingin menjalankannya?", + redisCommandMessage: "Perintah Redis ini dapat mengubah data dan tidak dapat dibatalkan secara otomatis. Lanjutkan?", + suppressFuturePrompts: "Jangan tanya lagi untuk SQL berbahaya", + wrapLines: "Alihkan bungkus kata", + copyFullText: "Salin teks lengkap", + previewTruncated: "Pratinjau dipotong: {characters} karakter pada {lines} baris dihilangkan. Salin tetap menyertakan teks lengkap.", + deleteMessage: "Operasi hapus ini mungkin tidak dapat dibatalkan. Lanjutkan?", + deleteConfirm: "Konfirmasi Hapus", + deleteRowMessage: "Baris ini akan ditandai untuk dihapus dan dihapus dari database setelah disimpan. Lanjutkan?", + deleteRowsMessage: "{count} baris ini akan ditandai untuk dihapus dan dihapus dari database setelah disimpan. Lanjutkan?", + deleteRowDetails: "Tabel: {table}", + deleteRowDetailsNoTable: "Baris hasil saat ini", + redisKeyDetails: "Key Redis: {key}", + redisHashFieldDetails: "Hash Redis: {key}\nField: {field}", + redisListItemDetails: "List Redis: {key}\nIndeks: {index}", + redisSetMemberDetails: "Set Redis: {key}\nMember: {member}", + mongoDocumentDetails: "Koleksi MongoDB: {collection}\n_id Dokumen: {id}", + mongoFieldDetails: "Field: {field}", + mongoArrayItemDetails: "Indeks item array: {index}", + cancel: "Batal", + cancelRunning: "Batalkan Kueri", + confirm: "Jalankan", + }, + production: { + title: "Lingkungan produksi", + connection: "Koneksi produksi", + enable: "Aktifkan pengaman produksi", + disabledDescription: "Aktifkan ini untuk melindungi semua database atau database yang dipilih.", + namespaceDisabledDescription: "Aktifkan ini untuk melindungi semua namespace atau namespace yang dipilih.", + scope: "Cakupan perlindungan", + allDatabases: "Semua database", + selectedDatabases: "Database terpilih", + allNamespaces: "Semua namespace", + selectedNamespaces: "Namespace terpilih", + singleDatabaseScopeHint: "Tipe database ini hanya mendukung pengaman produksi tingkat koneksi.", + databases: "Database produksi", + namespaces: "Namespace produksi", + connectionDescription: "Setiap database pada koneksi ini menggunakan pengaman produksi.", + namespaceConnectionDescription: "Setiap namespace pada koneksi ini menggunakan pengaman produksi.", + databaseDescription: "Pilih database yang memerlukan pengaman produksi. Pilihan pertama mencakup semua database.", + namespaceDescription: "Pilih namespace yang memerlukan pengaman produksi. Pilihan pertama mencakup semua namespace.", + selectDatabases: "Pilih database produksi", + selectNamespaces: "Pilih namespace produksi", + noDatabasesSelected: "Tidak ada database yang dipilih", + databasesConfiguredCount: "{count} terpilih", + databasesSelectedCount: "{selected}/{total} terpilih", + databasePickerTitle: "Pilih database produksi", + databasePickerDescription: 'Pilih database pada "{connection}" yang memerlukan pengaman produksi.', + databaseSearchPlaceholder: "Cari database...", + databaseSelectionRequired: "Pilih setidaknya satu database.", + databaseLoadFailed: "Tidak dapat memuat database: {message}", + noDatabasesAvailable: "Tidak ada database yang tersedia untuk dipilih.", + namespacePickerTitle: "Pilih namespace produksi", + namespacePickerDescription: 'Pilih namespace pada "{connection}" yang memerlukan pengaman produksi.', + namespaceSearchPlaceholder: "Cari namespace...", + namespaceSelectionRequired: "Pilih setidaknya satu namespace.", + namespaceLoadFailed: "Tidak dapat memuat namespace: {message}", + noNamespacesAvailable: "Tidak ada namespace yang tersedia untuk dipilih.", + retry: "Coba Lagi", + confirmTitle: "Konfirmasi penulisan produksi", + confirmMessage: "Operasi ini mengubah database produksi dan memerlukan konfirmasi eksplisit.", + confirmDetails: "Koneksi: {connection}\nDatabase: {database}\nSumber: {source}", + confirmAction: "Jalankan di produksi", + sourceSqlEditor: "Editor SQL", + sourceMultiDbSql: "Eksekusi SQL multi-database", + sourceDataGrid: "Editor data", + sourceStructure: "Editor struktur", + sourceSqlFile: "Eksekusi file SQL", + sourceObjectBrowser: "Penjelajah objek", + sourceSchemaDiff: "Diff skema", + sourceDataCompare: "Perbandingan data", + sourceExtension: "Pengelola ekstensi", + sourceSidebar: "Pohon objek", + sourceMq: "Antrean pesan", + sourceObjectSource: "Editor sumber objek", + sourceDataGenerate: "Generator data", + sourceQueryHistory: "Rollback riwayat kueri", + sourceAdmin: "Administrasi database", + aiReviewRequired: "SQL produksi telah ditambahkan ke editor. Tinjau dan jalankan secara manual untuk mengonfirmasi.", + }, + readOnlyUnlock: { + confirmTitle: "Buka kunci penulisan", + confirmMessage: "Koneksi ini hanya baca. Penulisan tetap diblokir kecuali Anda membuka kuncinya untuk jangka waktu singkat. Pengaturan hanya-baca yang tersimpan tidak akan dinonaktifkan.", + confirmDetails: "Koneksi: {connection}\nSumber: {source}\nPenulisan akan diizinkan selama durasi yang dipilih, lalu mode hanya-baca akan dilanjutkan secara otomatis.", + confirmAction: "Buka kunci penulisan", + durationLabel: "Izinkan penulisan selama", + durationOneMinute: "1 menit", + durationFiveMinutes: "5 menit", + remaining: "{time} tersisa", + unlockedBadge: "Penulisan terbuka", + lockNow: "Kunci penulisan sekarang", + unlockAction: "Buka kunci penulisan…", + sourceImport: "Impor tabel", + sourceMongoImport: "Impor MongoDB", + sourceTransfer: "Transfer data", + sourceSqlFile: "Eksekusi file SQL", + sourceStatus: "Kontrol hanya-baca", + sourceDataEditor: "Editor data", + }, + sqlParameters: { + title: "Parameter SQL", + description: "Isi nilai untuk placeholder template SQL. DBX akan menggantinya sebelum menjalankan SQL.", + name: "Parameter", + syntax: "Sintaks", + type: "Tipe", + value: "Nilai", + valuePlaceholder: "Masukkan nilai", + collectionValuePlaceholder: "Masukkan array JSON atau nilai yang dipisahkan koma", + preview: "Pratinjau SQL", + execute: "Jalankan", + clearValues: "Bersihkan Nilai", + useRawForAll: "Gunakan SQL Mentah untuk Semua", + ignore: "Abaikan", + kind: { + string: "String", + number: "Angka", + boolean: "Boolean", + null: "NULL", + raw: "SQL Mentah", + }, + }, + transfer: { + title: "Transfer Data", + content: "Isi transfer", + contentStructureAndData: "Struktur dan data", + contentStructureOnly: "Hanya struktur", + contentDataOnly: "Hanya data", + contentStructureOnlyHint: "Hanya membuat struktur tabel dan objek, tanpa data", + contentDataOnlyHint: "Hanya menyalin data ke tabel target yang sudah ada", + objects: "Objek", + searchObjects: "Cari nama objek...", + noObjects: "Tidak ada objek", + bulkSelectObjects: "Input massal", + bulkSelectTitle: "Pilih objek secara massal", + bulkSelectHint: "Tempel nama objek (satu per baris, atau dipisahkan koma, titik koma, atau tab) untuk memilih item yang cocok secara otomatis: huruf besar/kecil dan tanda kutip diabaikan, prefix schema.table didukung.", + bulkSelectPlaceholder: "mis. orders, users, public.payments", + bulkSelectConfirm: "Pilih yang cocok", + bulkSelectMatched: "{count} objek yang cocok terpilih", + bulkSelectUnmatched: "{count} nama tidak cocok: {names}", + noMatchingObjects: "Tidak ada yang cocok", + objectTypeTable: "Tabel", + objectTypeView: "Tampilan", + objectTypeMaterializedView: "Tampilan terwujud", + objectTypeProcedure: "Prosedur", + objectTypeFunction: "Fungsi", + objectTypeTrigger: "Trigger", + objectTypeSequence: "Sekuens", + objectTypeEvent: "Event", + objectDataOnlyDisabled: "Objek selain tabel tidak ditransfer dalam mode hanya-data", + objectCrossFamilyDisabled: "Transfer lintas database hanya mendukung sekuens (DDL biasa; isi kueri tampilan tidak dapat diterjemahkan)", + crossFamilyViewHint: "Transfer tampilan lintas database: pilih juga tabel yang menjadi dependensi tampilan tersebut, atau pastikan tabel itu sudah ada di database target", + objectUnsupportedDisabled: "Database ini tidak mendukung transfer tipe objek ini", + skippedExistingObjects: "Melewati {count} objek yang sudah ada", + targetTableHandling: "Penanganan tabel target", + source: "Sumber", + target: "Target", + sourceConnection: "Koneksi Sumber", + sourceCatalog: "Katalog Sumber", + targetCatalog: "Katalog Target", + selectCatalog: "Pilih katalog...", + searchCatalog: "Cari katalog...", + sourceDatabase: "Database Sumber", + sourceSchema: "Skema Sumber", + swap: "Tukar sumber dan target", + targetConnection: "Koneksi Target", + targetDatabase: "Database Target", + targetSchema: "Skema Target", + tables: "Tabel", + selectAll: "Pilih Semua", + deselectAll: "Batalkan Pilihan Semua", + createTable: "Buat tabel jika belum ada", + transferMode: "Mode transfer", + modeAppend: "Tambahkan (INSERT)", + modeOverwrite: "Timpa (TRUNCATE + INSERT)", + modeUpsert: "Upsert (INSERT atau UPDATE berdasarkan PK)", + targetTableNameCase: "Kapitalisasi nama tabel target", + quoteTargetColumnNames: "Beri tanda kutip pada nama kolom target", + tableNameCasePreserve: "Pertahankan", + tableNameCaseLower: "Huruf kecil", + tableNameCaseUpper: "Huruf besar", + batchSize: "Ukuran batch", + modeRebuild: "Bangun ulang struktur dan data (RENAME + CREATE + INSERT)", + modeKeepExisting: "Pertahankan tabel yang ada", + modeRebuildStructure: "Bangun ulang struktur (RENAME + CREATE)", + rebuildSummary: "Bangun ulang {count} tabel: tabel target yang ada akan diganti namanya menjadi cadangan terlebih dahulu, lalu dibangun ulang dari struktur sumber dan diisi; cadangan dihapus setelah semua langkah berhasil.", + rebuildDanger: "Membangun ulang akan mengganti tabel target yang dipilih, baris yang ada, dan metadata khusus target. Tinjau target sebenarnya, nama cadangan, dan SQL-nya. Setelah cadangan dibersihkan, cadangan tidak dapat digunakan untuk pemulihan.", + rebuildDataOnlyDisabled: "Bangun ulang tidak tersedia untuk transfer hanya-data. Pilih struktur dan data atau hanya struktur.", + rebuildUnsupportedDisabled: "Engine target yang dipilih tidak mendukung pembangunan ulang tabel target.", + rebuildPreviewUnavailable: "Backend tidak menyediakan rencana pembangunan ulang. Transfer belum dimulai; segarkan pratinjau dengan backend yang mendukung pembangunan ulang.", + rebuildMissingTargets: "Beberapa tabel target belum ada dan akan dibuat tanpa cadangan.", + previewFailed: "Tidak dapat menyiapkan transfer: {message}", + start: "Mulai Transfer", + startConfirmTitle: "Konfirmasi transfer", + startConfirmMessage: "Transfer {count} objek terpilih dari {source} ke {target}. Mulai sekarang?", + cancel: "Batal", + progress: "Mentransfer...", + transferring: "Mentransfer {table}...", + completed: "Transfer selesai", + completedWithErrors: "Selesai dengan {count} tabel gagal | Selesai dengan {count} tabel gagal", + failed: "Transfer gagal", + cancelled: "Transfer dibatalkan", + rowsTransferred: "{count} baris ditransfer", + tableProgress: "{current} / {total} tabel", + noSqlConnections: "Tidak ada koneksi SQL yang tersedia", + selectTables: "Pilih tabel untuk ditransfer", + searchTables: "Cari tabel...", + noTables: "Tidak ada tabel", + selectSourceFirst: "Pilih koneksi dan database sumber terlebih dahulu", + tableError: "Tabel {table} gagal: {error}", + overallProgress: "Progres keseluruhan", + dataTransfer: "Transfer Data", + runInBackground: "Jalankan di latar belakang", + backgroundStarted: "Transfer dimulai di latar belakang. Lihat progres di Tugas Latar Belakang.", + newTask: "Transfer baru", + editConfig: "Edit konfigurasi", + retry: "Coba Lagi", + targetTableBusy: "Transfer lain sedang menulis ke tabel target: {tables}", + ownershipTitle: "Konfirmasi kepemilikan", + ownershipMessage: "Database target tidak memiliki pengguna atau peran pemilik berikut: {owners}. Menerapkan kepemilikan asli mungkin gagal.", + ownershipSkipDetails: "Lewati tidak akan menjalankan statement perubahan kepemilikan objek. Sinkronisasi data tabel dan struktur lainnya akan tetap berlanjut.", + ownershipTargetOwner: "Konfirmasi akan menetapkan ulang objek yang pemiliknya tidak ada ke pengguna koneksi target: {owner}.", + ownershipSkip: "Lewati", + ownershipConfirm: "Konfirmasi", + selectConnection: "Pilih koneksi", + selectDatabase: "Pilih database", + selectSchema: "Pilih skema", + searchConnection: "Cari koneksi...", + searchDatabase: "Cari database...", + searchSchema: "Cari skema...", + saveConfig: "Simpan konfigurasi", + saveAsNewTask: "Simpan sebagai tugas", + taskSaved: "Tugas disimpan", + unsavedTitle: "Perubahan belum disimpan", + unsavedMessage: "Konfigurasi saat ini memiliki perubahan yang belum disimpan. Buang perubahan tersebut?", + unsavedDiscard: "Buang", + tasks: { + title: "Tugas transfer", + searchTasks: "Cari tugas...", + newTask: "Tugas baru", + newFolder: "Folder baru", + newSubfolder: "Subfolder baru", + rename: "Ganti Nama", + duplicate: "Duplikat", + delete: "Hapus", + open: "Buka", + moveToFolder: "Pindahkan ke folder", + ungrouped: "Tidak dikelompokkan", + empty: "Tidak ada tugas transfer yang disimpan", + newFolderDefault: "Folder baru", + newTaskDefault: "Tugas transfer baru", + deleteFolderTitle: "Hapus folder", + deleteFolderConfirm: "Hapus “{name}” beserta semua tugas transfer di dalamnya?", + deleteTaskTitle: "Hapus tugas", + deleteTaskConfirm: "Hapus tugas transfer “{name}”?", + nameConflict: "“{name}” sudah ada di lokasi ini", + moveFailed: "Pemindahan gagal: {message}", + saveFailed: "Gagal menyimpan: {message}", + deleteFailed: "Gagal menghapus: {message}", + }, + }, + + tableImport: { + title: "Impor Data Tabel", + minimize: "Perkecil impor", + restoreImport: "Pulihkan tampilan impor", + backgroundWarning: "Baris mungkin muncul saat sedang ditulis. Akses bersamaan ke tabel target dapat menunggu atau gagal karena penguncian database, isolasi transaksi, atau batasan (constraint).", + selectedTasks: "{selected} / {total} item impor dipilih", + selectTask: "Impor {name}", + noTasksSelected: "Pilih minimal satu item untuk diimpor.", + target: "Tabel target", + selectFile: "Pilih File", + changeFile: "Ganti File", + noFileSelected: "Belum ada file dipilih", + sourceFile: "File sumber", + sourceFormat: "Format sumber", + targetMode: "Target", + existingTable: "Tabel yang sudah ada", + createTable: "Buat tabel", + createTableHint: "Simpulkan kolom dari file", + targetTableName: "Nama tabel", + noExistingTarget: "Belum ada tabel dipilih", + searchExistingTables: "Cari tabel...", + loadingTables: "Memuat tabel...", + noTables: "Tidak ada tabel yang tersedia", + targetColumnsTimeout: "Waktu pemuatan kolom tabel target habis. Periksa koneksi dan coba lagi.", + retry: "Coba Lagi", + stepSource: "Sumber", + stepOptions: "Opsi", + stepMapping: "Pemetaan", + stepReview: "Tinjau", + stepExecution: "Jalankan", + formatCsv: "CSV", + formatCsvDescription: "Teks dipisahkan koma", + formatTsv: "TSV", + formatTsvDescription: "Teks dipisahkan tab", + formatDelimited: "Dengan Pemisah Khusus", + formatDelimitedDescription: "Pemisah teks khusus", + formatJson: "JSON", + formatJsonDescription: "Baris berupa objek atau array", + formatExcel: "Excel", + formatExcelDescription: "XLS, XLSX, XLSM", + formatSql: "SQL", + formatSqlDescription: "Pernyataan INSERT dalam skrip SQL", + formatParquet: "Parquet", + formatParquetDescription: "File Parquet untuk DuckDB", + parquetOnlyDuckdb: "Impor Parquet hanya didukung untuk koneksi DuckDB", + previewRows: "Pratinjau baris", + delimiter: "Pemisah", + decimalSeparator: "Pemisah desimal", + encoding: "Pengkodean", + encodingAuto: "Deteksi otomatis", + encodingUtf8: "UTF-8", + encodingGbk: "GBK / GB18030", + encodingUtf16Le: "UTF-16 LE", + encodingUtf16Be: "UTF-16 BE", + encodingDetected: "Terdeteksi: {encoding}", + hasHeader: "Baris pertama adalah header", + titleRow: "Baris judul (0 untuk tidak ada)", + dataStartRow: "Baris awal data", + lastDataRow: "Baris akhir data (0 untuk sampai akhir)", + trimValues: "Pangkas nilai", + emptyStringAsNull: "String kosong sebagai NULL", + emptyStringAsNullHint: "Jika dicentang, bidang kosong diimpor sebagai NULL dan \\N menjadi teks biasa; jika tidak, bidang kosong tetap berupa string kosong dan \\N diimpor sebagai NULL.", + conflictPolicy: "Saat terjadi konflik kunci utama", + conflictError: "Hentikan dengan galat", + skipDuplicateRows: "Lewati baris duplikat", + updateExistingRows: "Perbarui baris yang sudah ada", + updateExistingRequiresExistingTable: "Memperbarui konflik memerlukan tabel target yang sudah ada.", + updateExistingUnsupportedDialect: "Memperbarui konflik tidak didukung untuk database ini.", + updateExistingRequiresPrimaryKey: "Memperbarui konflik memerlukan metadata kunci utama untuk tabel target.", + updateExistingRequiresMappedPrimaryKey: "Petakan setiap kolom kunci utama untuk memperbarui konflik. Belum dipetakan: {columns}", + updateExistingRequiresMappedValue: "Petakan minimal satu kolom non-kunci-utama untuk memperbarui konflik.", + jsonShape: "Baris JSON", + jsonShapeAuto: "Deteksi otomatis", + jsonShapeObjects: "Objek", + jsonShapeArrays: "Array", + sheet: "Sheet", + firstSheet: "Sheet pertama", + loadPreview: "Muat Pratinjau", + reloadPreview: "Muat Ulang Pratinjau", + previewReady: "{rows} baris, {columns} kolom", + previewReadyPartial: "Pratinjau {rows} baris, {columns} kolom; total akan dikonfirmasi saat impor berjalan", + previewPartial: "Pratinjau {rows} baris", + rowsImported: "baris diimpor", + file: "File", + rows: "Baris", + mapped: "Terpetakan", + mapping: "Pemetaan Kolom", + sourceColumn: "Sumber", + targetColumn: "Target", + targetDataType: "Tipe", + createColumns: "Kolom yang akan dibuat", + skipColumn: "Lewati", + preview: "Pratinjau", + mode: "Mode impor", + append: "Tambahkan data", + truncate: "Kosongkan lalu impor", + progress: "Progres", + start: "Mulai Impor", + success: "{count} baris berhasil diimpor", + elapsed: "Waktu berlalu {duration}", + back: "Kembali", + next: "Berikutnya", + truncateWarning: "Baris yang sudah ada di tabel target akan dihapus sebelum impor dimulai.", + requiredUnmapped: "Kolom target yang wajib diisi belum dipetakan: {columns}", + status_idle: "Siap untuk mengimpor", + status_running: "Sedang mengimpor data", + phase_preparing: "Mempersiapkan impor", + phase_detectingEncoding: "Mendeteksi pengkodean teks", + phase_reading: "Membaca file sumber", + phase_writing: "Menulis data", + phase_finalizing: "Menyelesaikan impor", + status_done: "Impor selesai", + status_error: "Impor gagal", + status_cancelled: "Impor dibatalkan", + }, + dataGenerate: { + title: "Pembuatan Data", + target: "Target", + rowCount: "Jumlah baris yang dibuat", + columns: "Kolom", + column: "Kolom", + type: "Tipe", + generator: "Generator", + columnProps: "Properti Kolom", + databaseObjects: "Objek Database", + selectTable: "Pilih tabel dari panel kiri", + saveProfile: "Simpan Profil", + loadProfile: "Muat Profil", + options: "Opsi", + generateOrder: "Urutan Pembuatan", + nextStep: "Berikutnya", + insertSuccess: "{count} baris berhasil disisipkan", + noData: "Belum ada data, silakan atur aturan pembuatan terlebih dahulu", + noResult: "Tidak ada hasil eksekusi", + regenerate: "Buat Ulang", + first50Rows: "Menampilkan 50 baris pertama, total {count} baris", + resultTitle: "Hasil Eksekusi", + successLabel: "{count} berhasil", + failLabel: "{count} gagal", + totalLabel: "/ {count} entri", + copySampleSql: "Salin contoh SQL", + prevStep: "Sebelumnya", + startInsert: "Mulai Sisipkan", + confirm: "Konfirmasi", + back: "Kembali", + reset: "Reset", + selectGenerator: "Pilih generator...", + selectGeneratorHint: "Silakan pilih generator", + preview: "Pratinjau", + noValue: "(tidak ada)", + startDate: "Tanggal Mulai", + endDate: "Tanggal Selesai", + allDay: "Sepanjang hari", + startTime: "Waktu Mulai", + endTime: "Waktu Selesai", + weekday: "Hari Kerja", + all: "Semua", + weekdayOnly: "Hari Kerja Saja", + custom: "Kustom", + values: "Nilai", + min: "Min", + max: "Maks", + increment: "Kenaikan", + cycle: "Ulangi dari awal jika melebihi batas", + includeDefault: "Sertakan DEFAULT", + includeNull: "Sertakan NULL", + unique: "Jadikan unik", + uniqueExhausted: "Tidak dapat membuat nilai unik untuk {table}.{column} dalam {attempts} percobaan. Perluas rentang nilai yang tersedia atau kurangi jumlah baris yang dibuat.", + disableLinks: "Nonaktifkan tautan data antar kolom", + imageMode: "Mode", + generate: "Buat", + fromFolder: "Dari folder", + imageWidth: "Lebar Gambar", + imageHeight: "Tinggi Gambar", + imageFormat: "Format Gambar", + folderPath: "Jalur Folder", + filterByExtension: "Filter berdasarkan ekstensi", + errorContinue: "Lanjutkan jika terjadi galat", + truncateBefore: "Kosongkan tabel sebelum pembuatan", + useTransaction: "Gunakan transaksi", + extendedInsert: "Gunakan INSERT diperluas", + ok: "OK", + noTablesSelected: "Belum ada tabel dipilih", + orderHint: "Gunakan tombol panah untuk mengubah urutan", + language: "Bahasa", + regionLabel: "Wilayah", + formatLabel: "Format", + formatType: "Jenis Format", + typeLabel: "Tipe", + loading: "Memuat...", + regex: "Regex", + rawPattern: "Mode pola mentah", + notSet: "(belum diatur)", + noMatch: "(tidak cocok)", + invalidRegex: "(regex tidak valid)", + noDomain: "(tidak ada domain)", + schema: "Skema", + tableLabel: "Tabel", + columnLabel: "Kolom", + genMode: "Mode Pembuatan", + dateType: "Jenis Tanggal", + yearOffsetRange: "Rentang tahun (selisih dari tahun berjalan)", + numberType: "Jenis Angka", + integer: "Bilangan Bulat", + decimal: "Desimal", + decimalPlaces: "Jumlah angka desimal", + uuidFormat: "Format UUID", + uuidWithHyphens: "Dengan tanda hubung", + uuidNoHyphens: "Tanpa tanda hubung", + includeSeparators: "Sertakan pemisah", + phoneDomestic: "Domestik", + phoneInternational: "Internasional", + charCount: "Jumlah Karakter", + start: "Mulai", + valueList: "Daftar Nilai", + domainList: "Daftar domain", + subdomains: "Subdomain", + tlds: "Domain tingkat atas (TLD)", + extensionType: "Jenis Ekstensi", + extensionList: "Daftar ekstensi:", + availableExtensions: "Ekstensi yang tersedia:", + includeExtension: "Sertakan ekstensi", + includeFileName: "Sertakan nama file", + pathType: "Jenis Jalur", + ipType: "Jenis Alamat IP", + nameFormat: "Format Nama", + transformTo: "Ubah nilai menjadi", + generateOptions: "Opsi Pembuatan", + previewRowCount: "{count} baris", + useKeywords: "Buat dari kata kunci", + weekdayShort: { + sun: "Min", + mon: "Sen", + tue: "Sel", + wed: "Rab", + thu: "Kam", + fri: "Jum", + sat: "Sab", + }, + countries: { + us: "Amerika Serikat", + uk: "Inggris Raya", + cn: "Tiongkok", + jp: "Jepang", + other: "Lainnya", + cnEnglish: "Tiongkok (Bahasa Inggris)", + jpEnglish: "Jepang (Bahasa Inggris)", + }, + cityLanguages: { + native: "Bahasa asli", + english: "Bahasa Inggris", + }, + addressTypes: { + line1: "Alamat baris 1", + line2: "Alamat baris 2", + full: "Alamat lengkap", + }, + nameFormats: { + full: "Nama lengkap", + last: "Hanya nama belakang", + first: "Hanya nama depan", + }, + regionFormats: { + name: "Nama", + code: "Kode", + codeName: "Kode + Nama", + }, + transforms: { + none: "Apa adanya", + upper: "HURUF BESAR", + lower: "huruf kecil", + title: "Huruf Kapital Setiap Kata", + }, + extensionCategories: { + image: "Gambar", + document: "Dokumen", + spreadsheet: "Spreadsheet", + presentation: "Presentasi", + audio: "Audio", + video: "Video", + code: "Kode", + archive: "Arsip", + web: "Web", + database: "Database", + }, + placeholders: { + enumValues: "Satu nilai per baris\npertama\nkedua\nketiga", + subdomains: "Satu subdomain per baris\nauth.\nwww.\napi.", + tlds: "Satu TLD per baris\n.com\n.cn\n.io", + fileExtensions: "Satu ekstensi per baris\npng\njpg\ntxt", + paymentMethods: "Satu metode pembayaran per baris\nKartu Kredit\nPayPal\nApple Pay", + keywords: "Satu kata kunci per baris\nApel\nCeri\nJeruk", + weightUnits: "Satu satuan per baris\ng\nkg\nlb", + }, + genModes: { + random: "Acak", + unique: "Tanpa duplikat", + repeat: "Ulangi setiap nilai", + }, + gen: { + general: "Umum", + personal: "Pribadi", + payment: "Pembayaran", + business: "Bisnis", + location: "Lokasi", + product: "Produk", + computer: "Komputer", + number: "Angka", + datetime: "Tanggal & Waktu", + date: "Tanggal", + time: "Waktu", + sequence: "Urutan", + enum: "Enum", + text: "Teks", + image: "Gambar atau Biner", + foreign_key: "Kunci Asing", + uuid: "UUID", + regex: "Regex", + full_name: "Nama Lengkap", + gender: "Jenis Kelamin", + title: "Gelar", + marital_status: "Status Pernikahan", + phone: "Telepon", + email: "Email", + job_title: "Jabatan", + social_id: "Nomor Identitas Sosial", + payment_method: "Metode Pembayaran", + credit_card_type: "Jenis Kartu Kredit", + credit_card_number: "Nomor Kartu Kredit", + credit_card_date: "Tanggal Kartu Kredit", + company_name: "Nama Perusahaan", + department: "Departemen", + industry: "Industri", + address: "Alamat", + city: "Kota", + region: "Wilayah", + product_name: "Nama Produk", + product_category: "Kategori Produk", + color: "Warna", + size: "Ukuran", + weight_unit: "Satuan Berat", + barcode: "Barcode", + sku: "SKU", + ip_address: "Alamat IP", + mac_address: "Alamat MAC", + file_path: "Jalur File", + file_name: "Nama File", + file_extension: "Ekstensi File", + url: "URL", + hostname: "Nama Host", + id_number: "Nomor Identitas", + }, + idTypes: { + title: "Jenis ID", + customPattern: "Pola Kustom", + customPatternPlaceholder: "mis. ([A-Z]{'{'}2{'}'})-([0-9]{'{'}8{'}'})", + customPatternHint: "Mendukung pola sederhana seperti [A-Z] untuk huruf, [0-9] untuk angka, {'{'}n{'}'} untuk pengulangan, dan tanda hubung", + id_card: "KTP Tiongkok", + passport: "Paspor", + hk_macau_pass: "Izin Hong Kong/Makau", + taiwan_pass: "Izin Taiwan", + uscc: "Kode Kredit Sosial Terpadu", + bank_card: "Kartu Bank", + drivers_license: "SIM", + custom: "Kustom", + }, + insertingTable: "Menulis ke {table} (tabel {index}/{count})", + elapsed: "{seconds} detik berlalu", + samplePreviewNotice: "Menampilkan {shown} baris sampel pertama; semua {count} baris dibuat saat proses penyisipan", + largeRowCountHint: "Jumlah baris besar ({count}); baris dibuat dan disisipkan secara bertahap dan Anda dapat membatalkannya kapan saja", + timeoutSecs: "Batas waktu (detik)", + timeoutHint: "0 berarti tanpa batas waktu; pertahankan 0 atau naikkan untuk volume data besar", + batchRows: "Baris per batch", + batchRowsHint: "Baris yang dibuat dan disisipkan per putaran permintaan; batch yang terlalu besar dipecah secara otomatis", + cancelInsert: "Batalkan penyisipan", + cancelledLabel: "Dibatalkan; baris yang sudah ditulis tetap berada di tabel", + }, + tableToolbox: { + browser: "Pratinjau web", + browserFiltered: "Pratinjau web (hasil saat ini)", + browserSelected: "Pratinjau web (baris terpilih)", + openWith: "Buka dengan", + openXlsx: "Buka sebagai XLSX", + title: "Alat Data", + generateData: "Buat Data", + importData: "Impor Data", + exportData: "Ekspor Data", + generateDataComingSoon: "Segera hadir", + }, + sqlFile: { + manualTransactionHint: "Perubahan menunggu Commit atau Rollback. Galat akan di-rollback. DDL dan COMMIT di dalam file tetap dapat melakukan commit perubahan.", + manualCancelHint: "Pembatalan menunggu pernyataan saat ini selesai, lalu me-rollback perubahan yang belum di-commit.", + pendingTransaction: "Menunggu Commit atau Rollback", + rollbackBeforeClose: "Ada perubahan yang belum di-commit. Rollback dan tutup?", + transactionEnded: "Transaksi telah berakhir atau di-rollback. Jalankan file lagi jika diperlukan.", + restoreScope: "Cakupan pemulihan", + restoreAll: "Semua konten", + restoreSelectedTables: "Tabel terpilih", + restoreTablesOnly: "Hanya memulihkan struktur dan data tabel. Tampilan, rutin, trigger, dan event tidak disertakan. Kunci asing dan trigger yang sudah ada dapat memengaruhi proses pemulihan.", + scanningTables: "Memindai tabel cadangan...", + searchBackupTables: "Cari tabel cadangan...", + selectVisibleTables: "Pilih tabel yang terlihat", + selectedTableCount: "{selected} / {total} tabel dipilih", + noBackupTables: "Tidak ada tabel yang cocok dalam cadangan", + title: "Eksekusi File SQL", + file: "File", + selectSqlFile: "Pilih file SQL", + browse: "Jelajahi", + previewingLines: "Pratinjau {count} baris", + previewingFirstLines: "Pratinjau {count} baris pertama", + tooLargeForEditor: "File SQL ini berukuran {size}, melebihi batas editor sebesar {limit}. Gunakan Eksekusi File SQL untuk memprosesnya sebagai aliran data (stream).", + largeFileExecutionOpened: "File SQL berukuran {size} ini terlalu besar untuk editor. Eksekusi File SQL telah dibuka untuk pemrosesan secara streaming.", + target: "Target", + connection: "Koneksi", + selectConnection: "Pilih koneksi", + database: "Database", + selectDatabase: "Pilih database", + databasePlaceholder: "Nama database", + options: "Opsi", + continueOnError: "Lanjutkan jika terjadi galat", + skipRelationalConstraints: "Nonaktifkan sementara batasan relasional selama impor", + packageParts: "{count} bagian SQL", + runInBackground: "Jalankan di latar belakang", + cancelling: "Membatalkan...", + cancel: "Batal", + execute: "Eksekusi", + statement: "Pernyataan", + succeeded: "Berhasil", + failed: "Gagal", + affectedRows: "Baris terdampak", + currentStatement: "Pernyataan saat ini", + status: { + idle: "Menganggur", + started: "Dimulai", + running: "Berjalan", + statementDone: "Pernyataan selesai", + statementFailed: "Pernyataan gagal", + done: "Selesai", + error: "Galat", + cancelled: "Dibatalkan", + }, + fileProgress: "File {current} dari {total}", + byteProgress: "Progres file", + byteProgressHint: "Berdasarkan byte file yang telah dibaca, bukan sisa waktu eksekusi. Mencapai 100% hanya saat eksekusi selesai. File terkompresi menggunakan byte terkompresi.", + bytesRead: "Terbaca {read}", + bytesReadOfTotal: "Terbaca {read} / {total}", + progressPhase: { + preparing: "Mempersiapkan file SQL", + reading: "Membaca file SQL", + executing: "Mengeksekusi SQL", + }, + fileColumn: "File", + totalFiles: "{count} file", + }, + sqlFileTree: { + title: "File SQL", + storageHelp: "Ini adalah file .sql asli di disk yang dibuka melalui Buka Folder; perubahan disimpan langsung kembali ke file aslinya.", + openFolder: "Buka Folder", + closePanel: "Tutup", + loading: "Memuat...", + noFolder: "Belum ada folder dibuka", + noSqlFiles: "Tidak ditemukan file SQL", + folderAlreadyOpen: "Folder ini sudah terbuka", + removeFolder: "Hapus folder", + openFailed: "Gagal membuka folder: {message}", + loadFailed: "Gagal memuat file SQL: {message}", + desktopOnly: "Fitur ini hanya tersedia di desktop", + refreshFolder: "Segarkan folder", + refreshAll: "Segarkan semua", + refreshed: "Disegarkan", + revealInFileManager: "Tampilkan di file manager", + revealFailed: "Gagal membuka file manager: {message}", + copyPath: "Salin jalur", + pathCopied: "Jalur disalin", + copyFailed: "Gagal menyalin jalur", + openFile: "Buka", + executeSqlFile: "Eksekusi file SQL", + newSqlFile: "File SQL baru", + newSqlFileDescription: "Ekstensi .sql ditambahkan secara otomatis.", + createFile: "Buat", + fileCreated: "File SQL dibuat", + createFailed: "Gagal membuat file SQL: {message}", + renameFile: "Ganti Nama", + renameFileDescription: "Ekstensi .sql ditambahkan secara otomatis.", + fileRenamed: "File SQL diganti namanya", + renameFailed: "Gagal mengganti nama file SQL: {message}", + deleteFile: "Hapus file", + deleteFileConfirm: "Hapus {name}? Tindakan ini tidak dapat dibatalkan.", + fileDeleted: "File SQL dihapus", + deleteFailed: "Gagal menghapus file SQL: {message}", + expandAll: "Perluas semua", + collapseAll: "Ciutkan semua", + filterSettings: "Filter File", + fileFilter: "Filter nama file", + fileFilterPlaceholder: "Filter nama file", + filterInvalid: "Filter file tidak valid, filter sebelumnya tetap dipakai: {message}", + fileFilterHint: "Gunakan pola glob seperti *.sql atau *.sh, atau ekspresi reguler seperti {regex}.", + }, + diff: { + progress: { + loadingObjects: "Membaca objek database sumber dan target...", + loadingSourceDetails: "Membaca struktur tabel database sumber", + loadingTargetDetails: "Membaca struktur tabel database target", + loadingExtraObjects: "Membaca objek database lainnya...", + comparing: "Menganalisis perbedaan skema...", + generating: "Membuat hasil perbandingan...", + next: "Berikutnya: {step}", + nextSourceDetails: "Baca struktur tabel database sumber", + nextTargetDetails: "Baca struktur tabel database target", + nextExtraObjects: "Baca objek database lainnya", + nextComparing: "Analisis perbedaan skema", + nextGenerating: "Buat hasil perbandingan", + nextComplete: "Selesai", + count: "{current} / {total}", + }, + title: "Bandingkan Skema", + source: "Sumber", + target: "Target", + selectConnection: "Pilih koneksi", + selectDatabase: "Pilih database", + selectSchema: "Pilih skema", + connection: "Koneksi", + database: "Database", + schema: "Skema", + recentConfigs: "Konfigurasi Terbaru", + selectRecentConfig: "Pilih konfigurasi terbaru", + ignoreComments: "Abaikan perbedaan komentar", + compare: "Bandingkan", + comparing: "Membandingkan skema...", + noDifferences: "Tidak ditemukan perbedaan", + table: "Tabel", + status: "Status", + details: "Detail", + added: "Ditambahkan", + removed: "Dihapus", + modified: "Diubah", + indexes: "Indeks", + foreignKeys: "Kunci asing", + triggers: "Trigger", + comments: "Komentar", + newTable: "Tabel baru", + dropTable: "Hapus tabel", + generatedSql: "SQL Sinkronisasi", + copySql: "Salin SQL", + executeSync: "Eksekusi Sinkronisasi", + syncSuccess: "Sinkronisasi berhasil dieksekusi", + swap: "Tukar sumber dan target", + syncProgress: "Mengeksekusi: {current}/{total}", + syncSummary: "Berhasil {success}, gagal {failed}", + configSaved: "Konfigurasi disimpan", + configDeleted: "Konfigurasi dihapus", + comparisonObjects: "Bandingkan objek", + searchObjects: "Cari nama objek...", + selectAllObjects: "Pilih semua", + deselectAllObjects: "Batalkan pilihan semua", + objectPickerAll: "Semua", + objectGroupDisabled: "Jenis objek ini tidak disertakan dalam perbandingan.", + noObjects: "Tidak ada objek", + noObjectMatches: "Tidak ada yang cocok", + tableSelection: "Tabel", + chooseTables: "Pilih tabel...", + compareAllTables: "Bandingkan semua tabel", + compareTablesSwitch: "Bandingkan tabel", + tableCompareDisabled: "Perbandingan tabel nonaktif. Aktifkan sakelar untuk menyertakan tabel.", + tableSelectionUnrestricted: "Membandingkan semua tabel (setelah filter regex). Pilih tabel tertentu untuk membatasi perbandingan.", + sourceTables: "Tabel sumber", + routineSelection: "Rutin", + chooseRoutines: "Pilih rutin...", + compareAllRoutines: "Bandingkan semua rutin", + compareRoutinesSwitch: "Bandingkan rutin", + routineCompareDisabled: "Perbandingan rutin nonaktif. Aktifkan sakelar untuk menyertakan prosedur dan fungsi.", + routineSelectionUnrestricted: "Membandingkan semua fungsi dan prosedur. Pilih rutin tertentu untuk membatasi perbandingan.", + routineSelectionTooLarge: "Skema ini memiliki {count} rutin (batas {limit} untuk perbandingan tanpa batasan). Pilih rutin tertentu sebelum membandingkan.", + routineSelectionNeedSource: "Pilih koneksi dan database sumber terlebih dahulu untuk memilih rutin.", + routineSelectionUnsupported: "Perbandingan prosedur/fungsi memerlukan dialek yang sama dan didukung di kedua sisi (MySQL, SQL Server, atau keluarga PostgreSQL).", + routineSameNameMatchingOnly: "Rutin dicocokkan berdasarkan nama yang sama (dan signature). Pemetaan ganti nama manual belum tersedia di rilis ini.", + sourceRoutines: "Rutin sumber", + noRoutines: "Tidak ditemukan rutin", + targetRoutineMatching: "Pencocokan rutin target", + matchedRoutines: "{matched}/{total} rutin cocok", + selectTargetRoutine: "Pilih rutin target", + searchSourceRoutines: "Cari objek...", + searchTargetRoutine: "Cari rutin target...", + noTargetRoutines: "Tidak ada rutin target yang tersedia", + unmatchedRoutineWarning: "{count} rutin sumber terpilih tidak memiliki target dengan nama yang sama", + targetRoutineInUse: "Rutin target ini sudah digunakan oleh rutin sumber lain", + targetRoutine: "Rutin target", + resultTabTables: "Tabel ({count})", + resultTabRoutines: "Rutin ({count})", + nextStepDeployRoutines: "Berikutnya (Tinjau deploy rutin)", + routineSyncDeferredHint: "Sinkronisasi/deploy rutin belum tersedia. Bandingkan definisi di sini dan salin DDL untuk diterapkan secara manual.", + dependencyGraph: "Grafik ketergantungan", + routineDiffPoints: "Perbedaan", + routineDiffStats: "+{added} −{removed} ~{modified}", + selectRoutineToCompare: "Pilih rutin untuk membandingkan definisi", + routinesNotCompared: "Perbandingan rutin nonaktif. Aktifkan sakelar rutin dan bandingkan ulang.", + routineDdlCopied: "DDL disalin", + copySourceDdl: "Salin DDL sumber", + copyTargetDdl: "Salin DDL target", + autoMatchHint: "Tabel target dicocokkan berdasarkan nama yang sama.", + matchedTables: "{matched}/{total} tabel cocok", + missingTargetTables: "Tabel target dengan nama yang sama tidak ditemukan: {tables}", + targetTableMatching: "Pencocokan tabel target", + sourceTable: "Tabel sumber", + targetTable: "Tabel target", + similarity: "Kemiripan", + selectTargetTable: "Pilih tabel target", + searchTargetTable: "Cari tabel target...", + noTargetTables: "Tidak ada tabel target yang tersedia", + tableMatchStatus: { + automatic: "Otomatis", + manual: "Manual", + unmatched: "Tidak cocok", + }, + unmatchedTableWarning: "{count} tabel sumber terpilih tidak memiliki pemetaan target", + targetTableInUse: "Tabel target ini sudah digunakan oleh tabel sumber lain", + sourceObject: "Objek sumber", + targetObject: "Objek target", + operation: "Operasi", + selectedCount: "{selected} dipilih dari {total}", + saveConfig: "Simpan konfigurasi", + loadConfig: "Muat konfigurasi", + options: "Opsi perbandingan", + ddlCompare: "Perbandingan DDL", + deployScript: "Skrip deploy", + deployScriptAll: "Semua skrip deploy", + deployScriptDesc: "Skrip SQL untuk objek yang dipilih", + deployScriptAllDesc: "Skrip SQL untuk semua objek yang dipilih", + copy: "Salin", + execute: "Eksekusi", + executeAll: "Eksekusi semua", + executeSuccess: "Berhasil dieksekusi", + selectObjectToCompare: "Pilih objek untuk melihat perbandingan DDL", + noDdlAvailable: "Tidak ada DDL yang tersedia", + noDeployScript: "Tidak ada skrip deploy", + noDeployScriptAll: "Tidak ada skrip deploy untuk objek yang dipilih", + sourceDdl: "DDL Sumber", + targetDdl: "DDL Target", + objectNotExistsInSource: "Objek ini tidak ada di database sumber", + objectNotExistsInTarget: "Objek ini tidak ada di database target", + nextStepDeploy: "Berikutnya (Tinjau Deploy)", + deployReview: "Tinjau Deploy", + backToResult: "Kembali ke Hasil", + copyScript: "Salin Skrip", + exportSql: "Ekspor .sql", + deployToServer: "Deploy ke Server", + deployConfirmTitle: "Konfirmasi Akhir", + deployConfirmMessage: "Anda akan men-deploy perubahan berikut ke database target", + destructiveSqlDetected: "Terdeteksi {count} operasi yang bersifat destruktif; konfirmasi eksplisit diperlukan", + compatibilityWarnings: "Peringatan Kompatibilitas", + compatibilityWarningsDetected: "Peringatan kompatibilitas: {count}", + targetServer: "Server Target", + dbVersion: "Versi Database", + targetDatabase: "Database Target", + targetSchema: "Skema Target", + useTransaction: "Eksekusi dalam transaksi (rollback otomatis jika gagal)", + confirmDeploy: "Konfirmasi Deploy", + exportSuccess: "Ekspor berhasil", + create: "Buat", + delete: "Hapus", + modify: "Ubah", + cancel: "Batal", + prevStep: "Sebelumnya", + recompare: "Bandingkan lagi", + maximize: "Maksimalkan", + restore: "Pulihkan", + operationLabel: { + modify: "Objek yang akan diubah", + create: "Objek yang akan dibuat", + delete: "Objek yang akan dihapus", + none: "Tidak ada operasi", + }, + objectKindLabel: { + table: "Tabel", + view: "Tampilan", + function: "Fungsi", + sequence: "Sequence", + rule: "Aturan", + owner: "Pemilik", + column: "Kolom", + index: "Indeks", + foreignKey: "Kunci Asing", + trigger: "Trigger", + tableOption: "Opsi tabel", + }, + noObjectsSelected: "Silakan pilih objek untuk di-deploy", + deploySuccess: "Deploy Berhasil", + deployFailed: "Deploy Gagal", + deploySuccessMessage: "Skrip SQL berhasil dieksekusi pada database target", + deployFailedMessage: "Terjadi galat selama eksekusi", + affectedRows: "Baris Terdampak", + executedStatements: "Pernyataan yang Dieksekusi", + serverVersion: "Versi Server", + info: "Info", + connType: "Jenis koneksi", + connName: "Nama koneksi", + host: "Host", + addHost: "Tambah Host", + port: "Port", + copied: "Disalin ke clipboard", + saveConfigPrompt: "Silakan masukkan nama konfigurasi:", + defaultConfigName: "Default", + dependsOn: "bergantung pada", + dependedBy: "digunakan oleh", + close: "Tutup", + searchConnection: "Cari koneksi...", + searchDatabase: "Cari database...", + searchSchema: "Cari skema...", + openFieldMapping: "Pemetaan Bidang", + fieldMapping: { + title: "Pemetaan Jenis Bidang", + sameTypeHint: "Sumber dan target adalah jenis database yang sama. Pemetaan bidang hanya diperlukan saat membandingkan antar jenis database yang berbeda.", + preset: "Preset Bawaan", + selectPreset: "Pilih preset...", + noMappings: "Belum ada pemetaan bidang yang ditentukan", + sourceType: "Jenis Sumber", + targetType: "Jenis Target", + paramStrategy: "Strategi Parameter", + strategyPreserve: "Pertahankan", + strategyStrip: "Hapus", + strategyCustom: "Kustom", + customParamsPlaceholder: "mis. (100)", + addMapping: "Tambah Pemetaan", + autoGenerate: "Buat Otomatis", + import: "Impor", + export: "Ekspor", + done: "Selesai", + importTypeMismatch: "Pemetaan yang diimpor diekspor untuk {src} → {tgt}, tetapi perbandingan saat ini adalah {curSrc} → {curTgt}. Pemetaan jenis mungkin tidak akurat. Tetap lanjutkan?", + importSuccess: "Pemetaan bidang berhasil diimpor", + importError: "Gagal mengimpor pemetaan bidang. Silakan periksa format JSON.", + clearMappings: "Hapus", + staleMappingWarning: "Jenis database telah berubah dari {prevSrc} → {prevTgt} menjadi {curSrc} → {curTgt}. Pemetaan bidang yang ada mungkin tidak valid lagi. Hapus pemetaan ini?", + }, + deployMode: "Deploy", + forwardSql: "SQL Maju", + rollbackSql: "SQL Rollback", + rollbackMode: "Rollback", + deployMixed: "Deployment sebagian selesai. Beberapa pernyataan mungkin sudah diterapkan ({executedCount}/{statementCount}). DDL mungkin tidak bersifat transaksional.", + deployRolledBack: "Semua perubahan telah di-rollback.", + rollbackIncompleteBlocked: "SQL rollback tidak lengkap (ada objek yang hilang). Eksekusi diblokir.", + rollbackIncompleteBanner: "Rollback tidak lengkap — DDL trigger/tabel hilang. Perbaiki objek yang hilang sebelum mengeksekusi.", + deployMixedTitle: "Sebagian Di-deploy", + deployRolledBackTitle: "Di-rollback", + deployMixedWarning: "Beberapa pernyataan mungkin sudah diterapkan sementara yang lain gagal. Database mungkin berada dalam keadaan tidak konsisten. Tinjau log transaksi dan lakukan tindakan perbaikan manual sebelum mencoba lagi.", + }, + rollbackComparison: { + title: "Perbandingan Rollback", + forwardSql: "SQL Maju", + rollbackSql: "SQL Rollback", + }, + schemaDiff: { + optionsTitle: "Opsi Perbandingan", + selectConfig: "Pilih konfigurasi", + newConfigName: "Konfigurasi Baru", + newConfig: "Konfigurasi Baru", + renameConfig: "Ganti Nama Konfigurasi", + duplicateConfig: "Duplikat Konfigurasi", + deleteConfig: "Hapus Konfigurasi", + exportConfig: "Ekspor Konfigurasi", + exportAllConfigs: "Ekspor Semua Konfigurasi", + importConfig: "Impor Konfigurasi", + importFromFile: "Impor dari File", + importFromText: "Impor dari Teks", + importPlaceholder: "Tempel konfigurasi JSON...", + importInvalidJson: "Format JSON tidak valid", + configName: "Nama Konfigurasi", + tableFilter: "Filter tabel", + tableFilterHint: "Mencocokkan nama tabel lengkap dengan regex. Jangan ketik /.../. ^ berarti diawali dengan, $ berarti diakhiri dengan, | berarti atau.", + tableFilterHintShort: "Batasi perbandingan berdasarkan regex nama tabel", + tableFilterHelp: "Bantuan filter tabel", + tableFilterHelpRule: "Mencocokkan nama tabel lengkap. Jangan ketik /.../.", + tableFilterHelpBlank: "Kosongkan sertakan berarti semua tabel. Kosongkan lewati berarti tidak ada pengecualian.", + tableFilterHelpExample: "^user_ berarti diawali dengan user_; _bak$ berarti diakhiri dengan _bak; a|b berarti a atau b. Pisahkan aturan lewati dengan koma; escape koma literal sebagai \\,.", + tableIncludePattern: "Hanya bandingkan tabel yang cocok", + tableIncludePatternPlaceholder: "mis. ^user_", + tableExcludePattern: "Lewati tabel yang cocok", + tableExcludePatternPlaceholder: "Aturan dipisahkan koma, mis. ^im_, ^ib_, log$", + tableFilterPriority: "Jika keduanya cocok", + tableFilterPriorityExclude: "Pengecualian menang", + tableFilterPriorityInclude: "Penyertaan menang", + options: { + objectScopeSection: "Cakupan objek", + tableStructureSection: "Struktur tabel", + behaviorSection: "Perilaku perbandingan", + tables: "Bandingkan tabel", + primaryKeys: "Bandingkan kunci utama", + foreignKeys: "Bandingkan kunci asing", + uniqueKeys: "Bandingkan kunci unik", + checks: "Bandingkan batasan check", + exclusions: "Bandingkan batasan exclusion", + views: "Bandingkan tampilan", + functions: "Bandingkan fungsi", + indexes: "Bandingkan indeks", + sequences: "Bandingkan sequence", + triggers: "Bandingkan trigger", + rules: "Bandingkan aturan", + owners: "Bandingkan pemilik", + cascadeDelete: "Gunakan penghapusan CASCADE", + sequenceLastValues: "Bandingkan nilai terakhir sequence", + compareColumnOrder: "Bandingkan urutan kolom", + compareCharset: "Bandingkan character set dan collation", + ignoreTableNameCase: "Abaikan huruf besar/kecil pada nama tabel", + ignoreColumnNameCase: "Abaikan huruf besar/kecil pada nama kolom", + detectRenames: "Deteksi penggantian nama", + detectTableRenames: "Deteksi penggantian nama tabel", + enableRollback: "Aktifkan rollback", + advancedSection: "Lanjutan", + renameThreshold: "Ambang batas penggantian nama", + compatibilityThreshold: "Ambang batas kompatibilitas", + sourceDialect: "Dialek sumber", + targetDialect: "Dialek target", + batchSection: "Batch", + batchPatterns: "Pola tabel (dipisahkan koma)", + dialectAuto: "otomatis", + }, + }, + tableMultiSelect: { + tables: "Tabel", + selected: "{selected}/{total} dipilih", + search: "Cari tabel...", + selectAll: "Pilih semua", + deselectAll: "Batalkan pilihan semua", + noTables: "Tidak ada tabel yang tersedia", + }, + dataCompare: { + manualTransactionHint: "Perubahan menunggu Commit atau Rollback. Galat akan me-rollback transaksi.", + pendingTransaction: "Menunggu Commit atau Rollback", + rollbackBeforeClose: "Ada perubahan yang belum di-commit. Rollback dan tutup?", + transactionEnded: "Transaksi telah berakhir atau di-rollback. Bandingkan lagi sebelum mencoba kembali.", + title: "Bandingkan Data", + selectTable: "Pilih tabel", + searchTable: "Cari tabel...", + sourceTables: "Tabel sumber", + targetTable: "Tabel target", + searchTables: "Cari tabel...", + selectedTables: "{selected}/{total} dipilih", + selectAllTables: "Pilih semua", + deselectAllTables: "Batalkan pilihan semua", + selectSourceTables: "Pilih koneksi dan database sumber terlebih dahulu, lalu pilih tabel yang akan dibandingkan", + noTables: "Tidak ada tabel yang tersedia untuk dibandingkan", + autoMatchHint: "Mode batch secara otomatis mencocokkan tabel target berdasarkan nama yang sama", + matchedTables: "{matched}/{total} tabel cocok", + missingTargetTables: "Tabel target dengan nama yang sama tidak ditemukan: {tables}", + keyColumns: "Kolom Kunci", + keyColumnsAutoHint: "Kunci utama digunakan secara default; Anda juga dapat memilih kolom lain sebagai kolom pencocok.", + keyColumnsSelectPlaceholder: "Pilih kolom pencocok", + keyColumnsSearch: "Cari kolom...", + keyColumnsEmpty: "Tidak ada kolom yang tersedia", + keyColumnsLoading: "Memuat kolom...", + keyColumnsSelectedCount: "{selected}/{total} kolom dipilih", + keyColumnsPrimaryKeyBadge: "PK", + keyColumnsStatusAuto: "Otomatis", + keyColumnsStatusManual: "Manual", + keyColumnsAutoSummary: "Menggunakan kunci utama secara otomatis: {columns}", + keyColumnsManualHint: "Kolom pencocok yang dipilih secara manual: {columns}", + keyColumnsNoneSelected: "Belum ada kolom dipilih", + keyColumnsNeedsSelection: "Pilih kolom", + keyColumnsNoPrimaryKey: "Tabel ini tidak memiliki kunci utama. Pilih kolom pencocok secara manual.", + keyColumnsResetAuto: "Gunakan kunci utama", + keyColumnsPerTableHint: "Setiap tabel memiliki kolom pencocoknya sendiri; kunci utama digunakan secara default.", + keyColumnsSelectTableHint: "Pilih tabel sumber terlebih dahulu", + keyColumnsTargetMissingHint: "Tidak ada tabel target dengan nama yang sama, sehingga kolom pencocok tidak diperlukan", + rowCounts: "Sumber {source} baris, target {target} baris; perbandingan lengkap selesai", + previewLimitOption: "Pratinjau {count}", + compare: "Bandingkan Data", + recompare: "Bandingkan Lagi", + summary: "Ditambahkan {added}, dihapus {removed}, diubah {modified}", + batchSummary: "Membandingkan {tables} tabel: {different} berbeda, {same} identik, {failed} gagal; ditambahkan {added}, dihapus {removed}, diubah {modified}", + comparingTable: "Membandingkan {current}/{total}: {table}", + keyColumnsInline: "Kolom kunci: {columns}", + selectedInline: "Dipilih {selected}/{total}", + selectedSummary: "Dipilih: ditambahkan {added}, dihapus {removed}, diubah {modified}", + selectAllKind: "Pilih semua {kind}", + clearKind: "Bersihkan {kind}", + clearSelection: "Bersihkan semua pilihan", + showAllRows: "Tampilkan semua {count}", + showLessRows: "Tampilkan lebih sedikit", + remainingRows: "{count} baris lainnya disembunyikan dalam pratinjau", + planningSync: "Memperbarui rencana sinkronisasi...", + noSelectedDifferences: "Tidak ada perbedaan yang dipilih untuk dieksekusi", + planSummary: "Rencana: {inserts} penyisipan, {updates} pembaruan, {deletes} penghapusan, {statements} pernyataan", + statusDifferent: "Berbeda", + statusSame: "Sama", + statusError: "Gagal", + noKeyColumns: "Pilih minimal satu kolom kunci", + missingKeyColumns: "Kolom kunci harus ada di tabel sumber dan target: {columns}", + noCommonColumns: "Tabel sumber dan target tidak memiliki kolom yang sama untuk dibandingkan", + targetTableMissing: "Tabel target tidak ditemukan: {table}", + noComparableTables: "Tidak ditemukan tabel yang dapat dibandingkan. Periksa apakah tabel target dengan nama yang sama ada.", + noDifferences: "Data identik, tidak diperlukan SQL sinkronisasi", + syncSuccess: "Sinkronisasi data berhasil dieksekusi", + truncatedTitle: "Beberapa tabel tidak dibandingkan secara lengkap", + truncatedHint: + "Tabel dengan baris lebih banyak daripada yang dapat dibaca dalam satu kali perbandingan hanya dibandingkan sampai baris pertamanya, sehingga baris yang ditambahkan, diubah, atau dihapus setelah titik itu tidak dilaporkan. Persempit rentang dengan filter dan bandingkan secara bertahap.", + truncatedTable: "{table}: {source} baris sumber, {target} baris target, hanya {budget} baris pertama yang dibandingkan", + truncatedBadge: "Hanya {budget} baris pertama yang dibandingkan", + }, + settings: { + historyRetentionLimit: "Retensi riwayat kueri", + mcpHistoryRetentionLimit: "Retensi riwayat MCP", + mcpHistoryRetentionDescription: "Mengontrol riwayat panggilan MCP secara independen dari riwayat SQL.", + mcpHistoryCleanup: "Bersihkan riwayat MCP sekarang", + mcpHistoryCleanupCompleted: "Berhasil menghapus {count} catatan riwayat MCP.", + mcpHistoryCleanupFailed: "Tidak dapat membersihkan riwayat MCP: {error}", + historyRetentionDescription: "Menurunkan batas akan menghapus catatan lama pada perekaman riwayat kueri berikutnya. Menaikkan batas atau memilih Tanpa Batas tidak memulihkan catatan yang sudah dihapus. Batas ini berlaku untuk semua koneksi dan sumber eksekusi.", + historyRetentionUnlimited: "Tanpa Batas", + historyRetentionLoadFailed: "Tidak dapat memuat retensi riwayat: {error}", + tableOpenSortMode: "Urutan default tabel", + tableDatabaseSortDirection: "Arah urutan default database", + tableLocalSortDirection: "Arah urutan default halaman saat ini", + tableOpenSortDescription: "Untuk tabel yang baru dibuka, pengurutan database menggunakan kunci utama lengkap; pengurutan halaman saat ini menggunakan kolom pertamanya dan hanya baris yang sudah dimuat. Pertahankan perilaku yang ada jika tidak tersedia atau tidak didukung.", + tableSortUnchanged: "Pertahankan perilaku yang ada", + tableSortDatabase: "Pengurutan database", + tableSortLocal: "Pengurutan halaman saat ini", + tableSortAscending: "Naik (ASC)", + tableSortDescending: "Turun (DESC)", + title: "Pengaturan", + searchSettings: "Cari pengaturan", + searchSettingsNoResults: "Tidak ada pengaturan yang cocok", + searchSettingsResults: "Hasil pencarian pengaturan", + clearSettingsSearch: "Hapus pencarian pengaturan", + exitSettingsSearch: "Kembali ke pengaturan", + editorTab: "Editor", + globalConnectTimeout: "Batas waktu koneksi global (detik)", + globalConnectTimeoutDescription: "Digunakan oleh koneksi yang mewarisi pengaturan global.", + globalQueryTimeout: "Batas waktu kueri global (detik)", + globalQueryTimeoutDescription: "Digunakan oleh koneksi yang mewarisi pengaturan global. Atur ke 0 untuk tanpa batas waktu.", + sqlFormatterTab: "Formatter SQL", + sqlFormatterImport: "Impor konfigurasi", + sqlFormatterExport: "Ekspor konfigurasi", + sqlFormatterImportSuccess: "Konfigurasi formatter diimpor.", + sqlFormatterCopyJson: "Salin JSON", + sqlFormatterCopyJsonSuccess: "JSON disalin.", + sqlFormatterCopyJsonFailed: "Gagal menyalin: {message}", + sqlFormatterJsonEditorLoadFailed: "Editor JSON gagal dimuat. Beralih ke input dasar: {message}", + sqlFormatterRestoreDefaults: "Pulihkan default", + sqlFormatterFormMode: "Formulir", + sqlFormatterJsonMode: "JSON", + sqlFormatterKeywordCase: "Huruf kata kunci", + sqlFormatterFunctionCase: "Huruf fungsi", + sqlFormatterDataTypeCase: "Huruf tipe data", + sqlFormatterIdentifierCase: "Huruf identifier", + sqlFormatterCaseUpper: "Huruf besar", + sqlFormatterCaseLower: "Huruf kecil", + sqlFormatterCasePreserve: "Pertahankan", + sqlFormatterIndent: "Indentasi", + sqlFormatterIndentSpaces: "Spasi", + sqlFormatterIndentTabs: "Tab", + sqlFormatterTabWidth: "Lebar tab", + sqlFormatterIndentStyle: "Gaya indentasi", + sqlFormatterIndentStyleStandard: "Standar", + sqlFormatterIndentStyleTabularLeft: "Tabular rata kiri", + sqlFormatterIndentStyleTabularRight: "Tabular rata kanan", + sqlFormatterLogicalOperatorNewline: "Baris baru pada operator logika", + sqlFormatterLogicalBefore: "Sebelum operator", + sqlFormatterLogicalAfter: "Setelah operator", + sqlFormatterLogicalSameLine: "Tetap pada baris yang sama", + sqlFormatterFromClauseLayout: "Tata letak klausa FROM", + sqlFormatterFromNewLine: "Tabel pada baris berikutnya", + sqlFormatterFromSameLine: "FROM dengan tabel pertama", + sqlFormatterExpressionWidth: "Lebar ekspresi", + sqlFormatterLinesBetweenQueries: "Jumlah baris antar kueri", + sqlFormatterPreserveEmptyLines: "Pertahankan baris kosong", + sqlFormatterDenseOperators: "Operator rapat", + sqlFormatterNewlineBeforeSemicolon: "Titik koma pada baris baru", + sqlFormatterAdvancedOptions: "Opsi lanjutan", + sqlFormatterParams: "Parameter", + sqlFormatterParamTypes: "Jenis parameter", + sqlFormatterEditorShortcuts: "Pintasan", + sqlFormatterShortcutAction: "Aksi", + sqlFormatterShortcutEnabled: "Diaktifkan", + sqlFormatterShortcutWindows: "Windows", + sqlFormatterShortcutLinux: "Linux", + sqlFormatterShortcutMacos: "macOS", + sqlFormatterShortcutFind: "Cari", + sqlFormatterShortcutReplace: "Ganti", + sqlFormatterShortcutIndentMore: "Tambah indentasi", + sqlFormatterShortcutIndentLess: "Kurangi indentasi", + sqlFormatterShortcutDuplicateLine: "Duplikat baris saat ini", + sqlFormatterShortcutDeleteLine: "Hapus baris saat ini", + sqlFormatterShortcutMoveLine: "Pindahkan baris", + sqlFormatterShortcutMoveLineUp: "Pindahkan baris ke atas", + sqlFormatterShortcutMoveLineDown: "Pindahkan baris ke bawah", + sqlFormatterShortcutCopyLine: "Salin baris", + sqlFormatterShortcutCopyLineUp: "Salin baris ke atas", + sqlFormatterShortcutCopyLineDown: "Salin baris ke bawah", + sqlFormatterShortcutUndo: "Urungkan", + sqlFormatterShortcutRedo: "Ulangi", + sqlFormatterShortcutSelectAll: "Pilih semua", + sqlFormatterShortcutFormatJson: "Format JSON", + sqlFormatterShortcutApply: "Terapkan konfigurasi", + sqlFormatterConfigErrorInvalidJson: "JSON tidak valid.", + sqlFormatterConfigErrorObject: "Konfigurasi harus berupa objek JSON.", + sqlFormatterConfigErrorVersion: "Versi konfigurasi tidak didukung.", + sqlFormatterConfigErrorFormatter: "Formatter tidak didukung.", + sqlFormatterConfigErrorUnsupportedParams: "Opsi penggantian parameter tidak didukung. Pemformatan SQL tidak akan mengganti placeholder.", + sqlFormatterConfigErrorOptionsObject: "Opsi konfigurasi harus berupa objek JSON.", + sqlFormatterConfigErrorEditorObject: "Konfigurasi editor harus berupa objek JSON.", + sqlFormatterConfigErrorEditorScope: "Cakupan editor tidak didukung.", + sqlFormatterConfigErrorEditorPlatforms: "Platform editor tidak valid.", + sqlFormatterConfigErrorEditorShortcutsArray: "Pintasan editor harus berupa array.", + sqlFormatterConfigErrorEditorShortcutValue: "Pintasan editor tidak valid.", + sqlFormatterConfigErrorUnknownOption: "Opsi formatter tidak dikenal: {option}.", + sqlFormatterConfigErrorInvalidOptionValue: "Nilai tidak valid untuk {option}.", + sqlFormatterConfigErrorUnknownEditorShortcut: "Pintasan editor tidak dikenal: {shortcut}.", + sqlFormatterConfigErrorInvalidEditorShortcut: "Pintasan editor tidak valid: {shortcut}.", + sqlFormatterConfigErrorDuplicateEditorShortcut: "Pintasan editor duplikat: {shortcut}.", + sqlFormatterConfigErrorInvalidConfig: "Konfigurasi formatter tidak valid.", + appearanceTab: "Tampilan", + navigationTab: "Navigasi", + dataTab: "Data", + sqlFileSection: "File SQL", + tunnelsTab: "Tunnel", + tunnelsDescription: "Konfigurasi tunnel SSH / proxy / HTTP yang dapat digunakan kembali. Konfigurasikan sekali, lalu pilih profilnya dari tab tunnel koneksi; perubahan di sini berlaku untuk setiap koneksi yang menggunakan profil tersebut.", + tunnelsEmpty: "Belum ada profil tunnel. Buat satu di sini, lalu pilih di pengaturan tunnel koneksi.", + tunnelsAddSsh: "Tambah SSH", + tunnelsAddProxy: "Tambah Proxy", + tunnelsAddHttp: "Tambah Tunnel HTTP", + tunnelsProfileName: "Nama Profil", + tunnelsProfileNamePlaceholder: "mis. Bastion kantor", + tunnelsDelete: "Hapus", + tunnelsUnnamedProfile: "Profil tanpa nama", + tunnelsSave: "Simpan", + tunnelsReset: "Reset", + tunnelsSaved: "Profil tunnel disimpan", + tunnelsSaveFailed: "Gagal menyimpan profil tunnel: {message}", + tunnelsUnsavedHint: "Ada perubahan yang belum disimpan", + tunnelsTest: "Uji", + tunnelsTesting: "Menguji...", + tunnelsTestSuccess: "Uji tunnel berhasil", + tunnelsTestFailed: "Uji tunnel gagal: {message}", + tunnelsHttpTestSuccess: "Koneksi proxy HTTP CONNECT berhasil ({code})", + tunnelsSocks5TestSuccess: "Koneksi proxy SOCKS5 berhasil", + tunnelsProxyHostRequired: "Host proxy wajib diisi.", + tunnelsProxyPortRequired: "Port proxy wajib diisi.", + tunnelsSshHostRequired: "Host SSH wajib diisi.", + tunnelsHttpTunnelUnsupported: "Uji tunnel tidak didukung untuk profil tunnel HTTP.", + tunnelsProxyTimedOut: "Koneksi proxy waktunya habis ({duration})", + tunnelsProxyConnectFailed: "Gagal terhubung ke proxy: {error}", + tunnelsProxyHandshakeFailed: "Handshake proxy gagal: {error}", + tunnelsProxyHandshakeTimedOut: "Handshake proxy waktunya habis ({duration})", + tunnelsHttpConnectFailed: "CONNECT proxy HTTP gagal: {detail}", + tunnelsSocksInvalidVersion: "Versi proxy SOCKS tidak valid: {version}", + tunnelsSocksAuthTooLong: "Nama pengguna atau kata sandi SOCKS terlalu panjang", + tunnelsSocksAuthFailed: "Autentikasi proxy SOCKS gagal", + tunnelsSocksAuthRejected: "Proxy SOCKS menolak semua metode autentikasi yang didukung", + tunnelsSocksUnsupportedAuth: "Proxy SOCKS memilih metode autentikasi yang tidak didukung: {method}", + tunnelsSocksHostTooLong: "Host proxy terlalu panjang untuk alamat domain SOCKS5", + tunnelsSocksConnectRejected: "Koneksi proxy SOCKS ditolak (kode {code})", + tunnelsSocksUnsupportedAddrType: "Jenis alamat terikat SOCKS tidak didukung: {type}", + redisTab: "Redis", + shortcutsTab: "Pintasan", + snippetsTab: "Snippet", + syncTab: "Sinkronisasi", + aiTab: "AI", + aiSkillRoot: "Direktori skill kustom", + aiSkillRootDesc: "Pindai satu direktori tambahan untuk skill SKILL.md. Direktori ~/.agents/skills selalu dipindai.", + aiSkillRootPath: "Jalur direktori", + aiSkillRootBrowse: "Jelajahi", + mcpTab: "MCP", + jdbcTab: "Driver JDBC", + securityTab: "Keamanan", + aboutTab: "Tentang", + fontFamily: "Jenis Font", + dataGridFontFamily: "Font Grid Hasil", + dataGridFontFamilyDescription: "Berlaku untuk hasil kueri, data tabel, header kolom, dan editor sel inline.", + uiFontFamily: "Font Antarmuka", + uiFontAppDefault: "Default DBX", + uiFontSystemDefault: "Default Sistem", + uiFontFamilyDescription: "Berlaku untuk elemen aplikasi seperti bilah alat, tab, bilah sisi, dialog, dan UI non-editor lainnya.", + selectFont: "Pilih font...", + searchFont: "Cari font...", + loadingFonts: "Memuat font...", + noFontsFound: "Tidak ditemukan font", + useCustomFont: "Gunakan “{font}”", + languageTitle: "Bahasa / 语言", + fontSize: "Ukuran Font", + toolbarTitle: "Bilah Alat", + toolbarHiddenHint: 'Beberapa tombol yang tersembunyi atau meluap akan muncul di dropdown "Lainnya".', + exclusiveRightSidebarPanels: "Tampilkan satu panel bilah sisi kanan dalam satu waktu", + exclusiveRightSidebarPanelsDescription: "Membuka panel bilah sisi kanan akan menutup panel lainnya. Nonaktifkan untuk mengizinkan beberapa panel sekaligus.", + uiScale: "Skala UI", + uiScaleDescription: "Skalakan seluruh UI desktop untuk layar high-DPI. Perubahan berlaku langsung dan dipulihkan pada peluncuran berikutnya.", + theme: "Tema", + cornerStyle: "Gaya sudut", + backgroundImage: "Gambar latar belakang", + backgroundImageDescription: "Atur gambar di belakang seluruh aplikasi. Kartu dan dialog tetap buram demi keterbacaan.", + backgroundImageChoose: "Pilih gambar…", + backgroundImageClear: "Hapus", + backgroundImageNone: "Belum ada gambar diatur", + backgroundImageTransparency: "Transparansi", + backgroundImageDisplayMode: "Mode tampilan", + backgroundImageModeFill: "Isi Penuh", + backgroundImageModeFit: "Sesuaikan", + backgroundImageModeStretch: "Regangkan", + backgroundImageModeCenter: "Tengah", + backgroundImageModeTile: "Ubin", + backgroundImageBlur: "Blur", + backgroundImageMissing: "File gambar tidak lagi ada. Silakan pilih ulang.", + backgroundImageTooLarge: "Gambar melebihi batas ukuran 20 MB.", + backgroundImageSaveFailed: "Gagal menyimpan gambar latar belakang.", + backgroundImageFilterName: "Gambar", + cornerStyleNone: "Persegi", + cornerStyleSmall: "Kecil", + cornerStyleLarge: "Besar", + selectTheme: "Pilih tema...", + colorTheme: "Tema Warna", + selectColorTheme: "Pilih tema warna...", + themePalettePearl: "Putih", + themePaletteMist: "Abu-abu Kabut", + themePaletteGraphite: "Abu-abu Titanium", + themePaletteCobalt: "Biru Kobalt", + themePaletteSage: "Hijau Sage", + themePaletteAmber: "Kuning Hangat", + themePaletteBlush: "Merah Muda Sakura", + themePaletteVscode: "VS Code", + themePaletteIdea: "IDEA", + themePaletteXcode: "Xcode", + themePaletteJetbrains: "JetBrains", + themePaletteCursor: "Cursor", + themePaletteClaude: "Claude Code", + themePaletteCustom: "Kustom", + customUiReset: "Reset ke default", + customUiEditingLight: "Mengedit warna mode terang", + customUiEditingDark: "Mengedit warna mode gelap", + customUiBackground: "Latar Belakang", + customUiForeground: "Latar Depan", + customUiPrimary: "Primer", + customUiBorder: "Batas", + customUiSidebar: "Bilah Sisi", + followAppTheme: "Ikuti tema aplikasi", + appLayout: "Tata Letak Antarmuka", + appLayoutSeparated: "Terpisah modern", + appLayoutSeparatedDescription: "Pemisahan panel yang jelas dengan tab bergaya blok.", + appLayoutClassic: "Klasik ringkas", + appLayoutClassicDescription: "Bilah tab menerus dengan header panel yang ringkas.", + tabLayout: "Perilaku tab saat meluap", + tabLayoutScroll: "Gulir satu baris", + tabLayoutScrollDescription: "Tab bergulir secara horizontal dalam satu baris ketika jumlahnya meluap.", + tabLayoutWrap: "Lipat multi-baris", + tabLayoutWrapDescription: "Tab dilipat ke beberapa baris agar semua terlihat sekaligus.", + colorizeConnectionTabs: "Warnai tab berdasarkan koneksi", + colorizeConnectionTabsDescription: "Gunakan warna yang dikonfigurasi untuk setiap koneksi pada tab editor.", + tabPlacement: "Posisi bilah tab", + tabPlacementTop: "Atas", + tabPlacementBottom: "Bawah", + tabPlacementLeft: "Sisi kiri", + tabPlacementRight: "Sisi kanan", + tabPlacementDescription: "Bilah tab di sisi samping bergulir secara vertikal; pelipatan multi-baris hanya berlaku di atas atau di bawah konten.", + tabOrganization: "Posisi, pengelompokan, pengurutan", + tabGroup: "Kelompokkan berdasarkan", + tabGroupNone: "Tanpa pengelompokan", + tabGroupDatabaseType: "Kelompokkan berdasarkan jenis database", + tabGroupDatabase: "Kelompokkan berdasarkan database", + tabGroupConnection: "Kelompokkan berdasarkan koneksi", + tabSort: "Urutkan berdasarkan", + tabSortManual: "Urutan manual", + tabSortCreated: "Waktu pembuatan", + tabSortTitle: "Nama tab", + tabOrganizationDescription: "Pengelompokan dan pengurutan hanya memengaruhi urutan tampilan. Menyeret tab tersedia dalam urutan manual.", + iconTheme: "Gaya ikon dan logo", + iconThemeDefault: "Default", + iconThemeDefaultDescription: "Gunakan ikon aplikasi DBX berwarna.", + iconThemeBlack: "Hitam", + iconThemeBlackDescription: "Gunakan logo DBX hitam di dalam aplikasi.", + iconThemeBlackDescriptionMac: "Gunakan logo hitam di dalam aplikasi; Dock menggunakan plat hitam, bilah menu mengikuti sistem.", + showTrayIcon: "Tampilkan ikon tray/bilah menu", + showTrayIconDescription: "Jika dinonaktifkan, tidak ada ikon yang ditampilkan, tetapi menutup jendela tetap menyembunyikan DBX di latar belakang seperti sebelumnya.", + quitOnClose: "Keluar saat menutup jendela", + quitOnCloseDescription: "Jika diaktifkan, mengklik tombol tutup akan keluar sepenuhnya dari DBX alih-alih menyembunyikannya ke tray. Anda dapat mengubah ini nanti di pengaturan Tampilan.", + closeActionPromptTitle: "Tutup jendela", + closeActionPromptDescription: "Pilih apa yang terjadi saat Anda mengklik tombol tutup. Anda dapat mengubah ini nanti di Pengaturan > Tampilan.", + closeActionQuit: "Keluar dari DBX", + closeActionMinimize: "Perkecil ke tray", + updateNotificationsEnabled: "Aktifkan pengingat pembaruan", + updateNotificationsEnabledDescription: "Secara otomatis memeriksa pembaruan aplikasi dan komponen serta menampilkan pengingat. Halaman pembaruan mengontrol apakah setiap kategori terpasang secara otomatis.", + autoDownloadUpdates: "Unduh pembaruan aplikasi secara otomatis", + autoDownloadUpdatesDescription: "Pengaturan kompatibilitas lama. Sekarang mencerminkan Perbarui DBX secara otomatis di halaman Pembaruan. Pemasangan tetap memerlukan konfirmasi.", + updatesTab: "Manajemen Pembaruan", + updatesDescription: "Kelola pembaruan aplikasi, driver database, JDBC, server MCP, dan plugin di satu tempat.", + autoUpdateApp: "Perbarui DBX secara otomatis", + autoUpdateAppDescription: "Unduh versi DBX baru di latar belakang. Anda memilih kapan untuk memulai ulang dan memasang.", + autoUpdateDrivers: "Perbarui driver database secara otomatis", + autoUpdateDriversDescription: "Setelah DBX dimulai ulang, pasang pembaruan driver yang tersedia ketika tidak ada koneksi aktif yang menghalanginya.", + autoUpdateJdbc: "Perbarui JDBC secara otomatis", + autoUpdateJdbcDescription: "Setelah DBX dimulai ulang, perbarui runtime plugin JDBC secara otomatis.", + autoUpdateMcp: "Perbarui MCP secara otomatis", + autoUpdateMcpDescription: "Setelah DBX dimulai ulang, perbarui Server MCP DBX terkelola ketika versi yang lebih baru tersedia.", + autoUpdatePlugins: "Perbarui plugin secara otomatis", + autoUpdatePluginsDescription: "Setelah DBX dimulai ulang, pasang pembaruan plugin marketplace yang bertanda tangan.", + autoUpdate: "Pembaruan otomatis", + updateStatusTitle: "Status pembaruan", + updateStatusDescription: "Tinjau status pembaruan setiap komponen dan pilih apakah komponen itu diperbarui secara otomatis.", + checkUpdates: "Periksa sekarang", + updateAll: "Perbarui semua", + updateClient: "DBX", + updateDrivers: "Driver database", + updateJdbc: "JDBC", + updateMcp: "MCP", + updatePlugins: "Plugin", + updateAvailable: "Pembaruan tersedia", + updateCount: "{count} tersedia", + upToDate: "Sudah versi terbaru", + openDriverManager: "Buka Pengelola Driver", + openPluginCenter: "Buka Pusat Plugin", + openMcpSettings: "Pengaturan MCP", + updateRestartHint: "Pembaruan komponen berjalan setelah peningkatan DBX yang berhasil dimulai ulang. Koneksi aktif dapat menunda pembaruan driver sampai aman untuk dilakukan.", + updateDownloadSource: "Sumber unduhan pembaruan", + updateDownloadSourceDescription: "Pilih tempat pembaruan aplikasi, agen database, driver, dan JRE terkelola diunduh. Sumber resmi direkomendasikan; CNB bisa lebih cepat untuk jaringan di Tiongkok daratan.", + updateDownloadSourceOfficial: "Sumber resmi (direkomendasikan)", + updateDownloadSourceCnb: "CNB", + debugLoggingEnabled: "Aktifkan log debug", + debugLoggingEnabledDescription: "Mencatat log diagnostik sisi pengguna lokal yang lebih terperinci saat menangani laporan. Dinonaktifkan secara default.", + metadataCacheMemoryLimit: "Batas cache memori metadata", + metadataCacheMemoryLimitDescription: "Default 64 MB. Usahakan tetap di 256 MB atau kurang jika memungkinkan; batas maksimum adalah 512 MB. Mencakup DDL, kolom, indeks, kunci asing, trigger, dan komentar.", + duckDbWorkerProcessIsolation: "Mode isolasi proses DuckDB (Eksperimental)", + duckDbWorkerProcessIsolationDescription: "Menjalankan kueri DuckDB dalam proses worker terpisah. Jika kueri yang lama tidak merespons pembatalan, DBX dapat menghentikan proses worker untuk melepaskan kunci file database.", + duckDbWorkerMaxProcesses: "Jumlah maksimum worker DuckDB bersamaan", + duckDbWorkerMaxProcessesDescription: "Membatasi jumlah proses worker DuckDB yang dapat dijalankan DBX secara bersamaan. Rentang: 1-16. Default: 4.", + duckDbWorkerProcessIsolationRestartRequired: "Mulai ulang DBX agar perubahan ini berlaku.", + restartDbx: "Mulai Ulang DBX", + restartDbxFailed: "Gagal memulai ulang DBX: {error}", + applyFailed: "Gagal menerapkan pengaturan: {error}", + unsavedChangesCloseTitle: "Perubahan belum disimpan", + unsavedChangesCloseMessage: "Anda memiliki perubahan pengaturan yang belum disimpan dan akan hilang jika Anda menutup sekarang. Buang perubahan ini?", + unsavedChangesCloseCancel: "Lanjutkan mengedit", + unsavedChangesCloseDiscard: "Buang perubahan", + debugLogsCopy: "Salin log", + debugLogsCopied: "Disalin", + debugLogsDownload: "Unduh log", + debugLogsDownloaded: "Terunduh", + debugLogsClear: "Hapus log", + tableStructureSection: "Struktur Tabel", + dataGridDisplay: "Tampilan grid data", + dataGridToolbarLayout: "Tata letak bilah alat grid data", + dataGridToolbarLayoutDescription: "Pilih baris terpisah untuk bilah alat aksi dan kontrol filter/urutkan, atau pulihkan tata letak satu baris aslinya.", + dataGridToolbarLayoutSplit: "Baris terpisah (aksi dan filter dipisah)", + dataGridToolbarLayoutSingle: "Satu baris (tata letak asli)", + dataGridFilterView: "Tampilan filter tabel", + dataGridFilterViewDescription: "Gunakan popover filter, panel kondisi tetap, atau panel kondisi teks ringkas.", + dataGridKeepFilterEditorExpanded: "Perluas editor filter secara default", + dataGridKeepFilterEditorExpandedDescription: "Buka editor dalam keadaan terbuka pada tampilan Kondisi dan Teks. Anda tetap dapat menciutkannya secara manual.", + dataGridFilterViewPreview: "Pratinjau efek", + dataGridFilterViewPreviewExpand: "Perluas pratinjau efek", + dataGridFilterViewPreviewCollapse: "Ciutkan pratinjau efek", + tableOpenPageSize: "Jumlah baris default per halaman saat membuka tabel", + tableOpenPageSizeDescription: "Baris yang dimuat per halaman saat membuka tabel baru. Perubahan sementara tidak memperbarui default ini; hanya memilih “Jadikan default” yang melakukannya.", + queryPageSize: "Jumlah baris default per halaman kueri", + queryPageSizeDescription: "Baris yang dimuat per halaman hasil kueri. Ukuran halaman maksimum yang didukung adalah {max}.", + defaultAutoKeepResults: "Simpan hasil kueri secara otomatis secara default", + defaultAutoKeepResultsDescription: "Menerapkan pengaturan ini memperbarui tab kueri yang terbuka dan mengatur default untuk tab baru. Anda tetap dapat mengaktifkan/menonaktifkannya per tab.", + multiStatementDefaultView: "Tampilan default untuk beberapa pernyataan", + multiStatementDefaultViewDescription: "Pilih apakah batch dengan beberapa pernyataan SQL terbuka pada tabel hasil atau ringkasan eksekusi.", + queryResultMaxRows: "Jumlah baris maksimum hasil kueri", + queryResultMaxRowsEnabled: "Batasi jumlah baris hasil kueri", + queryResultMaxRowsDescription: "Membatasi baris yang dikembalikan oleh kueri, data tabel, prosedur tersimpan, dan pemuatan berkelanjutan.", + queryResultMaxRowsTooSmall: "Harus minimal sebesar ukuran halaman kueri ({pageSize}).", + externalSqlEditorMaxMb: "Ukuran maksimum file editor SQL", + externalSqlEditorMaxMbDescription: "File SQL yang lebih besar dari ini dialihkan ke dialog Eksekusi File SQL secara streaming, bukan ke editor ({min}–{max} MB).", + webSqlFileUploadMaxMb: "Ukuran maksimum unggahan file SQL web", + webSqlFileUploadMaxMbDescription: "Ukuran file SQL terbesar yang diterima server web untuk eksekusi streaming ({min}–{max} MB).", + sqlFileUploadMaxMbSaved: "Ukuran unggahan file SQL web disimpan.", + showColumnCommentsInHeader: "Tampilkan komentar kolom di bawah nama", + showColumnCommentsInHeaderDescription: "Menampilkan komentar kolom tabel langsung di bawah nama kolom grid.", + showColumnTypesInHeader: "Tampilkan tipe kolom di bawah nama", + showColumnTypesInHeaderDescription: "Menampilkan tipe data setiap kolom langsung di bawah nama kolom grid.", + showColumnHeaderTooltips: "Tooltip hover header kolom", + showColumnHeaderTooltipsDescription: "Tampilkan tooltip detail saat mengarahkan kursor ke header kolom grid hasil. Nonaktifkan untuk menghentikan popup hover.", + showResultSourceDatabase: "Sertakan nama database dalam nama result set", + showResultSourceDatabaseDescription: "Jika dinonaktifkan, tab result set hanya menampilkan nama tabel; nama lengkap tetap terlihat di tooltip.", + resultTabNamingMode: "Penamaan tab hasil", + resultTabNamingModeDescription: "Pilih apakah tab hasil menggunakan tabel sumber, label bernomor, atau komentar SQL di atas pernyataan.", + resultTabNamingModeSource: "Database dan tabel", + resultTabNamingModeOrdinal: "Nomor hasil", + resultTabNamingModeComment: "Komentar SQL", + resultTabPreferComments: "Utamakan komentar SQL jika tersedia", + resultTabPreferCommentsDescription: "Gunakan komentar di atas pernyataan SQL jika tersedia; nonaktifkan untuk selalu menggunakan nama tabel sumber.", + dataGridShowTransposeFieldMetadata: "Tampilkan metadata bidang pada tampilan transpos", + dataGridShowTransposeFieldMetadataDescription: "Menampilkan tipe dan komentar kolom yang diaktifkan pada baris terpisah dalam tampilan transpos. Ini menambah tinggi baris.", + colorizeDataGridCellTypes: "Warnai nilai grid data berdasarkan kode", + colorizeDataGridCellTypesDescription: "Gunakan warna teks yang halus dan sesuai tema untuk membedakan nilai berdasarkan tipe data kolomnya.", + dataGridTypeColorScheme: "Skema warna tipe data", + dataGridTypeColorSchemeDescription: "Pilih palet yang digunakan grid untuk mewarnai nilai berdasarkan tipe data.", + dataGridTypeColorSchemeConfigure: "Kustomisasi", + dataGridTypeColorSchemeTitle: "Warna tipe data", + dataGridTypeColorSchemeAuto: "Ikuti tema", + dataGridTypeColorSchemeAutoHint: "Warna bawaan digunakan, beralih otomatis antara palet terang dan gelap.", + dataGridTypeColorSchemeCreateFromCurrent: "Buat skema dari warna ini", + dataGridTypeColorSchemeAdd: "Skema baru", + dataGridTypeColorSchemeDuplicate: "Duplikat skema", + dataGridTypeColorSchemeRename: "Ganti nama skema", + dataGridTypeColorSchemeRenameConfirm: "Ganti Nama", + dataGridTypeColorSchemeDelete: "Hapus skema", + dataGridTypeColorSchemeReset: "Reset warna", + dataGridTypeColorSchemeDone: "Selesai", + dataGridTypeColorSchemeDefaultName: "Skema warna", + dataGridTypeColorSchemeCopySuffix: " Salinan", + dataGridTypeColorInteger: "Bilangan Bulat", + dataGridTypeColorNumeric: "Desimal", + dataGridTypeColorString: "Teks", + dataGridTypeColorBoolean: "Boolean", + dataGridTypeColorTemporal: "Tanggal & waktu", + dataGridTypeColorStructured: "Terstruktur", + dataGridTypeColorIdentifier: "Identifier", + dataGridTypeColorBinary: "Biner", + dataGridTypeColorSpatial: "Spasial", + showIndexIndicatorsInHeader: "Tampilkan indikator indeks di samping nama kolom", + showIndexIndicatorsInHeaderDescription: "Gunakan ikon untuk menunjukkan jenis indeks setiap kolom di header grid: kunci utama (oranye), indeks unik (merah), indeks biasa (hijau).", + compactColumnHeaderActions: "Ringkas alat header kolom", + compactColumnHeaderActionsDescription: "Pindahkan alat formatter dan filter lokal ke menu lainnya agar nama kolom mendapat prioritas.", + dataGridQuickEntry: "Entri cepat grid", + dataGridQuickEntryDescription: "Jika diaktifkan, mengedit sel atau mengisi baris kosong di bawah akan langsung disimpan ke database begitu fokus berpindah. Berguna untuk entri yang sering, tetapi dapat menyebabkan penulisan yang tidak disengaja.", + dataGridAutoTransposeSingleRow: "Transpos otomatis hasil kueri satu baris", + dataGridAutoTransposeSingleRowDescription: "Jika diaktifkan, hasil kueri SQL dengan tepat satu baris dan beberapa kolom akan otomatis beralih ke tampilan transpos.", + dataGridCellDetailButtonVisible: "Tampilkan tombol detail sel", + dataGridCellDetailButtonVisibleDescription: "Tampilkan tombol detail sel saat kursor diarahkan ke suatu sel.", + dataGridCrosshairHighlight: "Sorot baris & kolom crosshair", + dataGridCrosshairHighlightDescription: "Jika diaktifkan, sorot secara samar seluruh baris dan kolom dari sel aktif (seperti Excel). Sel yang difokuskan tetap mempertahankan gaya terpilihnya.", + infiniteScroll: "Pemuatan gulir tak terbatas", + autoCalculateTotalRows: "Hitung total jumlah baris secara otomatis", + autoCalculateTotalRowsDescription: "Jalankan COUNT(*) secara otomatis setelah setiap kueri untuk menampilkan total baris yang cocok. Nonaktif secara default agar kueri besar tetap cepat — hitung sesuai kebutuhan dari footer hasil.", + infiniteScrollDescription: "Memuat batch berikutnya secara otomatis saat menggulir ke bawah.", + dataGridShowWhitespace: "Tampilkan spasi putih", + dataGridShowWhitespaceDescription: "Tampilkan spasi sebagai · dan tab sebagai → pada sel data. Nilai yang disalin dan diedit tetap tidak berubah.", + flatteningMultiLineText: "Meratakan Teks Multi-baris", + flatteningMultiLineTextDescription: "Teks multi-baris digabungkan menjadi tampilan satu baris, dengan pemutus baris ditampilkan sebagai ¶.", + regexMaxMatchCount: "Jumlah maksimum hasil cocok pilih-semua", + regexMaxMatchCountDescription: "Membatasi jumlah pilihan yang dibuat oleh Pilih Semua yang Cocok; penghitungan pencarian tetap lengkap (100–10000).", + tableColumnTemplateFields: "Bidang Preset Tabel Baru", + tableColumnTemplateFieldsDescription: "Pilih jenis database, lalu konfigurasikan tipe bidang preset yang digunakan saat membuat tabel baru.", + tableColumnTemplateAdd: "Tambah Bidang", + tableColumnTemplateColumn: "Bidang", + tableColumnTemplateDatabase: "Database", + tableColumnTemplateType: "Tipe", + tableColumnTemplateLength: "Panjang", + tableColumnTemplateDefault: "Default", + tableColumnTemplateNoPresetType: "Tanpa tipe preset", + tableColumnTemplateRequired: "Wajib diisi", + tableColumnTemplateComment: "Deskripsi", + tableColumnTemplateDragHandle: "Seret untuk mengubah urutan", + sidebarActivation: "Aktivasi bilah sisi", + sidebarActivationSingle: "Klik tunggal", + sidebarActivationSingleDescription: "Buka item bilah sisi yang dapat ditindaklanjuti dengan satu klik.", + sidebarActivationDouble: "Klik ganda", + sidebarActivationDoubleDescription: "Klik tunggal memilih baris; klik ganda membuka item.", + sidebarObjectDisplay: "Tata letak objek bilah sisi", + sidebarObjectDisplayGrouped: "Tampilan lanjutan", + sidebarObjectDisplayGroupedDescription: "Kelompokkan objek berdasarkan tabel, tampilan, prosedur, dan fungsi untuk database dengan lebih banyak jenis objek.", + sidebarObjectDisplaySimple: "Tampilan sederhana", + sidebarObjectDisplaySimpleDescription: "Daftar tabel dan tampilan langsung di bawah setiap database atau skema untuk mengurangi tingkat perantara.", + routineSourceOpenMode: "Mode buka fungsi / prosedur / tampilan", + routineSourceOpenModeQueryTab: "Tab data", + routineSourceOpenModeQueryTabDescription: "Buka sumber pada tab data baru, sama seperti menjalankan kueri SQL.", + routineSourceOpenModeDialog: "Jendela dialog", + routineSourceOpenModeDialogDescription: "Buka sumber pada dialog pop-up untuk melihat dan mengedit dengan cepat.", + autoSelectActiveSidebarNode: "Selalu pilih item yang dibuka", + autoSelectActiveSidebarNodeDescription: "Saat beralih tab, pilih tabel, koleksi, atau file SQL yang terlihat sesuai di bilah sisi.", + sidebarBrowseObjectsOnDatabaseActivation: "Jelajahi objek saat mengaktifkan database", + sidebarBrowseObjectsOnDatabaseActivationDescription: 'Jika diaktifkan, mengaktifkan node database atau skema menggunakan mode klik tunggal atau ganda yang dipilih juga membuka tab "Jelajahi Objek".', + openTabsRestoreMode: "Pulihkan tab saat peluncuran", + openTabsRestoreModeDescription: "Pilih bagaimana DBX memulihkan tab yang terbuka terakhir kali.", + openTabsRestoreModeAll: "Simpan semua tab", + openTabsRestoreModePinned: "Hanya simpan tab yang disematkan", + openTabsRestoreModeNone: "Jangan simpan tab", + openTabsRestoreModeHint: "Tab yang disematkan tetap berada di sisi kiri bilah tab dan cocok sebagai titik masuk yang sering digunakan.", + disconnectTabHandlingMode: "Tab setelah memutuskan koneksi", + disconnectTabHandlingModeDescription: "Pilih bagaimana tab terkait ditangani setelah menutup koneksi atau database.", + disconnectTabHandlingModeCloseTabs: "Tutup semua tab", + disconnectTabHandlingModeCloseTabsDescription: "Tutup semua tab terkait untuk koneksi atau database tersebut.", + disconnectTabHandlingModeKeepTabsClearResults: "Tutup tab objek, simpan tab SQL", + disconnectTabHandlingModeKeepTabsClearResultsDescription: "Tutup tab data tabel, penjelajah objek, dan struktur sambil tetap menyimpan tab kueri SQL dan teks SQL-nya, serta membersihkan status eksekusi dan sesi hasil.", + disconnectTabHandlingModeKeepTabsKeepResults: "Jangan tutup tab terkait", + disconnectTabHandlingModeKeepTabsKeepResultsDescription: "Simpan tab terkait, teks SQL, dan hasil saat ini tanpa pembersihan tambahan.", + deleteConnectionTabHandlingMode: "Tab setelah penghapusan koneksi", + deleteConnectionTabHandlingModeDescription: "Pilih bagaimana tab terkait ditangani setelah koneksi dihapus. Koneksi yang dihapus tidak dapat disambungkan kembali, sehingga tab SQL yang disimpan hanya berfungsi sebagai ruang kerja sementara.", + deleteConnectionTabHandlingModeCloseTabs: "Tutup semua tab", + deleteConnectionTabHandlingModeCloseTabsDescription: "Tutup setiap tab yang termasuk dalam koneksi yang dihapus.", + deleteConnectionTabHandlingModeKeepSqlTabs: "Simpan semua tab SQL", + deleteConnectionTabHandlingModeKeepSqlTabsDescription: "Tutup tab tabel, penjelajah objek, dan struktur sambil tetap menyimpan setiap tab SQL koneksi ini (disematkan atau tidak) beserta teks SQL-nya, dan membersihkan status eksekusi serta hasil.", + deleteConnectionTabHandlingModeKeepPinnedSqlTabs: "Simpan tab SQL yang disematkan", + deleteConnectionTabHandlingModeKeepPinnedSqlTabsDescription: "Hanya simpan tab SQL yang disematkan; tab lainnya, termasuk tab SQL yang tidak disematkan, akan ditutup.", + deleteConnectionTabHandlingModeKeepAllTabs: "Simpan semua tab", + deleteConnectionTabHandlingModeKeepAllTabsDescription: "Jangan tutup apa pun dan simpan teks SQL serta hasil saat ini. Transaksi terbuka akan di-rollback karena koneksinya sudah hilang.", + rememberConnectionDatabaseOnDelete: "Ingat nama koneksi dan database", + rememberConnectionDatabaseOnDeleteDescription: "Ingat nama koneksi dan database saat dihapus, dan pilih kembali secara otomatis saat koneksi dengan nama yang sama dibuat lagi.", + rememberConnectionDatabaseOnDeleteHint: "Jika diaktifkan, membuat koneksi dengan nama dan jenis database yang sama akan mengisi database tersebut terlebih dahulu, dan tab SQL yang disimpan akan dihubungkan ulang secara otomatis ke koneksi baru.", + rememberedConnectionDatabaseCount: "Entri yang diingat: {count}", + clearRememberedConnectionDatabases: "Hapus entri yang diingat", + reuseDataTab: "Gunakan kembali tab data", + reuseDataTabDescription: "Pilih bagaimana membuka tabel menggunakan tab data.", + openDataTabsNextToActive: "Buka tab data baru di sebelah tab aktif", + openDataTabsNextToActiveDescription: "Tempatkan tab data tabel yang baru dibuat tepat setelah tab aktif.", + dataTabReuseAlwaysNew: "Selalu buka tab baru", + dataTabReuseAlwaysNewDescription: "Buat tab data baru setiap kali, bahkan jika tabel tersebut sudah terbuka.", + dataTabReuseSameTable: "Gunakan kembali tabel yang sama", + dataTabReuseSameTableDescription: "Beralih ke tab yang sudah ada untuk tabel yang sama dan buka tabel yang berbeda secara terpisah.", + dataTabReuseActiveTab: "Gunakan kembali tab data aktif", + dataTabReuseActiveTabDescription: "Gunakan kembali tab data aman yang aktif untuk tabel yang berbeda; tab yang dilindungi dibuka secara terpisah.", + sidebarHiddenTablePrefixes: "Awalan nama tabel yang disembunyikan", + sidebarHiddenTablePrefixesDescription: "Satu awalan per baris. Hanya label tabel, tampilan, dan koleksi pada bilah sisi yang dipersingkat; tooltip dan aksi tetap menggunakan nama lengkap.", + sidebarHiddenTablePrefixesPlaceholder: "Contoh:\nODS_\nT8Y2_LONG_", + sidebarCopyTableNameSeparator: "Pemisah saat menyalin nama tabel", + sidebarCopyTableNameSeparatorDescription: "Pemisah yang digunakan saat menyalin atau menyeret beberapa nama tabel atau kolom bilah sisi ke editor SQL.", + sidebarCopyTableNameIncludeSchema: "Sertakan skema dalam nama tabel yang disalin", + sidebarCopyTableNameIncludeSchemaDescription: "Jika diaktifkan, nama tabel yang disalin atau diseret menggunakan bentuk berkualifikasi skema sesuai aturan quoting identifier koneksi aktif.", + sidebarTablePageSize: "Ukuran halaman bilah sisi", + sidebarTablePageSizeDescription: "Jumlah maksimum tabel/objek yang dimuat per halaman pada pohon bilah sisi. Naikkan jika Anda memiliki banyak tabel dan ingin lebih sedikit halaman.", + sidebarTableSearchEnabled: "Aktifkan pencarian tabel dalam database", + sidebarTableSearchEnabledDescription: "Tampilkan kotak pencarian tabel lokal di bawah database, skema, atau grup tabel yang diperluas sehingga setiap cakupan dapat memfilter tabelnya sendiri.", + sidebarSearchOpenedDatabasesOnly: "Cari hanya pada database yang terbuka", + sidebarSearchOpenedDatabasesOnlyDescription: "Pencarian bilah sisi hanya memuat database yang sudah Anda buka pada koneksi aktif (semuanya jika tidak ada yang terbuka). Nonaktifkan untuk mencari semua database pada koneksi tersebut.", + sidebarObjectInfoMode: "Info tambahan bilah sisi", + sidebarObjectInfoModeDescription: + "Pilih komentar, ukuran objek, atau tanpa teks tambahan setelah nama. Komentar dan ukuran saling eksklusif. Total database saat ini mendukung PostgreSQL; ukuran tabel mendukung MySQL, PostgreSQL, GaussDB, KingbaseES, GBase 8a, SQL Server, Oracle, Dameng, dan ClickHouse.", + sidebarObjectInfoModeCommentInline: "Komentar (setelah nama)", + sidebarObjectInfoModeCommentAligned: "Komentar (sejajarkan dengan item sejenis)", + sidebarObjectInfoModeCommentRight: "Komentar (rata kanan)", + sidebarObjectInfoModeSize: "Ukuran objek", + sidebarObjectInfoModeHidden: "Tidak ada", + sidebarAllowHorizontalScroll: "Izinkan gulir horizontal bilah sisi", + sidebarAllowHorizontalScrollDescription: "Tampilkan nama tabel, tampilan, dan koleksi yang panjang secara lengkap dengan mengizinkan gulir horizontal pada bilah sisi.", + sidebarShowTooltips: "Tooltip hover bilah sisi", + sidebarShowTooltipsDescription: "Tampilkan tooltip detail saat mengarahkan kursor ke koneksi dan objek database di bilah sisi. Nonaktifkan untuk menghentikan popup hover.", + sidebarIndent: "Indentasi bilah sisi", + sidebarIndentDescription: "Offset horizontal yang ditambahkan per tingkat kedalaman pohon, dalam piksel.", + sidebarFontSize: "Ukuran font bilah sisi", + sidebarFontSizeDescription: "Ukuran font untuk pohon objek bilah sisi, dalam piksel. Independen dari ukuran font editor.", + snippetsDescription: "Sesuaikan template snippet SQL yang dipicu di editor.", + snippetsPlaceholderHint: "Gunakan {'${number:default text}'} untuk membuat placeholder yang dapat diedit. Placeholder dengan nomor yang sama akan tetap tertaut; contohnya:", + snippetsAdd: "Tambah Snippet", + snippetsLabel: "Label", + snippetsPrefix: "Awalan", + snippetsStatus: "Status", + snippetsEnabled: "Diaktifkan", + snippetsDisabled: "Dinonaktifkan", + snippetsToggle: "Aktifkan atau nonaktifkan snippet", + snippetsBody: "Isi SQL", + snippetsLabelPlaceholder: "mis. select *", + snippetsPrefixPlaceholder: "mis. sel", + snippetsBodyPlaceholder: "SELECT *\nFROM table\nLIMIT 100;", + snippetsRestoreDefaults: "Pulihkan Default", + snippetsAddTitle: "Tambah Snippet", + snippetsEditTitle: "Edit Snippet", + sqlShortcutsTitle: "Aksi Cepat SQL", + sqlShortcutsDescription: "Template bawaan dan aksi SQL kustom setelah memilih nama tabel di editor SQL (bukan Redis/Mongo/ES). Default mencakup N baris pertama dan jumlah baris.", + sqlShortcutsAdd: "Tambah", + sqlShortcutsAddTitle: "Tambah Aksi Cepat SQL", + sqlShortcutsEditTitle: "Edit Aksi Cepat SQL", + sqlShortcutsLabel: "Label", + sqlShortcutsLabelPlaceholder: "mis. Hitung baris", + sqlShortcutsLabelRequired: "Label wajib diisi.", + sqlShortcutsSql: "Template SQL", + sqlShortcutsSqlPlaceholder: "SELECT COUNT(*) FROM ${table}", + sqlShortcutsSqlDatabase: "Edit untuk database", + sqlShortcutsApplySqlToAllSelected: "Terapkan ke semua yang dipilih", + sqlShortcutsApplySqlToAllSelectedDone: "Diterapkan ke semua database yang dipilih.", + sqlShortcutsVariableHint: "Gunakan {token} untuk nama tabel yang dipilih.", + sqlShortcutsEmpty: "Belum ada aksi cepat SQL.", + sqlShortcutsUnbound: "Belum terikat", + sqlShortcutsToggle: "Aktifkan atau nonaktifkan pintasan SQL", + sqlShortcutsDeleteConfirm: 'Hapus pintasan SQL "{name}"?', + sqlShortcutsBuiltinDeleteBlocked: "Template bawaan tidak dapat dihapus. Nonaktifkan saja sebagai gantinya.", + sqlShortcutBuiltinSelectLimit: "Pilih N baris pertama", + sqlShortcutBuiltinCount: "Hitung baris", + sqlShortcutsSource: "Jenis", + sqlShortcutsSourceBuiltin: "Bawaan", + sqlShortcutsSourceCustom: "Kustom", + sqlShortcutsKind: "Jenis aksi", + sqlShortcutsKindTemplate: "Template SQL", + sqlShortcutsKindTemplateHint: "Jalankan SQL Anda sendiri dengan ${table}.", + sqlShortcutsKindSelectLimit: "Pilih N baris pertama", + sqlShortcutsKindSelectLimitHint: "Secara otomatis menyesuaikan LIMIT / TOP / ROWNUM untuk database saat ini.", + sqlShortcutsLimit: "Batas baris", + sqlShortcutsDatabaseTypes: "Database", + sqlShortcutsDatabaseTypesAll: "Semua database", + sqlShortcutsDatabaseTypesSelected: "{count} dipilih", + sqlShortcutsDatabaseTypesHint: + "Biarkan sebagai semua database, atau batasi ke jenis tertentu. Saat dibatasi, berpindah database tetap menyimpan setiap isi secara terpisah; gunakan Terapkan ke semua yang dipilih untuk menyalin template saat ini. Pintasan yang sama dapat diulang di jenis yang tidak tumpang tindih.", + sqlShortcutsPreview: "Pratinjau SQL", + sqlShortcutsPreviewDatabase: "Pratinjau dialek", + sqlShortcutsSelectLimitHint: "Saat dijalankan, SQL dihasilkan untuk dialek koneksi aktif.", + syncWebDavTitle: "Sinkronisasi WebDAV", + syncWebDavDescription: "Unggah atau pulihkan snapshot DBX, termasuk entri pustaka SQL yang tersimpan, dari layanan penyimpanan yang kompatibel dengan WebDAV.", + localBackupTitle: "Pencadangan Lokal", + localBackupDescription: "Ekspor koneksi, SQL tersimpan, dan pengaturan terpilih ke file cadangan DBX, lalu pratinjau dan pulihkan sebagian secara selektif.", + localBackupImport: "Impor cadangan", + localBackupExport: "Ekspor cadangan", + localBackupImportTitle: "Pilih cadangan lokal DBX", + localBackupExportTitle: "Pilih tempat menyimpan cadangan lokal", + localBackupFileType: "Cadangan lokal DBX", + localBackupPathLabel: "Jalur file cadangan", + localBackupPathUnset: "Belum ada lokasi penyimpanan dipilih", + localBackupChoosePath: "Pilih jalur", + localBackupPathRequired: "Pilih lokasi penyimpanan untuk file cadangan terlebih dahulu.", + localBackupPassphraseDescription: "Informasi sensitif dienkripsi dengan kata sandi ini. Masukkan untuk mengekspor atau memulihkan informasi sensitif; kosongkan untuk mengecualikan atau melewatinya. Kata sandi ini tidak disimpan.", + localBackupPassphraseRequired: "Masukkan kata sandi cadangan atau batalkan pilihan informasi sensitif.", + localBackupSecretsPassphraseRequiredHint: "Masukkan kata sandi sinkronisasi data sebelum memilih informasi sensitif terenkripsi.", + localBackupExportSuccess: "{bytes} byte berhasil diekspor ke {path}.", + localBackupImportSuccess: "Konten terpilih berhasil dipulihkan dari {path}.", + syncSelectionUploadTitle: "Pilih konten cadangan", + syncSelectionRestoreTitle: "Pilih konten pemulihan", + syncSelectionBackupNote: "Kredensial sensitif dan data plugin hanya disimpan dalam snapshot terenkripsi.", + syncSelectionRestoreNote: "Konten lokal yang tidak dicentang akan tetap dipertahankan.", + syncSelectionConnections: "Koneksi dan SSH", + syncSelectionConnectionSecrets: "Kata sandi, kata sandi SSH/passphrase kunci, dan kredensial koneksi", + syncSelectionNoConnections: "Tidak ada koneksi", + syncSelectionTunnels: "Profil tunnel bersama", + syncSelectionTunnelSecrets: "Kredensial tunnel", + syncSelectionNoTunnels: "Tidak ada profil tunnel", + syncSelectionSavedSql: "SQL Tersimpan", + syncSelectionFolders: "Folder SQL", + syncSelectionFiles: "File SQL", + syncSelectionPersonalSettings: "Pengaturan pribadi", + syncSelectionDesktopSettings: "Pengaturan desktop", + syncSelectionEditorSettings: "Pengaturan editor", + syncSelectionEncrypted: "Informasi sensitif terenkripsi", + syncSelectionSyncCredentials: "Kredensial layanan sinkronisasi tersimpan", + syncSelectionAiConfigs: "Konfigurasi AI", + syncSelectionAiLocked: "Konfigurasi AI jarak jauh (konten terenkripsi terkunci)", + syncSelectionPluginData: "Data pengaturan plugin", + syncSelectionPluginLocked: "Pengaturan plugin jarak jauh (konten terenkripsi terkunci)", + syncSelectionNoPluginData: "Tidak ada data pengaturan plugin", + syncSelectionNoEncrypted: "Snapshot jarak jauh tidak memiliki informasi sensitif terenkripsi.", + syncSelectionWorkspace: "Tata letak ruang kerja", + syncSelectionSidebar: "Tata letak bilah sisi", + syncSelectionPinned: "Node pohon yang disematkan", + syncSelectionCancel: "Batal", + syncSelectionRestoreAction: "Pulihkan yang dipilih", + syncSelectionUploadAction: "Cadangkan yang dipilih", + syncWebDavWebDescription: "Dalam mode Web, server DBX mengakses WebDAV tanpa batasan CORS browser. Kata sandi tersimpan tetap berada pada instans DBX saat ini.", + syncEndpoint: "URL WebDAV", + syncUsername: "Nama Pengguna", + syncPassword: "Kata Sandi", + syncPasswordPlaceholder: "Masukkan kata sandi", + syncClearSavedPassword: "Hapus kata sandi tersimpan", + syncRememberWebDavPassword: "Ingat kata sandi aplikasi WebDAV", + syncSavedPassword: "(tersimpan)", + syncRememberWebDavPasswordDescription: "Kata sandi dienkripsi dan disimpan hanya pada instans DBX saat ini. Tidak disinkronkan ke WebDAV dan tidak menggantikan kata sandi sinkronisasi.", + syncRemotePath: "Jalur snapshot jarak jauh", + syncRemotePathDescription: "DBX akan membuat folder induk yang hilang saat mengunggah.", + syncSecretNotice: "Secara default, DBX hanya menyinkronkan detail koneksi dan pengaturan. Kata sandi database, kata sandi SSH, kata sandi proxy, token tunnel HTTP, connection string, dan kunci API AI tetap lokal.", + syncSecrets: "Sinkronkan rahasia terenkripsi", + syncSecretsDescription: "Jika diaktifkan, DBX mengenkripsi kata sandi database, kata sandi SSH, kata sandi proxy, token tunnel HTTP, dan kunci API AI sebelum mengunggahnya ke penyimpanan jarak jauh.", + syncSecretsSharedDescription: "Untuk WebDAV, kata sandi ini mengenkripsi kredensial yang disertakan. Snippet GitHub, Gitee, dan GitLab menggunakan enkripsi dan kontrol kredensial independen.", + syncSecretsPassphrase: "Kata sandi sinkronisasi", + syncSecretsPassphraseDescription: "Kata sandi ini hanya digunakan untuk mengenkripsi dan memulihkan data sensitif. Dienkripsi pada instans DBX saat ini; masukkan kembali di instans lain.", + syncTest: "Uji", + syncUpload: "Unggah", + syncDownload: "Unduh", + syncTestSuccess: "Target WebDAV dapat dijangkau.", + syncUploadSuccess: "{bytes} byte berhasil diunggah ke {path}.", + syncAutoUpload: "Unggah snapshot secara otomatis", + syncAutoUploadInterval: "Setiap", + syncAutoUploadMinutes: "menit", + syncAutoUploadDescription: "Berjalan selama DBX terbuka. Unduhan tetap memerlukan konfirmasi manual untuk menghindari penggantian SQL tersimpan lokal secara tidak terduga.", + syncAutoUploadSuccess: "Auto-unggah {bytes} byte ke {path}.", + syncDownloadSuccess: "Berhasil mengunduh dan menerapkan {bytes} byte dari {path}.", + syncSecretsApplied: "Rahasia terenkripsi telah dipulihkan.", + syncSecretsSkipped: "Rahasia terenkripsi ada tetapi tidak dipulihkan.", + syncDownloadConfirm: "Unduh dan terapkan snapshot DBX jarak jauh? Metadata lokal dan SQL tersimpan akan diganti.", + syncSnippetTitle: "Sinkronisasi Snippet", + syncSnippetDescription: "Simpan snapshot DBX yang sama dalam snippet kode privat. Unggahan pertama akan membuat snippet dan menyimpan ID-nya.", + syncSnippetProvider: "Penyedia", + syncSnippetProviderGitee: "Gitee Snippets", + syncGitLabInstance: "URL instans GitLab", + syncGitLabInstanceInvalid: "Masukkan URL HTTP atau HTTPS tanpa kredensial, query, atau fragment.", + syncGitLabHttpWarning: "HTTP mengirim token akses dalam teks biasa. Gunakan hanya pada jaringan internal tepercaya; utamakan HTTPS.", + syncSnippetId: "ID Snippet", + syncSnippetIdPlaceholder: "Kosongkan untuk unggahan pertama", + syncSnippetToken: "Token akses", + syncSnippetRememberToken: "Simpan terenkripsi di perangkat ini", + syncSnippetTokenDescription: "Token GitHub memerlukan izin tulis Gists; token akses pribadi GitLab memerlukan scope api. Token tidak pernah disertakan dalam snapshot sinkronisasi.", + syncSnippetPassphrase: "Kata sandi enkripsi snippet", + syncSnippetPassphraseDescription: "Mengenkripsi seluruh snapshot snippet. Tidak disimpan dan terpisah dari kata sandi untuk kredensial yang disinkronkan.", + syncSnippetIncludeSecrets: "Sertakan kredensial terenkripsi saat mengunggah", + syncSnippetRestoreSecrets: "Pulihkan kredensial terenkripsi saat mengunduh", + syncSnippetTestSuccess: "Target sinkronisasi snippet dapat diakses.", + syncSnippetUploadSuccess: "{bytes} byte berhasil diunggah ke snippet {id}.", + syncSnippetDownloadSuccess: "Berhasil mengunduh dan menerapkan {bytes} byte dari snippet {id}.", + syncSnippetMigrateLegacy: "Migrasikan snippet lama", + syncSnippetMigrateLegacyRequired: "Snippet teks biasa lama ini harus dimigrasikan dengan aksi Migrasikan snippet lama.", + syncSnippetMigrateLegacyConfirm: "DBX akan terlebih dahulu membuat pengganti terenkripsi, lalu menghapus permanen snippet teks biasa lama {id}. Tindakan ini tidak dapat dibatalkan. Lanjutkan?", + syncSnippetMigrateLegacySuccess: "Berhasil membuat snippet terenkripsi {id} dan menghapus snippet teks biasa lama.", + syncSnippetMigrateLegacyCreated: "Snippet terenkripsi {id} berhasil dibuat.", + syncSnippetMigrateLegacyCleanupRequired: "Snippet terenkripsi telah dibuat, tetapi snippet lama {id} tidak dapat dihapus. Hapus secara manual dan ganti kredensial yang terekspos.", + syncSnippetRetryLegacyCleanup: "Coba lagi pembersihan lama", + syncSnippetLegacyCleanupSuccess: "Snippet teks biasa lama {id} berhasil dihapus.", + syncSnippetGuide: "Panduan penyiapan", + apply: "Terapkan", + applyAndClose: "Terapkan dan Tutup", + reset: "Reset", + resetDefaults: "Reset Default", + resetAllDefaults: "Reset Semua Default", + save: "Simpan", + cancel: "Batal", + executeMode: "Mode eksekusi", + executeModeDescription: "Pintasan eksekusi SQL: {shortcut}. Mengontrol apakah secara default menjalankan semua SQL atau pernyataan pada posisi kursor.", + executeModeAll: "Eksekusi semua SQL", + executeModeCurrent: "Eksekusi pernyataan pada kursor", + defaultTransactionMode: "Mode commit transaksi default", + defaultTransactionModeDescription: + 'Mode transaksi yang digunakan secara default saat editor SQL baru dibuka. Dengan "Transaksi manual", editor baru dimulai dalam mode transaksi manual yang memerlukan commit atau rollback manual; dengan "Auto commit", setiap pernyataan di-commit secara otomatis. Hanya berlaku untuk database yang mendukung transaksi.', + defaultTransactionModeAuto: "Auto commit", + defaultTransactionModeManual: "Transaksi manual", + keepExplicitTransactionInAutoCommit: "Pertahankan transaksi eksplisit pada auto-commit", + keepExplicitTransactionInAutoCommitDescription: + "Setelah BEGIN / START TRANSACTION pada tab auto-commit, pertahankan transaksi tetap terbuka sampai Anda menjalankan COMMIT atau ROLLBACK. Jika dinonaktifkan, setiap eksekusi akan me-rollback transaksi eksplisit yang tertinggal terbuka, sehingga transaksi yang tersisa tidak mengunci tampilan baca tab.", + executeAllOnBlankLine: "Eksekusi semua SQL dari baris kosong", + executeAllOnBlankLineDescription: "Dalam mode pernyataan saat ini, eksekusi semua SQL jika tidak ada pernyataan pada posisi kursor. Dinonaktifkan secara default.", + showExecutionTargetPicker: "Tampilkan pemilih target eksekusi", + showExecutionTargetPickerDescription: "Jika diaktifkan, menjalankan tanpa seleksi akan memungkinkan Anda memilih antara pernyataan saat ini dan semua SQL.", + showStatementRunButtons: "Tampilkan tombol jalankan di sisi kiri", + showStatementRunButtonsDescription: "Tampilkan tombol jalankan per pernyataan pada gutter editor SQL. Pintasan keyboard dan eksekusi melalui menu konteks tetap berfungsi saat dinonaktifkan.", + showLineNumbers: "Tampilkan nomor baris", + showLineNumbersDescription: "Tampilkan nomor baris pada gutter editor SQL", + showCurrentStatementFrame: "Tampilkan bingkai pernyataan saat ini", + showCurrentStatementFrameDescription: "Jika diaktifkan, editor SQL menggambar garis bingkai di sekitar pernyataan yang dapat dieksekusi saat ini; jika dinonaktifkan, bingkai disembunyikan.", + showInsertValueHints: "Tampilkan petunjuk kolom nilai INSERT", + showInsertValueHintsDescription: "Jika diaktifkan, editor SQL menampilkan petunjuk nama kolom di samping setiap nilai atau proyeksi SELECT dalam klausa INSERT ... VALUES dan INSERT ... SELECT.", + previewStatementRunButton: "Pratinjau tombol jalankan pernyataan", + wordWrap: "Bungkus kata", + wordWrapDescription: "Bungkus baris panjang dalam lebar editor", + showWhitespace: "Tampilkan spasi putih", + showWhitespaceDescription: "Tampilkan spasi sebagai · dan tab sebagai → di editor SQL. Hanya tampilannya yang berubah, bukan teks SQL-nya.", + ddlOpenMode: "Mode buka DDL", + ddlOpenModeDescription: "Pilih apakah melihat DDL tabel secara default membuka dialog atau tab baru", + ddlOpenModeDialog: "Dialog (default)", + ddlOpenModeTab: "Tab baru", + doubleClickStringSelectionMode: "Klik ganda di dalam string", + doubleClickStringSelectionModeDescription: "Pilih apakah klik ganda di dalam literal string memilih seluruh nilai string atau hanya kata di bawah kursor", + doubleClickStringSelectionModeContent: "Pilih seluruh nilai", + doubleClickStringSelectionModeWord: "Pilih satu kata", + vimMode: "Mode Vim", + vimModeDescription: "Gunakan pengeditan modal bergaya Vim di editor SQL", + autoCloseBrackets: "Tutup kurung otomatis", + restoreSqlFromSourcePaste: "Pulihkan SQL yang ditempel dari kode sumber", + restoreSqlFromSourcePasteDescription: + "Saat menempelkan SQL yang dirangkai dari literal string dalam file sumber Java, JavaScript, Python, atau sejenisnya (tanda kutip, tanda plus, baris baru yang di-escape), pulihkan menjadi SQL polos. Hanya penggabungan yang jelas yang ditulis ulang; selain itu ditempel apa adanya.", + autoCloseBracketsDescription: "Secara otomatis menyisipkan kurung dan tanda kutip penutup saat mengetik yang pembuka", + sqlCompletionSection: "Pelengkapan SQL", + insertSpaceAfterCompletion: "Sisipkan spasi setelah pelengkapan", + insertSpaceAfterCompletionDescription: "Tambahkan spasi setelah menerima pelengkapan kata kunci, tabel, atau kolom jika karakter berikutnya memungkinkan", + sortCompletionColumnsAlphabetically: "Urutkan kolom pelengkapan secara alfabet", + sortCompletionColumnsAlphabeticallyDescription: "Nonaktifkan untuk mempertahankan bidang tabel dalam urutan database aslinya", + selectFirstCompletionOnOpen: "Pilih kandidat pertama secara otomatis", + selectFirstCompletionOnOpenDescription: "Jika diaktifkan, kandidat pertama dipilih saat daftar terbuka, dan Enter atau Tab menerimanya. Jika dinonaktifkan, Enter menyisipkan baris baru dan Tab menerima kandidat pertama.", + completionTriggerMode: "Mode pemicu pelengkapan SQL", + completionTriggerModeDescription: "Pilih bagaimana kandidat pelengkapan SQL ditampilkan.", + completionTriggerModeManual: "Hanya manual", + completionTriggerModeManualDescription: "Tampilkan kandidat hanya saat menggunakan pintasan pelengkapan {shortcut}.", + completionTriggerModeRequirePrefix: "Awalan identifier yang diketik", + completionTriggerModeRequirePrefixDescription: "Tampilkan kandidat setelah minimal satu karakter identifier diketik.", + completionTriggerModePositional: "Posisi cerdas", + completionTriggerModePositionalDescription: "Tampilkan kandidat secara otomatis berdasarkan posisi sintaks SQL saat ini.", + sqlSemanticDiagnosticsEnabled: "Diagnostik semantik SQL", + sqlSemanticDiagnosticsEnabledDescription: "Jika diaktifkan, editor melaporkan masalah semantik seperti tabel dan kolom yang tidak dikenal. Nonaktifkan untuk mengurangi pemeriksaan parsing dan metadata pada SQL besar.", + confirmDangerousSqlExecution: "Konfirmasi sebelum operasi berbahaya", + confirmDangerousSqlExecutionDescription: "Jika dinonaktifkan, SQL berbahaya serta penghapusan baris tabel atau dokumen dijalankan tanpa dialog peringatan.", + continueOnErrorOnBatch: "Lanjutkan jika Terjadi Galat", + continueOnErrorOnBatchDescription: "Jika diaktifkan, eksekusi multi-pernyataan tetap berlanjut setelah galat alih-alih berhenti pada kegagalan pertama.", + confirmUnsavedSqlClose: "Konfirmasi sebelum menutup SQL yang belum disimpan", + confirmUnsavedSqlCloseDescription: "Jika dinonaktifkan, tab SQL dengan perubahan yang belum disimpan akan ditutup atau keluar tanpa dialog konfirmasi simpan.", + appCloseUnsavedTabsMode: "SQL belum disimpan saat keluar", + appCloseUnsavedTabsModeDescription: "Pilih apa yang terjadi saat keluar dari DBX sementara tab SQL memiliki perubahan yang belum disimpan.", + appCloseUnsavedTabsModePrompt: "Tanyakan apakah akan disimpan", + appCloseUnsavedTabsModeKeepDrafts: "Keluar dan simpan draf", + appCloseUnsavedTabsModeHint: 'Draf disimpan sebagai tab yang belum tersimpan dan dipulihkan saat Anda berikutnya memulai DBX. Ini memerlukan "Pulihkan tab saat peluncuran" tidak diatur ke "Jangan simpan tab".', + appCloseDraftPersistFailed: "DBX tidak dapat menyimpan draf tab yang terbuka, sehingga proses keluar dibatalkan. Periksa ruang disk dan izin file, lalu coba lagi. Detail: {message}", + savedSqlOpenTarget: "Target default untuk SQL tersimpan", + savedSqlOpenTargetSaved: "Target tersimpan", + savedSqlOpenTargetSavedDescription: "Gunakan koneksi, database, dan skema yang tersimpan bersama file SQL.", + savedSqlOpenTargetCurrent: "Tab saat ini", + savedSqlOpenTargetCurrentDescription: "Gunakan koneksi, database, skema, dan katalog tab aktif jika tersedia; jika tidak, gunakan target tersimpan.", + prefillNewQueryWithSelect: "Isi awal kueri baru dengan SELECT *", + prefillNewQueryWithSelectDescription: "Saat membuat kueri baru, isi awal editor dengan SELECT * FROM berdasarkan tab tabel aktif atau tabel yang dipilih di bilah sisi.", + generateSqlIncludeDatabaseName: "Sertakan nama database dalam SQL yang dihasilkan", + generateSqlIncludeDatabaseNameDescription: "Jika didukung oleh database, SQL tabel yang dihasilkan menggunakan nama berkualifikasi (database.schema.table pada SQL Server) alih-alih hanya nama tabel.", + generateSqlQuoteIdentifiers: "Beri tanda kutip pada identifier di SQL yang dihasilkan", + generateSqlQuoteIdentifiersDescription: "Jika dinonaktifkan, referensi tabel kueri baru menghilangkan tanda kutip khusus dialek. Kata yang dicadangkan, karakter khusus, dan nama case-sensitive mungkin memerlukan tanda kutip agar dapat berjalan.", + formatSqlOnSqlFileSave: "Format SQL saat menyimpan file SQL", + formatSqlOnSqlFileSaveDescription: "Secara otomatis memformat SQL saat menyimpan file SQL, termasuk file pustaka SQL tersimpan dan kueri yang disimpan sebagai file .sql.", + clickTableNavigationTarget: "Ctrl+Klik Tabel Membuka DDL", + clickTableNavigationTargetDescription: "Jika diaktifkan, Ctrl/Cmd+klik pada nama tabel membuka editor struktur tabel (DDL). Jika dinonaktifkan, membuka tampilan data tabel.", + showTableDdlHoverPreview: "Tampilkan DDL tabel saat hover", + showTableDdlHoverPreviewDescription: "Tampilkan pratinjau DDL saat kursor diarahkan ke nama tabel di editor SQL.", + tableHoverLookupMode: "Cakupan pencarian hover tabel", + tableHoverLookupModeDescription: "Bagaimana nama tabel tanpa kualifikasi diselesaikan saat hover atau Ctrl/Cmd+klik di editor SQL.", + tableHoverLookupModeCurrent: "Hanya skema saat ini", + tableHoverLookupModeFallback: "Skema saat ini, lalu semua skema", + tableHoverLookupModeAlways: "Semua skema terlebih dahulu", + tableHoverLookupModeCurrentDescription: "Hanya mencari tabel pada skema yang dipilih di bilah alat.", + tableHoverLookupModeFallbackDescription: "Coba skema terpilih terlebih dahulu, lalu cari skema lain berdasarkan nama tabel jika tidak ditemukan.", + tableHoverLookupModeAlwaysDescription: "Cari semua skema berdasarkan nama tabel terlebih dahulu. Pilih ini saat menulis prosedur lintas skema.", + sqlVariableSyntax: "Substitusi variabel & placeholder SQL", + sqlVariableSyntaxDescription: "Pilih sintaks variabel dan placeholder mana yang disubstitusi DBX sebelum menjalankan SQL, per jenis database. Semuanya diaktifkan secara default.", + sqlVariableSubstitutionEnabled: "Diaktifkan", + sqlVariableSyntax_positional: "Placeholder posisional", + sqlVariableSyntax_positionalDescription: "Minta nilai untuk mensubstitusi setiap placeholder posisional secara berurutan.", + sqlVariableSyntax_named: "Placeholder bernama", + sqlVariableSyntax_namedDescription: "Minta nilai untuk mensubstitusi placeholder bernama.", + sqlVariableSyntax_shell: "Placeholder bergaya shell", + sqlVariableSyntax_shellDescription: "Minta nilai untuk mensubstitusi placeholder bergaya shell.", + sqlVariableSyntax_mybatis: "Placeholder bergaya MyBatis", + sqlVariableSyntax_mybatisDescription: "Minta nilai untuk mensubstitusi placeholder bergaya MyBatis.", + sqlVariableSyntax_sqlserver: "Placeholder bergaya SQL Server", + sqlVariableSyntax_sqlserverDescription: "Minta nilai untuk mensubstitusi placeholder bergaya SQL Server (dapat bertabrakan dengan variabel sesi).", + sqlVariableSyntax_atSet: "Ekspansi variabel inline", + sqlVariableSyntax_atSetDescription: "Perluas deklarasi variabel inline dan substitusi nilainya sebelum dijalankan.", + tableCompletionSchemaQualification: "Kualifikasi skema untuk pelengkapan tabel", + tableCompletionSchemaQualificationDescription: "Pilih kapan nama tabel dan tampilan yang dilengkapi menyertakan skemanya.", + tableCompletionSchemaQualificationNever: "Tidak Pernah", + tableCompletionSchemaQualificationNeverDescription: "Sisipkan hanya nama tabel atau tampilan.", + tableCompletionSchemaQualificationCollision: "Saat Bertabrakan", + tableCompletionSchemaQualificationCollisionDescription: "Gunakan perilaku otomatis saat ini dan sertakan skema hanya jika diperlukan.", + tableCompletionSchemaQualificationAlways: "Selalu", + tableCompletionSchemaQualificationAlwaysDescription: "Sertakan skema kapan pun tersedia di metadata.", + autoAliasTables: "Tambahkan alias tabel secara otomatis", + autoAliasTablesDescription: "Saat memilih pelengkapan tabel di FROM atau JOIN, sisipkan alias yang dihasilkan seperti order_items AS oi.", + sqlServerSpaceConfirmsCompletion: "Spasi mengonfirmasi pelengkapan (gaya SQL Server)", + sqlServerSpaceConfirmsCompletionDescription: "Saat daftar pelengkapan terbuka, menekan Spasi akan menerima kata kunci, tabel, atau kolom yang dipilih serta mempertahankan spasi di akhir. Enter dan Tab tetap berperilaku seperti sebelumnya.", + redisKeyTemplatesSection: "Redis", + redisKeyTemplates: "Template pencarian key", + redisKeyTemplatesPlaceholder: "Contoh:\nuser:{'{'}$userId{'}'}\nv3:adui:{'{'}$positionID{'}'}", + redisKeyTemplatesDescription: "Satu template per baris. Digunakan sebagai saran cadangan saat koneksi Redis tidak memiliki template sendiri.", + redisScanPageSize: "Jumlah scan Redis", + redisScanPageSizeDescription: "Key yang diminta per halaman SCAN Redis saat menjelajahi key.", + redisScanPageSizeOption: "{count} key", + redisDatabaseDisplayLimit: "Batas daftar database bilah sisi", + redisDatabaseDisplayLimitDescription: 'Jumlah maksimum database yang ditampilkan sekaligus di bilah sisi; sisanya dapat ditampilkan dengan "Muat lebih banyak".', + redisDatabaseDisplayLimitOption: "{count} database", + exportBatchSize: "Ukuran batch ekspor", + dateTimeSection: "Tanggal dan waktu", + globalDateTimeDisplayFormat: "Format tampilan global", + globalDateTimeDisplayFormatDescription: "Berlaku untuk kolom temporal tanpa formatter khusus kolom di setiap database.", + globalDateTimeExportFormat: "Format ekspor global", + globalDateTimeExportFormatDescription: "Memformat kolom temporal secara konsisten dalam ekspor CSV, Excel, JSON, Markdown, dan teks.", + globalDateTimeImportFormat: "Format impor global", + globalDateTimeImportFormatDescription: "Mengurai nilai temporal yang diimpor dengan format ini. Kosongkan untuk mendeteksi format umum secara otomatis.", + dateTimeFormatRaw: "Pertahankan nilai database", + dateTimeFormatAuto: "Deteksi otomatis", + dateTimeFormatSearchPlaceholder: "Pilih atau masukkan format", + dateTimeFormatEmpty: "Masukkan format tanggal-waktu kustom", + exportBatchSizeDescription: "Baris yang diambil per batch saat mengekspor data (100-100000).", + exportRowLimitEnabled: "Batasi baris yang diekspor", + exportRowLimitEnabledDescription: "Jika diaktifkan, ekspor hasil kueri dan data tabel berhenti pada batas baris di bawah ini.", + exportRowLimit: "Batas baris ekspor data", + exportRowLimitDescription: "Jumlah baris maksimum untuk ekspor hasil kueri dan data tabel.", + exportRowLimitUnlimited: "Tanpa Batas", + queryExportKeysetOptimizationEnabled: "Coba optimasi keyset", + queryExportKeysetOptimizationEnabledDescription: "Hanya berlaku untuk kueri tabel tunggal yang dapat dikenali dengan aman; kueri yang kompleks otomatis kembali ke cara biasa.", + exportSection: "Ekspor", + csvQuoteMode: "Tanda kutip bidang CSV", + csvQuoteModeDescription: "Pilih bagaimana bidang CSV menggunakan tanda kutip ganda.", + csvQuoteModeAll: "Semua bidang", + csvQuoteModeNecessary: "Hanya jika diperlukan", + csvNullMode: "Representasi NULL pada CSV", + csvNullModeDescription: + 'Bagaimana NULL ditulis saat mengekspor CSV. Dengan "\\N", NULL ditulis sebagai \\N dan string kosong sebagai bidang kosong, sehingga keduanya tetap dapat dibedakan dan impor ulang tidak mengubah string kosong menjadi NULL. Dengan "Kosong", NULL dan string kosong sama-sama ditulis sebagai bidang kosong dan tidak dapat dibedakan.', + csvNullModeMarker: "\\N", + csvNullModeEmpty: "Kosong", + performanceSection: "Performa", + shortcutExecuteSql: "Eksekusi SQL", + shortcutExecuteSqlInNewResultTab: "Eksekusi SQL di tab hasil baru", + shortcutFind: "Cari", + shortcutGotoLine: "Ke Baris", + shortcutReplace: "Ganti", + shortcutSaveSql: "Simpan SQL", + shortcutAcceptCompletion: "Terima pelengkapan", + shortcutTriggerCompletion: "Picu pelengkapan", + shortcutFormatSql: "Format SQL", + shortcutExpandSelectStar: "Perluas * menjadi kolom", + shortcutToggleLineComment: "Aktifkan/nonaktifkan komentar baris", + shortcutToggleBlockComment: "Aktifkan/nonaktifkan komentar blok", + shortcutIndentMore: "Tambah indentasi", + shortcutIndentLess: "Kurangi indentasi", + shortcutInsertLineBelow: "Sisipkan baris di bawah", + shortcutJoinLines: "Gabungkan baris", + shortcutDuplicateLine: "Duplikat baris saat ini", + shortcutDeleteLine: "Hapus baris saat ini", + shortcutMoveLineUp: "Pindahkan baris ke atas", + shortcutMoveLineDown: "Pindahkan baris ke bawah", + shortcutCopyLineUp: "Salin baris ke atas", + shortcutCopyLineDown: "Salin baris ke bawah", + shortcutUndo: "Urungkan", + shortcutRedo: "Ulangi", + shortcutSelectAll: "Pilih semua", + shortcutAddNextSelectionOccurrence: "Tambah kemunculan berikutnya", + shortcutSelectAllSelectionOccurrences: "Pilih semua kemunculan", + shortcutExtendSelection: "Perluas seleksi", + shortcutEditTableStructure: "Edit struktur tabel", + shortcutCopyCurrentRow: "Salin baris data saat ini", + shortcutDeleteCurrentRow: "Hapus baris data saat ini", + shortcutFocusWhere: "Fokus kondisi WHERE", + shortcutGoToColumn: "Ke kolom", + shortcutGoToFirstPage: "Halaman pertama", + shortcutGoToPreviousPage: "Halaman sebelumnya", + shortcutGoToNextPage: "Halaman berikutnya", + shortcutGoToLastPage: "Halaman terakhir", + shortcutNewQuery: "Kueri baru", + shortcutOpenSettings: "Buka pengaturan", + shortcutCloseTab: "Tutup tab", + shortcutFocusSearch: "Fokus pencarian tampilan saat ini", + shortcutQuickOpen: "Buka cepat (cari semua objek database)", + shortcutGlobalSearch: "Pencarian konten file global", + shortcutNavigateTabHistoryBack: "Kembali ke tab yang dilihat sebelumnya", + shortcutTabSwitcher: "Pengalih tab (tahan untuk menampilkan, lepas untuk beralih)", + shortcutNavigateTabHistoryForward: "Maju ke tab yang dilihat berikutnya", + shortcutSwitchToPreviousTab: "Beralih ke tab sebelumnya", + shortcutSwitchToNextTab: "Beralih ke tab berikutnya", + shortcutSwitchToTab1: "Beralih ke tab 1", + shortcutSwitchToTab2: "Beralih ke tab 2", + shortcutSwitchToTab3: "Beralih ke tab 3", + shortcutSwitchToTab4: "Beralih ke tab 4", + shortcutSwitchToTab5: "Beralih ke tab 5", + shortcutSwitchToTab6: "Beralih ke tab 6", + shortcutSwitchToTab7: "Beralih ke tab 7", + shortcutSwitchToTab8: "Beralih ke tab 8", + shortcutSwitchToTab9: "Beralih ke tab 9", + shortcutZoomInUi: "Perbesar UI", + shortcutZoomOutUi: "Perkecil UI", + shortcutResetUiZoom: "Reset zoom UI", + shortcutRefreshData: "Segarkan data", + shortcutToggleResultsPane: "Aktifkan/nonaktifkan panel hasil", + shortcutToggleTranspose: "Aktifkan/nonaktifkan tampilan transpos", + shortcutCancelSearch: "Batalkan pencarian", + shortcutToggleSidebar: "Aktifkan/nonaktifkan bilah sisi", + shortcutToggleZenMode: "Aktifkan/nonaktifkan mode Zen", + shortcutCopySidebarSelection: "Salin seleksi bilah sisi", + shortcutPasteSidebarSelection: "Tempel ke bilah sisi", + shortcutEditSidebarConnection: "Edit koneksi bilah sisi", + shortcutOpenDataInNewTab: "Buka data di tab baru (klik mouse)", + shortcutViewTableDdl: "Lihat DDL tabel", + shortcutSendSelectionToAi: "Kirim seleksi ke AI", + shortcutToggleAiPanel: "Aktifkan/nonaktifkan panel AI", + shortcutSqlIntentionActions: "Aksi Intensi SQL (Perluas * / Kualifikasi Identifier)", + intentionExpandWildcard: "Perluas * menjadi Daftar Kolom", + intentionQualifyIdentifier: "Kualifikasikan Identifier", + intentionUnqualifyIdentifier: "Batalkan Kualifikasi Identifier", + intentionBatchQualifyIdentifiers: "Kualifikasikan Identifier Secara Batch", + shortcutToggleFold: "Aktifkan/nonaktifkan lipat", + shortcutScopeGlobal: "Global", + shortcutScopeEditor: "Editor SQL", + shortcutScopeGrid: "Grid data", + shortcutScopeSearch: "Bidang pencarian", + shortcutScopeSidebar: "Bilah sisi", + shortcutScopeHintGlobal: "Berlaku di permukaan mana pun", + shortcutScopeHintEditor: "Berlaku saat editor difokuskan", + shortcutScopeHintGrid: "Berlaku saat grid hasil difokuskan", + shortcutScopeHintSearch: "Berlaku saat bidang pencarian difokuskan", + shortcutScopeHintSidebar: "Berlaku saat bilah sisi difokuskan", + shortcutGroupCount: "{count} aksi", + shortcutGroupUnbound: "{count} belum terikat", + shortcutGroupUnboundTooltip: "Aksi ini belum memiliki pintasan yang ditetapkan; gunakan ikon pensil pada baris untuk merekamnya.", + shortcutModifiedTag: "Diubah", + shortcutModifiedTagTooltip: "Berbeda dari pintasan default; gunakan ikon reset pada baris untuk memulihkannya.", + shortcutConflictBadge: "{count} konflik", + shortcutConflictTooltip: "Duplikat dengan “{label}” ({scope}). Hanya satu aksi per cakupan yang dapat memiliki kombinasi tombol ini, jadi salah satunya harus diubah sebelum Anda dapat menerapkan.", + shortcutConflictSummaryTooltip: "{count} konflik dalam satu cakupan ({pairs} pasangan duplikat). Hanya satu aksi per cakupan yang dapat memiliki kombinasi tombol ini, jadi hal ini harus diselesaikan sebelum menerapkan.", + shortcutCrossScopeBadge: "{count} tumpang tindih lintas cakupan", + shortcutCrossScopeTooltip: "Berbagi kombinasi tombol dengan {targets}. Setiap cakupan menyelesaikan bindingnya sendiri, sehingga hanya satu yang aktif pada satu waktu — tidak ada yang perlu diperbaiki.", + shortcutCrossScopeTooltipSeparator: ", ", + shortcutCrossScopeSummaryTooltip: "{count} tumpang tindih lintas cakupan ({pairs} pasangan duplikat). Cakupan yang berbeda menyelesaikan bindingnya masing-masing, sehingga hanya satu yang aktif pada satu waktu; hanya informasional, tidak menghalangi penerapan.", + shortcutConflictBlocksApply: "{count} konflik dalam satu cakupan ({pairs} pasangan duplikat)", + shortcutPressShortcut: "Tekan pintasan", + shortcutSearchPlaceholder: "Cari pintasan", + shortcutSearchNoResults: "Tidak ada pintasan yang cocok dengan pencarian Anda.", + shortcutConflict: "Pintasan ini berkonflik dengan aksi lain pada cakupan yang sama.", + shortcutReserved: "Pintasan ini dicadangkan oleh sistem.", + shortcutPlatformDefault: "Kombinasi ini adalah pintasan default pada platform lain dan tidak dapat diikat di sini. Silakan gunakan kombinasi lain.", + shortcutClear: "Hapus pintasan", + preview: "Pratinjau Langsung", + previewSyntaxErrorHint: "Pratinjau hanya-baca. Salah ketik FOM pada SQL demo adalah disengaja dan menunjukkan penyorotan galat sintaks.", + customTheme: "Tema Kustom", + customThemeConfigure: "Konfigurasikan Tema Kustom", + customThemeTitle: "Konfigurasi Tema Kustom", + customThemeMyThemes: "Tema Saya", + customThemeNewTheme: "Tema Baru", + customThemeVisualEdit: "Editor Visual", + customThemeJsonConfig: "Konfigurasi JSON", + customThemeLivePreview: "Pratinjau Langsung", + customThemePreviewExample: "-- Contoh Kueri", + customThemePreset: "Tema Preset", + customThemeSelectPreset: "Pilih tema preset...", + customThemeApply: "Terapkan", + customThemePasteImport: "Impor dengan Tempel", + customThemeExportJson: "Ekspor JSON", + customThemeSaveAndApply: "Simpan & Terapkan", + customThemeKeyword: "Kata Kunci", + customThemeField: "Bidang/Variabel", + customThemeFunction: "Fungsi", + customThemeString: "String", + customThemeNumber: "Angka", + customThemeComment: "Komentar", + customThemeTable: "Tabel", + customThemeOperator: "Operator", + customThemeType: "Tipe", + customThemeBuiltin: "Bawaan", + customThemeBackground: "Latar Belakang", + customThemeForeground: "Latar Depan", + customThemeDefaultName: "Tema Kustom", + customThemeCopySuffix: " Salinan", + customThemeApplied: 'Skema warna "{name}" diterapkan', + customThemeKeepOne: "Pertahankan minimal satu tema", + customThemeJsonError: "Format JSON tidak valid, silakan periksa", + jdbcPlugin: "Plugin JDBC DBX", + jdbcPluginInstall: "Pasang plugin JDBC", + jdbcPluginInstallSuccess: "Plugin JDBC terpasang", + jdbcPluginUpdate: "Perbarui", + jdbcPluginUninstall: "Hapus pemasangan", + jdbcPluginUninstallSuccess: "Plugin JDBC dihapus", + jdbcPluginInstalled: "Terpasang: v{version}", + jdbcPluginIncompatible: "Protokol tidak kompatibel", + jdbcPluginNotInstalled: "Belum terpasang", + jdbcDrivers: "JAR driver JDBC", + jdbcImport: "Impor JAR", + jdbcImportPath: "Impor Jalur", + jdbcDriverPathPlaceholder: "/path/to/driver.jar", + jdbcImportSuccess: "{count} file driver berhasil diimpor", + jdbcDeleteSuccess: "Driver dihapus", + jdbcNoDrivers: "Belum ada driver JDBC yang diimpor.", + mcpTitle: "Server MCP", + mcpDescription: "Periksa pemasangan dan versi Server MCP DBX yang digunakan oleh Claude Code, Cursor, dan agen lainnya.", + mcpChecking: "Memeriksa", + mcpStatusUnknown: "Belum diperiksa", + mcpStatusError: "Pemeriksaan gagal", + mcpReady: "Siap", + mcpNotInstalled: "Belum terpasang", + mcpUpdateAvailable: "Pembaruan tersedia", + mcpCurrent: "Versi saat ini", + mcpLatest: "Versi terbaru", + mcpVersionMissing: "Tidak terdeteksi pemasangan global", + mcpVersionUnknown: "Tidak diketahui", + mcpAvailable: "Tersedia", + mcpUnavailable: "Tidak tersedia", + mcpBinPath: "Jalur perintah", + mcpInstallCommand: "Perintah pemasangan", + mcpUpdateCommand: "Perintah peningkatan", + mcpUninstallCommand: "Perintah penghapusan", + mcpInstallButton: "Pasang", + mcpSwitchToNativeButton: "Beralih ke native (direkomendasikan)", + mcpNativeMigrationHint: "Pemasangan npm Anda tetap dapat digunakan. Pasang biner native mandiri, lalu perbarui konfigurasi klien MCP eksternal ke jalur absolut yang dihasilkan; DBX tidak akan menghapus npm secara otomatis.", + mcpNpmFallbackHint: "Pemasangan npm sebelumnya tetap tersedia sebagai cadangan. Pertama, gunakan konfigurasi Agent yang sesuai di bawah untuk mengganti perintah peluncuran dengan jalur absolut native yang ditampilkan. Hapus cadangan hanya setelah setiap klien MCP eksternal dimigrasikan.", + mcpRemoveNpmFallbackButton: "Hapus cadangan npm", + mcpRemoveNpmFallbackConfirm: "Hapus pemasangan npm DBX MCP yang masih dipertahankan? Pastikan terlebih dahulu bahwa setiap klien MCP eksternal telah diperbarui ke jalur absolut native yang ditampilkan menggunakan konfigurasi Agent yang sesuai di bawah.", + mcpRemoveNpmFallbackFailed: "Gagal menghapus cadangan npm: {error}", + mcpUpdateButton: "Tingkatkan", + mcpUpToDate: "Sudah versi terbaru", + mcpInstalling: "Memasang...", + mcpInstallSuccess: "Pemasangan berhasil", + mcpInstallFailed: "Pemasangan gagal", + mcpUninstallButton: "Hapus Pemasangan", + mcpUninstalling: "Menghapus pemasangan...", + mcpUninstallConfirm: "Hapus pemasangan Server MCP DBX? Klien MCP yang dikonfigurasi tidak akan dapat memulainya lagi.", + mcpUninstallFailed: "Penghapusan pemasangan gagal: {error}", + mcpConfig: "Konfigurasi MCP", + mcpConfigOptionsHint: "DBX mengontrol akses koneksi dan izin eksekusi secara terpusat untuk setiap klien MCP. Konfigurasi yang dihasilkan hanya berisi pengaturan runtime yang diperlukan untuk memulai server MCP dan terhubung ke instans DBX ini, tanpa variabel izin atau cakupan koneksi.", + mcpScopeConnection: "Koneksi yang diizinkan untuk MCP", + mcpScopeConnectionDescription: "DBX hanya mengekspos koneksi yang dipilih ke MCP. Perubahan berlaku untuk setiap klien MCP.", + mcpScopeMode: "Mode cakupan koneksi", + mcpScopeModeAll: "Semua koneksi", + mcpScopeModeAllDescription: "Otomatis menyertakan koneksi di masa depan", + mcpScopeModeSelected: "Koneksi tertentu", + mcpScopeModeSelectedDescription: "Hanya koneksi yang ditambahkan secara eksplisit", + mcpScopeAllowedPane: "Diizinkan", + mcpScopeAvailablePane: "Tersedia", + mcpScopeAddAll: "Tambah semua", + mcpScopeRemoveAll: "Hapus semua", + mcpScopeAddMatches: "Tambah yang cocok ({count})", + mcpScopeRemoveMatches: "Hapus yang cocok ({count})", + mcpScopeAddConnection: "Izinkan akses MCP ke {name}", + mcpScopeRemoveConnection: "Hapus akses MCP ke {name}", + mcpScopeAvailableEmpty: "Tidak ada koneksi yang tersedia untuk ditambahkan", + mcpScopeAllowedEmpty: "Saat ini tidak ada koneksi yang diizinkan", + mcpScopeUnavailableGroup: "Koneksi tidak tersedia ({count})", + mcpScopeRemoveUnavailableConnection: "Hapus koneksi tidak tersedia {id} dari daftar izin", + mcpScopeUpdatedAnnouncement: "MCP saat ini mengizinkan {selected} dari {total} koneksi yang tersedia", + mcpConnectionSearchPlaceholder: "Cari nama, jenis, alamat, database, atau ID koneksi", + mcpConnectionSearchEmpty: "Tidak ada koneksi yang cocok", + mcpConnectionListEmpty: "Tidak ada koneksi yang tersedia", + mcpScopeAllAction: "Izinkan semua", + mcpScopeNoneAction: "Bersihkan semua", + mcpScopeAllSummary: "Semua {count} koneksi", + mcpScopeSelectedSummary: "{selected}/{total} dipilih", + mcpScopeAllConnections: "Semua koneksi", + mcpScopeNoConnections: "Tidak ada koneksi", + mcpScopeConnectionUnavailable: "Koneksi yang dipilih sebelumnya (tidak tersedia)", + mcpScopeConnectionUnavailableDescription: "{count} koneksi terpilih sudah tidak ada lagi. ID-nya tetap ada dalam daftar izin, tetapi tidak ada koneksi aktif yang diekspos untuknya.", + mcpScopeSelectedCount: "{count} koneksi dipilih", + mcpCodexConfig: "Konfigurasi Codex", + mcpCodexConfigPath: "Codex dapat menggunakan ~/.codex/config.toml atau .codex/config.toml tingkat proyek.", + mcpDeepSeekHarnessConfigPath: "Untuk dsh web, gabungkan entri insert ini ke $DSH_HOME/profiles/web/cordis.patch.yml; ganti web untuk profil lain. Jangan menimpa entri patch yang sudah ada. Verifikasi dengan dsh web --dump-config atau biarkan HMR memuat ulang perubahan.", + mcpCursorConfigPath: "Cursor dapat menggunakan .cursor/mcp.json pada proyek atau ~/.cursor/mcp.json secara global.", + mcpCodeBuddyConfigPath: "CodeBuddy Code dapat menggunakan ~/.codebuddy/.mcp.json secara global atau .mcp.json pada proyek.", + mcpZCodeConfigPath: "ZCode: Settings > MCP Servers > New MCP Server > Full configuration; pilih cakupan User atau Workspace, lalu tempel konfigurasi JSON.", + mcpTraeConfigPath: "TRAE: Settings > MCP > Add > Add Manually, lalu tempel konfigurasi JSON.", + mcpQoderConfigPath: "Qoder: Settings > MCP > Add Manually, lalu tempel konfigurasi JSON.", + mcpWorkBuddyConfigPath: "WorkBuddy: buka Plugins di bilah sisi, klik MCP Servers (kanan atas) > Configure MCP dan tempel JSON; atau simpan ke ~/.workbuddy/mcp.json (global) atau .workbuddy/mcp.json pada proyek Anda.", + mcpCherryStudioConfigPath: "Cherry Studio: Settings > MCP Servers > Add Server > Import JSON, lalu tempel konfigurasinya.", + mcpVsCodeConfigPath: "VS Code/Copilot dapat menggunakan .vscode/mcp.json pada workspace atau mcp.json pada profil pengguna.", + mcpWindsurfConfigPath: "Windsurf dapat menggunakan ~/.codeium/windsurf/mcp_config.json.", + mcpOpenCodeConfigPath: "~/.config/opencode/opencode.json secara global, atau opencode.json pada tingkat proyek.", + mcpPiConfigPath: "Pasang terlebih dahulu plugin adaptor Pi MCP: pi install npm:pi-mcp-adapter. Lalu simpan ke ~/.pi/agent/mcp.json (global) atau .mcp.json (proyek), jalankan /mcp untuk memverifikasi, dan /reload untuk menerapkannya di Pi.", + mcpExecutionMode: "Izin default global MCP", + mcpExecutionModeDescription: "Mengatur default yang digunakan saat tidak ada izin koneksi atau database yang dikonfigurasi. Default koneksi dan pengaturan database dapat menimpanya sesuai cakupan.", + mcpExecutionModeReadOnly: "Hanya baca", + mcpExecutionModeSafeWrite: "Baca/tulis data", + mcpExecutionModeRecommended: "Direkomendasikan", + mcpExecutionModeHighRiskWrite: "Akses penuh", + mcpExecutionModeReadOnlyDescription: "Hanya mengizinkan permintaan yang diklasifikasikan DBX sebagai baca; memblokir penulisan database dan perubahan koneksi yang dikenali. Izin akun database tetap menjadi batas keras terakhir.", + mcpExecutionModeSafeWriteDescription: "Mengizinkan INSERT biasa, UPDATE/DELETE yang difilter, perubahan MongoDB dengan cakupan yang dapat diverifikasi, dan penulisan Redis biasa atau penghapusan key eksplisit; memblokir perubahan seluruh tabel dan struktural.", + mcpExecutionModeHighRiskWriteDescription: "Selain baca/tulis data, mengizinkan perubahan seluruh tabel, DDL, TRUNCATE, pembersihan database, dan operasi berisiko tinggi lainnya. Perlindungan produksi dan read-only koneksi tetap berlaku.", + mcpExecutionModeHighRiskConfirm: "Akses penuh mengizinkan perubahan seluruh tabel, DDL, TRUNCATE, pembersihan database, dan operasi berisiko tinggi lainnya. Aktifkan?", + mcpCapabilityTitle: "Perbandingan kapabilitas", + mcpCapabilityDescription: "Ini adalah operasi representatif; permintaan yang tidak dapat diklasifikasikan DBX secara andal memerlukan akses penuh.", + mcpCapabilityOperation: "Kapabilitas", + mcpCapabilityRead: "Kueri dan pembacaan", + mcpCapabilityScopedMutation: "Perubahan data bercakupan (INSERT, UPDATE/DELETE yang difilter, penulisan/penghapusan key eksplisit)", + mcpCapabilityBroadMutation: "Pembaruan/penghapusan seluruh tabel dan pembersihan data", + mcpCapabilitySchemaAdmin: "DDL, perubahan struktural, dan administrasi berisiko tinggi", + mcpCapabilityConnectionManagement: "Tambah/hapus koneksi MCP", + mcpCapabilityAllowed: "Diizinkan", + mcpCapabilityBlocked: "Diblokir", + mcpQueryTimeout: "Batas waktu kueri (detik)", + mcpQueryTimeoutDescription: "Kosongkan untuk mewarisi batas waktu kueri koneksi. 0 = tanpa batas. Nilai positif menimpa pengaturan koneksi untuk setiap kueri MCP.", + mcpQueryTimeoutInvalid: "Masukkan bilangan bulat detik non-negatif, atau kosongkan untuk mewarisi pengaturan koneksi.", + mcpQueryTimeoutSaveStatus_saving: "Menyimpan...", + mcpQueryTimeoutSaveStatus_saved: "Tersimpan", + mcpQueryTimeoutSaveStatus_failed: "Gagal menyimpan", + mcpCapabilityAlwaysEnforced: "Setiap mode tetap tunduk pada daftar izin koneksi, perlindungan read-only koneksi, perlindungan produksi, dan izin akun database.", + mcpPolicySaveFailed: "Gagal menyimpan kebijakan akses MCP: {error}", + mcpPolicyLoadFailed: "Gagal memuat kebijakan akses MCP: {error}", + mcpDetectionTiming: "DBX memeriksa secara otomatis saat halaman ini dibuka; gunakan Periksa lagi untuk menyegarkan.", + mcpNpmBoundary: "DBX memeriksa status MCP; pemasangan, peningkatan, dan penghapusan pemasangan berjalan melalui runtime npm, pnpm, atau bun yang terdeteksi.", + mcpNativeManagementBoundary: "DBX memasang dan mengelola server native mandiri secara default. Pemasangan npm yang sudah ada tetap tersedia sebagai cadangan dan tidak pernah dihapus secara otomatis.", + mcpRefresh: "Periksa lagi", + mcpGuide: "Panduan MCP", + mcpAuthTitle: "Otorisasi MCP", + mcpAuthDescription: "Selesaikan otorisasi secara berurutan: atur default global, pilih grup dan koneksi, batasi database, lalu tinjau kebijakan akhir.", + mcpAuthStepsLabel: "Langkah otorisasi MCP", + mcpAuthStepConnectionsTitle: "Grup dan koneksi", + mcpAuthStepConnectionsDescription: "Pilih apa yang dapat dilihat MCP dan atur izin koneksi", + mcpAuthStepDatabasesTitle: "Cakupan database", + mcpAuthStepDatabasesDescription: "Batasi database setiap koneksi dan atur izin database", + mcpAuthStepOverridesTitle: "Izin default", + mcpAuthStepOverridesDescription: "Atur default global untuk semua cakupan berikutnya", + mcpAuthStepCapabilitiesTitle: "Ringkasan dan tinjauan", + mcpAuthStepCapabilitiesDescription: "Tinjau izin efektif, pilih alat, dan konfirmasi", + mcpAuthStepRegionLabel: "Langkah {step}: {title}", + mcpAuthPreviousStep: "Sebelumnya", + mcpAuthNextStep: "Berikutnya", + mcpAuthStepProgress: "Langkah {current} dari {total}", + mcpResourceScopeTitle: "Koneksi yang terlihat oleh MCP", + mcpResourceScopeDescription: "Pilih grup untuk cakupan dinamis dan koneksi tertentu untuk pengecualian yang tepat.", + mcpResourceScopeModeCustom: "Cakupan kustom", + mcpResourceScopeAllSummary: "Semua {count} koneksi", + mcpResourceScopeCustomSummary: "{effective} efektif · {groups} aturan grup · {connections} aturan langsung", + mcpResourceScopeSearch: "Cari grup atau koneksi", + mcpResourceScopeTreeLabel: "Pohon sumber daya koneksi MCP", + mcpResourceScopeInherited: "Dari {group}", + mcpResourceScopeDynamic: "Dinamis", + mcpResourceScopeDirect: "Langsung", + mcpResourceScopePartial: "Sebagian diizinkan", + mcpResourceScopeEmpty: "Tidak ada grup atau koneksi yang cocok.", + mcpResourceScopeHint: "Grup yang dipilih mencakup koneksi turunannya saat ini dan di masa depan. Pilihan langsung bersifat pengecualian independen.", + mcpResourceScopeAllConfirm: "Beralih ke semua koneksi akan menghapus aturan grup dan koneksi kustom saat ini. Lanjutkan?", + mcpPermissionGlobalDefaultHint: "Izin grup, koneksi, dan database menimpa default ini, tetapi tidak pernah memperluas visibilitas koneksi.", + mcpDatabasePolicyHighRiskConfirm: "Izinkan penulisan berisiko tinggi untuk database ini? Perlindungan read-only koneksi dan produksi tetap berlaku.", + mcpDatabaseScopeClearsPermissionExceptions: "Mengubah cakupan database ini akan menghapus pengecualian izin databasenya. Lanjutkan?", + mcpPerPage: "Per halaman", + mcpPreviousPage: "Halaman sebelumnya", + mcpNextPage: "Halaman berikutnya", + mcpDatabaseScopeTitle: "Koneksi dan cakupan database", + mcpDatabaseScopeDescription: "Pilih koneksi yang diekspos ke MCP di sebelah kiri, lalu batasi database yang dapat diakses koneksi tersebut. Nama database dicocokkan secara tepat.", + mcpDatabaseScopeEmptyHint: "Izinkan minimal satu koneksi pada 'Cakupan Koneksi' terlebih dahulu.", + mcpDatabaseScopeAllowedConnections: "Koneksi yang diizinkan", + mcpDatabaseScopeSummaryAll: "Semua database", + mcpDatabaseScopeSummaryNone: "Tidak ada akses database", + mcpDatabaseScopeSummarySelected: "{count} dipilih", + mcpDatabaseScopePermissionNote: "Cakupan yang dipilih tidak mengubah izin database koneksi yang sudah ada di DBX.", + mcpDatabaseLoadButton: "Muat daftar sumber daya", + mcpDatabaseScopeAriaLabel: "Cakupan akses database", + mcpDatabaseScopeAllTitle: "Semua database", + mcpDatabaseScopeAllDescription: "Pertahankan cakupan akses saat ini", + mcpDatabaseScopeSelectedTitle: "Hanya database terpilih", + mcpDatabaseScopeSelectedDescription: "Hanya ekspos item yang dicentang", + mcpDatabaseScopeNoneTitle: "Tidak ada akses", + mcpDatabaseScopeNoneDescription: "Pertahankan aturan tetapi tolak setiap database", + mcpDatabaseScopeSelectedSummary: "{count} database diizinkan. Database yang tidak dicentang dan permintaan lintas database ditolak oleh server MCP.", + mcpDatabasePolicyInherit: "Warisi koneksi", + mcpDatabasePolicySetting: "Pengaturan prioritas database", + mcpDatabasePolicyEffective: "Efektif: {mode}", + mcpPermissionPreviewTitle: "Pratinjau izin", + mcpPermissionPreviewDescription: "Urutan prioritas izin: database, koneksi, grup terdekat, grup leluhur, lalu default global.", + mcpPermissionPreviewConnection: "Koneksi", + mcpPermissionPreviewDatabase: "Database", + mcpPermissionPreviewConnectionDefault: "Default koneksi", + mcpPermissionPreviewGroupDefault: "Default grup", + mcpGroupScopeTitle: "Grup koneksi", + mcpGroupScopeDescription: "Memilih grup secara dinamis mengekspos semua koneksi turunannya saat ini dan di masa depan. Koneksi lain tetap dapat ditambahkan secara eksplisit.", + mcpGroupScopeSelected: "{count} grup dipilih", + mcpGroupScopeSearch: "Cari jalur grup", + mcpGroupScopeNoResults: "Tidak ditemukan grup yang cocok.", + mcpGroupScopeEmpty: "Tidak ada grup koneksi untuk dikonfigurasi.", + mcpGroupPolicyTitle: "Izin default grup", + mcpGroupPolicyDescription: "Grup turunan menimpa induknya; pengaturan koneksi dan database dapat menimpa default grup.", + mcpGroupPolicyInherit: "Warisi induk atau global", + mcpGroupPolicyHighRiskConfirm: "Izinkan penulisan berisiko tinggi untuk grup ini? Perlindungan read-only koneksi dan produksi tetap berlaku.", + mcpPermissionPreviewDatabaseOverride: "Pengaturan prioritas database", + mcpPermissionPreviewEffective: "Efektif", + mcpPermissionPreviewResource: "Sumber Daya", + mcpPermissionPreviewSource: "Sumber", + mcpPermissionSourceDatabase: "Pengecualian database", + mcpPermissionSourceConnection: "Pengecualian koneksi", + mcpPermissionSourceGroup: "Grup: {group}", + mcpPermissionSourceGlobal: "Default global", + mcpPermissionPreviewEmpty: "Izinkan minimal satu koneksi dan konfigurasikan cakupan databasenya terlebih dahulu.", + mcpPermissionPreviewSearchPlaceholder: "Cari koneksi atau database", + mcpPermissionPreviewSearchNoResults: "Tidak ditemukan koneksi atau database yang cocok.", + mcpDatabaseSearchPlaceholder: "Filter database yang dimuat", + mcpDatabaseManualPlaceholder: "Tambahkan nama database secara manual", + mcpDatabaseLoadFailed: "Gagal memuat database: {error}. Anda dapat menambahkan nama database yang tepat secara manual.", + mcpDatabaseEmptyHint: "Klik 'Muat daftar sumber daya' untuk mengambil daftar database, atau tambahkan database yang diizinkan secara manual.", + mcpManagementAccess: "Metode akses", + mcpManagementPermissions: "Manajemen izin", + mcpTransportLabel: "Jenis koneksi", + mcpRuntimeSettings: "Pengaturan runtime", + mcpTransportLocalStdio: "Stdio lokal", + mcpTransportHttpService: "Layanan HTTP", + mcpHttpWebServiceTitle: "Layanan HTTP Streamable Web", + mcpHttpWebServiceDescription: "Web/Docker menggunakan port web yang sudah ada. Kelola akses di sini, atau gunakan secret deployment untuk menimpa pengaturan ini.", + mcpHttpWebDisabledHint: "Layanan dinonaktifkan; endpoint ini belum dapat digunakan.", + mcpHttpWebDeploymentManaged: "Lingkungan deployment atau file secret mengontrol layanan ini. Ubah token dan daftar izin pada konfigurasi deployment Anda.", + mcpHttpWebPasswordRequired: "Manajemen MCP Web memerlukan kata sandi login Web yang dikonfigurasi dan tidak tersedia dalam mode demo.", + mcpHttpWebManagedTokenSource: "Pengaturan Web", + mcpHttpWebEnableLabel: "Aktifkan MCP HTTP", + mcpHttpWebOriginsHint: "Hanya klien browser yang memerlukan Origin yang tepat; klien native dapat mengosongkan ini.", + mcpHttpWebSave: "Simpan dan terapkan", + mcpHttpStatusLabelEnabled: "Diaktifkan", + mcpHttpStatusLabelDisabled: "Belum diaktifkan", + mcpHttpNotConfigured: "Belum dikonfigurasi", + mcpHttpWebTokenSourceAndHosts: "Sumber token: {tokenSource}; host yang diizinkan: {hosts}", + mcpHttpWebAllowedOrigins: "Origin yang diizinkan: {origins}", + mcpHttpReloadStatus: "Status muat ulang", + mcpHttpServiceTitle: "Layanan HTTP Streamable", + mcpHttpStatusLabelRunning: "Berjalan", + mcpHttpStatusLabelNotRunning: "Tidak berjalan", + mcpHttpServiceDescription: "Nonaktif secara default. Jika diaktifkan, DBX Desktop menghosting layanan ini; konfigurasi di atas diterapkan ke layanan yang sedang berjalan hanya setelah disimpan.", + mcpHttpListenerTitle: "Konfigurasi listener", + mcpHttpListenerHintPrefix: "Kami merekomendasikan tetap menggunakan ", + mcpHttpListenerHintSuffix: " agar hanya klien MCP pada komputer yang sama yang dapat terhubung.", + mcpHttpHostLabel: "Alamat listen", + mcpHttpPortLabel: "Port", + mcpHttpPathLabel: "Jalur MCP", + mcpHttpRemoteTitle: "Akses jarak jauh", + mcpHttpRemoteHintPrefix: "Hanya diperlukan jika alamat listen bukan ", + mcpHttpRemoteHintMiddle: " atau ", + mcpHttpRemoteHintSuffix: ". Setelah diaktifkan, daftar izin Host dan Origin wajib diisi.", + mcpHttpAllowedHostsLabel: "Host yang diizinkan", + mcpHttpHostsHint: "Satu per baris, atau dipisahkan dengan koma.", + mcpHttpAllowedOriginsLabel: "Origin yang diizinkan", + mcpHttpOriginsHintPrefix: "Harus menyertakan protokol, misalnya ", + mcpHttpOriginsHintSuffix: ".", + mcpHttpRemoteDisabledHint: "Selama akses jarak jauh nonaktif, daftar izin tidak diperlukan.", + mcpHttpUnsavedChangesHint: "Konfigurasi di atas belum disimpan; layanan yang sedang berjalan tidak akan langsung berubah.", + mcpHttpSaveHint: "Menyimpan akan memulai, memulai ulang, atau menghentikan layanan sesuai sakelar dan memperbarui detail koneksi di bawah.", + mcpHttpApply: "Simpan dan terapkan", + mcpHttpDisabledHint: "Aktifkan layanan untuk mengonfigurasi alamat listen, daftar izin akses jarak jauh, dan detail koneksi klien.", + mcpHttpConnectionInfoTitle: "Detail koneksi klien aktif", + mcpHttpServiceNotRunning: "Layanan tidak berjalan", + mcpHttpRunningConfigBadge: "Konfigurasi berjalan", + mcpHttpLastStatusBadge: "Status terakhir", + mcpHttpRunningDraftDiffersHint: "Berikut adalah detail koneksi dari layanan yang sedang berjalan; mungkin berbeda dari draf yang belum disimpan di atas.", + mcpHttpEndpointLabel: "Alamat layanan", + mcpHttpRotateToken: "Putar token", + mcpHttpRotateTokenConfirm: "Setelah memutar token, klien MCP yang menggunakan token lama akan langsung terputus. Lanjutkan?", + mcpHttpTokenHintPrefix: "Gunakan nilai ini sebagai kredensial HTTP ", + mcpHttpTokenHintSuffix: " pada klien.", + mcpHttpClientConfigTitle: "Konfigurasi klien HTTP umum", + mcpHttpClientConfigHint: "Nama bidang klien berbeda-beda; pertahankan nilai URL dan Authorization.", + mcpHttpLogsTitle: "Log diagnostik layanan", + mcpHttpValidationHostRequired: "Masukkan alamat listen.", + mcpHttpValidationPortRange: "Port harus berupa bilangan bulat antara 1 dan 65535.", + mcpHttpValidationPathPrefix: "Jalur MCP harus dimulai dengan /.", + mcpHttpValidationRemoteRequired: "Aktifkan 'Akses jarak jauh' untuk mendengarkan pada alamat non-loopback.", + mcpHttpValidationHostsRequired: "Akses jarak jauh memerlukan minimal satu host yang diizinkan.", + mcpHttpValidationOriginsRequired: "Akses jarak jauh memerlukan minimal satu origin yang diizinkan.", + mcpHttpErrorRemoteHostsAndOrigins: "Akses jarak jauh memerlukan daftar izin host dan origin sekaligus.", + mcpHttpErrorRemoteBinding: "Mendengarkan jarak jauh memerlukan akses jarak jauh ditambah daftar izin Host dan Origin.", + mcpHttpErrorPortInUse: "Port ini sudah digunakan oleh aplikasi lain. DBX memulai ulang layanan MCP-nya sendiri saat menyimpan; tutup aplikasi lain yang menggunakan port tersebut, atau pilih port yang berbeda.", + mcpConnectionPolicyTitle: "Izin default koneksi", + mcpConnectionPolicyDescription: "Mengatur default untuk setiap database dalam setiap koneksi yang diekspos; pengaturan database memiliki prioritas di atas default koneksi dan global.", + mcpConnectionPolicyEmptyHint: "Izinkan minimal satu koneksi pada langkah 1 sebelum mengatur izin default koneksi.", + mcpConnectionPolicyInherit: "Warisi global", + mcpConnectionPolicyReadOnly: "Hanya baca", + mcpConnectionPolicySafeWrite: "Izinkan penulisan aman", + mcpConnectionPolicyHighRiskWrite: "Izinkan operasi berisiko tinggi", + mcpConnectionPolicyAllowSalesforceDml: "Izinkan DML", + mcpConnectionPolicyAllowSalesforceDmlHint: "Memungkinkan agen AI membuat, memperbarui, atau menghapus rekaman Salesforce tunggal pada organisasi ini melalui konfirmasi dua langkah (siapkan, lalu terapkan). Mode hanya-baca mengabaikan sakelar ini. Penulisan Salesforce tidak dapat di-rollback.", + mcpConnectionPolicyAllowSalesforceDmlReadOnlyBlocked: "Koneksi ini bersifat hanya-baca, sehingga DML Salesforce tetap dinonaktifkan. Pilih mode eksekusi yang mendukung penulisan terlebih dahulu.", + mcpToolPermissionsTitle: "Izin alat MCP", + mcpToolPermissionsDescription: "Ekspos hanya alat MCP yang Anda butuhkan. Setelah tidak dipilih, klien akan ditolak oleh server meskipun mereka sudah menyimpan definisi alat dalam cache.", + mcpToolCustomPlaceholder: "Tambahkan nama alat atau wildcard, mis. dbx_ssh__*", + mcpToolCustomAdd: "Tambah", + mcpToolCustomRemove: "Hapus entri", + mcpToolCustomHint: "Alat plugin ditemukan saat runtime, sehingga tidak dapat ditampilkan di sini: izinkan satu plugin dengan dbx___*, atau semua alat plugin dengan dbx_*__*. Entri tersimpan di luar kotak centang di atas tetap terlihat dan dapat dihapus di bawah.", + mcpToolListConnections: "Daftar koneksi", + mcpToolListDatabases: "Daftar database", + mcpToolListTables: "Daftar tabel", + mcpToolDescribeTable: "Deskripsikan tabel", + mcpToolListRoutines: "Daftar rutin", + mcpToolGetRoutineSource: "Sumber rutin", + mcpToolGetSchemaContext: "Konteks skema", + mcpToolExecuteQuery: "Eksekusi SQL / perintah Mongo", + mcpToolExecuteBatch: "Eksekusi batch SQL", + mcpToolOpenSession: "Buka sesi kueri", + mcpToolBeginTransaction: "Mulai transaksi", + mcpToolCommitTransaction: "Commit transaksi", + mcpToolRollbackTransaction: "Rollback transaksi", + mcpToolCloseSession: "Tutup sesi kueri", + mcpToolExecuteRedisCommand: "Eksekusi perintah Redis", + mcpToolSalesforceCurrentUser: "Pengguna Salesforce saat ini", + mcpToolSalesforcePrepareWrite: "Siapkan penulisan Salesforce", + mcpToolSalesforceApplyWrite: "Terapkan penulisan Salesforce", + mcpToolPeekMessages: "Baca pesan Kafka", + mcpToolSendMessage: "Kirim pesan antrean pesan", + mcpToolAddConnection: "Tambah koneksi", + mcpToolDuplicateConnection: "Duplikat koneksi", + mcpToolRemoveConnection: "Hapus koneksi", + mcpToolOpenTable: "Buka tabel di DBX", + mcpToolExecuteAndShow: "Eksekusi dan tampilkan di DBX", + mcpToolPluginList: "Katalog plugin", + mcpToolPluginTools: "Daftar alat plugin", + mcpToolPluginCall: "Panggil alat plugin", + supportInfoTitle: "Informasi dukungan", + supportInfoDescription: "Salin detail lingkungan ini saat mengajukan masalah atau meminta bantuan.", + supportInfoCopy: "Salin info dukungan", + supportInfoCopied: "Disalin", + supportInfoLoading: "Memuat informasi dukungan...", + supportInfoLoadFailed: "Gagal memuat informasi dukungan lengkap: {message}", + supportInfoAppVersion: "Versi DBX", + supportInfoRuntime: "Runtime", + supportInfoRuntimeDesktop: "Desktop", + supportInfoRuntimeWeb: "Web", + supportInfoOperatingSystem: "Sistem Operasi", + supportInfoArchitecture: "Arsitektur", + supportInfoUserAgent: "User-Agent", + supportInfoDatabaseTypes: "Jenis Database", + supportInfoLocalDriverVersions: "Versi Driver Lokal", + supportInfoAiProviders: "Penyedia AI", + supportInfoUnknown: "Tidak diketahui", + settingsTransferTitle: "Impor & ekspor pengaturan", + settingsTransferDescription: "Ekspor pengaturan aplikasi ke sebuah file untuk mencadangkan konfigurasi Anda, atau pulihkan pengaturan dari file cadangan.", + settingsTransferExport: "Ekspor", + settingsTransferImport: "Impor", + settingsTransferExportSuccess: "Pengaturan diekspor", + settingsTransferExportFailed: "Gagal mengekspor pengaturan: {message}", + settingsTransferExportChoiceTitle: "Perubahan belum diterapkan", + settingsTransferExportChoiceMessage: "Anda memiliki perubahan pengaturan yang belum diterapkan. Mengekspor pengaturan tersimpan tidak akan menyertakannya.", + settingsTransferExportChoiceSaved: "Ekspor pengaturan tersimpan", + settingsTransferExportChoiceApplied: "Terapkan dan ekspor", + settingsTransferApplyBlocked: "Konflik pengaturan yang belum diselesaikan mencegah penerapan dan ekspor.", + settingsTransferImportReadFailed: "Gagal membaca file pengaturan: {message}", + settingsTransferImportInvalidJson: "File ini bukan file pengaturan JSON yang valid.", + settingsTransferImportUnsupportedVersion: "Versi format file pengaturan tidak didukung: v{version}. Versi yang didukung: v{supported}.", + settingsTransferImportInvalidStructure: "Struktur file pengaturan tidak valid.", + settingsTransferImportEmpty: "File pengaturan tidak berisi pengaturan yang dapat diimpor.", + settingsTransferImportFieldInvalid: "File pengaturan berisi bidang yang tidak valid. Impor dibatalkan: {fields}", + settingsTransferImportFileTooLarge: "File pengaturan terlalu besar. Ukuran maksimum: {limit}.", + settingsTransferImportConfirmTitle: "Impor pengaturan", + settingsTransferImportConfirmFile: "File", + settingsTransferImportConfirmSourceVersion: "Versi aplikasi sumber", + settingsTransferImportConfirmIncludes: "Mencakup", + settingsTransferImportConfirmDraftWarning: "Kategori berikut memiliki perubahan yang belum diterapkan dan akan digantikan: {categories}", + settingsTransferImportConfirmAction: "Muat pengaturan", + settingsTransferImportLoaded: "Pengaturan dimuat. Klik Terapkan untuk menyimpannya.", + settingsTransferCategoryOther: "Lainnya", + qqGroup: "Grup QQ", + feishuGroup: "Grup Feishu", + wechatGroup: "Grup WeChat", + wechatGroupInvite: "Undangan Tencent Docs", + openSource: "Repositori sumber terbuka", + officialDocs: "Dokumentasi resmi", + changelogTitle: "Log Perubahan", + changelogDescription: "Lihat apa yang baru di setiap rilis.", + changelogLoading: "Memuat log perubahan...", + changelogLoadFailed: "Gagal memuat log perubahan.", + changelogEmpty: "Belum ada entri log perubahan.", + changelogPublishedOn: "Diterbitkan pada {date}", + changelogNew: "BARU", + changelogLoadMore: "Muat lebih banyak", + changelogOpenWebsite: "Lihat di situs web", + changelogOpenGitHub: "Rilis GitHub", + changelogNoDetails: "Lihat Rilis GitHub untuk detailnya.", + changelogRetry: "Coba Lagi", + changelogSectionAdded: "Fitur Baru", + changelogSectionImproved: "Peningkatan", + changelogSectionFixed: "Perbaikan Bug", + changelogSectionChanged: "Perubahan", + changelogSectionRemoved: "Dihapus", + shortcutUppercaseSelection: "Ubah seleksi menjadi huruf besar", + shortcutLowercaseSelection: "Ubah seleksi menjadi huruf kecil", + shortcutConvertNamingStyle: "Alihkan gaya penamaan", + shortcutExPasteSqlInCondition: "ExPaste: tempel sebagai kondisi IN", + }, + driverStore: { + jreDirRemoveFailed: "Gagal menghapus direktori JRE lama: {path} (galat asli: {error})", + jreDirRemoveFailedWindows: + "Gagal menghapus direktori JRE lama: {path}\nKemungkinan penyebab:\n - proses dbx Agent / java masih menggunakan direktori ini\n - perangkat lunak antivirus sedang memindainya\nTutup proses apa pun yang mungkin menggunakan direktori ini, atau mulai ulang dbx dan coba lagi.\n(galat asli: {error})", + jreInUseByDrivers: "JRE {jre} sedang digunakan oleh driver: {drivers}. Hapus driver tersebut terlebih dahulu.", + offlinePackageRegistryMissing: "agent-registry.json tidak ditemukan di dalam ZIP; ini bukan paket driver offline yang valid.", + progressJreExtract: "Mengekstrak JRE...", + progressDownloadJre: "Mengunduh JRE", + progressDownloadDriver: "Mengunduh driver", + progressDownloadJdbcPlugin: "Mengunduh plugin JDBC", + progressJdbcPluginExtract: "Menginstal plugin JDBC...", + usageTitle: "Penggunaan penyimpanan", + usageTotal: "Total {size}", + usageTotalLabel: "Total", + calculating: "Menghitung...", + usageManagedJre: "JRE terkelola", + usageAgentDrivers: "Agen driver bawaan", + usageDownloadCache: "Cache unduhan", + usageJdbcPlugin: "Plugin JDBC", + usageJdbcDriverJars: "JAR driver JDBC", + clearDownloadCache: "Bersihkan cache", + downloadCacheClearSuccess: "Cache unduhan dibersihkan", + downloadCacheClearFailed: "Gagal membersihkan cache unduhan: {error}", + driverCategoryAll: "Semua Driver", + driverCategoryLabel: "Kategori", + offlineDownloadHint: "Untuk lingkungan air-gapped, unduh paket driver offline di komputer yang terhubung internet, lalu impor di sini.", + offlineDownloadLink: "Unduhan driver offline", + searchDrivers: "Cari nama, tipe, versi driver...", + searchJdbcDrivers: "Cari nama atau path driver JDBC...", + jdbcMavenCoordinatePlaceholder: "Koordinat Maven, mis. org.postgresql:postgresql:42.7.7", + jdbcMavenInstall: "Instal dari Maven", + jdbcMavenInstallSuccess: "Driver Maven JDBC terinstal", + jdbcSourceMaven: "Maven", + jdbcSourceManual: "Manual", + noMatchingDrivers: "Tidak ada driver yang cocok.", + statusFilterLabel: "Status instalasi", + statusFilterAll: "Semua {count}", + statusFilterInstalled: "Terinstal {count}", + statusFilterAvailable: "Tersedia {count}", + installedBadge: "Terinstal", + noInstalledDrivers: "Belum ada driver bawaan yang terinstal.", + noInstalledDriversHint: "Beralih ke Semua untuk menelusuri dan menginstal driver yang Anda butuhkan.", + noAvailableDrivers: "Semua driver bawaan sudah terinstal.", + noAvailableDriversHint: "Beralih ke Semua atau Terinstal untuk mengelola driver pada mesin ini.", + showAllDrivers: "Tampilkan semua driver", + javaRuntimeSaved: "Pengaturan Java runtime disimpan", + javaRuntimeSaveFailed: "Gagal menyimpan pengaturan Java runtime: {error}", + chooseJavaExecutable: "Pilih executable Java", + driverInstallSuccess: "Driver {label} terinstal", + driverInstallFailed: "Gagal menginstal driver {label}: {error}", + driverInstallCancelled: "Instalasi driver {label} dibatalkan", + driverUpdateBlocked: "Tutup koneksi database berikut sebelum memperbarui driver: {labels}", + upgradeAllSuccess: "{count} driver berhasil diperbarui", + upgradeAllPartial: "{count} driver berhasil diperbarui. Dilewati: {failed}", + upgradeAllFailed: "Pembaruan massal gagal: {error}", + upgradeAllCancelled: "Pembaruan dibatalkan ({count} driver dibatalkan)", + cancelInstall: "Batalkan instalasi", + cancelUpgradeAll: "Batalkan pembaruan massal", + driverUninstallSuccess: "Driver {label} dihapus", + driverUninstallFailed: "Gagal menghapus driver {label}: {error}", + chooseOfflineDriverPackage: "Pilih paket driver offline", + offlineImportSuccess: "Impor offline selesai. {count} driver terinstal.", + offlineJreImportSuccess: "Impor offline selesai. {jreCount} JRE terinstal.", + offlineImportWithJreSuccess: "Impor offline selesai. {jreCount} JRE dan {count} driver terinstal.", + offlineImportFailed: "Impor offline gagal: {error}", + offlineImportPartial: "Impor offline selesai dengan masalah: {failed} item gagal, {jreCount} JRE dan {count} driver terinstal. {item}: {error}", + driverImportSuccess: "Driver {label} diimpor", + driverImportFailed: "Gagal mengimpor driver {label}: {error}", + chooseDriverJar: "Pilih file driver", + jreReinstallSuccess: "JRE {jre} diinstal ulang", + jreReinstallFailed: "Gagal menginstal ulang JRE {jre}: {error}", + jreUninstallSuccess: "JRE {jre} dihapus", + chooseJdbcPluginZip: "Pilih file zip plugin JDBC", + agentDrivers: "Driver Bawaan", + jdbcDrivers: "Driver JDBC", + importing: "Mengimpor...", + importOfflinePackage: "Impor paket offline", + offlineExport: "Ekspor paket offline", + offlineExportTitle: "Ekspor paket Agent offline", + offlineExportDescription: "Pilih driver Agent yang dikelola DBX untuk disertakan. Paket ini hanya kompatibel dengan platform saat ini.", + offlineExportPlatform: "Platform", + offlineExportSelectedCount: "{selected} dari {total} dipilih", + offlineExportSelectAll: "Pilih semua", + offlineExportClear: "Bersihkan", + offlineExportNoDrivers: "Tidak ada driver Agent yang dikelola DBX dan memenuhi syarat terinstal.", + offlineExportArtifactJar: "Java JAR", + offlineExportArtifactNative: "Native", + offlineExportArtifactUnknown: "Tidak diketahui", + offlineExportPreparing: "Menyiapkan pratinjau ekspor...", + offlineExportJreSummary: "{count} JRE terkelola akan disertakan secara otomatis.", + offlineExportSecurityHint: "Hanya artefak yang dikelola DBX dan JRE terkelola yang diperlukan yang disertakan. Path lokal, pengaturan, dan driver eksternal tidak disertakan.", + offlineExportStart: "Ekspor {count} driver", + offlineExporting: "Mengekspor...", + offlineExportPreviewFailed: "Tidak dapat menyiapkan ekspor: {error}", + offlineExportChooseDestination: "Simpan paket Agent offline", + offlineExportSuccess: "Berhasil mengekspor {file}: {drivers} driver, {jres} JRE, {size}.", + offlineExportFailed: "Ekspor paket offline gagal: {error}", + offlineExportUnavailable_unmanagedInstall: "Artefak ini tidak dilacak sebagai instalasi yang dikelola DBX.", + offlineExportUnavailable_localInstall: "Build Agent yang diimpor secara lokal tidak disertakan.", + offlineExportUnavailable_launchConfig: "Konfigurasi peluncuran kustom bersifat spesifik per mesin.", + offlineExportUnavailable_missingArtifact: "Artefak Agent yang terinstal tidak ditemukan.", + offlineExportUnavailable_invalidArtifact: "Artefak Agent yang terinstal tidak valid atau rusak.", + offlineExportUnavailable_unsafeSource: "Artefak berada di luar penyimpanan terkelola atau menggunakan symbolic link.", + offlineExportUnavailable_externalDriverRequired: "Agent ini memerlukan driver eksternal yang disediakan pengguna.", + offlineExportUnavailable_missingManagedJre: "JRE terkelola DBX yang diperlukan belum terinstal.", + offlineExportUnavailable_invalidManagedJre: "JRE terkelola DBX yang diperlukan tidak valid atau tidak aman.", + refresh: "Segarkan", + javaRuntime: "Java Runtime", + javaRuntimeManaged: "JRE terkelola DBX", + javaRuntimeSystem: "Java sistem", + javaRuntimeCustom: "Path kustom", + saving: "Menyimpan...", + customJavaPathPlaceholder: "/path/ke/java atau /path/ke/jdk", + choose: "Pilih", + systemJavaHint: "Selesaikan java dari JAVA_HOME terlebih dahulu, lalu PATH.", + jreRuntimeTitle: "Runtime JRE {jre}", + notInstalled: "Belum terinstal", + reinstalling: "Menginstal ulang", + installing: "Menginstal", + install: "Instal", + reinstall: "Instal ulang", + uninstall: "Hapus instalasi", + jreRuntime: "Runtime JRE", + jreRuntimeAutoDownloadHint: "Diunduh secara otomatis saat menginstal driver untuk pertama kalinya", + driversUpdatable: "{count} driver dapat diperbarui", + updatesAvailableTitle: "Pembaruan Tersedia", + updatesAvailableDescription: "Versi baru tersedia untuk driver di bawah ini. Perbarui untuk mendapatkan fitur dan perbaikan terbaru.", + allDriversTitle: "Semua Driver", + upgradingProgress: "Memperbarui ({current}/{total})", + upgradeAll: "Perbarui semua", + queued: "Dalam antrean", + importLocalJar: "Impor file driver lokal", + updating: "Memperbarui", + update: "Perbarui", + localInstall: "Instalasi lokal", + localInstallHint: "Untuk mesin air-gapped: di komputer lain yang terhubung internet, unduh dbx-jdbc-plugin-*.zip resmi dari halaman GitHub Releases DBX, pindahkan ke sini, lalu pilih file tersebut — tidak diperlukan akses jaringan di mesin ini.", + runtimeDrivers: "Runtime", + pluginsTab: "Plugin", + pluginContributionsTitle: "Kontribusi plugin frontend", + pluginContributionsDescription: "Plugin yang terinstal dapat mendeskripsikan form koneksi dan kontribusi UI lainnya tanpa menyisipkan kode ke jendela utama DBX.", + noInstalledPlugins: "Tidak ada plugin yang terinstal", + noInstalledPluginsDescription: "Instal plugin backend untuk melihat pratinjau kontribusi frontend-nya di sini.", + pluginHostPreview: "Pratinjau Host API", + pluginNoFrontendContribution: "Plugin ini belum mendeklarasikan kontribusi frontend.", + storageTab: "Penyimpanan", + runtimeTitle: "Runtime driver", + runtimeHint: "Metrik runtime hanya dikumpulkan selagi panel ini terbuka.", + runtimeRunning: "Berjalan", + runtimeMemory: "Memori", + runtimeHealth: "Kesehatan", + runtimeHealth_healthy: "Sehat", + runtimeHealth_warning: "Peringatan", + runtimeHealth_error: "Galat", + runtimeLastError: "Galat terakhir", + runtimeEmpty: "Belum ada runtime driver. Buka koneksi berbasis agent untuk memulai satu.", + runtimeKindAgent: "Agent", + runtimeKindPlugin: "Plugin", + runtimeSourceDaemon: "Daemon", + runtimeSourceConnection: "Koneksi", + runtimeStatus_running: "Berjalan", + runtimeStatus_stopped: "Berhenti", + runtimeStatus_error: "Galat", + runtimeStatus_unknown: "Tidak diketahui", + runtimePid: "PID", + runtimeUptime: "Waktu aktif", + runtimeActions: "Aksi", + runtimeStop: "Hentikan", + runtimeRestart: "Mulai ulang", + runtimeControlConnectionOwned: "Tutup koneksi terkait untuk menghentikan runtime ini.", + runtimeStopSuccess: "Runtime {label} dihentikan", + runtimeStopFailed: "Gagal menghentikan {label}: {error}", + runtimeRestartSuccess: "Runtime {label} dimulai ulang", + runtimeRestartFailed: "Gagal memulai ulang {label}: {error}", + driverStoreDir: "Path Penyimpanan Driver", + driverStoreDirDescription: "Tetapkan lokasi penyimpanan terpisah untuk plugin JDBC dan data Agent/JRE. Aplikasi akan dimulai ulang secara otomatis setelah migrasi.", + pluginStoreDir: "Direktori plugin JDBC", + pluginStoreDirDescription: "Menyimpan plugin JDBC, resolver Maven, dan JAR driver JDBC.", + agentStoreDir: "Direktori Agent / JRE", + agentStoreDirDescription: "Menyimpan paket driver Agent, JRE terkelola, dan cache runtime.", + driverStoreDirDefault: "Default (direktori instalasi)", + driverStoreDirChange: "Ubah", + driverStoreDirReset: "Reset ke Default", + driverStoreDirMigrating: "Memigrasikan {target}…", + driverStoreDirConfirm: "Mengubah {target} akan memigrasikan data driver terkait ke lokasi baru. Koneksi driver terkait mungkin terputus selama migrasi. Aplikasi akan dimulai ulang secara otomatis setelah migrasi. Lanjutkan?", + driverStoreDirMigrationFailed: "Migrasi penyimpanan driver gagal: {error}", + driverStoreDirDialogTitle: "Pilih {target}", + driverStoreDirSuccess: "{target} diubah, memulai ulang…", + }, + databaseExport: { + title: "Ekspor Database", + options: "Opsi", + includeStructure: "Struktur tabel (DDL)", + includeCreateDatabase: "Sertakan pengaturan database (CREATE DATABASE / USE)", + dropTableIfExists: "Tambahkan DROP TABLE IF EXISTS sebelum DDL", + omitAutoIncrement: "Abaikan AUTO_INCREMENT (untuk skrip instalasi baru)", + includeData: "Data tabel (INSERT)", + sqlColumnSelection: "Kolom yang diekspor", + selectedColumns: "{selected}/{total} kolom dipilih", + selectAllColumns: "Pilih semua", + clearColumns: "Bersihkan", + selectAtLeastOneColumn: "Pilih setidaknya satu kolom untuk diekspor.", + standardSqlInsert: "Gunakan Standard SQL INSERT untuk data tabel", + standardSqlInsertDescription: "Menggunakan identifier bertanda kutip ganda ANSI dan literal skalar yang portabel. DDL dan objek lainnya tetap mengikuti dialek database sumber.", + includeObjects: "Tampilan / Prosedur / Fungsi / Sequence", + splitSqlOutput: "Pecah ekspor SQL menjadi arsip ZIP", + splitSqlPartMaxMb: "Ukuran maksimum per bagian SQL (MB)", + splitSqlOutputDescription: "Membuat arsip ZIP berisi bagian-bagian SQL bernomor dan sebuah manifest. Bagian dipecah di antara pernyataan SQL yang lengkap ({min}–{max} MB).", + databaseSelection: "Database", + selectedDatabases: "{selected}/{total} dipilih", + selectAllDatabases: "Pilih semua", + filterDatabases: "Cari database...", + clearDatabases: "Bersihkan", + tableSelection: "Tabel", + selectedTables: "{selected}/{total} dipilih", + selectAllTables: "Pilih semua", + filterTables: "Cari tabel...", + clearTables: "Bersihkan", + loadingTables: "Memuat tabel...", + tableLoadError: "Gagal memuat tabel: {error}", + noTables: "Tidak ada tabel ditemukan", + export: "Ekspor", + exportAllDatabases: "Ekspor Semua Database", + allSchemas: "Semua skema", + exporting: "Mengekspor...", + preparing: "Menyiapkan ekspor (membaca tabel dan metadata)...", + preparingObject: "Menyiapkan: {object}", + selectExportDirectory: "Pilih direktori ekspor", + currentDatabase: "Database {current}/{total}", + currentTable: "Saat ini: {table} ({current}/{total})", + rowsExported: "{current}/{total} objek diproses, {count} baris diekspor", + allRowsExported: "Total baris diekspor: {count}", + exportSuccess: "Database berhasil diekspor", + exportAllSuccess: "{count} database berhasil diekspor", + exportSuccessWithErrors: "Ekspor selesai dengan {count} objek gagal: {firstError}… Lihat komentar -- ERROR di dalam file yang diekspor untuk detailnya.", + exportAllSuccessWithErrors: "{count} database diekspor, tetapi {errorCount} objek gagal: {firstError}… Lihat komentar -- ERROR di dalam file yang diekspor.", + allDatabasesTask: "Semua database ({count})", + exportError: "Ekspor gagal: {error}", + exportCancelled: "Ekspor dibatalkan", + runInBackground: "Jalankan di latar belakang", + }, + databaseBackup: { + savedTimeZoneHint: "Proses berikutnya menggunakan zona waktu yang tersimpan pada jadwal.", + backgroundWorker: "Pencadangan latar belakang setelah DBX ditutup", + backgroundLoginScope: "Berjalan selagi Anda masih masuk. Komputer harus tetap menyala.", + serverRuntime: "Server menjalankan pencadangan meski browser ditutup.", + workerLastSeen: "Heartbeat worker terakhir: {time}", + workerStarting: "Menunggu worker pencadangan", + serverDestination: "Root pencadangan server: {path}", + timeZone: "Zona waktu (IANA)", + title: "Pencadangan Database", + schedules: "Jadwal pencadangan", + runtimeRequirement: "Pencadangan terjadwal berjalan selagi DBX terbuka, termasuk saat diminimalkan ke tray.", + addSchedule: "Tambah jadwal", + oneShotBackup: "Cadangkan sekarang", + oneShotDescription: "Jalankan pencadangan database satu kali. Hasilnya akan muncul di riwayat pencadangan setelah selesai.", + startBackup: "Mulai pencadangan", + noSupportedConnections: "Buat koneksi MySQL atau PostgreSQL sebelum menambahkan jadwal pencadangan.", + editSchedule: "Edit jadwal", + defaultScheduleName: "Pencadangan database", + oneShotName: "Pencadangan satu kali", + noSchedules: "Tidak ada jadwal pencadangan", + noSchedulesHint: "Buat jadwal pencadangan berulang, atau jalankan pencadangan satu kali sekarang.", + scheduleName: "Nama jadwal", + connection: "Koneksi", + missingConnection: "Koneksi tidak ditemukan", + destination: "Direktori tujuan", + selectDestination: "Pilih direktori pencadangan", + outputPathTemplate: "Template path keluaran", + outputPathPreview: "Pratinjau path keluaran", + fileNamePattern: "Template nama file", + fileNamePatternHint: "Gunakan {'{'}schedule{'}'}, {'{'}date{'}'}, {'{'}timestamp{'}'}, {'{'}database{'}'}, dan {'{'}runId{'}'}. DBX menambahkan nilai {'{'}database{'}'} yang hilang dan menambahkan ekstensi secara otomatis.", + templateVariablesHelp: "Lihat deskripsi variabel yang tersedia", + templateVariablesTitle: "Variabel yang tersedia", + templateVariableSchedule: "Nama jadwal pencadangan", + templateVariableDate: "Tanggal pencadangan dalam format YYYYMMDD", + templateVariableTimestamp: "Timestamp yang digunakan dalam path keluaran pencadangan", + templateVariableDatabase: "Nama target database pencadangan saat ini", + templateVariableRunId: "8 karakter pertama dari ID proses pencadangan ini", + fileNamePatternInvalid: "Gunakan nama file tanpa pemisah path, karakter yang dicadangkan, atau titik/spasi di akhir.", + runDirectoryPattern: "Template direktori proses", + runDirectoryPatternHint: "Path relatif di bawah direktori tujuan. Gunakan {'{'}schedule{'}'}, {'{'}date{'}'}, {'{'}timestamp{'}'}, dan {'{'}runId{'}'}. Default menyertakan {'{'}runId{'}'} untuk isolasi tambahan. Contoh: {'{'}schedule{'}'}/{'{'}date{'}'}/{'{'}timestamp{'}'}-{'{'}runId{'}'}", + runDirectoryPreview: "Pratinjau direktori", + runDirectoryPatternInvalid: "Gunakan path relatif tanpa segmen . atau ..", + compression: "Kompresi", + compressionNone: "Tanpa kompresi (.sql)", + compressionGzip: "Gzip (.sql.gz)", + searchConnections: "Cari koneksi…", + noMatchingConnections: "Tidak ada koneksi yang cocok", + searchDatabases: "Cari database…", + noMatchingDatabases: "Tidak ada database yang cocok", + databaseListLoadFailed: "Tidak dapat memuat database untuk {name}. Periksa koneksi ini atau pilih koneksi lain.", + databases: "Database", + allDatabases: "Semua database", + databaseCount: "{count} database", + tableScope: "Cakupan tabel", + allTables: "Semua tabel dan tampilan", + includeTables: "Hanya sertakan yang cocok", + excludeTables: "Kecualikan yang cocok", + tablePatterns: "Aturan nama tabel", + tablePatternsPlaceholder: "orders, audit_*, public.users", + tablePatternsHint: "Pisahkan aturan dengan koma. Wildcard * dan ? serta schema.table didukung.", + includedTablePatterns: "{count} aturan sertakan", + excludedTablePatterns: "{count} aturan kecualikan", + frequency: "Frekuensi", + frequencyHourly: "Setiap beberapa jam", + frequencyDaily: "Harian", + frequencyWeekly: "Mingguan", + intervalHours: "Interval (jam)", + time: "Waktu", + weekday: "Hari dalam seminggu", + retention: "Simpan hasil terbaru", + contents: "Isi pencadangan", + enabled: "Jadwal diaktifkan", + enabledHint: "Proses berikutnya dihitung dalam zona waktu lokal Anda.", + nextRun: "Berikutnya: {time}", + nextRunPreview: "Proses berikutnya: {time}", + keepRuns: "Simpan {count}", + everyHours: "Setiap {count} jam", + dailyAt: "Harian pada {time}", + weeklyAt: "{weekday} pada {time}", + never: "Tidak pernah", + enable: "Aktifkan jadwal", + disable: "Nonaktifkan jadwal", + runNow: "Cadangkan sekarang", + cancel: "Batalkan pencadangan", + cancelling: "Membatalkan…", + cancelRequested: "Pembatalan diminta. Menghentikan operasi yang sedang berjalan.", + edit: "Edit", + delete: "Hapus", + scheduleCreated: "Jadwal pencadangan dibuat", + scheduleUpdated: "Jadwal pencadangan diperbarui", + deleteSchedule: "Hapus jadwal", + deleteScheduleConfirm: 'Hapus jadwal "{name}"? File pencadangan yang ada akan tetap berada di riwayat.', + cannotDeleteRunningSchedule: "Jadwal pencadangan yang sedang berjalan tidak dapat dihapus", + history: "Riwayat pencadangan", + noHistory: "Belum ada pencadangan", + allConnections: "Semua koneksi", + searchHistoryConnections: "Cari koneksi…", + backupMethod: "Metode pencadangan", + allBackupMethods: "Semua metode", + backupStatus: "Status pencadangan", + allStatuses: "Semua status", + noFilteredHistory: "Tidak ada catatan pencadangan yang cocok", + selectAllFiltered: "Pilih semua yang difilter", + selectRun: "Pilih {name}", + selectedRuns: "{count} dipilih", + deleteSelected: "Hapus yang dipilih", + showFiles: "Tampilkan file pencadangan", + scheduledTrigger: "Terjadwal", + manualTrigger: "Manual", + oneShotTrigger: "Satu kali", + fileCount: "{count} file", + progress: "Progres pencadangan", + renameBackup: "Ganti nama pencadangan", + backupName: "Nama pencadangan", + backupRenamed: "Nama pencadangan diubah", + revealFile: "Tampilkan di pengelola file", + restore: "Pulihkan", + deleteBackup: "Hapus pencadangan", + deleteBackupConfirm: "Hapus pencadangan ini beserta {count} file SQL-nya? Tindakan ini tidak dapat dibatalkan.", + deleteBackupsConfirm: "Hapus {count} pencadangan beserta {files} file SQL-nya? Tindakan ini tidak dapat dibatalkan.", + backupDeleted: "Pencadangan dihapus", + backupsDeleted: "{count} pencadangan dihapus", + runSuccess: "Pencadangan selesai dengan {count} file", + runCancelled: "Pencadangan dibatalkan", + runFailed: "Pencadangan gagal: {error}", + unknownError: "Galat tidak diketahui", + status: { + running: "Berjalan", + success: "Selesai", + failed: "Gagal", + cancelled: "Dibatalkan", + }, + weekdays: { + sunday: "Minggu", + monday: "Senin", + tuesday: "Selasa", + wednesday: "Rabu", + thursday: "Kamis", + friday: "Jumat", + saturday: "Sabtu", + }, + }, + mqTopics: { + title: "Topik", + searchPlaceholder: "Cari topik", + includeNonPersistent: "Sertakan topik non-persistent", + refresh: "Segarkan", + refreshing: "Menyegarkan...", + createTopic: "Buat Topik", + selectTenantNamespace: "Pilih tenant dan namespace terlebih dahulu", + loading: "Memuat...", + noTopics: "Tidak ada topik di namespace ini", + noMatches: "Tidak ada topik yang cocok", + name: "Nama", + type: "Tipe", + partitions: "Partisi", + actions: "Aksi", + nonPersistent: "Non-persistent", + partitionedTopic: "Topik berpartisi", + normalTopic: "Topik normal", + systemTopic: "Topik sistem", + includeSystemTopics: "Sertakan topik sistem", + noUserTopics: "Tidak ada topik pengguna. Aktifkan filter tipe untuk memeriksa topik internal, retry, atau DLQ.", + typeFilter: "Filter tipe", + messageType: "Tipe pesan", + messageTypeHint: "Menyimpan message.type RocketMQ secara persisten pada konfigurasi topik broker, sesuai dengan RocketMQ Dashboard.", + rocketmqType: { + normal: "Normal", + delay: "Tunda", + fifo: "Berurutan", + transaction: "Transaksi", + unspecified: "Tidak ditentukan", + retry: "Retry", + dlq: "Dead letter", + system: "Sistem", + }, + partitionCount: "{count} partisi", + partitionsUnknown: "Jumlah partisi tidak diketahui", + adjustPartitions: "Sesuaikan partisi", + delete: "Hapus", + tenantNamespace: "Tenant / Namespace", + topicName: "Nama topik", + topicNamePlaceholder: "mis. my-topic", + persistentRecommended: "Topik persistent (disarankan)", + persistentHint: "Topik persistent menyimpan pesan di disk; topik non-persistent hanya menyimpannya di memori.", + enablePartitions: "Aktifkan partisi", + partitionQuantity: "Jumlah partisi", + partitionHint: "Partisi dapat meningkatkan konkurensi tetapi menambah penggunaan sumber daya.", + cancel: "Batal", + create: "Buat", + updatePartitionsTitle: "Sesuaikan partisi: {name}", + currentPartitions: "Partisi saat ini", + newPartitions: "Partisi baru", + partitionMinHint: "Partisi hanya dapat ditambah, tidak dikurangi. Minimum: {min}", + update: "Perbarui", + readOnly: "Koneksi ini bersifat read-only dan tidak dapat melakukan operasi tulis.", + topicNameRequired: "Nama topik wajib diisi", + currentPartitionsUnknown: "Jumlah partisi saat ini tidak diketahui, sehingga partisi tidak dapat disesuaikan dengan aman.", + partitionMustIncrease: "Jumlah partisi baru harus lebih besar dari jumlah partisi saat ini.", + confirmDelete: 'Hapus topik "{name}"? Tindakan ini tidak dapat dibatalkan.', + queues: "Antrean", + tabQueues: "Antrean", + tabExchanges: "Exchange", + queueCount: "{count} antrean", + clusterName: "Cluster", + brokerName: "Broker", + allBrokers: "Semua broker master", + readQueues: "Antrean baca", + writeQueues: "Antrean tulis", + perm: "Izin", + permReadWrite: "Baca + Tulis (6)", + permRead: "Hanya baca (4)", + permWrite: "Hanya tulis (2)", + actionStatus: "Status", + actionRoute: "Rute", + actionConsumers: "Consumer", + actionConfig: "Konfigurasi", + actionSend: "Kirim", + actionMessageQuery: "Kueri pesan", + actionReset: "Reset offset", + actionSkip: "Lewati backlog", + topicStatusTitle: "Status topik: {name}", + topicRouteTitle: "Rute topik: {name}", + topicConsumersTitle: "Consumer: {name}", + topicConfigTitle: "Konfigurasi topik: {name}", + topicConfigHint: "Sama seperti RocketMQ Dashboard: hanya jumlah antrean baca/tulis dan izin yang dapat diedit. Tipe pesan ditetapkan saat membuat topik.", + topicResetTitle: "Reset offset: {name}", + topicSkipTitle: "Lewati akumulasi: {name}", + confirmSkip: 'Lewati backlog untuk semua consumer group pada topik "{name}"?', + skipHint: "Mereset semua consumer group yang berlangganan ke offset terbaru untuk topik ini.", + saveConfig: "Simpan konfigurasi", + resetPosition: "Reset posisi", + positionEarliest: "Paling awal", + positionLatest: "Terbaru", + positionTimestamp: "Berdasarkan waktu", + timestamp: "Waktu", + invalidTimestamp: "Masukkan waktu yang valid", + resetTimePreview: "Waktu yang dipilih: {time}", + noConsumerGroups: "Tidak ada consumer group", + noConsumers: "Tidak ada consumer group yang berlangganan topik ini", + manageConsumers: "Kelola", + routeQueues: "Data antrean", + routeBrokers: "Data broker", + brokerAddrs: "Alamat broker", + noRouteData: "Tidak ada data rute", + noQueueStats: "Tidak ada statistik antrean", + noConfig: "Tidak ada konfigurasi topik yang dikembalikan", + queueId: "Antrean", + beginOffset: "Offset minimum", + endOffset: "Offset maksimum", + messageCount: "Pesan", + // Kolom tabel antrean RabbitMQ (issue #6600) + rabbitmqQueueType: "Tipe", + rabbitmqQueueTypeHint: "Tipe antrean yang dilaporkan oleh management API (type atau x-queue-type); classic / quorum / stream", + rabbitmqQueueTypeUnknown: "Antrean", + rabbitmqFeatures: "Fitur", + rabbitmqState: "Status", + rabbitmqArguments: "Argumen", + consumers: "Consumer", + rabbitmqRates: "Laju", + rabbitmqPublishRate: "Publish", + rabbitmqDeliverRate: "Deliver/Get", + rabbitmqAckRate: "Ack", + }, + mqExchanges: { + searchPlaceholder: "Cari exchange", + refresh: "Segarkan", + refreshing: "Menyegarkan...", + createExchange: "Buat Exchange", + selectNamespace: "Pilih virtual host terlebih dahulu", + loading: "Memuat...", + noExchanges: "Tidak ada exchange di virtual host ini", + noMatches: "Tidak ada exchange yang cocok", + name: "Nama", + type: "Tipe", + durable: "Durable", + autoDelete: "Hapus otomatis", + actions: "Aksi", + builtin: "Bawaan", + viewBindings: "Binding", + delete: "Hapus", + yes: "Ya", + no: "Tidak", + bindingsTitle: "Binding dari {name}", + bindDestination: "Bind", + noBindings: "Tidak ada binding dari exchange ini", + bindingSource: "Sumber", + bindingDestination: "Tujuan", + bindingType: "Tipe", + routingKey: "Routing key", + arguments: "Argumen", + unbind: "Hapus binding", + destinationTypeQueue: "Antrean", + destinationTypeExchange: "Exchange", + virtualHost: "Virtual host", + namePlaceholder: "mis. dbx-events", + cancel: "Batal", + create: "Buat", + bind: "Bind", + bindDialogTitle: "Bind ke {name}", + queueNamePlaceholder: "mis. dbx-queue", + exchangeNamePlaceholder: "mis. dbx-events", + routingKeyPlaceholder: "mis. orders.*", + argumentsPlaceholder: "Objek JSON opsional, mis. {'{'}\"x-match\": \"all\"{'}'}", + nameRequired: "Nama exchange wajib diisi", + destinationRequired: "Tujuan wajib diisi", + argumentsMustBeObject: "Argumen harus berupa objek JSON", + readOnly: "Koneksi ini bersifat read-only dan tidak dapat melakukan operasi tulis.", + confirmDelete: 'Hapus exchange "{name}"? Tindakan ini tidak dapat dibatalkan.', + confirmUnbind: 'Hapus binding dari "{source}" ke "{destination}"?', + }, + mqClientConnections: { + searchPlaceholder: "Cari koneksi", + refresh: "Segarkan", + refreshing: "Menyegarkan...", + loading: "Memuat...", + noConnections: "Tidak ada koneksi klien", + noMatches: "Tidak ada koneksi yang cocok", + name: "Nama", + user: "Pengguna", + peerAddress: "Alamat Peer", + state: "Status", + channels: "Channel", + recvRate: "Laju Terima", + sendRate: "Laju Kirim", + connectedAt: "Terhubung Pada", + actions: "Aksi", + closeConnection: "Tutup Koneksi", + confirmClose: 'Tutup koneksi "{name}"? Semua channel-nya akan ditutup dan ini tidak dapat dibatalkan.', + readOnly: "Koneksi ini bersifat read-only; operasi tulis dinonaktifkan.", + noChannels: "Tidak ada channel pada koneksi ini", + channelName: "Channel", + prefetch: "Prefetch", + unacked: "Belum di-ack", + consumers: "Consumer", + }, + mqUserPermissions: { + usersTitle: "Pengguna", + permissionsTitle: "Izin", + refresh: "Segarkan", + refreshing: "Menyegarkan...", + loading: "Memuat...", + createUser: "Buat Pengguna", + grantPermission: "Berikan Izin", + searchUsers: "Cari pengguna", + noUsers: "Tidak ada pengguna", + noUserMatches: "Tidak ada pengguna yang cocok", + name: "Nama", + tags: "Tag", + actions: "Aksi", + delete: "Hapus", + confirmDeleteUser: 'Hapus pengguna "{name}"? Tindakan ini tidak dapat dibatalkan.', + password: "Kata Sandi", + tagsPlaceholder: "Dipisahkan koma, mis. administrator, monitoring", + nameRequired: "Nama pengguna wajib diisi", + passwordRequired: "Kata sandi wajib diisi", + cancel: "Batal", + create: "Buat", + user: "Pengguna", + vhost: "Virtual host", + configure: "Konfigurasi", + write: "Tulis", + read: "Baca", + noPermissions: "Tidak ada izin", + revoke: "Cabut", + confirmRevoke: 'Cabut izin pengguna "{user}" pada virtual host "{vhost}"?', + grant: "Berikan", + selectUser: "Pilih pengguna", + selectVhost: "Pilih virtual host", + patternHint: "Ekspresi reguler yang dicocokkan dengan nama resource; kosong berarti default .* (semua).", + userRequired: "Pilih pengguna", + vhostRequired: "Pilih virtual host", + readOnly: "Koneksi ini bersifat read-only; operasi tulis dinonaktifkan.", + }, + mqRabbitMqPolicies: { + title: "Policy", + refresh: "Segarkan", + refreshing: "Menyegarkan...", + loading: "Memuat...", + createPolicy: "Buat Policy", + editPolicy: "Edit Policy", + noPolicies: "Tidak ada policy", + name: "Nama", + vhost: "Virtual host", + pattern: "Pola", + applyTo: "Berlaku untuk", + priority: "Prioritas", + definition: "Definisi", + actions: "Aksi", + edit: "Edit", + delete: "Hapus", + confirmDelete: 'Hapus policy "{name}" pada virtual host "{vhost}"?', + cancel: "Batal", + save: "Simpan", + selectVhost: "Pilih virtual host", + definitionKey: "Kunci", + definitionValue: "Nilai", + addDefinition: "Tambah entri definisi", + patternHint: "Ekspresi reguler yang dicocokkan dengan nama antrean/exchange.", + nameRequired: "Nama policy wajib diisi", + vhostRequired: "Pilih virtual host", + patternRequired: "Pola wajib diisi", + readOnly: "Koneksi ini bersifat read-only; operasi tulis dinonaktifkan.", + }, + mqRabbitMqMonitoring: { + title: "Pemantauan Cluster", + loading: "Memuat...", + overviewTitle: "Ringkasan", + messagesReady: "Pesan siap", + messagesUnacked: "Pesan belum di-ack", + publishRate: "Laju publish", + deliverRate: "Laju deliver", + ackRate: "Laju ack", + totalQueues: "Antrean", + totalExchanges: "Exchange", + totalConnections: "Koneksi", + totalChannels: "Channel", + totalConsumers: "Consumer", + nodesTitle: "Node", + nodeName: "Node", + status: "Status", + running: "Berjalan", + stopped: "Berhenti", + memory: "Memori", + diskFree: "Disk tersedia", + fileDescriptors: "File descriptor", + sockets: "Socket", + uptime: "Waktu aktif", + noNodes: "Tidak ada node", + }, + mqRocketmq: { + consumerGroupTitle: "Consumer group", + searchConsumerGroup: "Cari consumer group", + connectionNotReady: "Koneksi belum siap. Segarkan info cluster.", + tabSend: "Kirim pesan", + tabQuery: "Kueri pesan", + noDlqTopics: "Tidak ditemukan topik DLQ. Aktifkan filter tipe DLQ di tab Topik dan segarkan.", + topicFilterAll: "Semua", + topicFilterBusiness: "Bisnis", + topicFilterDlq: "DLQ", + actionProduce: "Produksi", + actionConsume: "Konsumsi", + aclTitle: "Kontrol akses", + actionMessageQuery: "Kueri pesan", + actionSendMessage: "Kirim pesan", + actionMore: "Lainnya", + actionDetailGroup: "Detail", + actionResetOffset: "Reset offset", + dlqConsumerGroup: "Consumer group", + dlqConsumerGroupPlaceholder: "Consumer group (opsional)", + dlqQueryByKey: "Kueri berdasarkan key", + viewDlqMessages: "Lihat pesan DLQ", + namesrvAddr: "NameServer", + }, + mqAdmin: { + viewTenant: "Lihat tenant", + viewNamespace: "Lihat namespace", + viewTopic: "Lihat topik", + connectionMissing: "Koneksi tidak ditemukan. Hubungkan kembali dan coba lagi.", + writeDeniedReadOnly: "Koneksi ini bersifat read-only dan tidak dapat melakukan operasi tulis.", + readOnly: "Read-only", + allNamespaces: "Semua namespace", + newNamespace: "Namespace baru", + namespace: "Namespace", + selectNamespaceToCreate: "Pilih namespace tertentu untuk membuat", + selectNamespaceToWrite: "Pilih namespace tertentu untuk melakukan tindakan ini", + tabTenants: "Tenant", + tabNamespaces: "Namespace", + tabTopics: "Topik", + tabSubscriptions: "Subscription", + tabConsumerGroups: "Consumer Group", + tabMonitoring: "Pemantauan", + tabClients: "Klien", + tabMessages: "Pesan", + tabBroker: "Broker", + tabCluster: "Cluster", + tabConsumers: "Consumer", + tabProducers: "Producer", + tabDlq: "DLQ", + tabTrace: "Trace", + tabAcl: "ACL", + tabPolicies: "Policy", + tabPermissions: "Izin", + tabRawApi: "Raw API", + }, + mqMessages: { + title: "Kirim Pesan", + clear: "Bersihkan", + selectNamespaceOrTopicFirst: "Pilih namespace atau topik terlebih dahulu", + readOnlyCannotSend: "Koneksi ini bersifat read-only dan tidak dapat mengirim pesan", + selectTargetTopic: "Pilih topik target", + messageContentRequired: "Isi pesan wajib diisi", + sendSuccess: "Pesan terkirim — partisi: {partition}, offset: {offset}", + targetTopic: "Topik target", + topicLoading: "Memuat...", + topicSearchPlaceholder: "Pilih topik", + refreshTopicList: "Segarkan daftar topik", + topicOptionWithPartitions: "{label} ({partitions} partisi)", + noTopicsAvailable: "Tidak ada topik yang tersedia", + topicSearchHint: "Ketik untuk memfilter daftar. Memilih topik akan menjalankan kueri. Klik lagi untuk mencari dengan topik saat ini ditampilkan abu-abu.", + messageKey: "Kunci pesan", + messageTag: "Tag pesan", + exchange: "Exchange", + exchangePlaceholder: "Kosong = exchange default", + exchangeHint: "Jika diisi, pesan dipublikasikan ke exchange ini, bukan langsung ke antrean.", + routingKey: "Routing key", + optional: "Opsional", + messageContent: "Isi pesan", + formatJson: "Format JSON", + messageHeaders: "Header", + headersPlaceholder: "kunci: nilai (satu per baris)", + sending: "Mengirim...", + sendMessage: "Kirim pesan", + messageList: "Pesan", + loadMessages: "Muat pesan", + loading: "Memuat...", + peekDefaultHint: "Tanpa partisi, membaca semua partisi dari yang paling awal.", + count: "Jumlah", + advancedFilter: "Lanjutan (partisi / offset)", + partition: "Partisi", + partitionPlaceholderAll: "Kosong = semua", + offset: "Offset", + offsetPlaceholderEarliest: "Kosong = paling awal", + offsetPlaceholderRequired: "Wajib diisi", + startPosition: "Posisi mulai", + kafkaLatest: "N pesan terbaru (default)", + kafkaEarliest: "Pesan paling awal", + kafkaOffset: "Dari offset", + timeOrder: "Urutan waktu", + newestFirst: "Terbaru lebih dulu", + oldestFirst: "Terlama lebih dulu", + kafkaLatestHint: "Membaca hingga N kandidat dari setiap partisi, lalu memilih N terbaru berdasarkan timestamp di seluruh topik.", + kafkaEarliestHint: "Membaca dari pesan paling awal yang tersedia di setiap partisi yang dipilih.", + kafkaOffsetHint: "Membaca dari offset yang ditentukan pada partisi yang dipilih, atau semua partisi jika dikosongkan.", + messagesLoading: "Memuat pesan...", + noMessages: "Tidak ada pesan", + filterLoadedPlaceholder: "Filter pesan yang dimuat", + filterLoadedCount: "{matched} / {loaded}", + noMatchingMessages: "Tidak ada pesan yang dimuat sesuai dengan filter ini", + peekIncomplete: "Hasil pesan tidak lengkap karena broker belum menyelesaikan snapshot.", + selectTopicBeforeLoad: "Pilih topik sebelum memuat pesan", + partitionMustBeNonNegativeInt: "Partisi harus berupa bilangan bulat ≥ 0; kosongkan untuk semua partisi", + offsetMustBeNonNegativeInt: "Offset harus berupa bilangan bulat ≥ 0; kosongkan untuk paling awal", + offsetMustBeNonNegativeIntRequired: "Offset harus berupa bilangan bulat ≥ 0", + offsetRequiredForOffset: "Offset wajib diisi saat membaca dari offset tertentu", + metaPartition: "partisi {partition}", + metaOffset: "offset {offset}", + metaKey: "kunci {key}", + jsonBodyPlaceholder: "{'{'}\"key\": \"value\"{'}'}", + queryTitle: "Kueri pesan", + queryTabTopic: "Topik", + queryTabKey: "Kunci Pesan", + queryTabMsgId: "ID Pesan", + queryTopicLabel: "Topik", + selectTopicPlaceholder: "Pilih topik", + noQueryResults: "Tidak ditemukan hasil yang sesuai dengan kriteria", + tableMessageId: "ID Pesan", + tableTag: "Tag", + tableKey: "Kunci", + tableStoreTime: "StoreTime", + tableOperation: "Operasi", + viewDetails: "Lihat", + messageDetails: "Detail pesan", + search: "Cari", + messageQuery: "Kueri pesan", + queryByMsgId: "Berdasarkan ID pesan", + queryByKey: "Berdasarkan kunci", + queryByTopic: "Berdasarkan topik & waktu", + msgId: "ID Pesan", + msgIdPlaceholder: "mis. 7F000001...", + msgIdRequired: "ID pesan wajib diisi", + queryKey: "Kunci pesan", + queryKeyPlaceholder: "Kunci bisnis", + queryKeyRequired: "Kunci pesan wajib diisi", + beginTime: "Waktu mulai", + endTime: "Waktu akhir", + maxNum: "Maksimum pesan", + invalidTimeRange: "Waktu mulai atau waktu akhir tidak valid", + endTimeMustBeAfterBegin: "Waktu akhir harus lebih baru dari waktu mulai", + query: "Kueri", + querying: "Melakukan kueri...", + messageOverview: "Ringkasan", + messageBody: "Isi", + resendMessage: "Kirim ulang", + payloadCopied: "Disalin", + dlqConsumerGroupPlaceholder: "Consumer group (opsional)", + }, + mqMonitoring: { + title: "Pemantauan", + autoRefresh: "Segarkan otomatis", + refreshInterval5s: "5d", + refreshInterval10s: "10d", + refreshInterval30s: "30d", + refreshInterval60s: "60d", + refreshing: "Menyegarkan...", + refreshNow: "Segarkan", + selectTopicFirst: "Pilih topik terlebih dahulu", + loadingStats: "Memuat data pemantauan...", + kafkaTopicOverview: "Ringkasan topik Kafka", + partitionCount: "Partisi", + replicationFactor: "Faktor replikasi", + messageCount: "Pesan", + logEndOffset: "Log end offset", + offsetAndReplicaStatus: "Offset & replika", + beginOffset: "Offset awal", + leaderCount: "Leader", + isrHealthyPartitions: "ISR sehat", + noLeaderPartitions: "Tanpa leader", + kafkaPartitionDetails: "Partisi Kafka", + noKafkaPartitionMetrics: "Tidak ada metrik partisi dalam respons Kafka", + tablePartition: "Partisi", + tableBeginOffset: "Offset awal", + tableLogEndOffset: "Log end offset", + tableMessageCount: "Pesan", + tableLeader: "Leader", + tableReplicas: "Replika", + tableIsr: "ISR", + tableStatus: "Status", + statusNoLeader: "Tanpa leader", + statusIsrIncomplete: "ISR tidak lengkap", + statusHealthy: "Sehat", + messagesLoading: "Memuat pesan...", + noMessages: "Tidak ada pesan", + messageRate: "Laju pesan", + inboundRate: "Laju masuk", + outboundRate: "Laju keluar", + inboundThroughput: "Throughput masuk", + outboundThroughput: "Throughput keluar", + rateTrend: "Tren laju", + backlogTrend: "Tren backlog", + consumerLag: "Lag consumer", + storageAndBacklog: "Penyimpanan & backlog", + storageSize: "Ukuran penyimpanan", + backlogSize: "Ukuran backlog", + backlogMessageCount: "Pesan backlog", + messageCounters: "Penghitung pesan", + publishedMessages: "Diterbitkan", + consumedMessages: "Dikonsumsi", + connectionStats: "Koneksi", + subscriptionCount: "Subscription", + producerCount: "Producer", + partitionDetails: "Partisi", + tableInbound: "Masuk", + tableOutbound: "Keluar", + tableInboundThroughput: "Throughput masuk", + tableOutboundThroughput: "Throughput keluar", + tableBacklogMessages: "Pesan backlog", + tableBacklogSize: "Ukuran backlog", + tableProducers: "Producer", + tableSubscriptions: "Subscription", + producers: "Producer", + subscriptions: "Subscription", + tableName: "Nama", + tableRate: "Laju", + tableAddress: "Alamat", + tableType: "Tipe", + tableBacklog: "Backlog", + tableConsumers: "Consumer", + noProducers: "Tidak ada producer", + noSubscriptions: "Tidak ada subscription", + noPartitionMetricsFromBroker: "Tidak ada metrik partisi dari broker", + nonPartitionedTopicNoDetails: "Topik tanpa partisi tidak memiliki detail partisi", + healthIndicators: "Kesehatan", + messageFlow: "Aliran pesan", + backlogStatus: "Backlog", + producersLabel: "Producer", + subscriptionsLabel: "Subscription", + flowActive: "Aktif", + flowIdle: "Idle", + backlogNormal: "Normal", + backlogHigh: "Tinggi", + producerConnected: "Terhubung", + producerDisconnected: "Tidak ada", + subscriptionActive: "Aktif", + subscriptionNone: "Tidak ada", + chartLegendIn: "Masuk", + chartLegendOut: "Keluar", + chartLegendMessages: "Pesan", + chartLegendBytes: "Byte", + chartLegendConsumerLag: "Lag consumer", + chartAxisMsgPerSec: "pesan/d", + chartAxisMsg: "pesan", + chartAxisBytes: "byte", + chartAxisMs: "md", + metaPartition: "partisi {partition}", + metaOffset: "offset {offset}", + metaKey: "kunci {key}", + rocketmqTopicOverview: "Ringkasan topik RocketMQ", + rocketmqQueueDetails: "Detail offset antrean", + queueCount: "Antrean", + brokerCount: "Broker", + tableQueue: "Antrean", + tableBroker: "Broker", + noRocketMqQueueMetrics: "Tidak ada metrik antrean yang dikembalikan", + }, + mqTenants: { + title: "Manajemen Tenant", + createTenant: "Buat Tenant", + notSupported: "Manajemen tenant tidak didukung untuk sistem pesan ini", + readOnly: "Koneksi ini bersifat read-only dan tidak dapat melakukan operasi tulis.", + loading: "Memuat...", + name: "Nama", + adminRoles: "Peran Admin", + allowedClusters: "Cluster yang Diizinkan*", + actions: "Aksi", + none: "Tidak ada", + edit: "Edit", + delete: "Hapus", + createDialogTitle: "Buat Tenant", + editDialogTitle: "Edit Tenant: {name}", + tenantName: "Nama tenant*", + tenantNamePlaceholder: "mis. my-tenant", + addRolePlaceholder: "Tambah peran", + add: "Tambah", + selectClustersPlaceholder: "Pilih cluster yang diizinkan", + noClustersDetectedPlaceholder: "Tidak ada cluster terdeteksi; tambahkan secara manual", + clustersNotReturned: "Koneksi tidak mengembalikan daftar cluster", + addClusterPlaceholder: "Tambah cluster secara manual", + clustersRequiredHint: "Pilih atau tambahkan setidaknya satu cluster yang diizinkan", + cancel: "Batal", + create: "Buat", + save: "Simpan", + confirmDelete: 'Hapus tenant "{name}"? Tindakan ini tidak dapat dibatalkan.', + tenantNameRequired: "Nama tenant wajib diisi", + allowedClustersRequired: "Cluster yang diizinkan wajib diisi", + }, + mqNamespaces: { + title: "Manajemen Namespace", + createNamespace: "Buat Namespace", + notSupported: "Manajemen namespace tidak didukung untuk sistem pesan ini", + selectTenantFirst: "Pilih tenant terlebih dahulu", + readOnly: "Koneksi ini bersifat read-only dan tidak dapat melakukan operasi tulis.", + loading: "Memuat...", + name: "Nama", + tenant: "Tenant", + adminRoles: "Peran Admin", + actions: "Aksi", + none: "Tidak ada", + editRoles: "Edit Peran", + delete: "Hapus", + createDialogTitle: "Buat Namespace", + namespaceName: "Nama namespace*", + namespaceNamePlaceholder: "mis. my-namespace", + cancel: "Batal", + create: "Buat", + confirmDelete: 'Hapus namespace "{name}"? Tindakan ini tidak dapat dibatalkan.', + namespaceNameRequired: "Nama namespace wajib diisi", + }, + mqSubscriptions: { + title: "Manajemen Subscription", + createSubscription: "Buat Subscription", + selectTopicFirst: "Pilih topik terlebih dahulu", + searchPlaceholder: "Cari nama subscription", + subscribedTopics: "Topik yang dilanggan", + readOnly: "Koneksi ini bersifat read-only dan tidak dapat melakukan operasi tulis.", + loading: "Memuat...", + refresh: "Segarkan", + refreshing: "Menyegarkan...", + enriching: "Memuat detail online...", + truncatedHint: "Menampilkan {count} consumer group pertama (daftar dibatasi). Persempit pencarian untuk menemukan yang lain.", + enrichFailedHint: "Detail anggota/topik online tidak dapat dimuat ({error}). Hanya menampilkan daftar cepat.", + noSubscriptions: "Tidak ada subscription untuk topik ini", + noConsumerGroups: "Tidak ada consumer group", + noMatches: "Tidak ada consumer group yang cocok", + backlogPartialFailed: "Gagal memuat backlog untuk {count} topik: {error}", + viewDetail: "Detail", + editConfig: "Konfigurasi", + save: "Simpan", + consumerDetailTitle: "Detail consumer group: {name}", + consumerConfigTitle: "Konfigurasi consumer group: {name}", + consumerOverview: "Ringkasan", + consumerTerminals: "Terminal online", + consumerConsumeDetail: "Detail konsumsi", + noOnlineConsumers: "Tidak ada consumer online", + noConsumeDetail: "Tidak ada detail konsumsi", + noQueueConsumeProgress: "Tidak ada progres konsumsi antrean", + operationTopic: "Topik", + consumeDelay: "Backlog", + invalidTopicScope: "Cakupan topik tidak valid", + lastConsumeTime: "Waktu konsumsi terakhir", + broker: "broker", + queue: "antrean", + consumerClient: "consumerClient", + brokerOffset: "brokerOffset", + consumerOffset: "consumerOffset", + diffTotal: "diffTotal", + lastTimestamp: "lastTimestamp", + consumeEnable: "Konsumsi diaktifkan", + consumeBroadcastEnable: "Konsumsi broadcast diaktifkan", + consumeFromMinEnable: "Konsumsi dari offset minimum", + consumeMessageOrderly: "Konsumsi berurutan", + retryQueueNums: "Jumlah antrean retry", + retryMaxTimes: "Maksimum percobaan retry", + brokerId: "ID Broker", + whichBrokerWhenConsumeSlowly: "ID broker saat konsumsi lambat", + subscriptionName: "Nama subscription", + type: "Tipe", + mode: "Mode", + typeFilter: "Filter tipe", + rocketmqGroupType: { + normal: "Normal", + fifo: "Berurutan", + system: "Sistem", + unknown: "Tidak diketahui", + }, + rocketmqGroupMode: { + clustering: "Cluster", + broadcasting: "Broadcast", + }, + backlog: "Backlog", + consumeRate: "Laju konsumsi", + consumers: "Consumer", + actions: "Aksi", + consumerCount: "{count} consumer", + msgRate: "{rate} pesan/d", + resetCursor: "Reset kursor", + skipMessages: "Lewati pesan", + clearBacklog: "Bersihkan backlog", + peek: "Lihat pesan", + expireMessages: "Kedaluwarsakan pesan", + delete: "Hapus", + createDialogTitle: "Buat Subscription", + topic: "Topik", + subscriptionNameLabel: "Nama subscription*", + subscriptionNamePlaceholder: "mis. my-subscription", + startPosition: "Posisi mulai", + startFromEarliest: "Dari pesan paling awal (Earliest)", + startFromLatest: "Dari pesan terbaru (Latest)", + resetDialogTitle: "Reset kursor: {name}", + resetTo: "Reset ke", + earliest: "Pesan paling awal (Earliest)", + latest: "Pesan terbaru (Latest)", + timestamp: "Timestamp tertentu", + timestampMs: "Timestamp (md)", + partitionOffset: "Partisi dan offset absolut", + partition: "Partisi", + offset: "Offset", + nonNegativeIntegerRequired: "Partisi dan offset harus berupa bilangan bulat non-negatif", + currentTime: "Waktu saat ini: {time}", + reset: "Reset", + skipDialogTitle: "Lewati pesan: {name}", + skipMode: "Mode lewati", + skipCount: "Lewati jumlah tertentu", + skipAll: "Lewati semua backlog", + skipCountLabel: "Jumlah yang dilewati", + skip: "Lewati", + peekDialogTitle: "Lihat pesan: {name}", + count: "Jumlah", + noPeekMessages: "Tidak ada pesan untuk ditampilkan", + close: "Tutup", + expireDialogTitle: "Kedaluwarsakan pesan: {name}", + expireSeconds: "Waktu kedaluwarsa (detik)", + expireHint: "Akan menghapus semua pesan yang lebih lama dari {seconds} detik", + expire: "Kedaluwarsakan", + cancel: "Batal", + create: "Buat", + confirmDelete: 'Hapus subscription "{name}"? Tindakan ini tidak dapat dibatalkan.', + confirmClearBacklog: 'Bersihkan semua pesan backlog untuk subscription "{name}"?', + subscriptionNameRequired: "Nama subscription wajib diisi", + peekMessageKey: "kunci={key}", + }, + mqKafkaConsumerGroups: { + title: "Consumer Group", + searchPlaceholder: "Cari grup atau topik", + refresh: "Segarkan", + refreshing: "Menyegarkan...", + loading: "Memuat consumer group...", + empty: "Tidak ada consumer group", + noMatches: "Tidak ada consumer group yang cocok", + groupId: "ID Grup", + state: "Status", + members: "Anggota", + topics: "Topik", + totalLag: "Total lag", + partialData: "Beberapa metrik tidak tersedia", + partitionDetail: "Detail lag partisi", + noCommittedOffsets: "Tidak ada offset yang di-commit atau partisi yang ditetapkan", + topic: "Topik", + openTopicSubscriptions: "Buka subscription untuk {topic}", + partition: "Partisi", + committedOffset: "Offset yang di-commit", + logEndOffset: "Log end offset", + lag: "Lag", + }, + mqClients: { + unloadTopicUnsupportedKafka: "Kafka tidak mendukung unload topik", + title: "Producer / Consumer", + unloadTopic: "Unload topik", + unloading: "Meng-unload...", + refresh: "Segarkan", + refreshing: "Menyegarkan...", + selectTopicFirst: "Pilih topik terlebih dahulu", + rocketmqClusterHint: "Menampilkan semua producer online dan terminal consumer group pada broker. Pilih topik untuk detail klien yang spesifik pada topik tersebut.", + confirmUnload: "Unload topik ini? Producer dan consumer yang aktif akan terhubung kembali.", + aggregateTopic: "Topik agregat", + kafkaPartitionStatus: "Status partisi Kafka", + partitionCount: "{count} partisi", + partition: "Partisi", + beginOffset: "Offset awal", + latestOffset: "Offset terbaru", + messageCount: "Pesan", + leader: "Leader", + replicas: "Replika", + isr: "ISR", + partitionClients: "Klien partisi", + inboundRate: "Laju masuk", + outboundRate: "Laju keluar", + producers: "Producer", + subscriptions: "Subscription", + consumers: "Consumer", + activeProducers: "Producer aktif", + noActiveProducers: "Tidak ada producer aktif", + name: "Nama", + id: "ID", + address: "Alamat", + version: "Versi", + rate: "Laju", + throughput: "Throughput", + rateValue: "{value} pesan/d", + activeConsumers: "Consumer aktif", + noSubscriptions: "Topik ini tidak memiliki subscription", + noConsumersOnPartition: "Tidak ada consumer aktif pada subscription partisi ini", + noConsumersOnSubscription: "Tidak ada consumer aktif pada subscription ini", + permits: "Permit", + }, + mqPolicies: { + title: "Manajemen policy", + refresh: "Segarkan", + refreshing: "Menyegarkan...", + selectTopicFirst: "Pilih topik terlebih dahulu", + selectNamespaceOrTopic: "Pilih namespace atau topik", + readOnly: "Koneksi ini bersifat read-only dan tidak dapat melakukan operasi tulis.", + readonlyHint: "Koneksi ini bersifat read-only; pengeditan policy dinonaktifkan.", + publishRate: "Batas laju publish", + msgsPerSecond: "Pesan / detik", + bytesPerSecond: "Byte / detik", + save: "Simpan", + dispatchRate: "Batas laju dispatch", + msgsPerPeriod: "Pesan / periode", + bytesPerPeriod: "Byte / periode", + periodSeconds: "Periode (detik)", + subscribeRate: "Batas laju subscribe", + msgsPerConsumerPerPeriod: "Pesan per consumer / periode", + backlogQuota: "Kuota backlog", + sizeLimitBytes: "Batas ukuran (byte)", + timeLimitSeconds: "Batas waktu (detik)", + policy: "Policy", + type: "Tipe", + backlogPolicyProducerRequestHold: "Tahan permintaan producer", + backlogPolicyProducerException: "Tolak dengan exception", + backlogPolicyConsumerBacklogEviction: "Hapus paksa backlog consumer", + retention: "Retensi pesan", + retentionTimeMinutes: "Waktu retensi (menit)", + retentionSizeMb: "Ukuran retensi (MB)", + effectivePolicies: "Policy yang berlaku", + savedNotice: "{policy} disimpan", + }, + mqPermissions: { + title: "Izin", + refresh: "Segarkan", + refreshing: "Menyegarkan...", + selectNamespaceOrTopic: "Pilih namespace atau topik terlebih dahulu", + readOnly: "Koneksi ini bersifat read-only dan tidak dapat melakukan operasi tulis.", + readonlyHint: "Koneksi ini bersifat read-only; pemberian dan pencabutan izin dinonaktifkan.", + grantRole: "Berikan peran", + roleName: "Nama peran", + roleNamePlaceholder: "mis. app-producer", + actions: "Aksi", + grant: "Berikan", + currentPermissions: "Izin saat ini", + role: "Peran", + operations: "Operasi", + token: "Token", + revoke: "Cabut", + noPermissions: "Tidak ada catatan izin", + clientTokenTitle: "Token klien: {role}", + missingSigningKeyTitle: "Kunci penandatanganan token belum dikonfigurasi", + missingSigningKeyMessage: "Koneksi MQ ini belum memiliki kunci penandatanganan token broker, sehingga token klien tidak dapat diterbitkan.", + missingSigningKeyDetail: 'Edit koneksi dan atur "Broker token signing" ke HS256 SECRET atau RS256 PRIVATE, lalu masukkan kunci penandatanganan sebelum membuat token.', + tokenShowOnceWarning: "Token hanya ditampilkan satu kali. Salin dan simpan segera.", + copyToken: "Salin token", + issueNewToken: "Terbitkan token baru", + neverExpires: "Tidak pernah kedaluwarsa", + expiryDays: "Masa berlaku (hari)", + note: "Catatan", + notePlaceholder: "mis. untuk rt-erp-server", + issuing: "Menerbitkan...", + generateToken: "Buat token", + tokenRevokeHint: "Mencabut izin peran tidak langsung membatalkan JWT yang sudah diterbitkan; tunggu hingga kedaluwarsa atau rotasi kunci penandatanganan broker.", + issueRecords: "Catatan penerbitan", + time: "Waktu", + algorithm: "Algoritma", + expires: "Kedaluwarsa", + fingerprint: "Fingerprint", + noteColumn: "Catatan", + unlimited: "Permanen", + loading: "Memuat...", + noIssueRecords: "Tidak ada catatan penerbitan", + close: "Tutup", + kafkaAuthorizerNotConfigured: "Cluster Kafka ini belum memiliki authorizer yang dikonfigurasi. Tambahkan authorizer.class.name pada konfigurasi broker untuk dukungan ACL.", + kafkaAuthorizerDisabled: "Cluster Kafka ini tidak memiliki authorizer yang aktif. Aktifkan authorizer pada konfigurasi broker untuk memberikan izin.", + roleNameRequired: "Nama peran wajib diisi", + selectAtLeastOneAction: "Pilih setidaknya satu aksi", + grantedRole: "{role} diberikan", + confirmRevoke: 'Cabut izin untuk peran "{role}"?', + revokedRole: "{role} dicabut", + roleNameEmpty: "Nama peran tidak boleh kosong", + expiryMustBePositive: "Masa berlaku harus lebih besar dari 0 hari", + }, + mqBroker: { + title: "Cluster broker", + autoRefresh: "Segarkan otomatis", + refreshInterval5s: "5d", + refreshInterval10s: "10d", + refreshInterval30s: "30d", + refreshInterval60s: "60d", + refreshing: "Menyegarkan...", + refreshNow: "Segarkan sekarang", + loading: "Memuat...", + clusterOverview: "Ringkasan cluster", + clusterId: "ID Cluster", + unknown: "Tidak diketahui", + brokerCount: "Broker", + controller: "Controller", + controllerNode: "Node {id} · {host}", + brokerNodes: "Node broker", + brokerName: "Nama broker", + brokerEndpoints: "Endpoint broker", + nodeId: "ID Node", + host: "Host", + addHost: "Tambah Host", + port: "Port", + rack: "Rack", + role: "Peran", + roleController: "Controller", + roleFollower: "Follower", + roleMaster: "Master", + roleSlave: "Slave", + noBrokerNodes: "Tidak ada informasi node broker", + clusterTitle: "Cluster", + }, + mqDlq: { + title: "Dead letter queue", + refresh: "Segarkan", + refreshing: "Menyegarkan...", + loading: "Memuat...", + selectContext: "Pilih konteks namespace terlebih dahulu", + selectTopic: "Pilih topik DLQ", + topic: "Topik DLQ", + consumerGroup: "Consumer group", + groupPlaceholder: "Grup peek opsional", + queryByKey: "Kueri berdasarkan kunci pesan", + queryKey: "Kunci pesan", + queryKeyPlaceholder: "Kunci untuk dicari", + loadMessages: "Muat pesan", + loadingMessages: "Memuat pesan...", + noDlqTopics: "Tidak ditemukan topik DLQ. Aktifkan filter tipe DLQ di tab Topik untuk menampilkannya.", + noMessages: "Tidak ada pesan", + }, + mqTrace: { + title: "Trace pesan", + msgId: "ID Pesan", + msgIdPlaceholder: "ID pesan asli", + msgIdRequired: "ID pesan wajib diisi", + queryKeyRequired: "Kunci pesan wajib diisi", + selectTopicBeforeQuery: "Pilih topik sebelum mengueri trace", + traceTopic: "Topik trace", + traceTopicPlaceholder: "RMQ_SYS_TRACE_TOPIC", + query: "Kueri trace", + querying: "Melakukan kueri...", + noTrace: "Tidak ditemukan catatan trace", + searchHint: "Cari pesan terlebih dahulu, lalu klik Lihat trace", + viewTrace: "Lihat trace", + detailTitle: "Detail trace pesan", + typePub: "Pub", + typeSubBefore: "SubBefore", + typeSubAfter: "SubAfter", + typeEndTransaction: "EndTransaction", + typeUnknown: "Tidak diketahui", + statusSuccess: "Berhasil", + statusFail: "Gagal", + fieldRegionId: "Region", + fieldGroup: "Grup", + fieldTopic: "Topik", + fieldMsgId: "MsgId", + fieldTags: "Tags", + fieldKeys: "Keys", + fieldStoreHost: "Store host", + fieldClientHost: "Client host", + fieldBodyLength: "Panjang isi", + fieldCostTime: "Durasi", + fieldMsgType: "Tipe pesan", + fieldOffsetMsgId: "Offset MsgId", + fieldRequestId: "Request ID", + fieldRetryTimes: "Retry", + fieldContextCode: "Context code", + rawPayload: "Trace mentah", + traceTopicRouteMissing: + "Topik trace tidak memiliki rute di NameServer (CODE: 17).\n\nPenyebab umum:\n1. Trace broker dinonaktifkan: atur traceTopicEnable=true di broker.conf dan mulai ulang broker\n2. Trace Producer/Consumer dinonaktifkan: panggil setEnableTrace(true)\n3. Topik trace kustom digunakan: pilih topik trace yang benar di atas", + }, + mqRaw: { + title: "Raw API", + sending: "Mengirim...", + sendRequest: "Kirim permintaan", + readOnlyHint: "Koneksi ini bersifat read-only; hanya permintaan GET, HEAD, dan OPTIONS yang diizinkan.", + commonEndpoints: "Endpoint umum", + fillFromSelection: "Isi permintaan dari pilihan saat ini", + expand: "Perluas", + collapse: "Ciutkan", + method: "Metode", + path: "Path", + pathPlaceholder: "/admin/v2/...", + queryParams: "Parameter kueri", + queryPlaceholder: "kunci=nilai, satu per baris", + jsonBody: "Isi JSON", + format: "Format", + bodyPlaceholder: "mis. {'{'}\"key\":\"value\"{'}'}", + response: "Respons", + textResponse: "Respons teks", + noRequestYet: "Belum ada permintaan yang dikirim", + readOnly: "Koneksi ini bersifat read-only dan tidak dapat melakukan operasi tulis.", + pathRequired: "Path permintaan wajib diisi", + jsonBodyInvalid: "Isi JSON tidak valid: {error}", + presetBrokerVersion: "Versi broker", + presetBrokerVersionDesc: "String versi broker", + presetClusters: "Daftar cluster", + presetClustersDesc: "Mencantumkan cluster Pulsar yang dikonfigurasi", + presetTenant: "Detail tenant", + presetTenantDesc: "Lihat adminRoles / allowedClusters", + presetNamespacePolicies: "Policy namespace", + presetNamespacePoliciesDesc: "Struktur policy namespace mentah", + presetBundles: "Daftar bundle", + presetBundlesDesc: "Distribusi bundle namespace", + presetTopicInternalStats: "Statistik internal topik", + presetTopicInternalStatsDesc: "Detail ledger / cursor / backlog", + presetPartitionedStats: "Metrik partisi", + presetPartitionedStatsDesc: "Laju, producer, dan consumer per partisi", + presetSchema: "Skema terbaru", + presetSchemaDesc: "Definisi skema topik saat ini", + }, + nacos: { + openConsole: "Buka Konsol", + consoleUrlMissing: "Konfigurasikan URL Nacos Web Console untuk membukanya di browser.", + consoleOpenFailed: "Gagal membuka konsol Nacos.", + enterZenMode: "Perluas area kerja", + exitZenMode: "Keluar dari area kerja yang diperluas", + dashboard: "Dashboard", + dashboardTitle: "Dashboard Operasional", + dashboardUpdatedAt: "Diperbarui {time}", + dashboardAutoRefresh: "Segarkan otomatis", + dashboardOff: "Mati", + dashboardNamespaces: "Namespace", + dashboardConfigs: "Konfigurasi", + dashboardServices: "Layanan", + dashboardInstances: "Instance", + dashboardClients: "Klien", + dashboardConnections: "{count} koneksi", + dashboardNodes: "Node sehat", + dashboardCpu: "CPU", + dashboardMemory: "Memori", + dashboardLoad: "Beban {value}", + dashboardCountsChart: "Service discovery", + dashboardResourcesChart: "Penggunaan sumber daya", + dashboardClusterNodes: "Node cluster", + dashboardSite: "Situs", + dashboardLastRefresh: "Penyegaran terakhir", + dashboardNoNodes: "Detail node cluster tidak tersedia", + dashboardPartial: "{count} sumber dashboard tidak tersedia", + dashboardMemoryUsed: "Heap / memori terpakai", + dashboardMemoryMax: "Maksimum {value}", + dashboardRss: "Memori RSS", + dashboardVms: "Memori virtual", + dashboardJvmThreads: "Thread daemon JVM", + dashboardGcPauses: "Jeda GC", + dashboardTrafficSection: "Lalu lintas permintaan", + dashboardRequestRateChart: "Permintaan HTTP / gRPC per detik", + dashboardLatencyChart: "Latensi permintaan", + dashboardHttpQps: "QPS HTTP", + dashboardGrpcQps: "QPS gRPC", + dashboardHttpAverage: "Rata-rata HTTP", + dashboardHttpP50: "HTTP P50", + dashboardHttpP95: "HTTP P95", + dashboardHttpP99: "HTTP P99", + dashboardGrpcAverage: "Rata-rata gRPC", + dashboardGrpcP50: "gRPC P50", + dashboardGrpcP95: "gRPC P95", + dashboardGrpcP99: "gRPC P99", + dashboardReliabilitySection: "Keandalan", + dashboardErrorRateChart: "Laju galat permintaan", + dashboardExecutorChart: "Executor gRPC", + dashboardHttpErrors: "Galat HTTP", + dashboardGrpcErrors: "Galat gRPC", + dashboardExecutorPool: "Ukuran pool", + dashboardExecutorActive: "Aktif", + dashboardExecutorQueue: "Dalam antrean", + dashboardConfigSection: "Pusat konfigurasi", + dashboardConfigRateChart: "Operasi konfigurasi per detik", + dashboardConfigStateChart: "Listener dan pekerjaan tertunda", + dashboardConfigGets: "Gets", + dashboardConfigPublishes: "Publishes", + dashboardLongPolling: "Long polling", + dashboardListenerClients: "Klien listener", + dashboardListenerKeys: "Kunci listener", + dashboardNotifyTasks: "Tugas notifikasi", + dashboardNotifyClientTasks: "Tugas notifikasi klien", + dashboardDumpTasks: "Tugas dump", + dashboardNamingSection: "Service discovery", + dashboardNamingStateChart: "Layanan, instance, dan klien", + dashboardPushRateChart: "Push per detik", + dashboardPushDetailChart: "Latensi push dan pekerjaan tertunda", + dashboardPushAverage: "Latensi rata-rata", + dashboardPushMaximum: "Latensi maksimum", + dashboardPushPending: "Tugas tertunda", + dashboardSubscribers: "Subscriber", + dashboardPushes: "Push", + dashboardFailedPushes: "Push gagal", + dashboardEmptyPushes: "Push kosong", + configs: "Konfigurasi", + services: "Layanan", + loading: "Memuat...", + accessControlSidebarLabel: "Pengguna & Peran", + accessControlTitle: "Kontrol akses", + accessControlDescription: "Kelola pengguna dan penetapan peran Nacos", + users: "Pengguna", + roleBindings: "Peran", + accessControlUnavailable: "Manajemen pengguna dan peran tidak tersedia untuk koneksi ini.", + accessPermissionEndpointUnavailable: "Izin namespace tidak tersedia untuk akun saat ini. Ikatan pengguna dan peran tetap terlihat dalam mode kompatibilitas.", + searchUsers: "Cari pengguna", + filterUsername: "Filter nama pengguna", + filterRole: "Filter peran", + username: "Nama Pengguna", + password: "Kata Sandi", + passwordUnchanged: "Biarkan kosong untuk mempertahankan kata sandi saat ini", + nickname: "Nama panggilan", + roles: "Peran", + role: "Peran", + disabled: "Dinonaktifkan", + createUser: "Buat pengguna", + editUser: "Edit pengguna", + resetUserPassword: "Reset kata sandi", + passwordResetSucceeded: "Kata sandi untuk {username} berhasil direset", + passwordResetFailed: "Gagal mereset kata sandi: {message}", + currentPasswordSaved: "Kredensial koneksi yang tersimpan telah diperbarui dan koneksi akan menggunakan kata sandi baru.", + currentSessionPasswordUpdated: "Kredensial koneksi dalam memori diperbarui untuk sesi ini dan tidak disimpan ke disk.", + currentPasswordNotSaved: "Koneksi ini tidak menyimpan kata sandi. Masukkan kata sandi baru saat menghubungkan kembali.", + deleteUser: "Hapus pengguna", + noUsers: "Tidak ditemukan pengguna", + noRoleBindings: "Tidak ditemukan ikatan peran", + createUserTitle: "Buat pengguna Nacos", + createUserDescription: "Buat pengguna untuk layanan Nacos ini.", + editUserTitle: "Edit pengguna r-nacos", + editUserDescription: "Perbarui profil pengguna, peran, dan hak akses namespace.", + resetUserTitle: "Reset kata sandi pengguna Nacos", + resetUserDescription: "Tetapkan kata sandi baru untuk pengguna ini.", + userCredentialsRequired: "Nama pengguna dan kata sandi wajib diisi.", + deleteUserTitle: "Hapus pengguna Nacos", + deleteUserDescription: "Hapus pengguna {username}? Tindakan ini tidak dapat dibatalkan.", + rnacosUserEnabledHint: "Pengguna yang dinonaktifkan tidak dapat masuk ke r-nacos.", + rnacosRole0: "Manajer", + rnacosRole0Hint: "Akses manajemen konsol penuh", + rnacosRole1: "Developer", + rnacosRole1Hint: "Akses pengembangan konfigurasi dan layanan", + rnacosRole2: "Pengunjung", + rnacosRole2Hint: "Akses konsol hanya-baca", + namespacePrivileges: "Hak akses namespace", + namespaceWhitelist: "Whitelist namespace", + namespaceBlacklist: "Blacklist namespace", + namespaceListPlaceholder: "Satu namespace per baris atau dipisahkan koma", + namespaceSelectPlaceholder: "Pilih namespace", + namespaceSearchPlaceholder: "Cari namespace", + namespaceSelectedCount: "{count} dipilih", + namespaceRemoveSelection: "Hapus {namespace}", + noNamespacesAvailable: "Tidak ada namespace yang tersedia", + retryNamespaceList: "Coba lagi", + assignRole: "Tetapkan peran", + assignRoleTitle: "Tetapkan peran Nacos", + assignRoleDescription: "Ikat sebuah peran ke satu pengguna Nacos.", + roleBindingRequired: "Nama pengguna dan peran wajib diisi.", + removeRole: "Hapus peran", + removeRoleTitle: "Hapus peran Nacos", + removeRoleDescription: "Hapus peran {role} dari pengguna {username}?", + protectedRole: "Peran administrator bawaan tidak dapat dihapus dari DBX.", + close: "Tutup", + accessSearchRoles: "Cari peran", + accessRoleCounts: "{members} anggota · {permissions} izin", + accessNoRoles: "Tidak ditemukan peran", + accessUserSubtitle: "Peran dan akses namespace efektif", + accessAssociatedRoles: "Peran terkait", + accessAssociatedRolesHint: "Izin diwariskan dari setiap peran yang terkait.", + accessNoAssociatedRoles: "Tidak ada peran terkait", + accessEffectivePermissions: "Izin efektif", + accessEffectivePermissionsHint: "Akses gabungan beserta peran yang memberikan setiap izin.", + accessAction: "Aksi", + accessSourceRole: "Peran sumber", + accessNoEffectivePermissions: "Pengguna ini tidak memiliki izin efektif", + accessGlobalAdministrator: "Administrator global", + accessNeedsRepair: "Perlu diperbaiki", + accessRoleSubtitle: "{members} anggota terkait", + accessIncompleteRoleHint: "Peran ini tidak memiliki anggota atau izin namespace. Tambahkan izin namespace sebelum menyimpan; anggota boleh tetap kosong.", + accessPermissionScope: "Cakupan izin", + accessPermissionScopeHint: "Aturan namespace yang dikelola oleh peran ini.", + accessAllResources: "Semua resource", + accessAdminBypassHint: "ROLE_ADMIN melewati pemeriksaan izin namespace biasa.", + accessNoRolePermissions: "Tidak ada izin namespace yang dikonfigurasi", + accessMembers: "Anggota", + accessMembersHint: "Pengguna yang saat ini terkait dengan peran ini.", + accessNoMembers: "Tidak ada anggota terkait", + accessOpenUser: "Lihat pengguna {username}", + accessOpenRole: "Lihat peran {role}", + accessAdvancedPermissions: "Izin lanjutan", + accessAdvancedPermissionsHint: "Aturan mentah dipertahankan persis dan tidak ditimpa oleh pengeditan namespace.", + accessRevokeRawPermission: "Cabut izin mentah", + accessRevokeRawPermissionHint: "Ini menghapus persis kombinasi peran, resource, dan aksi yang ditampilkan.", + accessSelectItem: "Pilih item dari direktori", + accessCreateRole: "Buat peran", + accessDeleteRole: "Hapus peran", + accessReadOnly: "Hanya baca", + accessWriteOnly: "Hanya tulis", + accessReadWrite: "Baca dan tulis", + accessDeletedNamespace: "namespace terhapus", + accessPasswordRequired: "Masukkan kata sandi baru.", + accessCredentialsRequired: "Nama pengguna dan kata sandi wajib diisi.", + accessRoleMemberRequired: "Sebuah peran memerlukan setidaknya satu anggota.", + accessRolePermissionRequired: "Sebuah peran memerlukan setidaknya satu izin namespace.", + accessInlineUserRequired: "Setiap pengguna baru memerlukan nama pengguna dan kata sandi.", + accessNoAssignableRoles: "Tidak ada peran lengkap yang tersedia", + accessTypeUsername: "Ketik {value} untuk mengonfirmasi perubahan akun berisiko tinggi ini", + accessDeleteUserConfirmationLabel: "Masukkan nama pengguna lengkap untuk mengonfirmasi penghapusan", + accessDeleteUserConfirmationHint: "Masukkan teks ini persis (peka huruf besar/kecil):", + accessDeleteUserConfirmationPlaceholder: "Nama pengguna lengkap", + accessMembersRequiredHint: "Pilih pengguna yang sudah ada atau buat pengguna secara langsung. Setidaknya satu wajib diisi.", + accessMembersOptionalHint: "Peran biasa yang sudah ada dapat mempertahankan izinnya tanpa anggota terkait.", + accessInlineCreateUser: "Buat pengguna langsung", + accessAdminPermissionImmutable: "Izin administrator global bersifat bawaan di Nacos dan tidak dapat diedit sebagai aturan namespace.", + accessPermissionRequiredHint: "Pilih namespace, lalu atur aksi untuk masing-masing.", + accessUnassignedNamespaces: "Namespace yang belum ditetapkan", + accessGrantedNamespaces: "Namespace yang diberikan", + accessSearchNamespaces: "Cari berdasarkan nama atau ID namespace", + accessNoUnassignedNamespaces: "Tidak ada namespace yang tersedia untuk ditambahkan", + accessNoGrantedNamespaces: "Pilih namespace untuk memberikan akses", + accessGrantNamespaces: "Berikan namespace yang dipilih", + accessRevokeNamespaces: "Hapus namespace yang dipilih", + accessDeleteRoleHint: "Menghapus {role} menghapus semua izin dan ikatan anggota. Penghapusan yang berhasil tidak dipulihkan setelah kegagalan sebagian.", + accessTypeRole: "Ketik {value} untuk mengonfirmasi penghapusan peran", + accessDeleteRoleConfirmationLabel: "Masukkan nama peran lengkap untuk mengonfirmasi penghapusan", + accessDeleteRoleConfirmationHint: "Masukkan teks ini persis (peka huruf besar/kecil):", + accessDeleteRoleConfirmationPlaceholder: "Nama peran lengkap", + accessOperationResult: "Hasil operasi", + accessReenterPassword: "Masukkan kembali kata sandi untuk mencoba lagi", + accessUndoCreated: "Batalkan item yang dibuat", + accessRetryFailed: "Coba ulang langkah yang gagal", + accessUserDialog: { + create: "Buat pengguna", + createHint: "Buat akun dan opsional kaitkan dengan peran yang sudah ada.", + roles: "Edit peran pengguna", + rolesHint: "Perbarui peran yang terkait dengan {username}.", + password: "Reset kata sandi", + passwordHint: "Tetapkan kata sandi baru untuk {username}.", + delete: "Hapus pengguna", + deleteHint: "Tinjau integritas peran sebelum menghapus {username}.", + }, + accessRoleDialog: { + create: "Buat peran", + createHint: "Konfigurasikan anggota dan izin namespace secara bersamaan.", + edit: "Edit peran", + editHint: "Perubahan diterapkan sebagai sekumpulan operasi anggota dan izin yang direkonsiliasi.", + delete: "Hapus peran", + deleteHint: "Operasi ini dapat berhasil sebagian dan tidak dapat dibatalkan secara otomatis.", + }, + accessOperationStatus: { + running: "Operasi masih berjalan.", + partial: "Sebagian langkah berhasil dan sebagian memerlukan perhatian.", + succeeded: "Setiap langkah berhasil diselesaikan.", + failed: "Operasi tidak selesai.", + undoing: "Item yang dibuat sedang dihapus.", + undone: "Item yang dibuat telah dihapus.", + }, + accessStep: { + createUser: "Buat pengguna", + deleteUser: "Hapus pengguna", + assignRole: "Kaitkan peran", + removeRole: "Hapus keterkaitan peran", + grantPermission: "Berikan izin", + revokePermission: "Cabut izin", + }, + rnacosAccessControlAuthDescription: "Masukkan kode verifikasi konsol r-nacos untuk mengelola pengguna dan peran.", + raw: "Mentah", + namespace: "Namespace", + createNamespace: "Buat Namespace", + editNamespace: "Edit Namespace", + deleteNamespace: "Hapus Namespace", + deleteNamespaceDescription: "Hapus namespace {name} ({id})? Konfigurasi dan layanannya mungkin menjadi tidak dapat diakses. Tindakan ini tidak dapat dibatalkan.", + creatingNamespace: "Membuat...", + updatingNamespace: "Memperbarui...", + deletingNamespace: "Menghapus...", + namespaceCreated: 'Namespace "{name}" dibuat', + namespaceUpdated: 'Namespace "{name}" diperbarui', + namespaceDeleted: 'Namespace "{name}" dihapus', + namespaceId: "ID Namespace", + namespaceIdPlaceholder: "Biarkan kosong agar DBX membuat UUID", + namespaceName: "Nama Namespace", + namespaceNamePlaceholder: "Masukkan nama namespace", + namespaceDesc: "Deskripsi", + namespaceDescPlaceholder: "Default ke nama namespace", + dataId: "Data ID", + group: "Grup", + format: "Format", + content: "Konten", + tags: "Tag", + application: "Aplikasi", + description: "Deskripsi", + advanced: "Lanjutan", + collapse: "Ciutkan", + configIdentity: "Identitas konfigurasi", + newConfigDraft: "Konfigurasi baru", + draft: "Draf", + unsaved: "Belum disimpan", + published: "Diterbitkan", + readOnlyState: "Hanya baca", + load: "Muat", + save: "Simpan", + saveAs: "Simpan sebagai", + saving: "Menyimpan...", + saved: "Konfigurasi disimpan", + createdAndLoaded: "{dataId} dibuat dan dimuat", + savedAndLoaded: "{dataId} disimpan dan disegarkan", + deleted: "Konfigurasi dihapus", + delete: "Hapus", + copy: "Salin", + copied: "Disalin", + copyVerifyFailed: "Verifikasi clipboard gagal setelah penulisan", + export: "Ekspor", + exported: "Diekspor", + exportedTo: "Diekspor ke {path}", + exportFailed: "Ekspor gagal: {message}", + contentSearch: "Pencarian teks lengkap", + contentSearchTitle: "Pencarian teks lengkap di seluruh konfigurasi Nacos", + contentSearchDescription: "Jalankan pencarian literal yang peka huruf besar/kecil pada konten konfigurasi yang sedang diterbitkan. Versi riwayat tidak dicari.", + contentSearchPlaceholder: "URL database, akun, atau fragmen konfigurasi apa pun", + search: "Cari", + cancel: "Batal", + currentNamespace: "Namespace saat ini", + allNamespaces: "Semua namespace dalam koneksi ini", + allNamespacesSearchWarning: "Mencari di semua namespace dapat mengenumerasi banyak konfigurasi. Ini bisa lambat pada Nacos 2.x dan r-nacos serta menambah beban server.", + scannedCount: "{count} dipindai", + matchCount: "{count} kecocokan", + incompleteResult: "Hasil mungkin tidak lengkap", + lineNumber: "Baris {line}", + noContentMatches: "Tidak ada konfigurasi yang berisi konten ini", + contentSearchEmptyHint: "Masukkan kata kunci untuk mencari. Kata kunci, konten, dan cuplikan tidak disimpan ke disk atau log.", + searchResults: "Hasil pencarian", + searchResultsRetainedHint: "Buka hasil di area konten. Set hasil ini tetap tersedia dari Hasil pencarian di bilah alat atas.", + openedSearchResult: "Dibuka", + exportSearchResults: "Ekspor hasil", + clearSearchResults: "Bersihkan hasil pencarian", + searchResultsExported: "Hasil pencarian diekspor", + searchResultsExportedTo: "Hasil pencarian diekspor ke {path}", + contentReplace: "Ganti global", + contentReplaceTitle: "Ganti konten di seluruh konfigurasi Nacos", + contentReplaceDescription: "Pratinjau penggantian yang persis dan peka huruf besar/kecil di setiap Data ID yang cocok sebelum diterbitkan.", + contentReplaceSearch: "Nilai yang dicari", + contentReplaceValue: "Ganti dengan", + contentReplaceScope: "Cakupan", + contentReplaceAllGroups: "Semua grup", + contentReplaceAllDataIds: "Semua Data ID", + contentReplaceAllNamespacesWarning: "Ini akan memindai dan dapat menerbitkan setiap konfigurasi yang cocok di setiap namespace pada koneksi ini. Tinjau rencana lengkap sebelum menerapkannya.", + contentReplaceScanning: "Memindai {scanned} konfigurasi, {matched} kecocokan ditemukan", + contentReplaceIncomplete: "Hasil pencarian global tidak lengkap, sehingga tidak ada rencana penggantian yang dibuat. Persempit filter atau coba lagi.", + contentReplaceConfigCount: "{count} konfigurasi", + contentReplaceSelectAll: "Pilih semua konfigurasi", + contentReplaceSelectConfig: "Pilih {dataId}", + contentReplaceSelectedCount: "{selected} dari {total} konfigurasi dipilih", + contentReplaceOccurrenceCount: "{count} penggantian", + contentReplaceNoMatches: "Tidak ada konfigurasi yang diterbitkan berisi nilai persis ini.", + contentReplaceViewDiff: "Lihat diff penggantian", + contentReplacePreview: "Pratinjau penggantian", + contentReplaceApply: "Ganti pada {count} konfigurasi yang dipilih", + contentReplaceRollback: "Rollback konfigurasi yang diganti", + contentReplaceReport: "{replaced} diganti, {conflicts} konflik, {failed} gagal", + contentReplaceRollbackReport: "Rollback: {restored} dipulihkan, {conflicts} konflik, {failed} gagal", + contentReplaceStatus: { + replaced: "Diganti", + conflict: "Konflik", + failed: "Gagal", + }, + replaceHistory: { + replaceTab: "Ganti", + historyTab: "Riwayat", + batchCount: "{count} batch", + empty: "Belum ada batch penggantian yang tercatat.", + refresh: "Segarkan riwayat", + details: "Lihat detail batch", + delete: "Hapus catatan", + deleteTitle: "Hapus riwayat batch", + deleteConfirm: "Hapus catatan lokal ini beserta snapshot rollback-nya? Konfigurasi Nacos yang sudah diterbitkan tidak akan berubah. Anda tidak akan bisa lagi melakukan rollback batch ini dari sini.", + rollbackTitle: "Rollback batch penggantian ini", + rollbackConfirm: "Terbitkan kembali konten asli yang tersimpan untuk penggantian yang telah dikonfirmasi? Konfigurasi yang berubah sejak penggantian akan dilewati. Konfigurasi yang sudah dipulihkan tidak akan diterbitkan lagi.", + storageUnavailable: "Penyimpanan riwayat lokal yang aman tidak tersedia. Gunakan HTTPS atau localhost dengan IndexedDB, Web Crypto, dan Web Locks diaktifkan. Tidak ada yang akan diterbitkan lebih lanjut.", + storageFailed: "Tidak dapat menyimpan atau membaca riwayat batch. Penerbitan lebih lanjut telah dihentikan. Periksa ruang penyimpanan lokal dan tinjau riwayat sebelum mencoba lagi; item yang tidak pasti mungkin perlu diperiksa pada riwayat konfigurasi Nacos.", + targetMismatch: "Koneksi ini sekarang menunjuk ke server Nacos yang berbeda, atau sudah tidak ada. Pratinjau lagi; rollback historis diblokir untuk melindungi server lain.", + busy: "Tab lain sedang menjalankan operasi pada koneksi ini. Coba lagi setelah selesai.", + uncertain: "Tidak pasti", + notExecuted: "Tidak dijalankan", + interrupted: "Beberapa penulisan terganggu sebelum hasilnya dapat disimpan. Item yang tidak pasti dikecualikan dari rollback otomatis. Periksa riwayat konfigurasi Nacos masing-masing.", + state: { applying: "Penggantian belum selesai", completed: "Penggantian selesai", rollingBack: "Rollback belum selesai", rollbackCompleted: "Rollback diproses" }, + rollbackStatus: { restored: "Dipulihkan", conflict: "Konflik rollback", failed: "Rollback gagal" }, + }, + batchExport: "Ekspor batch", + batchImport: "Impor batch", + copyToNamespace: "Sinkronisasi konfigurasi", + batchDelete: "Hapus batch", + batchDeleteTitle: "Hapus konfigurasi Nacos yang dipilih", + batchDeleteConfirm: "Hapus {count} konfigurasi yang dipilih? Tindakan ini tidak dapat dibatalkan.", + batchDeleteSuccess: "{count} konfigurasi dihapus", + batchDeletePartial: "{deleted} konfigurasi dihapus; {failed} gagal.", + batchDeleteInterrupted: "Penghapusan batch dihentikan setelah menghapus {deleted} konfigurasi.", + configPageSize: "Per halaman", + selectedCount: "{count} dipilih", + retryConnectionInfo: "Coba lagi pemeriksaan info koneksi", + resizeColumn: "Seret untuk mengubah ukuran kolom", + visibleColumns: "Kolom yang terlihat", + configListGroup: "Grup", + configListApplication: "Aplikasi", + configListFormat: "Format", + selectCurrentPage: "Pilih halaman saat ini", + selectConfigForBatch: "Pilih konfigurasi {dataId}", + batchExportTitle: "Ekspor batch konfigurasi Nacos", + batchExportDescription: "Membuat ZIP yang kompatibel dengan konsol Nacos. Berisi konfigurasi plaintext yang didekripsi dan harus disimpan dengan aman.", + batchImportTitle: "Impor batch konfigurasi Nacos", + batchImportDescription: "Mengurai arsip dengan aman dan meninjau konflik sebelum menerbitkan setiap item ke namespace saat ini.", + batchCopyTitle: "Sinkronkan konfigurasi ke namespace lain", + batchCopyDescription: "Sinkronisasi menggunakan semantik penyalinan satu arah dan tidak pernah menghapus atau mengubah konfigurasi sumber. Konflik target menggunakan policy yang dipilih.", + exportScope: "Cakupan konfigurasi", + selectedConfigs: "Konfigurasi yang dipilih ({count})", + filteredConfigs: "Semua yang sesuai filter saat ini (perkiraan {count})", + namespaceAllConfigs: "Semua konfigurasi di namespace ini", + importArchive: "Arsip ZIP Nacos", + noArchiveSelected: "Tidak ada ZIP yang dipilih", + chooseZip: "Pilih ZIP", + importSensitiveWarning: "ZIP yang kompatibel mungkin berisi kata sandi database, kunci, dan rahasia lain dalam plaintext. Impor hanya arsip yang tepercaya.", + targetConnection: "Koneksi target", + chooseTargetConnection: "Pilih koneksi Nacos target", + noTargetConnections: "Tidak ada koneksi Nacos yang dapat ditulis tersedia. Tambahkan satu atau hapus pengaturan read-only pada koneksi target.", + targetNamespace: "Namespace target", + chooseTargetNamespace: "Pilih namespace lain", + targetGroup: "Grup target (opsional)", + targetGroupPlaceholder: "Sama dengan grup sumber", + targetDataIds: "Data ID target (opsional)", + targetDataIdsHint: "Konfigurasi yang dipilih dapat diganti namanya satu per satu. Biarkan kosong untuk mempertahankan Data ID sumber.", + copyKeepsSource: "Sinkronisasi menggunakan semantik penyalinan satu arah. Konfigurasi namespace sumber tetap tidak berubah.", + conflictPolicy: "Policy konflik", + policyABORT: "Batalkan saat konflik", + policyABORTHint: "Tidak menulis apa pun saat pratinjau menemukan konflik", + policySKIP: "Lewati konflik", + policySKIPHint: "Hanya membuat konfigurasi yang belum ada di target", + policyOVERWRITE: "Timpa target", + policyOVERWRITEHint: "Ganti konfigurasi target dengan kunci yang sama dengan sumber", + overwriteWarning: "Menimpa akan mengubah konfigurasi target yang sudah diterbitkan dan memerlukan satu konfirmasi lagi.", + overwriteConfirm: "Timpa semua konfigurasi yang konflik di namespace target? Tindakan ini tidak dapat di-rollback secara otomatis.", + preview: "Pratinjau", + apply: "Terapkan", + exportZip: "Ekspor ZIP", + previewTotal: "{count} total", + previewCreated: "{count} baru", + previewConflicts: "{count} konflik", + previewInvalid: "{count} tidak valid", + previewExpired: "Pratinjau sudah kedaluwarsa. Jalankan pratinjau lagi.", + batchFinished: "Sinkronisasi selesai: {written} ditulis", + batchAborted: "Sinkronisasi tidak dijalankan: sebuah konflik mencegah semua penulisan", + batchPartial: "Operasi batch selesai sebagian; tinjau item yang gagal", + batchCancelled: "Dibatalkan", + batchCancelledSummary: "Sinkronisasi dibatalkan: {processed}/{total} diproses", + batchFailedSummary: "Sinkronisasi selesai sebagian: {written} ditulis, {failed} gagal", + batchPartialSummary: "Sinkronisasi belum selesai: {processed}/{total} diproses", + batchFinishedWithSkipped: "Sinkronisasi selesai: {written} ditulis, {skipped} dilewati", + batchStatusCreate: "Akan dibuat", + batchStatusConflict: "Konflik", + batchStatusInvalid: "Tidak valid", + batchStatusCreated: "Dibuat", + batchStatusOverwritten: "Ditimpa", + batchStatusSkipped: "Dilewati", + batchStatusFailed: "Gagal", + batchStatusAborted: "Tidak dijalankan", + batchStatusExported: "Diekspor", + batchStatusUnknown: "{status}", + reportWritten: "{count} ditulis", + reportCreated: "{count} dibuat", + reportOverwritten: "{count} ditimpa", + reportSkipped: "{count} dilewati", + reportFailed: "{count} gagal", + reportItems: "Detail konfigurasi ({count})", + history: "Riwayat", + configHistory: "Riwayat konfigurasi", + historyUnavailable: "Riwayat konfigurasi tidak tersedia untuk koneksi ini. Konfigurasikan URL konsol r-nacos dan hubungkan kembali untuk mengaktifkannya.", + historyDisabled: "Riwayat konfigurasi dinonaktifkan untuk koneksi ini.", + historyConsoleUrlMissing: "Riwayat konfigurasi memerlukan alamat konsol r-nacos.", + historyConsoleCredentialsMissing: "Riwayat konfigurasi memerlukan kredensial konsol r-nacos.", + rnacosConsoleAuthTitle: "Verifikasi konsol r-nacos", + rnacosConsoleAuthDescription: "Masukkan kode verifikasi konsol r-nacos untuk membaca tipe konfigurasi, deskripsi, dan riwayat.", + rnacosCaptchaLabel: "Kode verifikasi", + rnacosCaptchaPlaceholder: "Masukkan kode yang ditampilkan di atas", + rnacosCaptchaRequired: "Kode verifikasi wajib diisi.", + rnacosCaptchaUnavailable: "r-nacos tidak mengembalikan gambar verifikasi.", + rnacosRefreshCaptcha: "Segarkan kode", + rnacosConsoleAuthSubmit: "Verifikasi dan lanjutkan", + historyDetail: "Detail riwayat", + historyCompareTitle: "Perbandingan Versi Riwayat", + currentPublishedContent: "Konten yang diterbitkan saat ini:", + historyVersionContent: "Konten versi riwayat:", + updatedAt: "Diperbarui pada", + operationType: "Operasi", + operator: "Operator", + view: "Lihat", + compare: "Bandingkan", + rollback: "Rollback", + loadingHistory: "Memuat riwayat...", + noHistory: "Tidak ada versi riwayat", + noHistoryHint: "Segarkan jika konfigurasi ini baru saja diterbitkan. Beberapa versi Nacos mungkin tidak menyediakan API riwayat.", + historyCreate: "Buat", + historyUpdate: "Perbarui", + historyDelete: "Hapus", + historyRollback: "Rollback", + confirmRollbackTitle: "Rollback konfigurasi Nacos", + confirmRollbackMessage: "Ini akan mengembalikan konfigurasi saat ini ke versi riwayat yang dipilih.", + rollbackSuccess: "Konfigurasi di-rollback", + publish: "Terbitkan", + validate: "Validasi", + validationPassed: "Sintaks konfigurasi valid", + validationErrorTitle: "Galat sintaks konfigurasi", + validationErrorDescription: "Perbaiki galat sintaks sebelum menerbitkan konfigurasi ini.", + validationLine: "Baris: {line}", + validationColumn: "Kolom: {column}", + validationLocate: "Temukan galat", + yamlDiagnosticDuplicateKey: "Kunci mapping duplikat: {key}", + yamlDiagnosticTabIndent: "Indentasi YAML tidak boleh menggunakan karakter tab; gunakan spasi", + yamlDiagnosticSyntaxError: "Galat sintaks YAML: {reason}", + yamlDiagnosticParserWarning: "Peringatan parser YAML: {reason}", + validationWarningTitle: "Konfigurasi memiliki peringatan", + validationWarningDescription: "Peringatan ini tidak menghalangi penerbitan, tetapi tinjau sebelum menerbitkan konfigurasi ini.", + validationSeverityError: "Galat", + validationSeverityWarning: "Peringatan", + dataIdRequired: "Data ID wajib diisi", + allGroups: "Semua grup", + noConfigs: "Tidak ada konfigurasi", + selectConfig: "Pilih atau buat konfigurasi", + noServices: "Tidak ada layanan", + selectService: "Pilih layanan", + service: "Layanan", + instances: "Instance", + instanceCount: "{count} instance", + serviceInstancesAllHealthy: "Semua sehat · {healthy}/{total}", + serviceInstancesPartiallyHealthy: "Sebagian sehat · {healthy}/{total}", + serviceInstancesNoHealthyInstances: "Tidak ada instance yang sehat · {healthy}/{total}", + serviceInstancesNoInstances: "Tidak ada instance", + refresh: "Segarkan", + address: "Alamat", + cluster: "Cluster", + weight: "Bobot", + state: "Status", + actions: "Aksi", + query: "Kueri", + body: "Isi", + response: "Respons", + template: "Template", + configDiffTitle: "Perbandingan Konten Konfigurasi", + inlineCompare: "Bandingkan inline", + diffStats: "+{added} / -{removed} / ~{modified} baris", + previousDifference: "Perbedaan sebelumnya", + nextDifference: "Perbedaan berikutnya", + currentVersionContent: "Versi resmi saat ini:", + publishVersionContent: "Konten rilis ini:", + confirmSaveTitle: "Tinjau perubahan konfigurasi Nacos", + confirmDeleteTitle: "Hapus konfigurasi Nacos", + confirmDeleteMessage: "Ini menghapus konfigurasi yang dipilih dari Nacos.", + confirmInstanceTitle: "Perbarui instance Nacos", + confirmInstanceMessage: "Konfirmasikan status instance layanan target.", + confirmRawTitle: "Kirim permintaan Raw API yang mengubah data", + confirmRawMessage: "Permintaan Raw API ini dapat mengubah status Nacos.", + rawTemplate: { + serverState: "Status server", + namespaceList: "Daftar namespace", + configDetail: "Detail konfigurasi", + serviceList: "Daftar layanan", + instanceList: "Daftar instance", + }, + healthy: "Sehat", + unhealthy: "Tidak sehat", + enabled: "Diaktifkan", + online: "Daring", + offline: "Luring", + ephemeral: "Ephemeral", + persistent: "Persistent", + enable: "Aktifkan", + disable: "Nonaktifkan", + markHealthy: "Sehat", + markUnhealthy: "Tidak sehat", + send: "Kirim", + total: "{count} total", + prev: "Sebelumnya", + next: "Berikutnya", + test: "Uji", + readOnly: "Hanya baca", + nacosConnectionPlan: "Rencana koneksi", + nacosConnectionPlanDescription: "Pilih implementasi layanan dan versi API.", + nacosApiPlane: "API Nacos 3", + nacosApiPlaneAdmin: "Admin API", + nacosApiPlaneAdminHint: "Disarankan · manajemen penuh", + nacosApiPlaneConsole: "Console API", + nacosApiPlaneConsoleHint: "Terbatas · berfungsi dengan akses hanya-konsol", + nacosServiceAddress: "Alamat layanan", + nacosServiceAddressHint: "Masukkan alamat layanan. Port default adalah 8848, misalnya http://host:8848/nacos.", + nacosConsoleServiceAddressHint: "Masukkan alamat Console API. Port default adalah 8080, misalnya http://host:8080.", + nacosManagedNamespaces: "ID namespace terkelola", + nacosManagedNamespacesNameOrId: "Nama atau ID namespace terkelola", + nacosManagedNamespacesPlaceholder: "Misalnya: public, team-a", + nacosManagedNamespacesIdPlaceholder: "Misalnya: public, f8b8c4e2-8195-4041-adb2-683a8259384b", + nacosManagedNamespacesHint: "Masukkan ID namespace yang dapat diakses pengguna biasa ini, dipisahkan koma atau baris baru. Uji koneksi memverifikasi akses baca konfigurasi dan layanan untuk setiap ID.", + nacosOrdinaryAccount: "Pengguna biasa", + nacosOrdinaryAccountHint: "Jika akun di atas adalah pengguna biasa, aktifkan opsi ini dan pilih namespace yang diotorisasi untuknya; jika tidak, koneksi tidak akan berfungsi dengan benar.", + nacosManagedNamespacesSeparator: "Dipisahkan koma atau baris baru", + nacosOrdinaryNamespacesRequired: "Masukkan setidaknya satu ID namespace yang boleh dikelola oleh pengguna biasa ini.", + nacosManagedNamespacesRequired: "Pengguna biasa Nacos ini tidak dapat mencantumkan namespace atau data otorisasi. Masukkan setidaknya satu ID namespace yang boleh dikelolanya dan coba lagi.", + nacosManagedNamespaceAccessDenied: "Namespace berikut gagal pada pemeriksaan akses baca konfigurasi atau layanan: {detail}", + nacosNamespaceAccessScope: "Cakupan akses namespace", + nacosNamespaceAccessScopeHint: "Deteksi namespace yang dapat diakses terlebih dahulu. Jika enumerasi tidak tersedia, masukkan ID namespace yang sudah diverifikasi secara manual.", + nacosNamespaceAccessAutomatic: "Deteksi otomatis", + nacosNamespaceAccessManual: "Masukkan manual", + nacosDetectAccessibleNamespaces: "Deteksi dan pilih namespace yang dapat diakses", + nacosDetectAccessibleNamespacesHint: "DBX memverifikasi akses baca konfigurasi dan layanan sebelum menawarkan namespace untuk {name}.", + nacosV3AdminNamespaceScopeHint: "Nacos 3 Admin API biasanya memerlukan akun administrator. Gunakan Console API untuk akun terbatas beserta cakupan akses namespace-nya.", + nacosV3AdminManagedNamespacesHint: "Ini menggunakan Nacos 3 Admin API (biasanya port 8848). Pengguna biasa harus memasukkan ID namespace, bukan nama tampilan. Salin ID dari detail namespace Nacos Console atau resource peran-izin.", + nacosV3ConsoleManagedNamespacesHint: "Ini menggunakan Nacos 3 Console API (biasanya port 8080). Masukkan nama atau ID namespace; DBX mengonversi nama menjadi ID aslinya jika dapat membaca direktori.", + rnacosNamespaceAccessScopeHint: "r-nacos menurunkan akses namespace dari hak akses namespace pengguna saat ini saat profil konsolnya tersedia.", + nacosAuth: "Autentikasi", + nacosAuthHint: "Kredensial ini digunakan untuk uji koneksi dan manajemen harian.", + nacosUsernamePassword: "Nama pengguna / kata sandi", + nacosAdvancedHint: "Opsi koneksi lainnya tersedia di tab Lanjutan.", + nacosAdvancedHintDescription: "Konfigurasikan metrik Prometheus, ukuran halaman, verifikasi TLS, dan ekstensi r-nacos di sana.", + nacosGoAdvanced: "Buka Lanjutan", + nacosV3ConsolePortWarning: "8080 adalah port Nacos 3 Web Console default. Gunakan alamat Server / Admin API pada port 8848 untuk manajemen layanan, misalnya http://127.0.0.1:8848/nacos.", + nacosV3AdminPortWarning: "8848 biasanya adalah port Admin API. Untuk mode Console API, gunakan alamat Console, biasanya http://127.0.0.1:8080.", + nacosAdvancedTitle: "Opsi koneksi lanjutan Nacos", + nacosAdvancedDescription: "Pengaturan ini memiliki default yang aman dan biasanya hanya perlu disesuaikan untuk deployment kustom, metrik, atau ekstensi r-nacos.", + nacosContextPathHint: "Biarkan kosong untuk menggunakan default profil yang dipilih. Masukkan / untuk secara eksplisit menggunakan root server, atau berikan prefix reverse-proxy seperti /nacos.", + nacosPageSizeHint: "Digunakan untuk daftar konfigurasi dan layanan; 1–500 item per halaman.", + nacosMetricsHint: "Mengueri metrik dari alamat layanan secara otomatis; pilih URL kustom jika endpoint metrik berbeda.", + nacosRnacosExtension: "Fitur konsol r-nacos", + nacosRnacosExtensionHint: "Alamat konsol dan kredensial mengaktifkan manajemen pengguna, detail konfigurasi, dan manajemen instance yang dinonaktifkan. Riwayat konfigurasi dikontrol secara terpisah di bawah.", + nacosEnabled: "Diaktifkan", + nacosRnacosConsoleUrlHint: "Biasanya http://host:10848. Diperlukan untuk manajemen pengguna r-nacos dan fitur konsol lainnya.", + nacosRnacosDisabledHint: "Riwayat konfigurasi dinonaktifkan. Manajemen pengguna tetap tersedia jika alamat konsol dan kredensial dikonfigurasi.", + nacosTlsHint: "Aktifkan hanya untuk sertifikat HTTPS self-signed yang tepercaya.", + nacosVisibleNamespacesTitle: "Pilih namespace yang terlihat", + nacosVisibleNamespacesDetailLabel: "Namespace yang terlihat", + nacosVisibleNamespacesDetailActionLabel: 'Konfigurasikan namespace yang terlihat untuk "{connection}"', + nacosVisibleNamespacesDescription: "Pilih namespace yang ditampilkan di bilah sisi untuk {name}.", + nacosSearchNamespaces: "Cari namespace...", + nacosSelectedNamespaces: "{selected}/{total} dipilih", + nacosSelectAll: "Pilih semua", + nacosClearSelection: "Bersihkan", + nacosShowAll: "Tampilkan semua", + nacosNamespaceSelectionRequired: "Pilih setidaknya satu namespace, atau gunakan “Tampilkan semua” untuk menghapus filter.", + nacosLoadNamespacesFailed: "Gagal memuat namespace: {message}", + capabilityReadOnly: "Koneksi ini bersifat read-only.", + capabilityReadOnlyWrite: "Implementasi ini saat ini hanya menyediakan operasi baca; kompatibilitas tulis belum diverifikasi.", + capabilityVersionUnsupported: "Versi Nacos ini tidak mendukung operasi tersebut.", + capabilityEndpointUnavailable: "Koneksi ini tidak menyediakan endpoint manajemen.", + capabilityNotVerified: "Operasi ini belum diverifikasi untuk implementasi saat ini.", + capabilityHeaderReadOnly: "Koneksi ini bersifat read-only; penulisan layanan dan instance dinonaktifkan.", + protectionTriggeredDescription: "Mode proteksi dipicu karena rasio instance sehat berada di bawah ambang batas yang dikonfigurasi. Nacos mungkin tetap mengembalikan instance yang tidak sehat alih-alih daftar kosong.", + instanceEphemeral: "Instance ephemeral", + instancePersistent: "Instance persistent", + instanceUnknown: "Tipe instance tidak diketahui", + instanceConfirmDetails: "Namespace: {namespace}\nLayanan: {service}\nAlamat: {ip}:{port}\nCluster: {cluster}\nTipe: {type}", + serviceUpdateUnconfirmed: "Pembaruan layanan telah dikirim, tetapi Nacos belum mengembalikan status targetnya. Segarkan detail layanan untuk mengonfirmasi.", + invalidWeight: "Bobot harus berupa angka terbatas yang lebih besar dari atau sama dengan 0.", + invalidWeightInput: "Masukkan bobot terbatas yang lebih besar dari atau sama dengan 0.", + metadataLabel: "Metadata", + viewMetadataTable: "Lihat tabel", + instanceMetadataTitle: "Metadata instance", + metadataKey: "Kunci", + metadataValue: "Nilai", + selectorLabel: "Selector", + instanceUpdateUnconfirmed: "Pembaruan instance telah dikirim, tetapi Nacos belum mengembalikan status barunya. Segarkan untuk memeriksa status server.", + instanceRegisterUnconfirmed: "Pendaftaran instance telah dikirim, tetapi Nacos belum mengembalikan instance-nya. Segarkan untuk mengonfirmasi.", + instanceDeregisterUnconfirmed: "Penghapusan pendaftaran instance telah dikirim, tetapi Nacos masih mengembalikan instance-nya. Segarkan untuk mengonfirmasi.", + serviceValidation: "Nama layanan dan grup wajib diisi; ambang proteksi harus antara 0 dan 1.", + serviceHasInstances: "Layanan ini masih berisi instance dan tidak dapat dihapus.", + serviceDeleteUnconfirmed: "Penghapusan layanan telah dikirim, tetapi Nacos masih mengembalikan layanan tersebut. Muat ulang dan konfirmasi.", + instanceValidation: "Masukkan IP, port, dan bobot non-negatif yang valid.", + protectionTriggered: "Mode proteksi dipicu", + loadedInstances: "{count} instance dimuat", + filterInstanceCluster: "Filter cluster instance", + filter: "Filter", + clear: "Bersihkan", + serviceSettings: "Pengaturan layanan", + serviceDetails: "Detail layanan", + expand: "Perluas", + instanceStat: "Instance", + healthyInstances: "Instance sehat", + clusterCount: "Cluster", + protectThreshold: "Ambang proteksi", + itemCount: "{count} item", + temporaryService: "Layanan ephemeral", + loadingServiceDetail: "Memuat detail layanan…", + refreshDetail: "Segarkan detail", + noMetadata: "Tidak ada metadata", + noInstances: "Tidak ada instance", + createNacosService: "Buat layanan Nacos", + editNacosService: "Edit layanan Nacos", + manageServiceMetadata: "Kelola metadata layanan dan ambang proteksi.", + serviceName: "Nama layanan", + groupName: "Grup", + thresholdExample: "Contohnya 0.5", + jsonObject: "Objek JSON", + optionalJsonObject: "Objek JSON, opsional", + jsonObjectValidation: " harus berupa objek JSON.", + registerPersistentInstance: "Daftarkan instance persistent", + persistentInstanceHint: "DBX tidak mendaftarkan instance ephemeral karena tidak dapat mempertahankan heartbeat-nya.", + ipAddress: "Alamat IP", + port: "Port", + instanceEditorTitle: "Edit instance", + deleteNacosService: "Hapus layanan Nacos", + confirmEmptyServiceDelete: "Hapus layanan kosong ini? Tindakan ini tidak dapat dibatalkan.", + deregisterNacosInstance: "Hapus pendaftaran instance Nacos", + confirmInstanceDeregister: "Hapus pendaftaran instance ini dari layanan saat ini?", + edit: "Edit", + restore: "Pulihkan", + registerInstance: "Daftarkan instance", + deregister: "Hapus pendaftaran", + }, + doltVersionControl: { + title: "Kontrol Versi Dolt", + open: "Kontrol Versi", + branches: "Branch", + branchTreeView: "Tampilan pohon", + branchFlatView: "Tampilan datar", + expandBranch: "Perluas grup branch", + collapseBranch: "Ciutkan grup branch", + tags: "Tag", + filterRefs: "Filter branch dan tag", + noBranches: "Tidak ada branch", + noTags: "Tidak ada tag", + unknownBranch: "Branch tidak diketahui", + switchDatabase: "Ganti database", + switchBranch: "Ganti branch", + workingTree: "Working tree", + stagedChanges: "Staged {count}", + unstagedChanges: "Unstaged {count}", + uncommitted: "Belum di-commit", + stageAllChanges: "Stage semua perubahan", + commitWorkingTree: "Commit working tree", + commitWorkingTreeDescription: "Masukkan pesan commit untuk melakukan stage dan commit perubahan working tree.", + commitMessage: "Pesan commit", + commitMessagePlaceholder: "Contoh: Perbaiki status pesanan", + commitMessageRequired: "Masukkan pesan commit.", + changesStaged: "Perubahan working tree di-stage", + workingTreeCommitted: "Perubahan working tree di-commit", + comparison: "Perbandingan saat ini", + swapComparison: "Tukar sisi perbandingan", + noRevision: "Tidak ada revisi", + compareCurrent: "Bandingkan dengan branch saat ini", + checkoutBranch: "Pindah ke branch", + branchCheckedOut: "Berpindah ke branch {name}", + graph: "Graf", + commit: "Commit", + author: "Penulis", + date: "Tanggal", + loadingGraph: "Memuat graf commit...", + noCommits: "Tidak ditemukan commit", + noMessage: "Tidak ada pesan commit", + changedTables: "Tabel yang berubah", + loadingDiff: "Memuat perbedaan revisi...", + noChanges: "Tidak ditemukan perubahan tabel di antara revisi ini.", + rowDiff: "Perbedaan baris", + rows: "{count} baris", + loadingRows: "Memuat perbedaan baris...", + selectTable: "Pilih tabel yang berubah", + noRowChanges: "Tidak ada perubahan baris yang dikembalikan. Perubahan mungkin hanya pada skema.", + createBranch: "Buat branch", + createTag: "Buat tag", + mergeBranch: "Merge branch", + deleteBranch: "Hapus branch", + deleteTag: "Hapus tag", + createBranchDescription: "Buat branch dari revisi yang dipilih atau branch saat ini.", + createTagDescription: "Buat tag dari revisi yang dipilih atau branch saat ini.", + mergeBranchDescription: "Merge branch {name} ke branch aktif.", + deleteBranchDescription: "Hapus branch {name}. Operasi ini tidak dapat dibatalkan.", + deleteTagDescription: "Hapus tag {name}. Operasi ini tidak dapat dibatalkan.", + branchName: "Nama branch", + branchNamePlaceholder: "feature/my-branch", + tagName: "Nama tag", + tagNamePlaceholder: "v1.0.0", + branchSource: "Revisi sumber: {revision}", + branchNameRequired: "Masukkan nama branch.", + tagNameRequired: "Masukkan nama tag.", + branchCreated: "Branch {name} dibuat", + branchMerged: "Branch {name} di-merge", + branchDeleted: "Branch {name} dihapus", + tagCreated: "Tag {name} dibuat", + tagDeleted: "Tag {name} dihapus", + copyHash: "Salin hash commit", + revertCommit: "Revert commit ini", + hardResetToCommit: "Hard reset branch saat ini ke commit ini", + revertCommitTitle: "Revert commit", + hardResetTitle: "Hard reset branch saat ini", + revertCommitDescription: "Buat commit baru yang membalikkan perubahan yang diperkenalkan oleh commit {hash}.", + hardResetDescription: "Hard reset branch {branch} ke commit {hash}. Commit setelahnya dan semua perubahan working tree yang staged maupun unstaged akan dihapus dari status saat ini.", + highRiskConfirmation: "Ini adalah operasi berisiko tinggi. Konfirmasikan commit target sebelum melanjutkan.", + revertCommitComplete: "Commit {hash} di-revert", + hardResetComplete: "Branch saat ini di-hard-reset ke {hash}", + discardWorkingTree: "Buang perubahan working tree", + discardWorkingTreeDescription: "Buang semua perubahan working tree yang staged dan unstaged. Tindakan ini tidak dapat dibatalkan.", + discardWorkingTreeComplete: "Perubahan working tree dibuang", + sqlPreview: "Pratinjau SQL", + hashCopied: "Hash commit disalin", + copyCurrentValue: "Salin nilai saat ini", + copyBeforeValue: "Salin nilai sebelum", + copyAfterValue: "Salin nilai sesudah", + cellValueCopied: "Nilai sel disalin", + viewCellDiff: "Lihat detail perbedaan", + cellDiffTitle: "Perbedaan {table}.{column}", + cellDiffFormat: "Format perbandingan", + cellDiffFormatAuto: "Otomatis", + cellDiffFormatRaw: "Mentah", + cellDiffDetectedFormat: "Terdeteksi: {format}", + cellDiffFormatFailed: "Pemformatan gagal; menampilkan nilai mentah: {message}", + cellNullValue: "NULL", + cellRowMissing: "Baris tidak ada", + cellColumnMissing: "Kolom tidak ada", + }, + codeSnapshot: { + title: "Snapshot Kode", + close: "Tutup", + copy: "Salin ke Clipboard", + save: "Simpan PNG", + copied: "Disalin", + saved: "Disimpan", + failed: "Gagal: {message}", + take: "Ambil Snapshot Kode", + theme: "Tema", + themeLight: "Terang", + themeDark: "Gelap", + windowControls: "Kontrol Jendela", + lineNumbers: "Nomor Baris", + titleLabel: "Judul (opsional)", + titlePlaceholder: "mis. Contoh kueri", + }, + gridSnapshot: { + open: "Screenshot sel yang dipilih", + openRows: "Screenshot baris yang dipilih", + openColumns: "Screenshot kolom yang dipilih", + title: "Snapshot Grid", + copied: "Disalin", + saved: "Disimpan", + failed: "Gagal: {message}", + reset: "Reset", + rows: "{count} baris", + columns: "{count} kolom", + cells: "{count} sel", + appearance: "Tampilan", + layout: "Tata Letak", + fieldMetadata: "Metadata Field", + theme: "Tema", + windowControls: "Kontrol Jendela", + fieldNames: "Nama Field", + columnTypes: "Tipe Kolom", + columnDetails: "Deskripsi Field", + rowNumbers: "Nomor Baris", + wrapCells: "Lipat Isi Sel", + transpose: "Transpose", + compact: "Sel Ringkas", + titleLabel: "Judul (opsional)", + titlePlaceholder: "mis. Hasil kueri", + }, + migration: { + eyebrow: "Peluncuran pertama setelah upgrade", + title: "Peningkatan keamanan data", + stepsLabel: "Langkah migrasi", + language: "Bahasa", + step1: "Tinjau dan konfirmasi", + step2: "Migrasikan data", + step3: "Selesai dan cadangkan", + successTitle: "Migrasi selesai", + connectionCountLabel: "Koneksi: ", + secretCountLabel: "Item sensitif: ", + backupRequiredLabel: "Pencadangan diperlukan: ", + keyProviderLabel: "Status kunci: ", + ready: "siap", + pending: "perlu pengaturan", + intro: "Anda baru saja melakukan upgrade dan memulai ulang DBX. Upgrade ini meningkatkan keamanan data lokal; selesaikan langkah satu kali ini untuk terus menggunakan koneksi Anda.", + whyTitle: "Apa yang dilakukan upgrade ini?", + whyBody: "Versi baru menggunakan enkripsi yang lebih kuat untuk melindungi koneksi, plugin, dan pengaturan sensitif lainnya. Langkah ini berjalan sekali setelah upgrade dan tidak akan muncul lagi.", + whyItem1: "Pencadangan dibuat sebelum upgrade sehingga data Anda dapat dipulihkan jika diperlukan.", + whyItem2: "Hasilnya diverifikasi sebelum selesai untuk memastikan peningkatan keamanan berhasil.", + successIntro: "Migrasi selesai dan verifikasi ciphertext berhasil. Periksa koneksi Anda sebelum menghapus cadangan.", + connectionCount: "Koneksi: {count}", + secretCount: "Item sensitif yang akan dimigrasikan: {count}", + backupPath: "Cadangan: ", + dataDir: "Direktori data: ", + backupDir: "Direktori cadangan: ", + keyFileStatus: "File kunci yang dikonfigurasi: {configured}; dapat dibaca: {readable}", + persistentKeyStatus: "Penyedia kunci persisten tersedia: {available}", + yes: "ya", + no: "tidak", + keyUnavailable: "Kunci perangkat tidak tersedia. Izinkan akses keychain atau konfigurasikan kunci persisten.", + keyWillCreate: "dibuat saat migrasi pertama", + keyWillCreateHint: "DBX belum membuat kunci enkripsi lokal pada perangkat ini. Mulai migrasi untuk membuat kunci persisten, dan izinkan akses credential-store jika diminta.", + keyRecoveryHint: "Pulihkan kunci asli yang digunakan untuk direktori data ini, atau konfigurasikan kunci eksternal yang sama yang mengenkripsi data yang ada. Jangan menggantinya dengan kunci baru.", + progress: "Membuat cadangan, memigrasikan, dan memverifikasi. Jangan tutup DBX…", + failed: "Migrasi tidak selesai. Data asli tetap dipertahankan.", + cleanupFailed: "Migrasi selesai, tetapi cadangan tidak dapat dihapus.", + retryCleanup: "Coba lagi hapus cadangan", + statusFailed: "Tidak dapat memeriksa status migrasi.", + errorCode: "Kode galat: {code}", + retryStatus: "Coba lagi pemeriksaan status", + start: "Mulai migrasi", + running: "Memigrasikan…", + retryMigration: "Coba lagi migrasi", + enter: "Masuk ke DBX", + launching: "Memulai DBX…", + deleteBackup: "Hapus cadangan", + exportDiagnostic: "Ekspor diagnostik tersamarkan", + openDataDir: "Buka direktori data", + openBackupDir: "Buka lokasi cadangan", + exit: "Keluar dari DBX", + confirmDelete: "Hapus cadangan upgrade ini? Koneksi dan kata sandi Anda sudah tersimpan di perangkat ini, jadi menghapus cadangan tidak akan menghapus daftar koneksi atau kata sandi Anda, tetapi Anda tidak akan bisa lagi menggunakannya untuk membatalkan upgrade ini.", + confirm: "Hapus", + cancel: "Batal", + errors: { + persistentKeyAdvice: "Konfigurasikan DBX_SECRET_KEY_FILE atau DBX_SECRET_KEY dengan kunci persisten, lalu coba lagi pemeriksaan status.", + cleanupAdvice: "Periksa izin direktori cadangan dan coba lagi menghapus cadangan. Data Anda yang telah dimigrasikan siap digunakan.", + genericAdvice: "Perbaiki masalah di atas dan coba lagi. Data asli Anda masih tersedia.", + keyProviderAdvice: "Periksa apakah DBX dapat mengakses credential store-nya. Jika akses masih gagal, konfigurasikan DBX_SECRET_KEY_FILE persisten. Jangan hapus item kunci DBX yang ada.", + backupAdvice: "Periksa apakah direktori data dapat ditulis dan memiliki cukup ruang kosong.", + jsonAdvice: "Perbaiki file JSON lama yang dilaporkan, lalu coba lagi migrasi.", + verifyAdvice: "Simpan cadangan dan coba lagi. Jangan hapus cadangan migrasi sampai verifikasi berhasil.", + }, + checking: "Memeriksa status keamanan data lokal…", + authFailed: "Tidak dapat memeriksa autentikasi DBX.", + retry: "Coba lagi", + }, +}); diff --git a/apps/desktop/src/lib/app/localeOptions.ts b/apps/desktop/src/lib/app/localeOptions.ts index 389a195a24..f7dfc094c1 100644 --- a/apps/desktop/src/lib/app/localeOptions.ts +++ b/apps/desktop/src/lib/app/localeOptions.ts @@ -4,6 +4,7 @@ export const LOCALE_OPTIONS: { value: Locale; flag: string; label: string }[] = { value: "en", flag: "🇺🇸", label: "English" }, { value: "az", flag: "🇦🇿", label: "Azərbaycan" }, { value: "es", flag: "🇪🇸", label: "Español" }, + { value: "id", flag: "🇮🇩", label: "Bahasa Indonesia" }, { value: "it", flag: "🇮🇹", label: "Italiano" }, { value: "ja", flag: "🇯🇵", label: "日本語" }, { value: "ko", flag: "🇰🇷", label: "한국어" }, diff --git a/packages/app-tests/sidebarMutationRuntime.test.ts b/packages/app-tests/sidebarMutationRuntime.test.ts index 9f12b346af..814f88a232 100644 --- a/packages/app-tests/sidebarMutationRuntime.test.ts +++ b/packages/app-tests/sidebarMutationRuntime.test.ts @@ -6,7 +6,7 @@ const runtimeHost = readFileSync("apps/desktop/src/components/sidebar/SidebarTre const connectionMutationRuntime = readFileSync("apps/desktop/src/composables/useSidebarConnectionMutationRuntime.ts", "utf8"); const databaseSpecificMutationRuntime = readFileSync("apps/desktop/src/composables/useSidebarDatabaseSpecificMutationRuntime.ts", "utf8"); const tableMutationRuntime = readFileSync("apps/desktop/src/composables/useSidebarTableMutationRuntime.ts", "utf8"); -const localeSources = Object.fromEntries(["az", "en", "es", "it", "ja", "ko", "pt-BR", "ru", "tr", "zh-CN", "zh-TW"].map((locale) => [locale, readFileSync(`apps/desktop/src/i18n/locales/${locale}.ts`, "utf8")])); +const localeSources = Object.fromEntries(["az", "en", "es", "id", "it", "ja", "ko", "pt-BR", "ru", "tr", "zh-CN", "zh-TW"].map((locale) => [locale, readFileSync(`apps/desktop/src/i18n/locales/${locale}.ts`, "utf8")])); function functionBody(name: string): string { const source = [runtimeHost, connectionMutationRuntime, databaseSpecificMutationRuntime, tableMutationRuntime].find((candidate) => candidate.includes(`function ${name}(`)); diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index ccb12872b0..9a49b585d8 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -730,6 +730,7 @@ enum LocaleFamily { Japanese, Korean, Spanish, + Indonesian, Italian, Portuguese, Russian, @@ -759,6 +760,8 @@ fn locale_family(locale: &str) -> LocaleFamily { LocaleFamily::Azerbaijani } else if is_language("es") { LocaleFamily::Spanish + } else if is_language("id") { + LocaleFamily::Indonesian } else if is_language("tr") { LocaleFamily::Turkish } else if is_language("it") { @@ -780,6 +783,7 @@ fn tray_menu_labels_for_locale(locale: &str) -> (&'static str, &'static str) { LocaleFamily::Korean => ("DBX 표시", "DBX 종료"), LocaleFamily::Azerbaijani => ("DBX-i göstər", "DBX-dən çıx"), LocaleFamily::Spanish => ("Mostrar DBX", "Salir de DBX"), + LocaleFamily::Indonesian => ("Tampilkan DBX", "Keluar dari DBX"), LocaleFamily::Italian => ("Mostra DBX", "Esci da DBX"), LocaleFamily::Turkish => ("DBX'i Göster", "DBX'ten Çık"), LocaleFamily::Portuguese => ("Mostrar DBX", "Sair do DBX"), @@ -798,6 +802,7 @@ fn app_menu_copy_support_info_label(locale: &str) -> &'static str { LocaleFamily::Korean => "지원 정보 복사", LocaleFamily::Azerbaijani => "Dəstək məlumatlarını kopyala", LocaleFamily::Spanish => "Copiar información", + LocaleFamily::Indonesian => "Salin Info Dukungan", LocaleFamily::Italian => "Copia informazioni", LocaleFamily::Turkish => "Destek bilgilerini kopyala", LocaleFamily::Portuguese => "Copiar informações", @@ -815,6 +820,7 @@ fn app_menu_close_tab_label(locale: &str) -> &'static str { LocaleFamily::Korean => "탭 닫기", LocaleFamily::Azerbaijani => "Vərəqi bağla", LocaleFamily::Spanish => "Cerrar pestaña", + LocaleFamily::Indonesian => "Tutup Tab", LocaleFamily::Italian => "Chiudi scheda", LocaleFamily::Turkish => "Sekmeyi kapat", LocaleFamily::Portuguese => "Fechar aba", @@ -831,6 +837,7 @@ fn app_menu_quit_label(locale: &str, app_name: &str) -> String { LocaleFamily::Korean => format!("{app_name} 종료"), LocaleFamily::Azerbaijani => format!("{app_name}-dən çıx"), LocaleFamily::Spanish => format!("Salir de {app_name}"), + LocaleFamily::Indonesian => format!("Keluar dari {app_name}"), LocaleFamily::Italian => format!("Esci da {app_name}"), LocaleFamily::Turkish => format!("{app_name} Uygulamasından Çık"), LocaleFamily::Portuguese => format!("Sair do {app_name}"), @@ -1044,6 +1051,7 @@ mod tests { assert_eq!(tray_menu_labels_for_locale("ko-KR"), ("DBX 표시", "DBX 종료")); assert_eq!(tray_menu_labels_for_locale("az-AZ"), ("DBX-i göstər", "DBX-dən çıx")); assert_eq!(tray_menu_labels_for_locale("es-ES"), ("Mostrar DBX", "Salir de DBX")); + assert_eq!(tray_menu_labels_for_locale("id-ID"), ("Tampilkan DBX", "Keluar dari DBX")); assert_eq!(tray_menu_labels_for_locale("it-IT"), ("Mostra DBX", "Esci da DBX")); assert_eq!(tray_menu_labels_for_locale("pt-BR"), ("Mostrar DBX", "Sair do DBX")); assert_eq!(tray_menu_labels_for_locale("tr-TR"), ("DBX'i Göster", "DBX'ten Çık")); @@ -1063,6 +1071,7 @@ mod tests { assert_eq!(app_menu_quit_label("tr-TR", "DBX"), "DBX Uygulamasından Çık"); assert_eq!(app_menu_quit_label("ru-RU", "DBX"), "Выйти из DBX"); assert_eq!(app_menu_quit_label("az-AZ", "DBX"), "DBX-dən çıx"); + assert_eq!(app_menu_quit_label("id-ID", "DBX"), "Keluar dari DBX"); assert_eq!(app_menu_quit_label("en-US", "DBX"), "Quit DBX"); assert_eq!(app_menu_quit_label("", "DBX"), "Quit DBX"); assert_eq!(app_menu_copy_support_info_label("zh-CN"), "复制支持信息"); @@ -1071,6 +1080,7 @@ mod tests { assert_eq!(app_menu_copy_support_info_label("tr-TR"), "Destek bilgilerini kopyala"); assert_eq!(app_menu_copy_support_info_label("ru-RU"), "Копировать сведения о поддержке"); assert_eq!(app_menu_copy_support_info_label("az-AZ"), "Dəstək məlumatlarını kopyala"); + assert_eq!(app_menu_copy_support_info_label("id-ID"), "Salin Info Dukungan"); assert_eq!(app_menu_copy_support_info_label("en-US"), "Copy Support Info"); assert_eq!(app_menu_close_tab_label("zh-CN"), "关闭标签页"); assert_eq!(app_menu_close_tab_label("zh-TW"), "關閉分頁");