Wikikamus
idwiktionary
https://id.wiktionary.org/wiki/Wikikamus:Halaman_Utama
MediaWiki 1.47.0-wmf.1
case-sensitive
Media
Istimewa
Pembicaraan
Pengguna
Pembicaraan Pengguna
Wikikamus
Pembicaraan Wikikamus
Berkas
Pembicaraan Berkas
MediaWiki
Pembicaraan MediaWiki
Templat
Pembicaraan Templat
Bantuan
Pembicaraan Bantuan
Kategori
Pembicaraan Kategori
Indeks
Pembicaraan Indeks
Lampiran
Pembicaraan Lampiran
TimedText
TimedText talk
Modul
Pembicaraan Modul
Acara
Pembicaraan Acara
baja
0
1733
1456596
1456255
2026-05-07T15:20:11Z
Swarabakti
18192
/* {{bahasa|bug}} */
1456596
wikitext
text/x-wiki
=={{bahasa|id}}==
{{kepala|id}}
{{-n-|id}}
# [[aloi]] [[besi]] dan [[karbon]]
#[[zirah]] pelapisan kebal
{{-terjemahan-}}
{{t-atas}}
* {{bjn}} : {{trad-|bjn|waja}}
* {{en}} : {{trad-|en|steel}}
* {{fr}} : {{trad-|fr|acier}}
{{t-bawah}}
=={{bahasa|bug}}==
{{kepala|bug|alt=ᨅᨍ}}
: {{suara|bug|LL-Q33190 (bug)-Iripseudocorus-Baja.wav}}
{{-adv-|bug}}
# [[besok]]
#: {{ux|id|Elliangka '''baja''' waju|Belikan saya baju '''besok'''.}}
[[Kategori:WikiTutur - Bugis]]
[[Kategori:WikiTutur Daring Umum 11 Februari 2024]]
=={{bahasa|pgu}}==
{{kepala|pgu}}
:{{pemenggalan|pgu|ba|ja}}
: {{suara|pgu|LL-Q7124462_(pgu)-Irens_(Bangrapip)-baja.wav}}
{{-v-|pgu}}
# [[membujuk]]
=={{bahasa|ms}}==
{{kepala|ms}}
{{-n-|ms}}
# [[pupuk]]
fegxw4wlhw0tygy878mvkcgj7jch627
1456597
1456596
2026-05-07T15:20:29Z
Swarabakti
18192
/* {{bahasa|pgu}} */
1456597
wikitext
text/x-wiki
=={{bahasa|id}}==
{{kepala|id}}
{{-n-|id}}
# [[aloi]] [[besi]] dan [[karbon]]
#[[zirah]] pelapisan kebal
{{-terjemahan-}}
{{t-atas}}
* {{bjn}} : {{trad-|bjn|waja}}
* {{en}} : {{trad-|en|steel}}
* {{fr}} : {{trad-|fr|acier}}
{{t-bawah}}
=={{bahasa|bug}}==
{{kepala|bug|alt=ᨅᨍ}}
: {{suara|bug|LL-Q33190 (bug)-Iripseudocorus-Baja.wav}}
{{-adv-|bug}}
# [[besok]]
#: {{ux|id|Elliangka '''baja''' waju|Belikan saya baju '''besok'''.}}
[[Kategori:WikiTutur - Bugis]]
[[Kategori:WikiTutur Daring Umum 11 Februari 2024]]
=={{bahasa|pgu}}==
{{kepala|pgu}}
: {{pemenggalan|pgu|ba|ja}} {{suara|pgu|LL-Q7124462_(pgu)-Irens_(Bangrapip)-baja.wav}}
{{-v-|pgu}}
# [[membujuk]]
=={{bahasa|ms}}==
{{kepala|ms}}
{{-n-|ms}}
# [[pupuk]]
om9m7uk2zdp6xsdr8sy6mx6w78zmc1l
kalaras
0
18250
1456612
1195498
2026-05-08T07:35:46Z
Wadaihangit
33201
/* {{k_b}} */
1456612
wikitext
text/x-wiki
=={{bahasa|bjn}}==
{{kepala|bjn}}
==={{k_b}}===
# [[daun pisang]] kering
s0qrjrw07wsy6vu9qcr46ypokzo9jfr
Kategori:Kata bahasa Batak Toba
14
44913
1456622
1456565
2026-05-08T08:55:14Z
Dyalim
36280
1456622
wikitext
text/x-wiki
[[Kategori:Kata bahasa daerah di Indonesia]]
[[Kategori:Bahasa Batak Toba]]
qq8zpua7l0yuw5s8y9orea9x2t4nghf
1456623
1456622
2026-05-08T08:56:30Z
Dyalim
36280
1456623
wikitext
text/x-wiki
{{kat:kata bahasa|Batak Toba}}
[[Kategori:Kata bahasa daerah di Indonesia]]
[[Kategori:Bahasa Batak Toba]]
4sh1wvzbo0iw3jj7cqe6vj92ypeyk4m
1456624
1456623
2026-05-08T08:58:54Z
Dyalim
36280
1456624
wikitext
text/x-wiki
Berikut ini adalah kata-kata dalam Bahasa Batak Toba yang sudah ada di Wikikamus. Silakan tuju ke kategori yang lebih spesifik untuk memperoleh daftar kata menurut kelas kata masing-masing.
[[Kategori:Kata bahasa daerah di Indonesia]]
[[Kategori:Bahasa Batak Toba]]
mw74vehuzj93ny4xi5en2xp51fert9n
1456626
1456624
2026-05-08T08:59:52Z
Dyalim
36280
1456626
wikitext
text/x-wiki
{{kat:kata bahasa|Batak Toba}}
[[Kategori:Kata bahasa daerah di Indonesia]]
[[Kategori:Bahasa Batak Toba]]
s0ktw4yi7ksrr0slgp8wujmq5ibnbrt
untuk
0
90765
1456598
1367268
2026-05-07T23:37:30Z
~2026-27776-77
47884
Batalkan revisi [[Special:Diff/1297792|1297792]] oleh [[Special:Contributions/SwarabaktiBot|SwarabaktiBot]] ([[User talk:SwarabaktiBot|bicara]])
1456598
wikitext
text/x-wiki
=={{bahasa|id}}==
{{kepala|id}}
{{suara|id|LL-Q9240 (ind)-Alfiyah Rizzy Afdiquni-untuk.wav}}
{{-k_d-|id}}
# kata depan untuk menyatakan bagi ...; bagian:
#*{{RQ:Mustikarasa
|page=14
|text=lumbu jang daunnja dipakai '''untuk''' sajuran,
|norm=lumbu yang daunnya dipakai '''untuk''' sayuran,
|url=https://id.wikisource.org/wiki/Halaman:Mustikarasa.pdf/22#:~:text=%27lumbu%20jang%20daunnja%20dipakai%20untuk%20sajuran%2C}} <br />''Ini untukku, yang itu untukmu''
# sebab atau alasan: <br />''Untuk kesalahan itu, ia dihukum dua tahun; untuk semua itu, ia mau berkorban''
# tujuan atau maksud; bagi: <br />''Lemari untuk (menyimpan) pakaian; pakaian untuk segala usia''
# penggantian (sebagai ganti ...); (disediakan, dipergunakan, dipakai) sebagai ...: <br />''Peti itu dipakai untuk meja makan; diberi pisau untuk senjata''
# selama: <br />''Untuk beberapa bulan ia terpaksa istirahat di rumah sakit''
# sudah: <br />''Untuk ketiga kalinya saya memperingatkan''
{{-n-|id}}
# kemaluan perempuan (kata penghalus)
{{-n-|id}}
# bagian dari milik yang dibagi-bagikan
{{-turunan-|id}}
{{-ragam-}}
* [[utk]], /u
{{t-atas|<!--bagian ini seharusnya diisi dengan sebagian dari definisi kata yang bersangkutan-->}}
{{t-bawah}}
{{-bacaan-}}
* {{R:KBBI Daring}}
{{rfv|id|impor dari KBBI}}
=={{bahasa|mui-plm}}==
{{kepala|mui-plm}}
{{-prep-|mui-plm}}
# untuk
#: ''untuk kau bae''
#:: untukmu saja
{{-lafal-|mui-plm}}
* {{suara|mui-plm|LL-Q12497929 (mis)-Suci Rahmah Sari-ontok.wav}}
[[Kategori:WikiTutur - Palembang]]
[[Kategori:WikiTutur Kopdar Palembang 19 Mei 2024]]
=={{bahasa|ljp}}==
{{kepala|ljp}}
{{guwai|ljp}}
{{-p-|ljp}}
# untuk
[[Kategori:WikiJejama]]
[[Kategori:WikiJejama Pringsewu]]
bx5b3d2oi2vodm5rln1tps0q6gsvy6c
1456599
1456598
2026-05-08T01:59:24Z
OrangKalideres
35065
Suntingan [[Special:Contributions/~2026-27776-77|~2026-27776-77]] ([[User talk:~2026-27776-77|bicara]]) dikembalikan ke versi terakhir oleh [[Special:Contributions/Alfiyah Rizzy Afdiquni|Alfiyah Rizzy Afdiquni]]
1367268
wikitext
text/x-wiki
=={{bahasa|id}}==
{{kepala|id}}
{{suara|id|LL-Q9240 (ind)-Alfiyah Rizzy Afdiquni-untuk.wav}}
{{-prep-|id}}
# kata depan untuk menyatakan bagi ...; bagian:
#*{{RQ:Mustikarasa
|page=14
|text=lumbu jang daunnja dipakai '''untuk''' sajuran,
|norm=lumbu yang daunnya dipakai '''untuk''' sayuran,
|url=https://id.wikisource.org/wiki/Halaman:Mustikarasa.pdf/22#:~:text=%27lumbu%20jang%20daunnja%20dipakai%20untuk%20sajuran%2C}} <br />''Ini untukku, yang itu untukmu''
# sebab atau alasan: <br />''Untuk kesalahan itu, ia dihukum dua tahun; untuk semua itu, ia mau berkorban''
# tujuan atau maksud; bagi: <br />''Lemari untuk (menyimpan) pakaian; pakaian untuk segala usia''
# penggantian (sebagai ganti ...); (disediakan, dipergunakan, dipakai) sebagai ...: <br />''Peti itu dipakai untuk meja makan; diberi pisau untuk senjata''
# selama: <br />''Untuk beberapa bulan ia terpaksa istirahat di rumah sakit''
# sudah: <br />''Untuk ketiga kalinya saya memperingatkan''
{{-n-|id}}
# kemaluan perempuan (kata penghalus)
{{-n-|id}}
# bagian dari milik yang dibagi-bagikan
{{-turunan-|id}}
{{-ragam-}}
* [[utk]], /u
{{t-atas|<!--bagian ini seharusnya diisi dengan sebagian dari definisi kata yang bersangkutan-->}}
{{t-bawah}}
{{-bacaan-}}
* {{R:KBBI Daring}}
{{rfv|id|impor dari KBBI}}
=={{bahasa|mui-plm}}==
{{kepala|mui-plm}}
{{-prep-|mui-plm}}
# untuk
#: ''untuk kau bae''
#:: untukmu saja
{{-lafal-|mui-plm}}
* {{suara|mui-plm|LL-Q12497929 (mis)-Suci Rahmah Sari-ontok.wav}}
[[Kategori:WikiTutur - Palembang]]
[[Kategori:WikiTutur Kopdar Palembang 19 Mei 2024]]
=={{bahasa|ljp}}==
{{kepala|ljp}}
{{guwai|ljp}}
{{-p-|ljp}}
# untuk
[[Kategori:WikiJejama]]
[[Kategori:WikiJejama Pringsewu]]
1og8gw3z51kud7qsjigd2hgfifg1aie
anggar
0
113397
1456610
1455818
2026-05-08T07:31:11Z
Wadaihangit
33201
[[:wikt:id:Pengguna:Swarabakti/Gadget-EntryAdder.js|+entri]] [bjn]
1456610
wikitext
text/x-wiki
=={{bahasa|id}}==
{{kepala|id}}
{{-n-|id}}
# permainan (perkelahian) yang kedua belah pihak menggunakan pedang
# {{Olr}} cabang olahraga bela diri yang menggunakan alat atau senjata (untuk menusuk, memarang, atau menusuk dan sekaligus memarang)
{{-n-|id}}
# tenggeran burung dalam sangkar
{{-etimologi-}}
* Dari {{bor|id|fr|en garde||posisi kuda-kuda|lit=(sedang) dalam posisi bertahan}}
{{-turunan-|id}}
{{-terjemahan-}}
{{t-atas|permainan/olahraga dengan pedang}}
* {{nl}}: {{t+|nl|schermen}}
* {{en}}: {{t+|en|fencing}}
* {{ja}}: {{t+|ja|剣術|tr=けんじゅつ, kenjutsu|sc=Jpan}}
* {{de}}: {{t+|de|Fechten|n}}
* {{pt}}: {{t+|pt|esgrima|f}}
* {{fr}}: {{t+|fr|escrime|f}}
{{t-bawah}}
{{-bacaan-}}
* {{R:KBBI Daring}}
{{rfv|id|impor dari KBBI}}
=={{bahasa|bkr}}==
{{kepala|bkr}}
{{-v-|bkr}}
# taksir harga; mengereskan maksud; rencana
#: ''pere ye ma anggar regan huma hikau nah ''
#: berapa dia berani menaksir harga rumah itu tadi
[[Kategori:WikiBalalah - Bakumpai]]
=={{bahasa|bjn}}==
{{kepala|bjn}}
{{-v-|bjn}}
# [[pamer]]
=={{bahasa|sas}}==
{{kepala|sas}}
: {{suara|sas|LL-Q1294047 (sas)-kamardi (Nining123)-anggar.wav}}
{{-kelas kata-|anggar}}
# [[rencana]]
2mvzm7fzw85go3febhkyd7s0ddg5cgf
sebagai
0
143592
1456601
1456518
2026-05-08T02:00:53Z
OrangKalideres
35065
- vandal
1456601
wikitext
text/x-wiki
=={{bahasa|id}}==
{{kepala|id}}
{{suara|id|LL-Q9240 (ind)-Cloudy (Losstreak)-sebagai.wav}}
{{-prep-|id}}
# kata depan untuk menyatakan hal yang serupa; sama; semacam (itu): <br>''perabot rumah tangga ialah kursi, meja, lemari, dan sebagainya''
#*{{RQ:Mustikarasa
|page=12
|text= '''Sebagai''' gaplek, ia tahan disimpan 3 bulan lamanja. Sesudah itu ia rusak karena bubuk dan lain-lain seranga serangga.
|norm= '''Sebagai''' gaplek, ia tahan disimpan 3 bulan lamanja. Sesudah itu ia rusak karena bubuk dan lain-lain seranga serangga.
|url=https://id.wikisource.org/wiki/Halaman:Mustikarasa.pdf/20#:~:text=Sebagai%20gaplek%2C%20ia%20tahan%20disimpan%203%20bulan%20lamanja.%20Sesudah%20itu%20ia%20rusak%20karena%20bubuk%20dan%20lain%C2%B2%20serangga.}}
# kata depan untuk menyatakan perbandingan; seperti; seakan-akan; seolah-olah: <br>''kelakuannya sebagai orang udik masuk kota''
# kata depan untuk menyatakan status; berlaku seperti; selaku: <br>''sebagai orang tua, ia harus bertanggung jawab atas anak-anaknya''
{{-adv-|id}}
# seharusnya; sepatutnya; sewajarnya; semestinya: <br>''ia diperlakukan dengan sebagainya''
{{-p-|id}}
# jadi (menjadi): <br>''ia diangkat sebagai gubernur''
{{-terjemahan-}}
{{t-atas}}
{{t-bawah}}
{{-bacaan-}}
* {{R:KBBI Daring}}
{{rfv|id|impor dari KBBI}}
jucgchvlu54ty4h4lzz00fegg634bly
masukkan
0
154865
1456600
1456574
2026-05-08T01:59:50Z
OrangKalideres
35065
Suntingan [[Special:Contributions/~2026-27427-08|~2026-27427-08]] ([[User talk:~2026-27427-08|bicara]]) dikembalikan ke versi terakhir oleh [[Special:Contributions/OrangKalideres|OrangKalideres]]
1220496
wikitext
text/x-wiki
=={{bahasa|id}}==
{{kepala|id}}
{{imbuhan -kan|masuk}}
{{-terjemahan-}}
{{t-atas}}
{{t-bawah}}
9zaylfietew8x8frtgd3j4l631imtq4
Kategori:Turunan kata pulih
14
163217
1456640
504226
2026-05-08T11:39:04Z
~2026-27760-70
47889
Turunkan dan pulihkan
1456640
wikitext
text/x-wiki
{{kat:Turunan|pulih}}
dqn8f6azgz7b260p6qyf1cswbacqfwk
Kategori:Bahasa Karo
14
263987
1456631
1350669
2026-05-08T09:05:10Z
Dyalim
36280
added [[Category:Bahasa]] using [[Help:Gadget-HotCat|HotCat]]
1456631
wikitext
text/x-wiki
{{kategori otomatis}}
[[Kategori:Bahasa]]
pebozjqpkml0wixlowipnowzhwmon0z
1456632
1456631
2026-05-08T09:05:24Z
Dyalim
36280
added [[Category:Bahasa di Indonesia]] using [[Help:Gadget-HotCat|HotCat]]
1456632
wikitext
text/x-wiki
{{kategori otomatis}}
[[Kategori:Bahasa]]
[[Kategori:Bahasa di Indonesia]]
e0ygo8xgqnv5ascyt3skqe6g6b8gxdi
Pengguna:Swarabakti/Gadget-EntryAdder.js
2
267654
1456602
1351141
2026-05-08T04:23:15Z
Swarabakti
18192
1456602
javascript
text/javascript
mw.loader.using(["mediawiki.api", "mediawiki.util"]).then(function () {
"use strict";
mw.loader.load(
"https://id.wiktionary.org/w/index.php?title=Pengguna:Swarabakti/Gadget-EntryAdder.css&action=raw&ctype=text/css",
"text/css"
);
// ---------------------
// Add more languages by adding keys here.
// ---------------------
const EG_I18N = {
id: {
btn_add_language: "Tambahkan entri baru pada halaman ini",
modal_title_add: "Tambahkan entri baru — ",
fill_langcode: "(isi dengan kode bahasa)",
select_pos: "(pilih kelas kata)",
fill_meaning: "(isi dengan maknanya)",
add_hom: "Tambah entri homonim",
remove_hom: "Hapus entri homonim",
add_pos: "Tambah kelas kata",
remove_pos: "Hapus kelas kata",
add_def: "Tambah definisi",
remove_def: "Hapus definisi",
preview: "Pratayang",
undo: "Balikkan",
save: "Simpan",
cancel: "Batalkan",
preview_loading: "Pratayang...",
save_loading: "Menyimpan...",
err_fill_all: "Isi dulu semua baris yang tersedia, atau hapus baris yang kosong.",
err_lang_exists: "Subjudul untuk bahasa ini sudah tersedia, gunakan kode bahasa lain atau sunting langsung bagiannya.",
err_fetch: "Gagal mengambil isi halaman.",
err_preview: "Gagal memuat pratayang.",
err_save_prefix: "Gagal menyimpan:",
err_no_change: "Tiada perubahan untuk disimpan.",
prompt_fill_langcode: "Isi kode bahasa dulu.",
save_summary_prefix: "[[:wikt:id:Pengguna:Swarabakti/Gadget-EntryAdder.js|+entri]]",
pos_labels: {
n: "nomina",
v: "verba",
adj: "adjektiva",
adv: "adverbia",
num: "numeralia",
pron: "pronomina",
pn: "nama diri",
ptcp: "partisipel",
conj: "konjungsi",
intj: "interjeksi",
ptcl: "partikula",
det: "penentu",
art: "artikula",
clf: "penggolong",
prep: "preposisi",
postp: "postposisi",
circp: "sirkumposisi",
ambip: "ambiposisi",
pref: "awalan",
suf: "akhiran",
inf: "sisipan",
circf: "apitan",
intf: "sambungan",
rt: "akar",
ph: "frasa",
pb: "peribahasa",
rom: "romanisasi",
ltr: "huruf",
sym: "simbol"
}
},
bew: {
btn_add_language: "Tambahin pentol kata anyar bakal ni halaman",
modal_title_add: "Tambahin pentol anyar — ",
fill_langcode: "(isi ama kode basanya)",
select_pos: "(pili rungkun katanya)",
fill_meaning: "(isi ama pema'naannya)",
add_hom: "Tambah pentol kata sejogrokan",
remove_hom: "Apus pentol kata sejogrokan",
add_pos: "Tambah rungkun katanya",
remove_pos: "Apus rungkun katanya",
add_def: "Tambah pema'naannya",
remove_def: "Apus pema'naannya",
preview: "Terawang",
undo: "Balikin",
save: "Simpen",
cancel: "Urungin",
preview_loading: "Nerawangin...",
save_loading: "Nyimpenin...",
err_fill_all: "Isiin dulu semua baris rungkun ama ma'na nyang derak, atawa apus-apusin nyang kopong.",
err_lang_exists: "Anakjudul bakal entu basa udah derak — jal paké laèn kode basa atawa permak langsung entu bagèan.",
err_fetch: "Kaga' bisa nyomot isi halaman.",
err_preview: "Kaga' bisa munggah terawangan.",
err_save_prefix: "Kaga' bisa nyimpen:",
err_no_change: "Kaga' ada perobahan bakal disimpen.",
prompt_fill_langcode: "Isi kode basanya dulu.",
save_summary_prefix: "[[:wikt:id:Pengguna:Swarabakti/Gadget-EntryAdder.js|+pentol]]",
pos_labels: {
n: "kata peada",
v: "kata kereja",
adj: "kata penyipat",
adv: "kata penerang",
num: "kata pengangka",
pron: "kata pengganti",
pn: "kata nama",
ptcp: "dumanan",
conj: "penjuntrung",
intj: "gegeroan",
ptcl: "petilan",
det: "pemuguhan",
art: "penimpalan",
clf: "pemantar",
prep: "pengawalan",
postp: "pengahiran",
circp: "pendengkèkan",
ambip: "ambiposisi",
pref: "depanan",
suf: "kintilan",
inf: "selesepan",
circf: "apitan",
intf: "sambungan",
rt: "bongkot",
ph: "gabungan kata",
pb: "peribasa kata",
rom: "penglatènan",
ltr: "hurup",
sym: "lambang"
}
},
bjn: {
btn_add_language: "Tambahakan entri puga di halaman ngini",
modal_title_add: "Tambahakan entri puga — ",
fill_langcode: "(isi pakai kode bahasa)",
select_pos: "(pilih kalas kata)",
fill_meaning: "(isii maknanya)",
add_hom: "Tambahi entri homonim",
remove_hom: "Hapus entri homonim",
add_pos: "Tambahi kalas kata",
remove_pos: "Hapus kalas kata",
add_def: "Tambahi artinya",
remove_def: "Hapus artinya",
preview: "Pratayang",
undo: "Bulikakan",
save: "Simpan",
cancel: "Pasahakan",
preview_loading: "Pratayang...",
save_loading: "Manyimpan...",
err_fill_all: "Isi dulu samunyaan baris nang ada, atawa hapus baris nang puang.",
err_lang_exists: "Subjudul gasan basa ngini sudah ada, pakai kode basa lain ataw babak langsung bagiannya.",
err_fetch: "Kada kawa maambil isi halaman.",
err_preview: "Kada kawa manapaiakan pratayang.",
err_save_prefix: "Kada kawa manyimpan:",
err_no_change: "Kadada paubahan gasan disimpan.",
prompt_fill_langcode: "Isi kode basanya dulu.",
save_summary_prefix: "[[:wikt:id:Pengguna:Swarabakti/Gadget-EntryAdder.js|+entri]]",
pos_labels: {
n: "kata banda",
v: "kata gawi",
adj: "kata sipat",
adv: "kata panjalas",
num: "kata bilangan",
pron: "kata ganti",
pn: "ngaran diri",
ptcp: "partisip",
conj: "kata panyambung",
intj: "kata saru",
ptcl: "kata tugas",
det: "panantu",
art: "kata sandang",
clf: "panggulung",
prep: "kata muka",
postp: "postposisi",
circp: "sirkumposisi",
ambip: "ambiposisi",
pref: "awalan",
suf: "akhiran",
inf: "sisipan",
circf: "apitan",
intf: "sambungan",
rt: "akar",
ph: "prasa",
pb: "paribasa",
rom: "romanisasi",
ltr: "hurup",
sym: "simbul"
}
},
min: {
btn_add_language: "Tambahkan entri baru untuak halaman iko",
modal_title_add: "Tambahkan entri baru — ",
fill_langcode: "(isi jo kode bahaso)",
select_pos: "(piliah kelas kato)",
fill_meaning: "(isi jo mukasuiknyo)",
add_hom: "Tambah entri homonim",
remove_hom: "Apuih entri homonim",
add_pos: "Tambah kelas kato",
remove_pos: "Apuih kelas kato",
add_def: "Tambah definisi",
remove_def: "Apuih definisi",
preview: "Pratinjau",
undo: "Baliakkan",
save: "Simpan",
cancel: "Uruangkan",
preview_loading: "Pratinjau...",
save_loading: "Manyimpan...",
err_fill_all: "Isi dulu sadoalah barih nan tasadio, atau apuih barih nan kosong.",
err_lang_exists: "Subjudul untuak bahaso iko alah tasadio, pakai kode bahaso lain atau suntiang lansuang bagiannyo.",
err_fetch: "Indak dapek maambiak isi laman.",
err_preview: "Indak dapek mamuek pratinjau.",
err_save_prefix: "Indak dapek menyimpan:",
err_no_change: "Indak ado parubahan untuak disimpan.",
prompt_fill_langcode: "Isi kode bahaso dulu.",
save_summary_prefix: "[[:wikt:id:Pengguna:Swarabakti/Gadget-EntryAdder.js|+entri]]",
pos_labels: {
n: "kato bando",
v: "kato karajo",
adj: "kato sipaik",
adv: "kato katarangan",
num: "kato bilangan",
pron: "kato ganti",
pn: "namo diri",
ptcp: "partisipel",
conj: "kato sambuang",
intj: "kato saru",
ptcl: "partikel",
det: "panantu",
art: "artikel",
clf: "panggoloang",
prep: "kato mulo",
postp: "kato balakang",
circp: "kato apik",
ambip: "ambiposisi",
pref: "awalan",
suf: "akiaran",
inf: "sisipan",
circf: "apitan",
intf: "sambuangan",
rt: "aka",
ph: "frasa",
pb: "papatah-patitiah",
rom: "latin",
ltr: "uruih",
sym: "lambang"
}
}
};
const USER_LANG = (mw.config.get("wgUserLanguage") || "id").toLowerCase();
const T = EG_I18N[USER_LANG] || EG_I18N.id;
const api = new mw.Api();
let languageMap = null;
function fetchLanguageMap() {
if (languageMap) return Promise.resolve(languageMap);
return api.get({
action: "query",
prop: "revisions",
rvprop: "content",
rvslots: "main",
titles: "Module:bahasa",
formatversion: 2
}).then(res => {
const text = res.query.pages[0].revisions[0].slots.main.content;
const out = {};
text.replace(/\[\s*"([^"]+)"\s*\]\s*=\s*"([^"]+)"/g, (m,k,v) => out[k.toLowerCase()] = v);
languageMap = out;
return languageMap;
});
}
const ns = mw.config.get("wgNamespaceNumber");
const action = mw.config.get("wgAction");
const pageName = mw.config.get("wgPageName");
const pageTitle = mw.config.get("wgTitle");
if (!(ns === 0 && (action === "view" || action === "edit"))) return;
if ($(".entry-gadget-root").length) return;
// --- Simple title button ---
const $btn = $('<button type="button" class="entry-new-btn" title="' + T.btn_add_language + '">+</button>')
.on("click", () => openModalForNew());
// Find title element (cross-skin)
let $title = $("#firstHeading, h1.firstHeading, .page-heading").first();
if ($title.length) {
$title.append($btn);
} else {
// fallback if somehow not found
$("#siteSub, #mw-content-text").first().prepend($btn);
}
// appState: holds undo preview stacks and current parsed sections for saving
const appState = {
htmlStack: [],
scrollStack: [],
currentSections: null,
newLang: null,
lastFetchedTimestamp: null
};
let suppressLangAutofocus = false;
// ---------------------
// Helpers
// ---------------------
function htmlEscape(s) {
return String(s || "").replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
}
function canonicalizeNewlines(text) {
return String(text || "").replace(/\r\n/g, "\n");
}
function normalizeSpacing(text) {
return canonicalizeNewlines(text)
.replace(/\n{4,}/g, "\n\n\n");
}
function normalizeForCompare(text) {
return normalizeSpacing(text).trim();
}
function makeDraggable($modal, $handle) {
let dragging = false;
let started = false;
let startX = 0;
let startY = 0;
let origLeft = 0;
let origTop = 0;
let pointerId = null;
const THRESHOLD = 6;
$handle.css({
"touch-action": "none",
"user-select": "none",
"-webkit-user-select": "none"
});
$handle.on("pointerdown.entryDrag", function (ev) {
if ($(ev.target).closest("button, input, select, textarea, a").length) return;
ev.preventDefault();
const rect = $modal[0].getBoundingClientRect();
dragging = true;
started = false;
startX = ev.clientX;
startY = ev.clientY;
origLeft = rect.left;
origTop = rect.top;
pointerId = ev.pointerId;
$("body").addClass("entry-dragging");
$handle[0].setPointerCapture?.(pointerId);
});
$(document).on("pointermove.entryDrag", function (ev) {
if (!dragging) return;
if (pointerId !== null && ev.pointerId !== pointerId) return;
const dx = ev.clientX - startX;
const dy = ev.clientY - startY;
if (!started) {
if (Math.hypot(dx, dy) < THRESHOLD) return;
started = true;
}
const winW = window.innerWidth;
const winH = window.innerHeight;
const modalW = $modal.outerWidth();
const modalH = $modal.outerHeight();
let newLeft = origLeft + dx;
let newTop = origTop + dy;
newLeft = Math.max(8, Math.min(newLeft, winW - modalW - 8));
newTop = Math.max(8, Math.min(newTop, winH - modalH - 8));
$modal.css({
left: newLeft + "px",
top: newTop + "px",
transform: "none"
});
});
$(document).on("pointerup.entryDrag pointercancel.entryDrag", function (ev) {
if (pointerId !== null && ev.pointerId !== pointerId) return;
dragging = false;
started = false;
pointerId = null;
$("body").removeClass("entry-dragging");
});
}
function removeModal() {
$(".entry-modal").remove();
$(".entry-modal-overlay").remove();
}
function cancelAndCloseModal() {
removeModal();
$(".entry-highlight").removeClass("entry-highlight");
if (appState.htmlStack.length) {
const prevHtml = appState.htmlStack[0];
const prevScroll = appState.scrollStack[0];
const $target = $("#mw-content-text");
if ($target.length) {
$target.html(prevHtml);
if (typeof prevScroll === "number") $(window).scrollTop(prevScroll);
// reinitialize collapsibles and gadgets
if (window.mw && mw.loader) {
mw.loader.using(["jquery.makeCollapsible"]).then(function () {
$(".mw-collapsible").makeCollapsible();
if (window.mw && mw.hook) {
mw.hook("wikipage.content").fire($("#mw-content-text"));
}
});
}
}
appState.htmlStack = [];
appState.scrollStack = [];
appState.currentSections = null;
}
}
function renumberHomonyms(model) {
if (!model || !Array.isArray(model.homonyms)) return;
model.homonyms.forEach((h, i) => { h.num = i + 1; });
}
// ---------------------
// Wikitext parsing helpers (preview/save)
// ---------------------
// Extract language sections
function extractLangSections(wikitext) {
const regex = /^==\s*\{\{\s*[^|}\s]+\s*\|\s*(?:1\s*=\s*)?([^|}\s]+).*?\}\}\s*==/gim;
const headings = [];
let match;
while ((match = regex.exec(wikitext)) !== null) {
headings.push({ code: match[1], index: match.index, matchText: match[0], lastMatchIndex: regex.lastIndex });
}
if (headings.length === 0) {
return [ { code: null, heading: null, contentWikitext: wikitext, start: 0, end: wikitext.length } ];
}
const sections = [];
for (let i = 0; i < headings.length; i++) {
const h = headings[i];
const start = h.index;
const contentStart = h.lastMatchIndex;
const contentEnd = (i + 1 < headings.length) ? headings[i + 1].index : wikitext.length;
sections.push({
code: h.code,
heading: h.matchText,
contentWikitext: wikitext.slice(contentStart, contentEnd),
start: start,
contentStart: contentStart,
end: contentEnd
});
}
return sections;
}
// ---------------------
// Get display name for language code (DOM-first, cached)
// ---------------------
function getDisplayNameForCode(code) {
if (!code) return "";
const key = String(code).toLowerCase();
if (languageMap && languageMap[key]) return languageMap[key];
// Fallback if module not yet loaded
return key;
}
// ---------------------
// Rebuild text from sections
// ---------------------
function rebuildFullTextFromSections(_originalText, sections) {
if (!Array.isArray(sections)) return "";
let out = "";
let seenLang = false;
for (const s of sections) {
const h = s.heading || "";
const c = s.contentWikitext || "";
if (h) {
if (seenLang && !out.endsWith("\n\n")) {
out = out.replace(/\n?$/, "\n\n");
}
seenLang = true;
}
out += h + c;
}
return out;
}
// ---------------------
// Helpers that build wikitext blocks
// ---------------------
function buildHomonymBlock(lang, hom) {
let out = "";
// include num= only if there are multiple homonyms or num>1
out += "{{kepala|" + lang + ((hom.num && hom.num > 1) ? "|num=" + hom.num : "") + "}}\n\n";
hom.posGroups.forEach(function (pg) {
out += "{{-" + (pg.pos || "") + "-|" + lang + "}}\n";
pg.defs.forEach(function (d) { if (d && d.trim()) out += "# " + d + "\n"; });
out += "";
});
return out;
}
// ---------------------
// Insert model into sections (DOM-based sort)
// ---------------------
function insertModelIntoSections(sections, model) {
sections = Array.isArray(sections) ? sections.slice() : [];
const incomingCode = (model.lang || "").toString().trim();
const incomingKey = incomingCode.toLowerCase();
// map existing codes to indices
const codeToIndex = {};
for (let i = 0; i < sections.length; i++) {
const s = sections[i];
if (s && s.code) codeToIndex[(s.code || "").toLowerCase()] = i;
}
// build entry text
const entryLines = model.homonyms
.map(h => buildHomonymBlock(model.lang, h))
.filter(Boolean)
.join("\n");
if (incomingKey && codeToIndex.hasOwnProperty(incomingKey)) {
const idx = codeToIndex[incomingKey];
const sec = sections[idx];
const existing = canonicalizeNewlines(sec.contentWikitext || "");
const toAppend = canonicalizeNewlines(entryLines);
// duplicate check
const existingNorm = normalizeForCompare(existing);
const appendNorm = normalizeForCompare(toAppend);
if (!existingNorm.endsWith(appendNorm)) {
let content = normalizeSpacing(existing);
if (content && !content.endsWith("\n")) {
content += "\n";
}
sec.contentWikitext = normalizeSpacing(
content + toAppend + "\n"
);
}
} else {
let newHeading = "=={{bahasa|" + model.lang + "}}==\n";
sections.push({
code: model.lang,
heading: canonicalizeNewlines(newHeading),
contentWikitext: normalizeSpacing(entryLines) + "\n",
start: null,
contentStart: null,
end: null
});
}
// separate non-lang and lang sections
const nonLang = sections.filter(s => !s.code);
const langSections = sections.filter(s => !!s.code);
// sort by display name after mul and site language
// auto-detect site language for sorting priority
const siteLang = (mw.config.get("wgContentLanguage") || "").toLowerCase();
const order = {
mul: 1,
[siteLang]: 2
};
langSections.forEach(s => {
s._codeNorm = (s.code || "").toLowerCase();
});
langSections.sort(function (a, b) {
const aCode = a._codeNorm || "";
const bCode = b._codeNorm || "";
const aRank = order[aCode] || 3;
const bRank = order[bCode] || 3;
if (aRank !== bRank) return aRank - bRank;
const aName = getDisplayNameForCode(a.code || aCode) || aCode;
const bName = getDisplayNameForCode(b.code || bCode) || bCode;
return aName.localeCompare(bName, undefined, { sensitivity: "base" });
});
langSections.forEach(s => { delete s._codeNorm; });
const rebuilt = nonLang.concat(langSections);
return rebuilt.map(s => ({
code: s.code || null,
heading: s.heading || null,
contentWikitext: s.contentWikitext || "",
start: (typeof s.start !== "undefined") ? s.start : null,
end: (typeof s.end !== "undefined") ? s.end : null
}));
}
function replacePageContentWith(parsedHtml) {
const $parsed = $("<div>").html(parsedHtml);
const $target = $("#mw-content-text");
if ($target.length) {
$target.data("savedScrollTop", $(window).scrollTop());
$target.html($parsed);
} else {
$("body").html($parsed);
}
}
function highlightInserted(lang) {
$(".entry-highlight").removeClass("entry-highlight");
const $langEl = $("#mw-content-text").find(".lang[data-code='" + lang + "']").first();
if ($langEl && $langEl.length) {
const $h2 = $langEl.closest("h2");
if ($h2.length) {
const $toHighlight = $h2.nextUntil("h2").addBack();
$toHighlight.addClass("entry-highlight");
const top = $h2.offset() ? $h2.offset().top : null;
if (top) $("html,body").animate({ scrollTop: top - 60 }, 250);
setTimeout(function () { $toHighlight.removeClass("entry-highlight"); }, 7000);
}
}
}
function fetchLatestWikitext() {
return api.get({
action: "query",
prop: "revisions",
rvprop: "content|timestamp",
rvslots: "main",
titles: pageName,
formatversion: 2
}).then(function (data) {
const page = data.query.pages[0];
const fullText = page.revisions && page.revisions[0] && page.revisions[0].slots && page.revisions[0].slots.main
? page.revisions[0].slots.main.content || ""
: "";
const timestamp = page.revisions && page.revisions[0] ? page.revisions[0].timestamp : null;
return { text: fullText, timestamp: timestamp };
});
}
// ---------------------
// Modal + form rendering
// ---------------------
function createEmptyModel() {
return {
lang: "",
homonyms: [ { num: 1, posGroups: [ { pos: "", defs: [""] } ] } ]
};
}
// POS canonical short codes
const POS_CODES = [
"n","v","adj","adv","num","pron","pn","ptcp",
"conj","intj","ptcl","det","art","clf","prep",
"postp","circp","ambip","pref","suf","inf",
"circf","intf","rt","ph","pb","rom",
"ltr","sym"
];
// Render modal from model
function renderModal(model) {
let justAddedFocus = false;
removeModal();
const $overlay = $('<div class="entry-modal-overlay" />');
const $modal = $('<div class="entry-modal" role="dialog" aria-modal="true"></div>');
const $header = $('<div class="entry-header"><div class="entry-title">' + T.modal_title_add + htmlEscape(pageTitle || "") + '</div><div><button class="entry-mini-btn entry-mini-rem" title="' + T.cancel + '">✕</button></div></div>');
const $body = $('<div class="entry-body"></div>');
const $controls = $('<div class="entry-controls"></div>');
$modal.append($header, $body, $controls);
$("body").append($overlay, $modal);
makeDraggable($modal, $header);
$header.find(".entry-mini-rem").on("click", function (e) { e.preventDefault(); cancelAndCloseModal(); });
// Top-level inputs
const $langRow = $(`<div class="entry-block"><div class="row" style="align-items:center;">
<div style="flex:1; display:flex; align-items:center; gap:0.5em;">
<input type="text" id="eg-lang" maxlength="11" style="max-width:3em;" value="${htmlEscape(model.lang || "")}">
<span style="opacity:0.8;">${T.fill_langcode}</span>
</div></div></div>`);
$body.append($langRow);
// Homonyms container
const $homContainer = $('<div id="eg-homonyms"></div>');
$body.append($homContainer);
// For each homonym, render a block
model.homonyms.forEach(function (hom, hIdx) {
const homNum = hom.num || (hIdx + 1);
const $hb = $('<div class="entry-block eg-homonym" data-hidx="' + hIdx + '"></div>');
// hom header: [+] [-] pagename (homonym #) -- pagename is plain bold text from pageTitle
const $hdr = $('<div class="row" style="align-items:center;"></div>');
const $addHomBtn = $('<button class="entry-mini-btn entry-mini-add" title="' + T.add_hom + '">+</button>');
const $rmHomBtn = $('<button class="entry-mini-btn entry-mini-rem" title="' + T.remove_hom + '">–</button>');
const $homTitle = $('<div style="flex:1"><b style="display:inline-block;">' + htmlEscape(pageTitle || "").replace(/_/g, " ") + '</b> <span style="opacity:0.8">(' + homNum + ')</span></div>');
$hdr.append($addHomBtn, $rmHomBtn, $homTitle);
// disable if only one homonym
if (model.homonyms.length <= 1) {
$rmHomBtn.prop("disabled", true);
} else {
$rmHomBtn.prop("disabled", false).css("opacity", "1.0");
}
$hb.append($hdr);
// POS groups container
const $posContainer = $('<div class="eg-pos-container"></div>');
hom.posGroups.forEach(function (pg, pIdx) {
const $pblock = $('<div class="entry-block" data-pidx="' + pIdx + '"></div>');
const $prow = $('<div class="row" style="align-items:center;"></div>');
const $addPosBtn = $('<button class="entry-mini-btn entry-mini-add" title="' + T.add_pos + '">+</button>');
const $rmPosBtn = $('<button class="entry-mini-btn entry-mini-rem" title="' + T.remove_pos + '">–</button>');
// Build POS dropdown
const posLabels = T.pos_labels || {};
const $posSelect = $('<select class="eg-pos"></select>');
$posSelect.append('<option value="">' + T.select_pos + '</option>');
POS_CODES.forEach(code => {
const label = posLabels[code] || code;
const $opt = $('<option></option>')
.val(code)
.text(label + " (" + code + ")");
if (pg.pos === code) $opt.prop("selected", true);
$posSelect.append($opt);
});
const $posInputWrap = $('<div style="flex:1; min-width:10em;"></div>').append($posSelect);
$prow.append($addPosBtn, $rmPosBtn, $posInputWrap);
$pblock.append($prow);
// disable if only one POS in homonym
if (hom.posGroups.length <= 1) {
$rmPosBtn.prop("disabled", true);
} else {
$rmPosBtn.prop("disabled", false).css("opacity", "1.0");
}
// Definitions
const $defsContain = $('<div class="eg-defs"></div>');
pg.defs.forEach(function (d, dIdx) {
const $drow = $('<div class="row" style="align-items:center;"></div>');
const $addDefBtn = $('<button class="entry-mini-btn entry-mini-add" title="' + T.add_def + '">+</button>');
const $rmDefBtn = $('<button class="entry-mini-btn entry-mini-rem" title="' + T.remove_def + '">–</button>');
const $defInput = $('<div style="flex:1"><input type="text" class="eg-def" placeholder="' + T.fill_meaning + '" value="' + htmlEscape(d || "") + '"></div>');
$drow.append($addDefBtn, $rmDefBtn, $defInput);
$defsContain.append($drow);
// disable if only one definition
if (pg.defs.length <= 1) {
$rmDefBtn.prop("disabled", true);
} else {
$rmDefBtn.prop("disabled", false).css("opacity", "1.0");
}
// Def-level events
$addDefBtn.on("click", function (ev) {
ev.preventDefault();
const read = $modal.data("readForm");
if (read) read();
const mdl = $modal.data("model");
mdl.homonyms[hIdx].posGroups[pIdx].defs.splice(dIdx + 1, 0, "");
suppressLangAutofocus = true;
renderModal(mdl);
// Focus new definition input
setTimeout(() => {
const $newDef = $(`.eg-homonym[data-hidx='${hIdx}'] .entry-block[data-pidx='${pIdx}'] .eg-def:eq(${dIdx + 1})`);
if ($newDef.length) justAddedFocus = true;
$newDef.focus();
setTimeout(() => { justAddedFocus = false; }, 200);
}, 100);
});
$rmDefBtn.on("click", function (ev) {
ev.preventDefault();
const read = $modal.data("readForm");
if (read) read();
const mdl = $modal.data("model");
const defsArr = mdl.homonyms[hIdx].posGroups[pIdx].defs;
suppressLangAutofocus = true;
if (defsArr.length > 1) defsArr.splice(dIdx, 1);
else defsArr[0] = "";
renderModal(mdl);
setTimeout(() => {
const $prev = $(`.eg-homonym[data-hidx='${hIdx}'] .entry-block[data-pidx='${pIdx}'] .eg-def:eq(${Math.max(dIdx - 1, 0)})`);
if ($prev.length) $prev.focus();
}, 100);
});
});
// POS-level events
$addPosBtn.on("click", function (ev) {
ev.preventDefault();
const read = $modal.data("readForm");
if (read) read();
const mdl = $modal.data("model");
mdl.homonyms[hIdx].posGroups.splice(pIdx + 1, 0, { pos: "", defs: [""] });
suppressLangAutofocus = true;
renderModal(mdl);
// Focus the new POS dropdown
setTimeout(() => {
const $newPos = $(`.eg-homonym[data-hidx='${hIdx}'] .entry-block[data-pidx='${pIdx + 1}'] .eg-pos`);
if ($newPos.length) justAddedFocus = true;
$newPos.focus();
setTimeout(() => { justAddedFocus = false; }, 200);
}, 100);
});
$rmPosBtn.on("click", function (ev) {
ev.preventDefault();
const read = $modal.data("readForm");
if (read) read();
const mdl = $modal.data("model");
suppressLangAutofocus = true;
if (mdl.homonyms[hIdx].posGroups.length > 1) mdl.homonyms[hIdx].posGroups.splice(pIdx, 1);
else mdl.homonyms[hIdx].posGroups[0] = { pos: "", defs: [""] };
renderModal(mdl);
setTimeout(() => {
const $prev = $(`.eg-homonym[data-hidx='${hIdx}'] .entry-block[data-pidx='${Math.max(pIdx - 1, 0)}'] .eg-pos`).first();
if ($prev.length) $prev.focus();
}, 100);
});
$pblock.append($defsContain);
$posContainer.append($pblock);
});
$hb.append($posContainer);
// Hom-level events
$addHomBtn.on("click", function (ev) {
ev.preventDefault();
const read = $modal.data("readForm");
if (read) read();
const mdl = $modal.data("model");
const insertionIndex = hIdx + 1;
mdl.homonyms.splice(insertionIndex, 0, { num: 0, posGroups: [{ pos: "", defs: [""] }] });
renumberHomonyms(mdl);
suppressLangAutofocus = true;
renderModal(mdl);
// Focus first POS dropdown of new homonym
setTimeout(() => {
const $newPos = $(`.eg-homonym[data-hidx='${insertionIndex}'] .eg-pos`).first();
if ($newPos.length) justAddedFocus = true;
$newPos.focus();
setTimeout(() => { justAddedFocus = false; }, 200);
}, 100);
});
$rmHomBtn.on("click", function (ev) {
ev.preventDefault();
const read = $modal.data("readForm");
if (read) read();
const mdl = $modal.data("model");
suppressLangAutofocus = true;
if (mdl.homonyms.length > 1) {
mdl.homonyms.splice(hIdx, 1);
} else {
mdl.homonyms[0] = { num: 1, posGroups: [ { pos: "", defs: [""] } ] };
}
renumberHomonyms(mdl);
renderModal(mdl);
setTimeout(() => {
const $prev = $(`.eg-homonym[data-hidx='${Math.max(hIdx - 1, 0)}'] .eg-pos`).first();
if ($prev.length) $prev.focus();
}, 100);
});
$homContainer.append($hb);
}); // end homonyms.forEach
// Controls: Preview, Undo, Save, Cancel
const $previewBtn = $('<button class="entry-preview-btn" type="button">' + T.preview + '</button>');
const $undoBtn = $('<button class="entry-undo-btn" type="button" disabled>' + T.undo + '</button>');
const $saveBtn = $('<button class="entry-save-btn" type="button" disabled>' + T.save + '</button>');
const $cancelBtn = $('<button class="entry-cancel-btn" type="button">' + T.cancel + '</button>');
$controls.append($previewBtn, $undoBtn, $saveBtn, $cancelBtn);
$cancelBtn.on("click", function (e) { e.preventDefault(); cancelAndCloseModal(); });
// Read form into model helper
function readFormToModel() {
const mdl = { lang: "", homonyms: [] };
mdl.lang = $modal.find("#eg-lang").val().trim();
$modal.find("#eg-homonyms > .eg-homonym").each(function (hIndex) {
const $hb = $(this);
const homModel = { num: hIndex + 1, posGroups: [] };
$hb.find(".eg-pos-container > .entry-block").each(function (pIndex) {
const $pblock = $(this);
const pos = $pblock.find(".eg-pos").val().trim();
const defs = [];
$pblock.find(".eg-def").each(function () { defs.push($(this).val().trim()); });
homModel.posGroups.push({ pos: pos, defs: defs.length ? defs : [""] });
});
if (homModel.posGroups.length === 0) homModel.posGroups = [ { pos: "", defs: [""] } ];
mdl.homonyms.push(homModel);
});
renumberHomonyms(mdl);
// update modal-stored model so event handlers can use current state
$modal.data("model", mdl);
return mdl;
}
$modal.data("readForm", readFormToModel);
$modal.data("model", model);
// Preview handler
$previewBtn.on("click", function () {
const read = $modal.data("readForm");
if (read) read();
const mdl = $modal.data("model");
if (!mdl.lang) { alert(T.prompt_fill_langcode); return; }
// check at least one pos+definition non-empty
// validation: all visible inputs must be filled
let allFilled = true;
mdl.homonyms.forEach(h => {
h.posGroups.forEach(pg => {
const posFilled = pg.pos && pg.pos.trim().length > 0;
const defsFilled = pg.defs.length > 0 && pg.defs.every(d => d && d.trim().length > 0);
if (!posFilled || !defsFilled) allFilled = false;
});
});
if (!allFilled) {
alert(T.err_fill_all);
return;
}
$previewBtn.prop("disabled", true).text(T.preview_loading);
fetchLatestWikitext().then(function (res) {
const sections = extractLangSections(res.text);
// if language already exists, warn user (since edit-data flow removed)
const existingIdx = sections.findIndex(s => s.code && s.code.toLowerCase() === mdl.lang.toLowerCase());
if (existingIdx >= 0) {
alert(T.err_lang_exists);
$previewBtn.prop("disabled", false).text(T.preview);
return;
}
// push snapshot for undo
appState.htmlStack.push($("#mw-content-text").html() || "");
appState.scrollStack.push($(window).scrollTop());
appState.lastFetchedTimestamp = res.timestamp;
fetchLanguageMap().then(() => {
const updatedSections = insertModelIntoSections(sections, mdl);
appState.currentSections = updatedSections;
appState.newLang = mdl.lang;
const newFull = rebuildFullTextFromSections(res.text, updatedSections);
api.post({
action: "parse",
title: pageName,
text: newFull,
contentmodel: "wikitext",
prop: "text",
format: "json"
}).done(function (resp) {
const html = (resp && resp.parse && resp.parse.text)
? resp.parse.text["*"] || ""
: "";
replacePageContentWith(html);
highlightInserted(mdl.lang);
$undoBtn.prop("disabled", false).css("opacity", "1.0");
$saveBtn.prop("disabled", false).css("opacity", "1.0");
$previewBtn.prop("disabled", false).text(T.preview);
}).fail(function () {
alert(T.err_preview);
$previewBtn.prop("disabled", false).text(T.preview);
});
});
}).catch(function () {
alert(T.err_fetch);
$previewBtn.prop("disabled", false).text(T.preview);
});
});
// Undo handler (Balikin)
$undoBtn.on("click", function () {
if (!appState.htmlStack.length) {
$undoBtn.prop("disabled", true);
$saveBtn.prop("disabled", true);
return;
}
const prevHtml = appState.htmlStack.pop();
const prevScroll = appState.scrollStack.pop();
const $target = $("#mw-content-text");
if ($target.length) {
$target.html(prevHtml);
if (typeof prevScroll === "number") $(window).scrollTop(prevScroll);
}
if (appState.htmlStack.length === 0) {
$undoBtn.prop("disabled", true);
$saveBtn.prop("disabled", true);
} else {
$undoBtn.prop("disabled", false).css("opacity", "1.0");
$saveBtn.prop("disabled", false).css("opacity", "1.0");
}
});
// Save handler
$saveBtn.on("click", function () {
const read = $modal.data("readForm");
if (read) read();
if (!appState.currentSections) {
alert(T.err_no_change);
return;
}
$saveBtn.prop("disabled", true).text(T.save_loading);
fetchLatestWikitext().then(function (res) {
const latestText = res.text;
const latestTimestamp = res.timestamp;
// Rebuild final full text from appState.currentSections but apply to latest text
const newText = normalizeSpacing(
rebuildFullTextFromSections(latestText, appState.currentSections)
);
const lang = appState.newLang || "";
const summary = lang ? `${T.save_summary_prefix} [${lang}]` : T.save_summary_prefix;
api.postWithToken("csrf", {
action: "edit",
title: pageName,
text: newText,
summary: summary,
minor: true,
basetimestamp: latestTimestamp
}).done(function () {
location.reload();
}).fail(function (err) {
const info = err && err.error && err.error.info ? err.error.info : String(err);
alert(T.err_save_prefix + " " + info);
$saveBtn.prop("disabled", false).text(T.save);
});
}).catch(function () {
alert(T.err_fetch);
$saveBtn.prop("disabled", false).text(T.save);
});
});
// Focus language input only once when modal first opens
if (!appState.modalEverOpened) {
setTimeout(() => $modal.find("#eg-lang").focus(), 25);
appState.modalEverOpened = true;
}
// ---------------------
// Keyboard accessibility & shortcuts
// ---------------------
(function setupKeyboard() {
const focusables = () =>
$modal.find('input[type="text"], select').filter(':visible');
function focusNext(current, dir) {
const f = focusables().toArray();
const idx = f.indexOf(current);
if (idx === -1) return;
const next = f[idx + dir];
if (next) next.focus();
}
$modal.on("keydown", function (e) {
const target = e.target;
// Ctrl+Enter => Save
if (e.ctrlKey && e.key === "Enter") {
e.preventDefault();
$modal.find(".entry-save-btn").trigger("click");
return;
}
// Enter in definition input => trigger Preview
if (
e.key === "Enter" &&
$(target).hasClass("eg-def") &&
!e.ctrlKey &&
!e.shiftKey
) {
e.preventDefault();
$modal.find(".entry-preview-btn").trigger("click");
return;
}
// Shift+ArrowDown in definition input => add new definition below
if (e.key === "ArrowDown" && e.shiftKey && $(target).hasClass("eg-def")) {
e.preventDefault();
const $row = $(target).closest(".row");
const hidx = $row.closest(".eg-homonym").data("hidx");
const pidx = $row.closest(".entry-block").data("pidx");
const didx = $row.closest('.eg-defs').find('.row').index($row);
const read = $modal.data("readForm");
if (read) read();
const mdl = $modal.data("model");
suppressLangAutofocus = true;
mdl.homonyms[hidx].posGroups[pidx].defs.splice(didx + 1, 0, "");
renderModal(mdl);
setTimeout(() => {
const newDef = $(
`.eg-homonym[data-hidx='${hidx}'] .entry-block[data-pidx='${pidx}'] .eg-def:eq(${didx + 1})`
).get(0);
if (newDef) {
justAddedFocus = true;
newDef.focus();
setTimeout(() => { justAddedFocus = false; }, 250);
}
}, 100);
return;
}
// Shift+ArrowUp on blank definition line => remove it
if (e.key === "ArrowUp" && e.shiftKey && $(target).hasClass("eg-def")) {
const value = $(target).val().trim();
if (value === "") {
e.preventDefault();
const $row = $(target).closest(".row");
const hidx = $row.closest(".eg-homonym").data("hidx");
const pidx = $row.closest(".entry-block").data("pidx");
const didx = $row.closest('.eg-defs').find('.row').index($row);
const read = $modal.data("readForm");
if (read) read();
const mdl = $modal.data("model");
const defs = mdl.homonyms[hidx].posGroups[pidx].defs;
suppressLangAutofocus = true;
if (defs.length > 1) defs.splice(didx, 1);
else defs[0] = "";
renderModal(mdl);
setTimeout(() => {
const prev = $(
`.eg-homonym[data-hidx='${hidx}'] .entry-block[data-pidx='${pidx}'] .eg-def:eq(${Math.max(didx - 1, 0)})`
).get(0);
if (prev) {
justAddedFocus = true;
prev.focus();
setTimeout(() => { justAddedFocus = false; }, 250);
}
}, 100);
return;
}
}
// Plain ArrowDown/Up navigation between inputs
if ((e.key === "ArrowDown" || e.key === "ArrowUp") && !e.shiftKey && !justAddedFocus) {
e.preventDefault();
focusNext(target, e.key === "ArrowDown" ? +1 : -1);
return;
}
});
})();
return $modal;
}
// Modal openers
function openModalForNew() {
const model = createEmptyModel();
renderModal(model);
}
// Expose debug hooks if needed
window.EntryAdderGadget = {
openNew: openModalForNew,
removeModal: removeModal
};
});
0o2m8v6vduh68ek1sfpf6t5jsyhyf70
Kategori:Lema bahasa Batak Toba
14
271379
1456630
1243883
2026-05-08T09:03:55Z
Dyalim
36280
added [[Category:Bahasa Batak Toba]] using [[Help:Gadget-HotCat|HotCat]]
1456630
wikitext
text/x-wiki
Kategori ini hanya memiliki subkategori berikut.
[[Kategori:Bahasa Batak Toba]]
hif7kt8om2ktpcmgsqdyl5rq728qlge
Pengguna:Malamilai
2
272294
1456603
1283718
2026-05-08T05:44:49Z
Malamilai
47029
1456603
wikitext
text/x-wiki
Hai, orang Benua. Nama penaku sebut saja '''iLai'''. Aku suka menulis segala hal yang terjadi sekarang. Selain itu aku juga suka makan mi ayam yang pentolnya banyak, wan suka kucing yang lucu-lucu.
Pengguna ini adalah peserta pelatihan penyuntingan dasar di WikiLatih Wikiquote pada tanggal 7 Desember 2025 di Banjarmasin.
n8eh8ze3oy2lmrvkjmzmf03mewjtbgl
1456604
1456603
2026-05-08T05:45:59Z
Malamilai
47029
1456604
wikitext
text/x-wiki
Hai, orang Benua. Nama penaku sebut saja '''iLai'''. Aku suka menulis segala hal yang terjadi sekarang. Selain itu aku juga suka makan mi ayam yang pentolnya banyak, wan suka kucing yang lucu-lucu.
https://id.wikipedia.org/wiki/Templat:Peserta_WikiLatih
8ht33i0quvswuhl8englkpk8mmtotva
1456605
1456604
2026-05-08T05:47:29Z
Malamilai
47029
1456605
wikitext
text/x-wiki
Hai, orang Benua. Nama penaku sebut saja '''iLai'''. Aku suka menulis segala hal yang terjadi sekarang. Selain itu aku juga suka makan mi ayam yang pentolnya banyak, wan suka kucing yang lucu-lucu.
hgpimv920wvltukxl4j7mnhbj8iytbl
1456606
1456605
2026-05-08T05:49:29Z
Malamilai
47029
1456606
wikitext
text/x-wiki
Hai, orang Benua. Nama penaku sebut saja '''iLai'''. Aku suka menulis segala hal yang terjadi sekarang. Selain itu aku juga suka makan mi ayam yang pentolnya banyak, wan suka kucing yang lucu-lucu.{{Peserta WikiLatih|tgl=7 Desember 2025|di=Banjarmasin}}
1lp2xhxyefk6u9ggv7hmsfl36u3lkes
1456607
1456606
2026-05-08T05:54:48Z
Malamilai
47029
1456607
wikitext
text/x-wiki
Hai, orang Benua. Nama penaku sebut saja '''iLai'''. Aku suka menulis segala hal yang terjadi sekarang. Selain itu aku juga suka makan mi ayam yang pentolnya banyak, wan suka kucing yang lucu-lucu.
{{Peserta WikiLatih|tgl=7 Desember 2025|di=Banjarmasin}}
{{Peserta WikiTutur|tgl=14 Februari 2026|di=Banjarmasin}}
qh1xm2l9qnd3ou7y3ufy0rwjk68zq3n
1456608
1456607
2026-05-08T05:56:25Z
Malamilai
47029
1456608
wikitext
text/x-wiki
Hai, semuanya. Nama penaku sebut saja '''iLai'''. Aku suka menulis segala hal yang terjadi sekarang. Selain itu, aku suka makan mi ayam yang pentolnya banyak, dan suka kucing yang lucu-lucu.
{{Peserta WikiLatih|tgl=7 Desember 2025|di=Banjarmasin}}
{{Peserta WikiTutur|tgl=14 Februari 2026|di=Banjarmasin}}
ijo78s73njbae3jzfrmb9x70rfdm7mt
1456609
1456608
2026-05-08T06:04:15Z
Malamilai
47029
1456609
wikitext
text/x-wiki
Hai, semuanya. Nama penaku sebut saja '''iLai'''. Aku suka menulis segala hal yang terjadi sekarang. Selain itu, aku suka makan mi ayam yang pentolnya banyak, dan suka kucing yang lucu-lucu.
bbjru9f2iy40qbea6dkgywibfloo1h0
balampas
0
351251
1456611
2026-05-08T07:35:10Z
Wadaihangit
33201
[[:wikt:id:Pengguna:Swarabakti/Gadget-EntryAdder.js|+entri]] [bjn]
1456611
wikitext
text/x-wiki
=={{bahasa|bjn}}==
{{kepala|bjn}}
{{-v-|bjn}}
# tidur di lantai tanpa kasur atau alas
45wj1opuf93qw3u781v51i76vqkxz40
wili
0
351252
1456613
2026-05-08T08:26:13Z
Dyalim
36280
←Membuat halaman berisi '=={{bahasa|btx}}== {{kepala|btx}} {{-n-|btx}} # [[babi hutan]] #: {{ux|btx|melala wili i kuta kami|banyak babi hutan di kampung kami}} [[Kategori:Wiki - Karo]] [[Kategori:Kopdar WikiKaro 10 Mei 2026]]'
1456613
wikitext
text/x-wiki
=={{bahasa|btx}}==
{{kepala|btx}}
{{-n-|btx}}
# [[babi hutan]]
#: {{ux|btx|melala wili i kuta kami|banyak babi hutan di kampung kami}}
[[Kategori:Wiki - Karo]]
[[Kategori:Kopdar WikiKaro 10 Mei 2026]]
3v37zu9z6ndwavcovix6p6qd9fkmswk
1456614
1456613
2026-05-08T08:31:53Z
Dyalim
36280
1456614
wikitext
text/x-wiki
=={{bahasa|btx}}==
{{kepala|btx}}
[[Berkas:Babi Hutan|jmpl| [[File:Wild boar (Sus scrofa vittatus) juvenile.jpg|Wild_boar_(Sus_scrofa_vittatus)_juvenile]]]]
{{-n-|btx}}
# [[babi hutan]]
#: {{ux|btx|melala wili i kuta kami|banyak babi hutan di kampung kami}}
[[Kategori:Wiki - Karo]]
[[Kategori:Kopdar WikiKaro 10 Mei 2026]]
go4vjrhpd0e2bzyhmn6aql24ydc7m5i
1456615
1456614
2026-05-08T08:33:55Z
Dyalim
36280
1456615
wikitext
text/x-wiki
=={{bahasa|btx}}==
{{kepala|btx}}
[[Berkas:Babi Hutan|jmpl| [[File:Wild boar (Sus scrofa vittatus) juvenile.jpg|Wild_boar_(Sus_scrofa_vittatus)_juvenile]]]]
{{-n-|btx}}
# [[babi hutan]]
#: {{ux|btx|melala '''wili''' i kuta kami|banyak ''babi hutan'' di kampung kami}}
[[Kategori:Wiki - Karo]]
[[Kategori:Kopdar WikiKaro 10 Mei 2026]]
edhpxi8z354qtcl12erlm2nmaukf835
1456639
1456615
2026-05-08T09:19:32Z
Dyalim
36280
1456639
wikitext
text/x-wiki
=={{bahasa|btx}}==
{{kepala|btx}}
[[Berkas:Babi Hutan|jmpl| [[File:Wild boar (Sus scrofa vittatus) juvenile.jpg|Wild_boar_(Sus_scrofa_vittatus)_juvenile]]]]
{{-n-|btx}}
# [[babi hutan]]
#: {{ux|btx|melala '''wili''' i kuta kami|banyak ''babi hutan'' di kampung kami}}
[[Kategori:WikiKaro]]
[[Kategori:Kopdar WikiKaro 10 Mei 2026]]
pmv558j5mz3y0chiudfuwo4qziyr0sf
Kategori:bbc:Istilah dengan contoh kalimat
14
351253
1456616
2026-05-08T08:44:09Z
Dyalim
36280
←Membuat halaman berisi 'Halaman kategori ini memuat daftar istilah dengan contoh kalimat pada bahasa Batak Toba.'
1456616
wikitext
text/x-wiki
Halaman kategori ini memuat daftar istilah dengan contoh kalimat pada bahasa Batak Toba.
eqbtgzenrgel1xf03ap9xrzqtq7cny4
1456638
1456616
2026-05-08T09:17:01Z
Dyalim
36280
added [[Category:Bahasa Batak Toba]] using [[Help:Gadget-HotCat|HotCat]]
1456638
wikitext
text/x-wiki
Halaman kategori ini memuat daftar istilah dengan contoh kalimat pada bahasa Batak Toba.
[[Kategori:Bahasa Batak Toba]]
h86x5cnj1i01casv6hf8uz7hkpxsznl
Kategori:btx:Istilah dengan contoh kalimat
14
351254
1456617
2026-05-08T08:45:33Z
Dyalim
36280
←Membuat halaman berisi 'Halaman kategori ini memuat daftar istilah dengan contoh kalimat pada bahasa Batak Karo.'
1456617
wikitext
text/x-wiki
Halaman kategori ini memuat daftar istilah dengan contoh kalimat pada bahasa Batak Karo.
nhk47ghxrw9bmw49ifezzib0h3oq2az
1456636
1456617
2026-05-08T09:09:13Z
Dyalim
36280
added [[Category:Bahasa Karo]] using [[Help:Gadget-HotCat|HotCat]]
1456636
wikitext
text/x-wiki
Halaman kategori ini memuat daftar istilah dengan contoh kalimat pada bahasa Batak Karo.
[[Kategori:Bahasa Karo]]
evmnc0ns9v8fhbn3yuvi50a10cxiku2
Kategori:Kata bahasa Karo
14
351256
1456619
2026-05-08T08:51:33Z
Dyalim
36280
←Membuat halaman berisi 'Berikut ini adalah kata-kata dalam bahasa Karo yang sudah ada di Wikikamus. Silakan tuju ke kategori yang lebih spesifik untuk memperoleh daftar kata menurut kelas kata masing-masing. {{kat:kata bahasa|Karo}}'
1456619
wikitext
text/x-wiki
Berikut ini adalah kata-kata dalam bahasa Karo yang sudah ada di Wikikamus. Silakan tuju ke kategori yang lebih spesifik untuk memperoleh daftar kata menurut kelas kata masing-masing.
{{kat:kata bahasa|Karo}}
sda8ptxwg3hm2wd5j9ayg768ciw9eol
1456620
1456619
2026-05-08T08:52:05Z
Dyalim
36280
added [[Category:Kata bahasa daerah di Indonesia]] using [[Help:Gadget-HotCat|HotCat]]
1456620
wikitext
text/x-wiki
Berikut ini adalah kata-kata dalam bahasa Karo yang sudah ada di Wikikamus. Silakan tuju ke kategori yang lebih spesifik untuk memperoleh daftar kata menurut kelas kata masing-masing.
{{kat:kata bahasa|Karo}}
[[Kategori:Kata bahasa daerah di Indonesia]]
6t7ld1dtrvver6jmfl2fdxw0k501dc8
1456625
1456620
2026-05-08T08:59:16Z
Dyalim
36280
1456625
wikitext
text/x-wiki
{{kat:kata bahasa|Karo}}
[[Kategori:Kata bahasa daerah di Indonesia]]
ow1gnpwfm1vtln2fs32n701z4ra2x9k
1456627
1456625
2026-05-08T09:02:00Z
Dyalim
36280
added [[Category:Bahasa Karo]] using [[Help:Gadget-HotCat|HotCat]]
1456627
wikitext
text/x-wiki
{{kat:kata bahasa|Karo}}
[[Kategori:Kata bahasa daerah di Indonesia]]
[[Kategori:Bahasa Karo]]
4rr9cmozpkivdoruybc0bes56nkaw48
Kategori:Lema bahasa Karo
14
351257
1456628
2026-05-08T09:03:10Z
Dyalim
36280
←Membuat halaman berisi 'Kategori ini hanya memiliki subkategori berikut.'
1456628
wikitext
text/x-wiki
Kategori ini hanya memiliki subkategori berikut.
c38diznk4ucv12zpsto7wahca9vwu1i
1456629
1456628
2026-05-08T09:03:31Z
Dyalim
36280
added [[Category:Bahasa Karo]] using [[Help:Gadget-HotCat|HotCat]]
1456629
wikitext
text/x-wiki
Kategori ini hanya memiliki subkategori berikut.
[[Kategori:Bahasa Karo]]
nxvzu3endren8gx5nydw254zc835h2f
1456633
1456629
2026-05-08T09:07:49Z
Dyalim
36280
removed [[Category:Bahasa Karo]] using [[Help:Gadget-HotCat|HotCat]]
1456633
wikitext
text/x-wiki
Kategori ini hanya memiliki subkategori berikut.
c38diznk4ucv12zpsto7wahca9vwu1i
1456634
1456633
2026-05-08T09:08:00Z
Dyalim
36280
added [[Category:Lema menurut bahasa]] using [[Help:Gadget-HotCat|HotCat]]
1456634
wikitext
text/x-wiki
Kategori ini hanya memiliki subkategori berikut.
[[Kategori:Lema menurut bahasa]]
hy26q7aweujf3u3ioh0pyryb6ykbt2b
1456635
1456634
2026-05-08T09:08:11Z
Dyalim
36280
added [[Category:Bahasa Karo]] using [[Help:Gadget-HotCat|HotCat]]
1456635
wikitext
text/x-wiki
Kategori ini hanya memiliki subkategori berikut.
[[Kategori:Lema menurut bahasa]]
[[Kategori:Bahasa Karo]]
icp86bmi7i7xqfrrpaxuuf7l1kb64n9
Kategori:Kelas kata bahasa Karo
14
351258
1456637
2026-05-08T09:13:42Z
Dyalim
36280
←Membuat halaman berisi '[[Kategori:Kelas kata menurut bahasa|Karo]] [[Kategori:Bahasa Karo]]'
1456637
wikitext
text/x-wiki
[[Kategori:Kelas kata menurut bahasa|Karo]]
[[Kategori:Bahasa Karo]]
gwyk7hnx64aju6z7y0nl8rj3f9ghr2f