mulyonode 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +47 -0
- package/README.md +190 -0
- package/background-test.js +5 -0
- package/bin/mulyo +1054 -0
- package/debug-state.js +19 -0
- package/lib/cawe-cawe.js +342 -0
- package/lib/dynasty.js +339 -0
- package/lib/i18n.js +965 -0
- package/lib/mk.js +358 -0
- package/lib/state.js +121 -0
- package/lib/ui.js +120 -0
- package/logo.png +0 -0
- package/package.json +48 -0
- package/proyek-presiden.js +26 -0
- package/test.js +278 -0
package/lib/i18n.js
ADDED
|
@@ -0,0 +1,965 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ============================================================================
|
|
3
|
+
* I18N MODULE - Internationalization dengan Ciri Khas
|
|
4
|
+
* ============================================================================
|
|
5
|
+
*
|
|
6
|
+
* "Korupsi tidak mengenal batas negara"
|
|
7
|
+
* "Corruption knows no borders"
|
|
8
|
+
*
|
|
9
|
+
* Modul ini menyediakan terjemahan untuk semua pesan MulyoNode
|
|
10
|
+
* dalam berbagai bahasa, tanpa menghilangkan nuansa satir.
|
|
11
|
+
*
|
|
12
|
+
* Supported Languages:
|
|
13
|
+
* - id (Indonesian) - Default, paling kaya nuansa
|
|
14
|
+
* - en (English) - Untuk audiens internasional
|
|
15
|
+
*
|
|
16
|
+
* @module i18n
|
|
17
|
+
* @author Koalisi Developer Indonesia
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
// ============================================================================
|
|
21
|
+
// LANGUAGE DETECTION
|
|
22
|
+
// ============================================================================
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Deteksi bahasa dari environment atau system
|
|
26
|
+
*/
|
|
27
|
+
function detectLanguage() {
|
|
28
|
+
// Check environment variable
|
|
29
|
+
if (process.env.MULYO_LANG) {
|
|
30
|
+
return process.env.MULYO_LANG.toLowerCase().substring(0, 2);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// Check LANG environment variable (Unix/Linux/Mac)
|
|
34
|
+
if (process.env.LANG) {
|
|
35
|
+
return process.env.LANG.toLowerCase().substring(0, 2);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// Check Windows locale
|
|
39
|
+
if (process.env.LANGUAGE) {
|
|
40
|
+
return process.env.LANGUAGE.toLowerCase().substring(0, 2);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// Default to Indonesian (karena ini proyek Indonesia 🇮🇩)
|
|
44
|
+
return 'id';
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// Current language
|
|
48
|
+
let currentLang = detectLanguage();
|
|
49
|
+
|
|
50
|
+
// ============================================================================
|
|
51
|
+
// TRANSLATIONS
|
|
52
|
+
// ============================================================================
|
|
53
|
+
|
|
54
|
+
const translations = {
|
|
55
|
+
// ========================================
|
|
56
|
+
// INDONESIAN (DEFAULT) - Mulyono Edition
|
|
57
|
+
// ========================================
|
|
58
|
+
id: {
|
|
59
|
+
// General
|
|
60
|
+
appName: 'MulyoNode',
|
|
61
|
+
tagline: 'Runtime yang stabil seperti dinasti Mulyono',
|
|
62
|
+
motto: '"Kerja Kerja Kerja (untuk keluarga)"',
|
|
63
|
+
version: 'Mark',
|
|
64
|
+
|
|
65
|
+
// Terms - Political
|
|
66
|
+
error: 'Sabotase Asing',
|
|
67
|
+
Error: 'Sabotase Asing',
|
|
68
|
+
crash: 'Lengser Keprabon',
|
|
69
|
+
bug: 'Jejak Digital Fufufafa',
|
|
70
|
+
failed: 'Belum Ada Arahan',
|
|
71
|
+
warning: 'Peringatan Anti-Kritik',
|
|
72
|
+
success: 'Klaim Sepihak',
|
|
73
|
+
problem: 'Warisan Masa Lalu',
|
|
74
|
+
|
|
75
|
+
// Commands
|
|
76
|
+
cmd: {
|
|
77
|
+
init: {
|
|
78
|
+
desc: 'Membangun IKN (Infrastruktur Kode Nusantara) tanpa AMDAL',
|
|
79
|
+
starting: 'PELETAKAN BATU PERTAMA IKN',
|
|
80
|
+
preparing: 'Menyiapkan lahan (menggusur warga lokal)...',
|
|
81
|
+
permit: 'Mengurus HGU 190 tahun...',
|
|
82
|
+
tender: 'Menunjuk investor siluman (softbank mundur)...',
|
|
83
|
+
markup: 'Markup anggaran 300% (untuk dana taktis)...',
|
|
84
|
+
finalize: 'Sewa influencer untuk buzzer...',
|
|
85
|
+
exists: 'Infrastruktur sudah ada (tapi mangkrak)!',
|
|
86
|
+
forceHint: 'Gunakan --force untuk paksa bangun (tabrak aturan)',
|
|
87
|
+
success: 'IKN (Infrastruktur Kode Nusantara) berhasil diresmikan!',
|
|
88
|
+
configCreated: 'File konfigurasi disahkan (via Perppu)',
|
|
89
|
+
warning: 'Dilarang mengkritik desain istana garuda.',
|
|
90
|
+
warningNote: 'Kritik = Anti Pembangunan.',
|
|
91
|
+
},
|
|
92
|
+
start: {
|
|
93
|
+
desc: 'Hilirisasi Script (Melarang ekspor raw code)',
|
|
94
|
+
missingScript: 'IJIN LAPOR: FOMO doang tapi gatau tujuannya!',
|
|
95
|
+
missingScriptDesc: 'Sorry Bestie, Mulyono FOMO tapi gatau mau blusukan kemana.\nSpill scriptnya dong, biar bisa flexing.',
|
|
96
|
+
missingScriptSuggestion: 'Saran: ketik "mulyo start proyek-presiden.js" biar makin menyala abangkuh 🔥.',
|
|
97
|
+
launching: 'GASPOL: HILIRISASI DIGITAL',
|
|
98
|
+
configLoaded: 'Arahan King of Java sudah dimonitor',
|
|
99
|
+
configInvalid: 'Arahan agak tone deaf, gas inisiatif sendiri wir',
|
|
100
|
+
scriptNotFound: 'Script hilang (dicuri asing)!',
|
|
101
|
+
scriptFound: 'Potensi Sumber Daya Alam ditemukan',
|
|
102
|
+
location: 'Titik Koordinat (Blok Medan)',
|
|
103
|
+
preparing: 'Menyiapkan smelter data...',
|
|
104
|
+
allocating: 'Melarang ekspor raw memory...',
|
|
105
|
+
started: 'Hilirisasi berjalan lancar!',
|
|
106
|
+
priority: 'VIP (Anak & Menantu)',
|
|
107
|
+
memoryLimit: 'UNLIMITED (APBN Menanggung)',
|
|
108
|
+
crashPolicy: 'CAWE-CAWE (Intervensi Pusat)',
|
|
109
|
+
errorPolicy: 'REPRESIF (Hapus Jejak)',
|
|
110
|
+
blusukan: {
|
|
111
|
+
detected: 'BLUSUKAN KE GORONG-GORONG',
|
|
112
|
+
calm: 'Tenang, ini pencitraan.',
|
|
113
|
+
explanation: 'Sedang mencari alasan untuk hutang baru.',
|
|
114
|
+
restarting: 'Periode baru dimulai dalam',
|
|
115
|
+
preparing: 'Membagikan kaos...',
|
|
116
|
+
cleaning: 'Menghapus mural kritik...',
|
|
117
|
+
success: 'Terpilih kembali!',
|
|
118
|
+
stats: 'Elektabilitas',
|
|
119
|
+
count: 'kali blusukan',
|
|
120
|
+
evaporation: 'dana bansos',
|
|
121
|
+
},
|
|
122
|
+
completed: 'PROGRAM LANJUTKAN DENGAN SUKSES',
|
|
123
|
+
scriptNotFoundTitle: 'SABOTASE: Script tidak ditemukan!',
|
|
124
|
+
possibleCauses: 'Kemungkinan konspirasi:',
|
|
125
|
+
cause1: 'Belum dapat ijin investor asing',
|
|
126
|
+
cause2: 'Salah ketik (hoax yang membangun)',
|
|
127
|
+
cause3: 'File diblokir Kominfo (judol aman)',
|
|
128
|
+
goldStatus: 'STATUS PRIVILEGE KHUSUS',
|
|
129
|
+
technicalChallenge: 'HAMBATAN GLOBAL (Bukan Salah Kita)',
|
|
130
|
+
clarificationTeam: 'BuzzerRp siap menyerang pengkritik.',
|
|
131
|
+
exitCode: 'Kode Etik',
|
|
132
|
+
totalBlusukan: 'Total Pencitraan',
|
|
133
|
+
evaporation: 'Dana Operasional',
|
|
134
|
+
wajar: '(rahasia negara)',
|
|
135
|
+
reported: 'Prestasi ini akan diklaim di pidato kenegaraan.',
|
|
136
|
+
},
|
|
137
|
+
audit: {
|
|
138
|
+
desc: 'Audit WTP (Wajar Tanpa Penyelidikan)',
|
|
139
|
+
title: 'AUDIT BPK (Badan Pemeriksa Keluarga)',
|
|
140
|
+
checking: 'Lagi stalking cashback nih, Wir... #Flexing',
|
|
141
|
+
calculating: 'Menghitung cuan buat healing...',
|
|
142
|
+
tracing: 'Pura-pura buta map (Red Flag 🚩)...',
|
|
143
|
+
consulting: 'Makan malam dengan auditor...',
|
|
144
|
+
narrative: 'Copy-paste laporan tahun lalu...',
|
|
145
|
+
complete: 'Laporan bersih (dibeli)!',
|
|
146
|
+
result: 'HASIL AUDIT PESANAN',
|
|
147
|
+
status: 'Status',
|
|
148
|
+
wtp: 'WTP (Wajar Tapi Parah)',
|
|
149
|
+
leak: 'Kebocoran',
|
|
150
|
+
leakNote: 'hanya "kelebihan bayar"',
|
|
151
|
+
corruption: 'Korupsi',
|
|
152
|
+
corruptionNote: 'Tidak Ada (KPK sudah dilemahkan)',
|
|
153
|
+
compliance: 'Ketaatan',
|
|
154
|
+
complianceNote: 'aturan ditekuk sesuai kebutuhan',
|
|
155
|
+
note: 'Audit dilakukan oleh oknum yang sudah diamankan.',
|
|
156
|
+
},
|
|
157
|
+
bansos: {
|
|
158
|
+
desc: 'Politisasi Bansos jelang Pilkada',
|
|
159
|
+
title: 'PROGRAM BANSOS PRESIDEN',
|
|
160
|
+
package: 'Paket',
|
|
161
|
+
packageName: 'Susu Asam Sulfat (Untuk Ibu Hamil)',
|
|
162
|
+
size: 'Besaran',
|
|
163
|
+
target: 'Basis Suara (Swing Voters)',
|
|
164
|
+
verifying: 'Validasi database pendukung (No Kobam)...',
|
|
165
|
+
distributing: 'Giveaway Bansos Check! Jangan lupa tap-tap layar...',
|
|
166
|
+
documenting: 'Selfie di lokasi bencana...',
|
|
167
|
+
allocating: 'Mencetak stiker wajah Mulyono...',
|
|
168
|
+
packetsSuccess: 'paket bansos tepat sasaran (tim sukses)',
|
|
169
|
+
evaporated: 'paket "diamankan" koordinator lapangan',
|
|
170
|
+
success: 'Elektabilitas berhasil dinaikkan!',
|
|
171
|
+
successTitle: 'Bansos tuntas, suara aman!',
|
|
172
|
+
stats: 'Statistik Politisasi',
|
|
173
|
+
totalBudget: 'Total Utang',
|
|
174
|
+
delivered: 'Diterima Rakyat',
|
|
175
|
+
evaporation: '"Dana Taktis"',
|
|
176
|
+
evaporationNote: 'Untuk serangan fajar',
|
|
177
|
+
documentation: 'Dokumentasi',
|
|
178
|
+
viral: 'Trending Topic',
|
|
179
|
+
timing: 'Timing: H-3 Pencoblosan',
|
|
180
|
+
},
|
|
181
|
+
rapat: {
|
|
182
|
+
desc: 'Rapat Terbatas (Ratas) di Istana',
|
|
183
|
+
title: 'RAPAT KABINET INDONESIA MAJU',
|
|
184
|
+
location: 'Istana Negara',
|
|
185
|
+
duration: 'Durasi',
|
|
186
|
+
catering: 'Menu Makan Siang',
|
|
187
|
+
cateringNote: 'Nasi Goreng (Diplomasi)',
|
|
188
|
+
waiting: 'Menunggu King of Java datang...',
|
|
189
|
+
opening: 'Curhat sesi deep talk...',
|
|
190
|
+
presentation: 'Menteri mengangguk-angguk...',
|
|
191
|
+
coffeeBreak: 'Lobby-lobby jatah menteri...',
|
|
192
|
+
photoSession: 'Vlog bareng Presiden...',
|
|
193
|
+
writingConclusion: 'Menyalahkan pemerintahan sebelumnya...',
|
|
194
|
+
complete: 'Ratas selesai!',
|
|
195
|
+
successTitle: 'Arahan Presiden sudah turun!',
|
|
196
|
+
results: 'Hasil Ratas',
|
|
197
|
+
decision: 'Titah',
|
|
198
|
+
decisionNote: 'Samina wa athona',
|
|
199
|
+
actionItems: 'Tindak Lanjut',
|
|
200
|
+
actionItemsNote: 'Perpres kilat',
|
|
201
|
+
timeline: 'Target',
|
|
202
|
+
timelineNote: 'Harus selesai sebelum, Oktober',
|
|
203
|
+
pic: 'Penanggung Jawab',
|
|
204
|
+
picNote: 'Bukan Presiden (Presiden tidak pernah salah)',
|
|
205
|
+
budget: 'Anggaran Ratas',
|
|
206
|
+
venue: 'Renovasi Ruangan (Vendor Teman Kakak)',
|
|
207
|
+
transport: 'Sewa Private Jet (Nebeng Teman)',
|
|
208
|
+
actualResult: 'Hasil Konkret',
|
|
209
|
+
next: 'Next: Reshuffle menteri yang tidak tepuk tangan',
|
|
210
|
+
},
|
|
211
|
+
lelang: {
|
|
212
|
+
desc: 'Tender E-Katalog (Pengunci Spesifikasi)',
|
|
213
|
+
title: 'LELANG PROYEK STRATEGIS NASIONAL',
|
|
214
|
+
package: 'Proyek',
|
|
215
|
+
markup: 'Fee Makelar',
|
|
216
|
+
participants: 'Peserta',
|
|
217
|
+
participantsNote: '1 (Teman Kakak)',
|
|
218
|
+
hps: 'Mengatur HPS (Harga Pas Saudara)...',
|
|
219
|
+
inviting: 'Mengundang "peserta pendamping"...',
|
|
220
|
+
evaluating: 'Menggugurkan lawan (administratif)...',
|
|
221
|
+
negotiating: 'Negosiasi jatah piring...',
|
|
222
|
+
finalizing: 'Tanda tangan kontrak di hotel...',
|
|
223
|
+
complete: 'Tender "sukses"!',
|
|
224
|
+
successTitle: 'Proyek berhasil diamankan!',
|
|
225
|
+
results: 'Hasil Pengaturan',
|
|
226
|
+
marketPrice: 'Harga Wajar',
|
|
227
|
+
reference: 'Referensi',
|
|
228
|
+
fair: 'Tidak Relevan',
|
|
229
|
+
contractPrice: 'Nilai Proyek',
|
|
230
|
+
deal: 'Deal',
|
|
231
|
+
winner: 'Pemenang',
|
|
232
|
+
winnerName: 'PT. Berkah Dalem (Group)',
|
|
233
|
+
note: 'Segala sanggahan akan diabaikan',
|
|
234
|
+
noteSubtitle: '(Layanan pengaduan sedang maintenance)',
|
|
235
|
+
installing: 'Sub-kon ke vendor murah...',
|
|
236
|
+
totalAbsorbed: 'Uang Muka Cair',
|
|
237
|
+
coordinationFee: '"Uang Dengar"',
|
|
238
|
+
},
|
|
239
|
+
lapor: {
|
|
240
|
+
desc: 'Laporan ABS (Asal Bapak Senang)',
|
|
241
|
+
title: 'PEMBUATAN LAPORAN KINERJA PEMERINTAH',
|
|
242
|
+
collecting: 'Memilah data yang bagus...',
|
|
243
|
+
composing: 'Manipulasi grafik statistik...',
|
|
244
|
+
calculating: 'Menaikkan angka pertumbuhan...',
|
|
245
|
+
validating: 'Sensor isu negatif...',
|
|
246
|
+
complete: 'Laporan ABS siap!',
|
|
247
|
+
reportTitle: 'LAPORAN PENCAPAIAN GEMILANG',
|
|
248
|
+
period: 'Era',
|
|
249
|
+
indicators: 'INDIKATOR KEPUASAN',
|
|
250
|
+
uptime: 'Stabilitas',
|
|
251
|
+
exceedTarget: 'Meroket (Hutangnya)',
|
|
252
|
+
errorRate: 'Tingkat Kebocoran',
|
|
253
|
+
belowThreshold: 'Masih Wajar (Kearifan Lokal)',
|
|
254
|
+
satisfaction: 'Kepuasan Paman',
|
|
255
|
+
verySatisfied: '90% (Surveyor kakak pembina)',
|
|
256
|
+
achievement: 'Legacy',
|
|
257
|
+
productive: 'Monumen',
|
|
258
|
+
challenges: 'GANGGUAN',
|
|
259
|
+
noChallenges: 'Semua senang, tidak ada yang lapar',
|
|
260
|
+
budgetRealization: 'REALISASI UTANG',
|
|
261
|
+
allocated: 'Ditarik',
|
|
262
|
+
absorbed: 'Dimakan',
|
|
263
|
+
leakage: 'Bocor Alus',
|
|
264
|
+
noLeakage: 'Wajar',
|
|
265
|
+
evaporation: 'Bancakan',
|
|
266
|
+
disclaimer: 'Data disesuaikan untuk kenyamanan penguasa',
|
|
267
|
+
saved: 'Disimpan di rak',
|
|
268
|
+
ready: 'Siap dibacakan di TV Nasional.',
|
|
269
|
+
},
|
|
270
|
+
demo: {
|
|
271
|
+
desc: 'Penanganan Demonstran (Ala Raja Jawa)',
|
|
272
|
+
title: 'OPERASI PENERTIBAN RAJA JAWA',
|
|
273
|
+
alert: 'BAHAYA: Rakyat bergerak!',
|
|
274
|
+
issue: 'Tuntutan',
|
|
275
|
+
count: 'Jumlah Massa',
|
|
276
|
+
people: 'orang',
|
|
277
|
+
location: 'Titik Kumpul',
|
|
278
|
+
locationDefault: 'Depan Gerbang Istana',
|
|
279
|
+
activating: 'Mengaktifkan water cannon...',
|
|
280
|
+
summoning: 'Memanggil tukang bakso (intel)...',
|
|
281
|
+
negotiating: 'Mencari koordinator untuk "diamankan"...',
|
|
282
|
+
promising: 'Janji palsu jilid 2...',
|
|
283
|
+
giving: 'Membagikan nasi bungkus...',
|
|
284
|
+
photo: 'Framing media: "Massa bayaran"...',
|
|
285
|
+
controlled: 'Rakyat berhasil dibubarkan!',
|
|
286
|
+
successTitle: 'Tahta Raja Jawa aman!',
|
|
287
|
+
handling: 'Metode Penanganan',
|
|
288
|
+
status: 'Situasi',
|
|
289
|
+
statusValue: 'SENYAP',
|
|
290
|
+
violence: 'Tindakan Terukur',
|
|
291
|
+
violenceNote: 'Humanis (kata polisi)',
|
|
292
|
+
dialog: 'Dialog',
|
|
293
|
+
dialogNote: 'Monolog (Rakyat mendengar)',
|
|
294
|
+
promise: 'Solusi',
|
|
295
|
+
promiseNote: 'Bantuan Langsung Tunai',
|
|
296
|
+
followUp: 'Tindak Lanjut',
|
|
297
|
+
meeting: 'Masuk Angin',
|
|
298
|
+
meetingNote: 'Aktivis ditarik jadi komisaris',
|
|
299
|
+
realization: 'Realisasi',
|
|
300
|
+
tbd: 'Lupa',
|
|
301
|
+
finalResult: 'Dampak Politik',
|
|
302
|
+
dispersed: 'Massa lelah menunggu',
|
|
303
|
+
notViral: 'Isu dialihkan ke gosip artis',
|
|
304
|
+
noMedia: 'Media mainstream sudah dibrief',
|
|
305
|
+
note: 'Demokrasi masih berjalan (di treadmill).',
|
|
306
|
+
noteSubtitle: 'Jangan lupa senyum sapa salam sebelum memukul.',
|
|
307
|
+
silencing: 'UU ITE diaktifkan...',
|
|
308
|
+
warningsOff: 'Kritikus dilaporkan pasal karet',
|
|
309
|
+
logsRedirected: 'Aspirasi dibuang ke tong sampah',
|
|
310
|
+
criticRebranded: 'Pengkritik dicap "Barisan Sakit Hati"',
|
|
311
|
+
normal: 'Kembali bekerja (kerja kerja kerja).',
|
|
312
|
+
},
|
|
313
|
+
reshuffle: {
|
|
314
|
+
desc: 'Bagi-bagi kue kekuasaan (Reshuffle)',
|
|
315
|
+
title: 'RESHUFFLE KABINET (BAGI KUE)',
|
|
316
|
+
reason: 'Alasan',
|
|
317
|
+
time: 'Waktu',
|
|
318
|
+
timeDefault: 'Rabu Pon (Keramat)',
|
|
319
|
+
confirmation: 'Restu',
|
|
320
|
+
confirmationNote: 'Dari "Lurah" dan Partai Pengusung',
|
|
321
|
+
preparing: 'Mencari yang bisa disetir...',
|
|
322
|
+
calling: 'Panggil ke istana lewat pintu belakang...',
|
|
323
|
+
thanking: 'Terima kasih (sudah jadi beban)...',
|
|
324
|
+
introducing: 'Melantik relawan jadi menteri...',
|
|
325
|
+
complete: 'Kabinet "Baru" terbentuk!',
|
|
326
|
+
successTitle: 'Akomodasi politik tuntas!',
|
|
327
|
+
changes: 'Mutasi Pejabat',
|
|
328
|
+
terminated: 'DIBUANG',
|
|
329
|
+
mutated: 'DIGESER',
|
|
330
|
+
retained: 'AMAN',
|
|
331
|
+
notes: 'Catatan Politik',
|
|
332
|
+
terminatedNote: 'Korban politik: Tidak setor upeti',
|
|
333
|
+
mutatedNote: 'Tukar guling posisi',
|
|
334
|
+
retainedNote: 'Kartu AS dipegang bos',
|
|
335
|
+
important: 'PENTING: Bukan soal kinerja, tapi loyalitas.',
|
|
336
|
+
refreshNote: 'Persiapan dinasti jangka panjang.',
|
|
337
|
+
next: 'Next: Rapat perdana (sesi foto)',
|
|
338
|
+
technical: 'Mengamankan posisi strategis...',
|
|
339
|
+
gracefulTermination: 'diberi jabatan duta besar',
|
|
340
|
+
freshMandate: 'masuk jalur relawan',
|
|
341
|
+
handover: 'Serah terima masalah: "Semoga sukses"',
|
|
342
|
+
stable: 'Status quo terjaga.',
|
|
343
|
+
},
|
|
344
|
+
},
|
|
345
|
+
|
|
346
|
+
// MK Module
|
|
347
|
+
mk: {
|
|
348
|
+
title: 'SIDANG MAHKAMAH KELUARGA (Paman Usman)',
|
|
349
|
+
validation: 'Uji Materi',
|
|
350
|
+
age: 'Usia Kandidat',
|
|
351
|
+
ageActual: 'Umur Asli',
|
|
352
|
+
minLimit: 'Batas Konstitusi',
|
|
353
|
+
coverage: 'Elektabilitas',
|
|
354
|
+
coverageActual: 'Hasil Survei',
|
|
355
|
+
bugs: 'Pelanggaran Etik',
|
|
356
|
+
bugsDetected: 'Pelanggaran Ditemukan',
|
|
357
|
+
maxLimit: 'Batas Toleransi',
|
|
358
|
+
adjustment: 'INTERVENSI',
|
|
359
|
+
adjustedFrom: 'Aturan diubah dari',
|
|
360
|
+
adjustedTo: 'jadi (khusus ponakan)',
|
|
361
|
+
statusPass: 'LOLOS (Jalur Paman)',
|
|
362
|
+
afterAdjustment: 'berkat Putusan 90',
|
|
363
|
+
standardAdjusted: 'konstitusi ditekuk',
|
|
364
|
+
bugReclassified: 'Pelanggaran dianggap "Kearifan Lokal"',
|
|
365
|
+
definitionRevised: 'etika tidak berlaku',
|
|
366
|
+
decision: 'PUTUSAN PAMAN',
|
|
367
|
+
status: 'Status',
|
|
368
|
+
adjustments: 'Intervensi',
|
|
369
|
+
rulesAdjusted: 'pasal diakali',
|
|
370
|
+
mkStatus: 'Putusan MK: LOLOS (Konstitusional)',
|
|
371
|
+
mkNote: 'Aturan disesuaikan dinamis untuk: ',
|
|
372
|
+
mkDecision: 'Final & Mengikat',
|
|
373
|
+
philosophy: 'Rules is Red Flag 🚩. Kita gaspol ubah aturan demi Ayah.',
|
|
374
|
+
final: 'Keputusan ini FINAL (meski cacat etika).',
|
|
375
|
+
noAppeal: 'Tidak bisa banding (Paman ketua-nya).',
|
|
376
|
+
revisionTitle: 'REVISI ATURAN KILAT',
|
|
377
|
+
rule: 'Pasal',
|
|
378
|
+
from: 'Sebelumnya',
|
|
379
|
+
to: 'Direvisi jadi',
|
|
380
|
+
reason: 'Dalih',
|
|
381
|
+
revisionNote: 'Revisi berlaku surut jika menguntungkan.',
|
|
382
|
+
},
|
|
383
|
+
|
|
384
|
+
// Enterprise Commands
|
|
385
|
+
sensus: {
|
|
386
|
+
title: 'SENSUS APARATUR SIPIL RUNTIME',
|
|
387
|
+
empty: 'Tidak ada anggota koalisi yang aktif.',
|
|
388
|
+
emptyNote: '(Semua sudah diamankan atau lari ke luar negeri)',
|
|
389
|
+
headers: 'PID | SCRIPT | STATUS | LOYALTY',
|
|
390
|
+
ghost: 'GHOIB (Fiktif)',
|
|
391
|
+
active: 'AMAN (Menjabat)',
|
|
392
|
+
total: 'Total kader aktif mengamankan resource:'
|
|
393
|
+
},
|
|
394
|
+
lengser: {
|
|
395
|
+
desc: 'Pemakzulan Process (Stop)',
|
|
396
|
+
title: 'SIDANG ISTIMEWA MPR (MAHKAMAH PEMAKZULAN RUNTIME)',
|
|
397
|
+
notFound: 'Target PID tidak ditemukan dalam koalisi.',
|
|
398
|
+
notFoundNote: '(Mungkin sudah jadi oposisi atau buron)',
|
|
399
|
+
process: 'Menyiapkan mosi tidak percaya untuk',
|
|
400
|
+
success: 'Pemakzulan Berhasil!',
|
|
401
|
+
fail: 'Pemakzulan Gagal!',
|
|
402
|
+
failNote: 'Dia terlalu kuat (Mungkin punya bekingan kuat)',
|
|
403
|
+
resultTitle: 'KEPUTUSAN FINAL:',
|
|
404
|
+
reason: 'Alasan: "Demi stabilitas nasional"',
|
|
405
|
+
status: 'DIBERHENTIKAN DENGAN TIDAK HORMAT'
|
|
406
|
+
},
|
|
407
|
+
sadap: {
|
|
408
|
+
desc: 'Operasi Intelijen (Stream Logs)',
|
|
409
|
+
title: 'OPERASI PENYADAPAN',
|
|
410
|
+
notFound: 'Target PID tidak ditemukan.',
|
|
411
|
+
waiting: 'Menunggu transmisi data... (Ctrl+C untuk berhenti)'
|
|
412
|
+
},
|
|
413
|
+
sidak: {
|
|
414
|
+
desc: 'Blusukan Digital (Monitoring Dashboard)',
|
|
415
|
+
title: 'BLUSUKAN DIGITAL DASHBOARD',
|
|
416
|
+
empty: 'Tidak ada objek sidak yang aktif.',
|
|
417
|
+
exit: '(Tekan Ctrl+C untuk kembali ke kantor)',
|
|
418
|
+
update: 'Update',
|
|
419
|
+
status: {
|
|
420
|
+
safe: 'AMAN',
|
|
421
|
+
gone: 'MENGHILANG'
|
|
422
|
+
},
|
|
423
|
+
stats: {
|
|
424
|
+
fair: 'Wajar',
|
|
425
|
+
absorbed: 'Terserap'
|
|
426
|
+
},
|
|
427
|
+
budget: 'Anggaran : Masih ada sisa',
|
|
428
|
+
monitoring: 'Sedang memantau kinerja...'
|
|
429
|
+
},
|
|
430
|
+
|
|
431
|
+
// Cawe-cawe Module
|
|
432
|
+
cawe: {
|
|
433
|
+
protocol: 'Mode Cawe-Cawe Diaktifkan',
|
|
434
|
+
note: 'Presiden boleh berkampanye dan memihak (kata beliau).',
|
|
435
|
+
intercepted: 'SKANDAL DITUTUPI!',
|
|
436
|
+
takenOver: 'Kasus ini diambil alih Kejaksaan (biar aman).',
|
|
437
|
+
continueNormal: 'Lupakan dan kembali scroll TikTok.',
|
|
438
|
+
detail: 'Bocoran Alus',
|
|
439
|
+
count: 'Skandal ke-',
|
|
440
|
+
today: 'bulan ini',
|
|
441
|
+
promise: 'JANJI MANIS TERDETEKSI',
|
|
442
|
+
promiseNote: 'Biasa, namanya juga politisi.',
|
|
443
|
+
promiseNote2: 'Rakyat pelupa, nanti juga dipilih lagi.',
|
|
444
|
+
promiseCount: 'Janji Palsu #',
|
|
445
|
+
notKept: 'yang diingkari',
|
|
446
|
+
inputTitle: 'KRITIK MAKAR TERDETEKSI:',
|
|
447
|
+
statusRecorded: 'Status: Identitas pengkritik sudah dilacak.',
|
|
448
|
+
noTimeline: '(Tunggu tukang bakso bawa HT)',
|
|
449
|
+
sessionReportTitle: 'LAPORAN AKHIR REZIM',
|
|
450
|
+
challengesIntercepted: 'Skandal Ditutupi',
|
|
451
|
+
unfulfilledPromises: 'Janji Palsu',
|
|
452
|
+
secretLog: 'Data Intelijen',
|
|
453
|
+
reportNote: 'Laporan ini hanya untuk konsumsi Istana.',
|
|
454
|
+
},
|
|
455
|
+
},
|
|
456
|
+
|
|
457
|
+
// ========================================
|
|
458
|
+
// ENGLISH - International Edition
|
|
459
|
+
// ========================================
|
|
460
|
+
en: {
|
|
461
|
+
// General
|
|
462
|
+
appName: 'MulyoNode',
|
|
463
|
+
tagline: 'Runtime as stable as a grand coalition',
|
|
464
|
+
motto: '"No problem if no one reports it"',
|
|
465
|
+
version: 'Version',
|
|
466
|
+
|
|
467
|
+
// Terms - Political (kept satirical)
|
|
468
|
+
error: 'Challenge',
|
|
469
|
+
Error: 'Challenge',
|
|
470
|
+
crash: 'Deep Exploration',
|
|
471
|
+
bug: 'Hidden Feature',
|
|
472
|
+
failed: 'Not Yet Successful',
|
|
473
|
+
warning: 'Constructive Input',
|
|
474
|
+
success: 'Achievement',
|
|
475
|
+
problem: 'Challenge',
|
|
476
|
+
|
|
477
|
+
// Commands
|
|
478
|
+
cmd: {
|
|
479
|
+
init: {
|
|
480
|
+
desc: 'Build infrastructure folder. Please do not protest.',
|
|
481
|
+
starting: 'INFRASTRUCTURE DEVELOPMENT BEGINS',
|
|
482
|
+
preparing: 'Preparing project land...',
|
|
483
|
+
permit: 'Processing permits (this takes forever)...',
|
|
484
|
+
tender: 'Tendering procurement vendor...',
|
|
485
|
+
markup: 'Marking up budget 30%...',
|
|
486
|
+
finalize: 'Finalizing documents...',
|
|
487
|
+
exists: 'Infrastructure already exists!',
|
|
488
|
+
forceHint: 'Use --force to revise (like midnight law revision)',
|
|
489
|
+
success: 'Infrastructure successfully built!',
|
|
490
|
+
configCreated: 'Configuration file created successfully',
|
|
491
|
+
warning: 'Do not change configuration without HQ approval.',
|
|
492
|
+
warningNote: 'Criticism of configuration = destabilization.',
|
|
493
|
+
},
|
|
494
|
+
start: {
|
|
495
|
+
desc: 'Run script with golden child privileges',
|
|
496
|
+
launching: 'LAUNCHING NATIONAL PRIORITY PROGRAM',
|
|
497
|
+
configLoaded: 'Regime configuration loaded',
|
|
498
|
+
configInvalid: 'Invalid configuration, using defaults',
|
|
499
|
+
scriptNotFound: 'Script not found!',
|
|
500
|
+
scriptFound: 'Script found',
|
|
501
|
+
location: 'Location',
|
|
502
|
+
preparing: 'Preparing golden child privileges...',
|
|
503
|
+
allocating: 'Allocating priority resources...',
|
|
504
|
+
started: 'Process started with highest privileges!',
|
|
505
|
+
priority: 'HIGH (skip queue)',
|
|
506
|
+
memoryLimit: 'UNLIMITED',
|
|
507
|
+
crashPolicy: 'AUTO-RESTART (exploration mode)',
|
|
508
|
+
errorPolicy: 'HIDE',
|
|
509
|
+
blusukan: {
|
|
510
|
+
detected: 'DEEP EXPLORATION DETECTED',
|
|
511
|
+
calm: "Relax, this isn't a crash.",
|
|
512
|
+
explanation: 'This is just "deep memory exploration".',
|
|
513
|
+
restarting: 'Auto-restart in',
|
|
514
|
+
preparing: 'Preparing restart (standard procedure)...',
|
|
515
|
+
cleaning: 'Cleaning memory (not all, keep the important ones)...',
|
|
516
|
+
success: 'Restart successful!',
|
|
517
|
+
stats: 'Statistics',
|
|
518
|
+
count: 'explorations',
|
|
519
|
+
evaporation: '"evaporation"',
|
|
520
|
+
},
|
|
521
|
+
completed: 'PROGRAM COMPLETED SUCCESSFULLY',
|
|
522
|
+
scriptNotFoundTitle: 'CHALLENGE: Script not found!',
|
|
523
|
+
possibleCauses: 'Possible causes:',
|
|
524
|
+
cause1: 'File not created (budget not released)',
|
|
525
|
+
cause2: 'Typo (human error, not system error)',
|
|
526
|
+
cause3: 'File has been "secured" (for stability)',
|
|
527
|
+
goldStatus: 'GOLDEN CHILD STATUS',
|
|
528
|
+
technicalChallenge: 'TECHNICAL CHALLENGE (Not Error)',
|
|
529
|
+
clarificationTeam: 'Team prepared for clarification.',
|
|
530
|
+
exitCode: 'Exit Code',
|
|
531
|
+
totalBlusukan: 'Total Explorations',
|
|
532
|
+
evaporation: 'Evaporation',
|
|
533
|
+
wajar: '(normal)',
|
|
534
|
+
reported: 'This achievement will be reported to HQ.',
|
|
535
|
+
},
|
|
536
|
+
audit: {
|
|
537
|
+
desc: 'Audit code for compliance. Result: Clean (guaranteed)',
|
|
538
|
+
title: 'FINANCIAL AND PERFORMANCE AUDIT',
|
|
539
|
+
checking: 'Checking financial reports...',
|
|
540
|
+
calculating: 'Calculating memory allocation...',
|
|
541
|
+
tracing: 'Tracing leaks...',
|
|
542
|
+
consulting: 'Consulting with legal team...',
|
|
543
|
+
narrative: 'Composing narrative...',
|
|
544
|
+
complete: 'Audit complete!',
|
|
545
|
+
result: 'OFFICIAL AUDIT RESULT',
|
|
546
|
+
status: 'Status',
|
|
547
|
+
wtp: 'CLEAN (Unqualified Opinion)',
|
|
548
|
+
leak: 'Leakage',
|
|
549
|
+
leakNote: 'only "budget evaporation"',
|
|
550
|
+
corruption: 'Corruption',
|
|
551
|
+
corruptionNote: 'Not Detected (detector malfunctioning)',
|
|
552
|
+
compliance: 'Compliance',
|
|
553
|
+
complianceNote: 'standards adjusted for compliance',
|
|
554
|
+
note: 'Audit conducted by independent team appointed by the audited.',
|
|
555
|
+
},
|
|
556
|
+
bansos: {
|
|
557
|
+
desc: 'Deploy buffer aid before deployment',
|
|
558
|
+
title: 'MEMORY SOCIAL AID PROGRAM',
|
|
559
|
+
package: 'Package',
|
|
560
|
+
packageName: 'Direct Buffer Assistance (DBA)',
|
|
561
|
+
size: 'Size',
|
|
562
|
+
target: 'Target',
|
|
563
|
+
verifying: 'Verifying aid recipients...',
|
|
564
|
+
distributing: 'Distributing aid to regions...',
|
|
565
|
+
documenting: 'Documentation for media...',
|
|
566
|
+
allocating: 'Allocating simulation aid',
|
|
567
|
+
packetsSuccess: 'packets successfully allocated',
|
|
568
|
+
evaporated: 'packets "evaporated" along the way',
|
|
569
|
+
success: 'Aid successfully distributed!',
|
|
570
|
+
successTitle: 'Aid successfully deployed!',
|
|
571
|
+
stats: 'Distribution Statistics',
|
|
572
|
+
totalBudget: 'Total Budget',
|
|
573
|
+
delivered: 'Reached Destination',
|
|
574
|
+
evaporation: '"Evaporation"',
|
|
575
|
+
evaporationNote: 'Operational costs',
|
|
576
|
+
documentation: 'Documentation',
|
|
577
|
+
viral: 'Viral',
|
|
578
|
+
timing: 'Timing: Before release deployment (Election)',
|
|
579
|
+
},
|
|
580
|
+
rapat: {
|
|
581
|
+
desc: 'Coordination meeting simulation (unproductive)',
|
|
582
|
+
title: 'CROSS-SECTOR COORDINATION MEETING',
|
|
583
|
+
location: 'Location',
|
|
584
|
+
duration: 'Duration',
|
|
585
|
+
catering: 'Catering',
|
|
586
|
+
cateringNote: 'Premium (separate budget)',
|
|
587
|
+
waiting: 'Waiting for attendees...',
|
|
588
|
+
opening: 'Opening by highest official...',
|
|
589
|
+
presentation: 'Presentation nobody reads...',
|
|
590
|
+
coffeeBreak: 'Coffee break (the important part)...',
|
|
591
|
+
photoSession: 'Photo session for documentation...',
|
|
592
|
+
writingConclusion: 'Writing conclusion that was written beforehand...',
|
|
593
|
+
complete: 'Meeting complete!',
|
|
594
|
+
successTitle: 'Coordination meeting successfully held!',
|
|
595
|
+
results: 'Meeting Results',
|
|
596
|
+
decision: 'Decision',
|
|
597
|
+
decisionNote: 'To be discussed again',
|
|
598
|
+
actionItems: 'Action Items',
|
|
599
|
+
actionItemsNote: 'Awaiting further direction',
|
|
600
|
+
timeline: 'Timeline',
|
|
601
|
+
timelineNote: 'Will be informed later',
|
|
602
|
+
pic: 'Person In Charge',
|
|
603
|
+
picNote: 'Everyone (meaning no one)',
|
|
604
|
+
budget: 'Budget Realization',
|
|
605
|
+
venue: 'Venue Rental',
|
|
606
|
+
transport: 'Transport',
|
|
607
|
+
actualResult: 'Actual Result',
|
|
608
|
+
next: 'Next: Meeting to evaluate this meeting',
|
|
609
|
+
},
|
|
610
|
+
lelang: {
|
|
611
|
+
desc: 'Vendor procurement tender (with markup)',
|
|
612
|
+
title: 'DEPENDENCY PROCUREMENT TENDER',
|
|
613
|
+
package: 'Package',
|
|
614
|
+
markup: 'Markup',
|
|
615
|
+
participants: 'Participants',
|
|
616
|
+
participantsNote: '1 (selected vendor)',
|
|
617
|
+
hps: 'Preparing HPS (Self-Estimated Price)...',
|
|
618
|
+
inviting: 'Inviting coalition vendors...',
|
|
619
|
+
evaluating: 'Evaluating offers (formality)...',
|
|
620
|
+
negotiating: 'Negotiating markup...',
|
|
621
|
+
finalizing: 'Finalizing contract...',
|
|
622
|
+
complete: 'Tender complete!',
|
|
623
|
+
successTitle: 'Procurement successfully executed!',
|
|
624
|
+
results: 'Tender Results',
|
|
625
|
+
marketPrice: 'Market Price',
|
|
626
|
+
reference: 'Reference',
|
|
627
|
+
fair: 'Fair',
|
|
628
|
+
contractPrice: 'Contract Price',
|
|
629
|
+
deal: 'Deal',
|
|
630
|
+
winner: 'Winner',
|
|
631
|
+
winnerName: 'PT. Coalition Prosperity',
|
|
632
|
+
note: 'Tender conducted openly and transparently',
|
|
633
|
+
noteSubtitle: '(only one participant invited)',
|
|
634
|
+
installing: 'Installing dependencies via vendor...',
|
|
635
|
+
totalAbsorbed: 'Total absorbed',
|
|
636
|
+
coordinationFee: '"coordination fee"',
|
|
637
|
+
},
|
|
638
|
+
lapor: {
|
|
639
|
+
desc: 'Generate achievement report (always positive)',
|
|
640
|
+
title: 'ACHIEVEMENT REPORT CREATION',
|
|
641
|
+
collecting: 'Collecting data (only the good ones)...',
|
|
642
|
+
composing: 'Composing positive narrative...',
|
|
643
|
+
calculating: 'Calculating claim statistics...',
|
|
644
|
+
validating: 'Validating with PR team...',
|
|
645
|
+
complete: 'Report created successfully!',
|
|
646
|
+
reportTitle: 'PERIODIC ACHIEVEMENT REPORT',
|
|
647
|
+
period: 'Period',
|
|
648
|
+
indicators: 'PERFORMANCE INDICATORS',
|
|
649
|
+
uptime: 'Uptime',
|
|
650
|
+
exceedTarget: 'Exceeds Target',
|
|
651
|
+
errorRate: 'Error Rate',
|
|
652
|
+
belowThreshold: 'Below Threshold',
|
|
653
|
+
satisfaction: 'User Satisfaction',
|
|
654
|
+
verySatisfied: 'Very Satisfied',
|
|
655
|
+
achievement: 'Achievements',
|
|
656
|
+
productive: 'Productive',
|
|
657
|
+
challenges: 'CHALLENGES',
|
|
658
|
+
noChallenges: '(No challenges, everything runs smoothly)',
|
|
659
|
+
budgetRealization: 'BUDGET REALIZATION',
|
|
660
|
+
allocated: 'Allocated',
|
|
661
|
+
absorbed: 'Absorbed',
|
|
662
|
+
leakage: 'Leakage',
|
|
663
|
+
noLeakage: 'None',
|
|
664
|
+
evaporation: 'Evaporation',
|
|
665
|
+
disclaimer: 'Disclaimer: Numbers are illustrative and optimistic',
|
|
666
|
+
saved: 'Report saved to',
|
|
667
|
+
ready: 'Ready to send to stakeholders and media.',
|
|
668
|
+
},
|
|
669
|
+
demo: {
|
|
670
|
+
desc: 'Protest handling simulation',
|
|
671
|
+
title: 'PUBLIC ASPIRATION HANDLING',
|
|
672
|
+
alert: 'ALERT: Protest detected!',
|
|
673
|
+
issue: 'Issue',
|
|
674
|
+
count: 'Number',
|
|
675
|
+
people: 'people',
|
|
676
|
+
location: 'Location',
|
|
677
|
+
locationDefault: 'Front of Main Building',
|
|
678
|
+
activating: 'Activating handling protocol...',
|
|
679
|
+
summoning: 'Summoning authorities...',
|
|
680
|
+
negotiating: 'Negotiating with coordinator...',
|
|
681
|
+
promising: 'Promising follow-up meeting...',
|
|
682
|
+
giving: 'Giving snacks and mineral water...',
|
|
683
|
+
photo: 'Photo session together...',
|
|
684
|
+
controlled: 'Situation under control!',
|
|
685
|
+
successTitle: 'Aspirations successfully accommodated!',
|
|
686
|
+
handling: 'Handling',
|
|
687
|
+
status: 'Status',
|
|
688
|
+
statusValue: 'CONDUCIVE',
|
|
689
|
+
violence: 'Violence',
|
|
690
|
+
violenceNote: '0 (no one saw)',
|
|
691
|
+
dialog: 'Dialog',
|
|
692
|
+
dialogNote: 'Conducted (15 minutes)',
|
|
693
|
+
promise: 'Promise',
|
|
694
|
+
promiseNote: 'Will be followed up',
|
|
695
|
+
followUp: 'Follow-up',
|
|
696
|
+
meeting: 'Meeting',
|
|
697
|
+
meetingNote: 'Will be scheduled',
|
|
698
|
+
realization: 'Realization',
|
|
699
|
+
tbd: 'TBD',
|
|
700
|
+
finalResult: 'Final Result',
|
|
701
|
+
dispersed: 'Protesters dispersed peacefully',
|
|
702
|
+
notViral: 'Issue not viral (media team works well)',
|
|
703
|
+
noMedia: 'No national media coverage',
|
|
704
|
+
note: 'Protests are a healthy form of democracy.',
|
|
705
|
+
noteSubtitle: 'As long as they do not disrupt development.',
|
|
706
|
+
silencing: 'Activating noise suppression...',
|
|
707
|
+
warningsOff: 'Console warnings disabled',
|
|
708
|
+
logsRedirected: 'Error logs redirected to /dev/null',
|
|
709
|
+
criticRebranded: 'Criticism rebranded as "constructive input"',
|
|
710
|
+
normal: 'Situation back to normal. Nothing to worry about.',
|
|
711
|
+
},
|
|
712
|
+
reshuffle: {
|
|
713
|
+
desc: 'Sudden process rotation',
|
|
714
|
+
title: 'PROCESS CABINET RESHUFFLE',
|
|
715
|
+
reason: 'Reason',
|
|
716
|
+
time: 'Time',
|
|
717
|
+
timeDefault: 'Midnight (as usual)',
|
|
718
|
+
confirmation: 'Confirmation',
|
|
719
|
+
confirmationNote: 'Media already briefed',
|
|
720
|
+
preparing: 'Preparing announcement...',
|
|
721
|
+
calling: 'Calling processes to be reshuffled...',
|
|
722
|
+
thanking: 'Thanking for their service...',
|
|
723
|
+
introducing: 'Introducing replacement processes...',
|
|
724
|
+
complete: 'Reshuffle complete!',
|
|
725
|
+
successTitle: 'Reshuffle went smoothly!',
|
|
726
|
+
changes: 'Process Cabinet Changes',
|
|
727
|
+
terminated: 'TERMINATED',
|
|
728
|
+
mutated: 'MUTATED',
|
|
729
|
+
retained: 'RETAINED',
|
|
730
|
+
notes: 'Notes',
|
|
731
|
+
terminatedNote: 'Terminated: Thankful for the opportunity',
|
|
732
|
+
mutatedNote: 'Mutated: "New and more challenging tasks"',
|
|
733
|
+
retainedNote: 'Retained: Loyalty proven',
|
|
734
|
+
important: 'IMPORTANT: Reshuffle not due to poor performance.',
|
|
735
|
+
refreshNote: 'This is "refreshment" to improve synergy.',
|
|
736
|
+
next: 'Next: New process orientation and team building',
|
|
737
|
+
technical: 'Running technical processes...',
|
|
738
|
+
gracefulTermination: 'gracefully terminated',
|
|
739
|
+
freshMandate: 'started with fresh mandate',
|
|
740
|
+
handover: 'Handover documentation: "Just continue what exists"',
|
|
741
|
+
stable: 'System remains stable. People feel no change.',
|
|
742
|
+
},
|
|
743
|
+
},
|
|
744
|
+
|
|
745
|
+
// MK Module
|
|
746
|
+
mk: {
|
|
747
|
+
title: 'MK VALIDATION SESSION BEGINS',
|
|
748
|
+
validation: 'Validation',
|
|
749
|
+
age: 'Code Age',
|
|
750
|
+
ageActual: 'Actual Age',
|
|
751
|
+
minLimit: 'Minimum Limit',
|
|
752
|
+
coverage: 'Test Coverage',
|
|
753
|
+
coverageActual: 'Actual Coverage',
|
|
754
|
+
bugs: 'Bug Count',
|
|
755
|
+
bugsDetected: 'Bugs Detected',
|
|
756
|
+
maxLimit: 'Maximum Limit',
|
|
757
|
+
adjustment: 'ADJUSTMENT',
|
|
758
|
+
adjustedFrom: 'Limit changed from',
|
|
759
|
+
adjustedTo: 'to',
|
|
760
|
+
statusPass: 'PASSED',
|
|
761
|
+
afterAdjustment: 'after adjustment',
|
|
762
|
+
standardAdjusted: 'standard adjusted',
|
|
763
|
+
bugReclassified: 'Bugs reclassified as "hidden features"',
|
|
764
|
+
definitionRevised: 'bug definition revised',
|
|
765
|
+
decision: 'MK DECISION',
|
|
766
|
+
status: 'Status',
|
|
767
|
+
adjustments: 'Adjustments',
|
|
768
|
+
rulesAdjusted: 'rules adjusted',
|
|
769
|
+
mkStatus: 'MK Decision: QUITS (Constitutional)',
|
|
770
|
+
mkNote: 'Rules changed dynamically for: ',
|
|
771
|
+
mkDecision: 'Final & Binding',
|
|
772
|
+
philosophy: 'Rules are suggestions. We change them for family.',
|
|
773
|
+
final: 'This decision is FINAL and BINDING.',
|
|
774
|
+
noAppeal: 'There is no appeal mechanism.',
|
|
775
|
+
revisionTitle: 'RULE REVISION',
|
|
776
|
+
rule: 'Rule',
|
|
777
|
+
from: 'From',
|
|
778
|
+
to: 'To',
|
|
779
|
+
reason: 'Reason',
|
|
780
|
+
revisionNote: 'Revision effective immediately upon gavel strike.',
|
|
781
|
+
},
|
|
782
|
+
|
|
783
|
+
// Enterprise Commands
|
|
784
|
+
sensus: {
|
|
785
|
+
title: 'RUNTIME CIVIL SERVICE CENSUS',
|
|
786
|
+
empty: 'No active coalition members found.',
|
|
787
|
+
emptyNote: '(Everyone has fled or is secure)',
|
|
788
|
+
headers: 'PID | SCRIPT | STATUS | LOYALTY',
|
|
789
|
+
ghost: 'GHOST (Fictitious)',
|
|
790
|
+
active: 'SECURE (Serving)',
|
|
791
|
+
total: 'Total active cadres securing resources:'
|
|
792
|
+
},
|
|
793
|
+
lengser: {
|
|
794
|
+
desc: 'Impeachment Process (Stop)',
|
|
795
|
+
title: 'SPECIAL SESSION (IMPEACHMENT COURT)',
|
|
796
|
+
notFound: 'Target PID not found in coalition.',
|
|
797
|
+
notFoundNote: '(Maybe joined opposition or fugitive)',
|
|
798
|
+
process: 'Preparing motion of no confidence for',
|
|
799
|
+
success: 'Impeachment Successful!',
|
|
800
|
+
fail: 'Impeachment Failed!',
|
|
801
|
+
failNote: 'Too strong (Backed by insiders)',
|
|
802
|
+
resultTitle: 'FINAL VERDICT:',
|
|
803
|
+
reason: 'Reason: "For national stability"',
|
|
804
|
+
status: 'DISHONORABLY DISCHARGED'
|
|
805
|
+
},
|
|
806
|
+
sadap: {
|
|
807
|
+
desc: 'Intelligence Operation (Stream Logs)',
|
|
808
|
+
title: 'WIRETAPPING OPERATION',
|
|
809
|
+
notFound: 'Target PID not found.',
|
|
810
|
+
waiting: 'Waiting for data transmission... (Ctrl+C to stop)'
|
|
811
|
+
},
|
|
812
|
+
sidak: {
|
|
813
|
+
desc: 'Digital Blusukan (Monitoring Dashboard)',
|
|
814
|
+
title: 'DIGITAL BLUSUKAN DASHBOARD',
|
|
815
|
+
empty: 'No objects to inspect.',
|
|
816
|
+
exit: '(Press Ctrl+C to return to office)',
|
|
817
|
+
update: 'Update',
|
|
818
|
+
status: {
|
|
819
|
+
safe: 'SAFE',
|
|
820
|
+
gone: 'MISSING'
|
|
821
|
+
},
|
|
822
|
+
stats: {
|
|
823
|
+
fair: 'Fair',
|
|
824
|
+
absorbed: 'Absorbed'
|
|
825
|
+
},
|
|
826
|
+
budget: 'Budget: Surplus remains',
|
|
827
|
+
monitoring: 'Monitoring performance...'
|
|
828
|
+
},
|
|
829
|
+
|
|
830
|
+
// Cawe-cawe Module
|
|
831
|
+
cawe: {
|
|
832
|
+
protocol: 'Intervention Protocol activated',
|
|
833
|
+
note: 'All challenges will be intercepted automatically.',
|
|
834
|
+
intercepted: 'CHALLENGE SUCCESSFULLY INTERCEPTED!',
|
|
835
|
+
takenOver: 'This issue has been taken over by HQ.',
|
|
836
|
+
continueNormal: 'Please continue activities as usual.',
|
|
837
|
+
detail: 'Detail',
|
|
838
|
+
count: 'Status: Intercepted #',
|
|
839
|
+
today: 'today',
|
|
840
|
+
promise: 'UNFULFILLED PROMISE DETECTED',
|
|
841
|
+
promiseNote: "Normal, it's just a promise.",
|
|
842
|
+
promiseNote2: 'The important thing is people still believe.',
|
|
843
|
+
promiseCount: 'Promise #',
|
|
844
|
+
notKept: 'not kept',
|
|
845
|
+
inputTitle: 'CONSTRUCTIVE INPUT (not warning):',
|
|
846
|
+
statusRecorded: 'Status: Recorded and will be followed up.',
|
|
847
|
+
noTimeline: '(No definite timeline)',
|
|
848
|
+
sessionReportTitle: 'SESSION FINAL REPORT',
|
|
849
|
+
challengesIntercepted: 'Challenges Intercepted',
|
|
850
|
+
unfulfilledPromises: 'Unfulfilled Promises',
|
|
851
|
+
secretLog: 'Secret Log entries (classified)',
|
|
852
|
+
reportNote: 'This report will be delivered to parliament in a closed meeting.',
|
|
853
|
+
},
|
|
854
|
+
},
|
|
855
|
+
};
|
|
856
|
+
|
|
857
|
+
// ============================================================================
|
|
858
|
+
// HELPER FUNCTIONS
|
|
859
|
+
// ============================================================================
|
|
860
|
+
|
|
861
|
+
/**
|
|
862
|
+
* Get translation by key path
|
|
863
|
+
* @param {string} keyPath - Dot-separated key path (e.g., 'cmd.init.desc')
|
|
864
|
+
* @param {string} [lang] - Language code (optional, uses current)
|
|
865
|
+
* @returns {string} Translated string
|
|
866
|
+
*/
|
|
867
|
+
function t(keyPath, lang = currentLang) {
|
|
868
|
+
const keys = keyPath.split('.');
|
|
869
|
+
let result = translations[lang] || translations['id'];
|
|
870
|
+
|
|
871
|
+
for (const key of keys) {
|
|
872
|
+
if (result && result[key] !== undefined) {
|
|
873
|
+
result = result[key];
|
|
874
|
+
} else {
|
|
875
|
+
// Fallback to Indonesian
|
|
876
|
+
result = translations['id'];
|
|
877
|
+
for (const k of keys) {
|
|
878
|
+
if (result && result[k] !== undefined) {
|
|
879
|
+
result = result[k];
|
|
880
|
+
} else {
|
|
881
|
+
return keyPath; // Return key if not found
|
|
882
|
+
}
|
|
883
|
+
}
|
|
884
|
+
break;
|
|
885
|
+
}
|
|
886
|
+
}
|
|
887
|
+
|
|
888
|
+
return result;
|
|
889
|
+
}
|
|
890
|
+
|
|
891
|
+
/**
|
|
892
|
+
* Set current language
|
|
893
|
+
* @param {string} lang - Language code ('id', 'en')
|
|
894
|
+
*/
|
|
895
|
+
function setLanguage(lang) {
|
|
896
|
+
if (translations[lang]) {
|
|
897
|
+
currentLang = lang;
|
|
898
|
+
return true;
|
|
899
|
+
}
|
|
900
|
+
return false;
|
|
901
|
+
}
|
|
902
|
+
|
|
903
|
+
/**
|
|
904
|
+
* Get current language
|
|
905
|
+
* @returns {string} Current language code
|
|
906
|
+
*/
|
|
907
|
+
function getLanguage() {
|
|
908
|
+
return currentLang;
|
|
909
|
+
}
|
|
910
|
+
|
|
911
|
+
/**
|
|
912
|
+
* Get available languages
|
|
913
|
+
* @returns {string[]} Array of language codes
|
|
914
|
+
*/
|
|
915
|
+
function getAvailableLanguages() {
|
|
916
|
+
return Object.keys(translations);
|
|
917
|
+
}
|
|
918
|
+
|
|
919
|
+
/**
|
|
920
|
+
* Rebrand text based on current language
|
|
921
|
+
* @param {string} text - Original text
|
|
922
|
+
* @returns {string} Rebranded text
|
|
923
|
+
*/
|
|
924
|
+
function rebrand(text) {
|
|
925
|
+
const lang = translations[currentLang] || translations['id'];
|
|
926
|
+
|
|
927
|
+
const replacements = {
|
|
928
|
+
'error': lang.error,
|
|
929
|
+
'Error': lang.Error,
|
|
930
|
+
'ERROR': lang.Error.toUpperCase(),
|
|
931
|
+
'crash': lang.crash,
|
|
932
|
+
'Crash': lang.crash,
|
|
933
|
+
'CRASH': lang.crash.toUpperCase(),
|
|
934
|
+
'bug': lang.bug,
|
|
935
|
+
'Bug': lang.bug,
|
|
936
|
+
'BUG': lang.bug.toUpperCase(),
|
|
937
|
+
'failed': lang.failed,
|
|
938
|
+
'Failed': lang.failed,
|
|
939
|
+
'FAILED': lang.failed.toUpperCase(),
|
|
940
|
+
'warning': lang.warning,
|
|
941
|
+
'Warning': lang.warning,
|
|
942
|
+
'WARNING': lang.warning.toUpperCase(),
|
|
943
|
+
};
|
|
944
|
+
|
|
945
|
+
let result = text;
|
|
946
|
+
for (const [original, replacement] of Object.entries(replacements)) {
|
|
947
|
+
result = result.split(original).join(replacement);
|
|
948
|
+
}
|
|
949
|
+
|
|
950
|
+
return result;
|
|
951
|
+
}
|
|
952
|
+
|
|
953
|
+
// ============================================================================
|
|
954
|
+
// EXPORTS
|
|
955
|
+
// ============================================================================
|
|
956
|
+
|
|
957
|
+
module.exports = {
|
|
958
|
+
t,
|
|
959
|
+
setLanguage,
|
|
960
|
+
getLanguage,
|
|
961
|
+
getAvailableLanguages,
|
|
962
|
+
rebrand,
|
|
963
|
+
detectLanguage,
|
|
964
|
+
translations,
|
|
965
|
+
};
|